This question was originally posted in wordpress.stackexchange , but deemed to be off-topic for some reason, so I'm posting here per the suggestion in the ruling comment.
I've created an AJAX taxonomy( product_cat
) filter that's used on my WooCommerce product archive page ( archive-product.php
). The page loads the normal WooCommerce shop loop onload:
woocommerce_product_loop_start();
if (wc_get_loop_prop('total')) {
while (have_posts()) {
the_post();
/**
* Hook: woocommerce_shop_loop.
*
* @hooked WC_Structured_Data::generate_product_data() - 10
*/
do_action('woocommerce_shop_loop');
wc_get_template_part('content', 'product');
}
}
woocommerce_product_loop_end();
That page loads correctly, showing all products. The filter also works great. It filters one or more taxonomies correctly.
The problem is when I uncheck all the checkboxes. I want it to clear any filters and show all products again. Instead, I currently get an error:
POST .../wp-admin/admin-ajax.php 500
The relevant product filter js:
function handleFilterCheckboxesChange(event) {
const data = {
action: 'wpf_update_products',
filters: get_current_filters()
};
$.ajax({
type: 'POST',
url: '/wp-admin/admin-ajax.php',
data: data,
success: function (res) {
console.log("AJAX Success: ", data.filters);
// > ["example_category_slug"]
$('.products').html(res);
},
error: function (err) {
console.error("AJAX Error: ", data.filters);
// > []
}
});
$(document.body).trigger('post-load');
}
function get_current_filters() {
const checkboxes = $('.product-cat-filter-checkbox').get();
let checked = [];
for (let i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked) {
checked.push(checkboxes[i].id);
};
}
return checked;
}
The server-side action:
function wpf_update_products() {
$filter_terms = $_POST['filters'];
$args = [
'post_type' => 'product',
'posts_per_page' => 20,
'post_status' => 'publish',
];
// I expect the next line to check for empty filter terms and "reset"/skip this tax_query, but I still get a 500 error
if ($filter_terms !== null && isset($filter_terms) && $filter_terms !== '' && !empty($filter_terms)) {
$args['tax_query'][] = [
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $_POST['filters']
];
}
$ajax_query = new WP_Query($args);
$response = '';
if ($ajax_query->have_posts()) {
ob_start();
while ($ajax_query->have_posts()) : $ajax_query->the_post();
$response .= wc_get_template_part('content', 'product');
endwhile;
$output = ob_get_contents();
ob_end_clean();
wp_reset_postdata();
} else {
echo __('Sorry, there are no products that fit your query.', 'wpf');
}
echo $output;
die();
}
...hooked from the same class:
add_action('wp_ajax_wpf_update_products', array($this, 'wpf_update_products'));
add_action('wp_ajax_nopriv_wpf_update_products', array($this, 'wpf_update_products'));
When I var_dump the query on successful filtering, it correctly shows the added tax_query, but I'm unable to dump the query on unsuccessful [empty] filtering because the server responds with 500.
Can't figure out why it's returning the error if I'm handling the empty $_POST['filters']
on the server side. Can anyone see what I'm missing?
UPDATE: I added an else to the server-side query, and was able to get around the 500 error. The updated if
statement to set the filter query args is:
if ($filter_terms !== null && isset($filter_terms) && $filter_terms !== '' && !empty($filter_terms)) {
$args['tax_query'][] = [
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $filter_terms
];
} else {
$args['tax_query'][] = [
'taxonomy' => 'product_cat'
];
}
Now, the query tries to run, but I get the 'Sorry, there are no products that fit your query.'
statement because no posts were found. WP_Query
doesn't seem to like a tax_query
with only the taxonomy
set. I var_dumped the query and see that the tax_query
is filled correctly with the three args when a filter is checked:
'tax_query' =>
array (size=1)
0 =>
array (size=3)
...
...and when all filters become unchecked, the tax_query
has the one 'taxonomy' => 'product_cat'
arg:
'tax_query' =>
array (size=1)
0 =>
array (size=1)
...
I just can't seem to clear the tax_query
if filters is empty. With the original code—no else
statement if filters is empty—I just got the 500 error, but even if my else statement sets the tax_query
completely empty like so: $args['tax_query'][] = []
, it still throws the 500 error. Why doesn't WP fall back to the rest of the original query if tax_query
is empty?
And finally, I also tried setting the query args manually to all possible taxonomy terms like so:
if ($filter_terms !== null && isset($filter_terms) && $filter_terms !== '' && !empty($filter_terms)) {
$args['tax_query'][] = [
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $filter_terms
];
} else {
$all_terms = get_terms(array('taxonomy' => 'product_cat', 'fields' => 'slugs'));
$args['tax_query'][] = [
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $all_terms
];
}
...but I just get the 500 error again:/ Dumping $all_terms
gives me this, a list of all terms that contain any products:
array (size=4)
0 => string 'bakeware' (length=8)
1 => string 'cookware' (length=8)
2 => string 'cutlery-kitchen-tools' (length=21)
3 => string 'linens' (length=6)
I don't see the $filter_terms
variable being set within the scope of your wpf_update_products()
function. If I'm understanding the intent of your code correctly, try the following:
// I expect the next line to check for empty filter terms and "reset"/skip this tax_query, but I still get a 500 error
if ( ! empty( $_POST['filters'] ) ) {
$args['tax_query'][] = [
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $_POST['filters']
];
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.