Custom search query - php

I've made a custom search form, a query using a custom post type with categories, custom taxonomy and meta fields and a search template for displaying them but cannot get the results to show. I'm using Wordpress. I've changed the way to make the query using pre_get_posts but have trouble now how to display the result. All variables are passed into query_vars.
Below is my code:
function my_get_posts( $query ) {
if ( is_admin() || ! $query->is_main_query() )
return;
if (is_home() || is_search() || is_archive() || is_page( 'search' ) )
{
$query->set('post_type', 'yacht');
$query->set('posts_per_page', 1000);
$query->set('s', '' );
$meta_query = array();
$meta_query[] = array(
array(
'key' => 'yachts_length',
'value' => array($_GET['min_length'], $_GET['max_length']),
'compare' => 'BETWEEN',
'type' => 'NUMERIC',
),
array(
'key' => 'yachts_price',
'value' => array($_GET['min_price'], $_GET['max_price']),
'compare' => 'BETWEEN',
'type' => 'NUMERIC',
),
array(
'key' => 'yachts_year',
'value' => array($_GET['min_year'], $_GET['max_year']),
'compare' => 'BETWEEN',
'type' => 'NUMERIC',
)
);
$meta_query['relation'] = 'AND';
$query->set('meta_query',$meta_query);
}
return $query;
}
add_action( 'pre_get_posts', 'my_get_posts');
And the query_vars output using the form:
Array
(
[cat] => 0
[page] => 0
[pagename] => search
[manufacturer] => 0
[min_length] => 3
[max_length] => 100
[min_price] => 500
[max_price] => 999999
[min_year] => 1970
[max_year] => 2015
[error] =>
[m] =>
[p] => 0
[post_parent] =>
[subpost] =>
[subpost_id] =>
[attachment] =>
[attachment_id] => 0
[name] => search
[static] =>
[page_id] => 0
[second] =>
[minute] =>
[hour] =>
[day] => 0
[monthnum] => 0
[year] => 0
[w] => 0
[category_name] =>
[tag] =>
[tag_id] =>
[author] =>
[author_name] =>
[feed] =>
[tb] =>
[paged] => 0
[comments_popup] =>
[meta_key] =>
[meta_value] =>
[preview] =>
[s] =>
[sentence] =>
[fields] =>
[menu_order] =>
[category__in] => Array
(
)
[category__not_in] => Array
(
)
[category__and] => Array
(
)
[post__in] => Array
(
)
[post__not_in] => Array
(
)
[tag__in] => Array
(
)
[tag__not_in] => Array
(
)
[tag__and] => Array
(
)
[tag_slug__in] => Array
(
)
[tag_slug__and] => Array
(
)
[post_parent__in] => Array
(
)
[post_parent__not_in] => Array
(
)
[author__in] => Array
(
)
[author__not_in] => Array
(
)
[orderby] => menu_order
[order] => ASC
[post_type] => yacht
[posts_per_page] => 1000
[meta_query] => Array
(
[0] => Array
(
[0] => Array
(
[key] => yachts_length
[value] => Array
(
[0] => 3
[1] => 100
)
[compare] => BETWEEN
[type] => NUMERIC
)
[1] => Array
(
[key] => yachts_price
[value] => Array
(
[0] => 500
[1] => 999999
)
[compare] => BETWEEN
[type] => NUMERIC
)
[2] => Array
(
[key] => yachts_year
[value] => Array
(
[0] => 1970
[1] => 2015
)
[compare] => BETWEEN
[type] => NUMERIC
)
)
[relation] => AND
)
[ignore_sticky_posts] =>
[suppress_filters] =>
[cache_results] => 1
[update_post_term_cache] => 1
[update_post_meta_cache] => 1
[nopaging] =>
[comments_per_page] => 50
[no_found_rows] =>
)

Related

Unexpected php usort result

I have an array with files. And I want to sort them by their min value (I'll explain below).
This is an example of array:
$files = array(
array(
'name' => "DevTools/tools/files/design/js/custom/http_build_query.js",
'range' => array(
'min' => 0
)
),
array(
'name' => "DevTools/tools/files/design/js/custom/Form.js",
'range' => array(
'min' => 0
)
),
array(
'name' => "DevTools/tools/files/design/js/custom/VanillaJS.js",
'range' => array(
'min' => 0
)
),
array(
'name' => "resources/js/plugins/jquery.js"
),
array(
'name' => "resources/js/plugins/jquery-ui.js"
),
array(
'name' => "resources/js/plugins/popper.js"
),
array(
'name' => "resources/js/plugins/bootstrap-v4/index.js",
'range' => array(
'min' => 800
)
),
array(
'name' => "resources/js/plugins/bootstrap-v4/util.js",
'range' => array(
'min' => 0
)
),
array(
'name' => "resources/js/plugins/bootstrap-v4/dropdown.js",
'range' => array(
'min' => 200
)
),
array(
'name' => "resources/js/plugins/bootstrap-v4/collapse.js",
'range' => array(
'min' => 0
)
),
array(
'name' => "resources/js/custom/global.js"
),
array(
'name' => "layouts/cms/.js/+0.js",
'range' => array(
'min' => 0
)
),
array(
'name' => "resources/js/plugins/module/delete.js"
),
array(
'name' => "resources/js/plugins/module/form.submit.js"
),
array(
'name' => "resources/js/plugins/module/piece.image.js"
),
array(
'name' => "resources/js/plugins/select2.js"
)
);
It's easy to understand. We have names for all files. And some of them have [range][min].
What I need to do is keeping their order, but sorting only files from same folder which have the [range][min], so we reorder these ones by [min].
My code
So I use this function:
usort($files, function (array $a, array $b) {
if (!isset($a['range']) || !isset($b['range'])
|| dirname($a['name']) != dirname($b['name'])
|| $a['range']['min'] == $b['range']['min']) {
return 0;
}
return $a['range']['min'] <=> $b['range']['min'];
});
Which does exactly what I said above. So only those ones are correcly reordered, as you can see here:
[6] => Array
(
[name] => resources/js/plugins/bootstrap-v4/util.js
[range] => Array
(
[min] => 0
)
)
[7] => Array
(
[name] => resources/js/plugins/bootstrap-v4/collapse.js
[range] => Array
(
[min] => 0
)
)
[8] => Array
(
[name] => resources/js/plugins/bootstrap-v4/dropdown.js
[range] => Array
(
[min] => 200
)
)
[9] => Array
(
[name] => resources/js/plugins/bootstrap-v4/index.js
[range] => Array
(
[min] => 800
)
)
Which is great.
The problem
Now I add in my $files array this one:
array(
'name' => "resources/js/plugins/module/piece.images.js"
)
Append it anywhere you want in $files, the usort will reorder entire array with no logic:
Array
(
[0] => Array
(
[name] => DevTools/tools/files/design/js/custom/http_build_query.js
[range] => Array
(
[min] => 0
)
)
[1] => Array
(
[name] => resources/js/plugins/bootstrap-v4/collapse.js
[range] => Array
(
[min] => 0
)
)
[2] => Array
(
[name] => resources/js/plugins/select2.js
)
[3] => Array
(
[name] => resources/js/plugins/module/piece.image.js
)
[4] => Array
(
[name] => resources/js/plugins/module/form.submit.js
)
[5] => Array
(
[name] => resources/js/plugins/module/delete.js
)
[6] => Array
(
[name] => layouts/cms/.js/+0.js
[range] => Array
(
[min] => 0
)
)
[7] => Array
(
[name] => resources/js/plugins/bootstrap-v4/util.js
[range] => Array
(
[min] => 0
)
)
[8] => Array
(
[name] => resources/js/custom/global.js
)
[9] => Array
(
[name] => resources/js/plugins/bootstrap-v4/dropdown.js
[range] => Array
(
[min] => 200
)
)
[10] => Array
(
[name] => DevTools/tools/files/design/js/custom/Form.js
[range] => Array
(
[min] => 0
)
)
[11] => Array
(
[name] => resources/js/plugins/bootstrap-v4/index.js
[range] => Array
(
[min] => 800
)
)
[12] => Array
(
[name] => resources/js/plugins/popper.js
)
[13] => Array
(
[name] => resources/js/plugins/jquery-ui.js
)
[14] => Array
(
[name] => resources/js/plugins/jquery.js
)
[15] => Array
(
[name] => DevTools/tools/files/design/js/custom/VanillaJS.js
[range] => Array
(
[min] => 0
)
)
[16] => Array
(
[name] => resources/js/plugins/module/piece.images.js
)
)
I have no idea why is that happening. If you can find out why, can you please see if there is a solution please?
If I didn't explain well, please ask in comments for clarification.
So, what I need to do is keeping their order, but sorting only files from same folder which have the [range][min], so we reorder these ones by [min].

Woocommerce: filter by attribute

I'm currently working on woocommerce, to make an specific request before displaying products. I'm using for that the hook woocommerce_product_query that is executed before the request is done in the class WC_Query in product_query method.
I can access the variable $q (query object), example bellow:
Now I would like to know how to filter this request by some custom attributes. I thought that would be something like that, but nothing is working maybe you could explain why.
add_action( 'woocommerce_product_query', 'filter_products_by_brand' );
function filter_products_by_brand( WP_Query $q ) {
$tax_query = (array) $q->get( 'tax_query' );
$tax_query[] = array(
'taxonomy' => 'cb-brand',
'field' => 'slug',
'terms' => array( 'jeep' ),
'operator' => 'IN'
);
$q->set( 'tax_query', $tax_query );
}
WP_Query Object
(
[query] => Array
(
[product_cat] => accessoires-2/attelages/faisceaux
)
[query_vars] => Array
(
[product_cat] => faisceaux
[error] =>
[m] =>
[p] => 0
[post_parent] =>
[subpost] =>
[subpost_id] =>
[attachment] =>
[attachment_id] => 0
[name] =>
[pagename] =>
[page_id] => 0
[second] =>
[minute] =>
[hour] =>
[day] => 0
[monthnum] => 0
[year] => 0
[w] => 0
[category_name] =>
[tag] =>
[cat] =>
[tag_id] =>
[author] =>
[author_name] =>
[feed] =>
[tb] =>
[paged] => 0
[meta_key] =>
[meta_value] =>
[preview] =>
[s] =>
[sentence] =>
[title] =>
[fields] =>
[menu_order] =>
[embed] =>
[category__in] => Array
(
)
[category__not_in] => Array
(
)
[category__and] => Array
(
)
[post__in] => Array
(
)
[post__not_in] => Array
(
)
[post_name__in] => Array
(
)
[tag__in] => Array
(
)
[tag__not_in] => Array
(
)
[tag__and] => Array
(
)
[tag_slug__in] => Array
(
)
[tag_slug__and] => Array
(
)
[post_parent__in] => Array
(
)
[post_parent__not_in] => Array
(
)
[author__in] => Array
(
)
[author__not_in] => Array
(
)
[orderby] => menu_order title
[order] => ASC
[meta_query] => Array
(
)
[tax_query] => Array
(
[relation] => AND
[0] => Array
(
[taxonomy] => product_visibility
[field] => term_taxonomy_id
[terms] => Array
(
[0] => 7
)
[operator] => NOT IN
)
)
[wc_query] => product_query
[posts_per_page] => 16
)
[tax_query] => WP_Tax_Query Object
(
[queries] => Array
(
[0] => Array
(
[taxonomy] => product_cat
[terms] => Array
(
[0] => faisceaux
)
[field] => slug
[operator] => IN
[include_children] => 1
)
)
[relation] => AND
[table_aliases:protected] => Array
(
)
[queried_terms] => Array
(
[product_cat] => Array
(
[terms] => Array
(
[0] => faisceaux
)
[field] => slug
)
)
[primary_table] =>
[primary_id_column] =>
)
[meta_query] =>
[date_query] =>
[queried_object] => WP_Term Object
(
[term_id] => 108
[name] => Faisceaux
[slug] => faisceaux
[term_group] => 0
[term_taxonomy_id] => 108
[taxonomy] => product_cat
[description] =>
[parent] => 106
[count] => 1
[filter] => raw
)
[queried_object_id] => 108
[post_count] => 0
[current_post] => -1
[in_the_loop] =>
[comment_count] => 0
[current_comment] => -1
[found_posts] => 0
[max_num_pages] => 0
[max_num_comment_pages] => 0
[is_single] =>
[is_preview] =>
[is_page] =>
[is_archive] => 1
[is_date] =>
[is_year] =>
[is_month] =>
[is_day] =>
[is_time] =>
[is_author] =>
[is_category] =>
[is_tag] =>
[is_tax] => 1
[is_search] =>
[is_feed] =>
[is_comment_feed] =>
[is_trackback] =>
[is_home] =>
[is_privacy_policy] =>
[is_404] =>
[is_embed] =>
[is_paged] =>
[is_admin] =>
[is_attachment] =>
[is_singular] =>
[is_robots] =>
[is_favicon] =>
[is_posts_page] =>
[is_post_type_archive] =>
[query_vars_hash:WP_Query:private] => a80e55b982d04f2e0de36fdd19a948d6
[query_vars_changed:WP_Query:private] =>
[thumbnails_cached] =>
[stopwords:WP_Query:private] =>
[compat_fields:WP_Query:private] => Array
(
[0] => query_vars_hash
[1] => query_vars_changed
)
[compat_methods:WP_Query:private] => Array
(
[0] => init_query_flags
[1] => parse_tax_query
)
)
Thanks.
If anyone wants to know.
To make an filter based on an attributes :
add_filter('woocommerce_product_query_tax_query', 'custom_product_query_meta_query', 10, 2);
function custom_product_query_meta_query( $tax_query, $query ) {
$taxonomy = 'pa_${NAME OF THE ATTRIBUTE}'; // Note: always start with "pa_" in Woocommerce
$tax_query[] = array(
'taxonomy' => $taxonomy,
'field' => 'name', // name or slug
'terms' => array( '1S026015002003' ),
'operator' => 'IN',
);
return $tax_query;
}

Using Dynamic multiple attributes With WP_Query

I have a form from where clicks on the attribute and based on that click, I change my query to fetch relevant results
Below Array is generated dynamically based on user selection
Array
(
[tax_query] => Array
(
[0] => Array
(
[taxonomy] => pa_timing
[field] => slug
[terms] => Array
(
[0] => day
)
)
[1] => Array
(
[taxonomy] => pa_size
[fields] => slug
[terms] => Array
(
[0] => s
)
)
)
[post_type] => product
[post_status] => publish
[product_cat] => pads
[posts_per_page] => -1
)
Based on the above array WP_Query generated
SELECT vsrc_posts.* FROM vsrc_posts LEFT JOIN vsrc_term_relationships ON (vsrc_posts.ID = vsrc_term_relationships.object_id) LEFT JOIN vsrc_term_relationships AS tt1 ON (vsrc_posts.ID = tt1.object_id) LEFT JOIN vsrc_term_relationships AS tt2 ON (vsrc_posts.ID = tt2.object_id) WHERE 1=1 AND (
vsrc_term_relationships.term_taxonomy_id IN (351)
AND
tt1.term_taxonomy_id IN (259,263,274,314)
AND
tt2.term_taxonomy_id IN (348)
) AND vsrc_posts.post_type = 'product' AND ((vsrc_posts.post_status = 'publish')) GROUP BY vsrc_posts.ID ORDER BY vsrc_posts.post_date DESC
Array
(
[tax_query] => Array
(
[0] => Array
(
[taxonomy] => pa_timing
[field] => slug
[terms] => Array
(
[0] => day
)
)
[1] => Array
(
[taxonomy] => pa_size
[fields] => slug
[terms] => Array
(
[0] => s
)
)
)
[post_type] => product
[post_status] => publish
[posts_per_page] => -1
[product_cat] => pads
[error] =>
[m] =>
[p] => 0
[post_parent] =>
[subpost] =>
[subpost_id] =>
[attachment] =>
[attachment_id] => 0
[name] =>
[static] =>
[pagename] =>
[page_id] => 0
[second] =>
[minute] =>
[hour] =>
[day] => 0
[monthnum] => 0
[year] => 0
[w] => 0
[category_name] =>
[tag] =>
[cat] =>
[tag_id] =>
[author] =>
[author_name] =>
[feed] =>
[tb] =>
[paged] => 0
[meta_key] =>
[meta_value] =>
[preview] =>
[s] =>
[sentence] =>
[title] =>
[fields] =>
[menu_order] =>
[embed] =>
[category__in] => Array
(
)
[category__not_in] => Array
(
)
[category__and] => Array
(
)
[post__in] => Array
(
)
[post__not_in] => Array
(
)
[post_name__in] => Array
(
)
[tag__in] => Array
(
)
[tag__not_in] => Array
(
)
[tag__and] => Array
(
)
[tag_slug__in] => Array
(
)
[tag_slug__and] => Array
(
)
[post_parent__in] => Array
(
)
[post_parent__not_in] => Array
(
)
[author__in] => Array
(
)
[author__not_in] => Array
(
)
[ignore_sticky_posts] =>
[suppress_filters] =>
[cache_results] => 1
[update_post_term_cache] => 1
[lazy_load_term_meta] => 1
[update_post_meta_cache] => 1
[nopaging] => 1
[comments_per_page] => 50
[no_found_rows] =>
[taxonomy] => pa_timing
[term] => day
[order] => DESC
)
But when I just hardcode the array and pass it to WP_Query it produces
SELECT vsrc_posts.* FROM vsrc_posts LEFT JOIN vsrc_term_relationships ON (vsrc_posts.ID = vsrc_term_relationships.object_id) LEFT JOIN vsrc_term_relationships AS tt1 ON (vsrc_posts.ID = tt1.object_id) LEFT JOIN vsrc_term_relationships AS tt2 ON (vsrc_posts.ID = tt2.object_id) WHERE 1=1 AND (
vsrc_term_relationships.term_taxonomy_id IN (351)
AND
tt1.term_taxonomy_id IN (274)
AND
tt2.term_taxonomy_id IN (348)
) AND vsrc_posts.post_type = 'product' AND ((vsrc_posts.post_status = 'publish')) GROUP BY vsrc_posts.ID ORDER BY vsrc_posts.post_date DESC
Array
(
[tax_query] => Array
(
[0] => Array
(
[taxonomy] => pa_timing
[field] => slug
[terms] => Array
(
[0] => day
)
)
[1] => Array
(
[taxonomy] => pa_size
[field] => slug
[terms] => Array
(
[0] => s
)
)
)
[post_type] => product
[post_status] => publish
[posts_per_page] => -1
[product_cat] => pads
[error] =>
[m] =>
[p] => 0
[post_parent] =>
[subpost] =>
[subpost_id] =>
[attachment] =>
[attachment_id] => 0
[name] =>
[static] =>
[pagename] =>
[page_id] => 0
[second] =>
[minute] =>
[hour] =>
[day] => 0
[monthnum] => 0
[year] => 0
[w] => 0
[category_name] =>
[tag] =>
[cat] =>
[tag_id] =>
[author] =>
[author_name] =>
[feed] =>
[tb] =>
[paged] => 0
[meta_key] =>
[meta_value] =>
[preview] =>
[s] =>
[sentence] =>
[title] =>
[fields] =>
[menu_order] =>
[embed] =>
[category__in] => Array
(
)
[category__not_in] => Array
(
)
[category__and] => Array
(
)
[post__in] => Array
(
)
[post__not_in] => Array
(
)
[post_name__in] => Array
(
)
[tag__in] => Array
(
)
[tag__not_in] => Array
(
)
[tag__and] => Array
(
)
[tag_slug__in] => Array
(
)
[tag_slug__and] => Array
(
)
[post_parent__in] => Array
(
)
[post_parent__not_in] => Array
(
)
[author__in] => Array
(
)
[author__not_in] => Array
(
)
[ignore_sticky_posts] =>
[suppress_filters] =>
[cache_results] => 1
[update_post_term_cache] => 1
[lazy_load_term_meta] => 1
[update_post_meta_cache] => 1
[nopaging] => 1
[comments_per_page] => 50
[no_found_rows] =>
[taxonomy] => pa_timing
[term] => day
[order] => DESC
)
Which I expect WP_Query to produce. the problem is that WP_query is not producing for the dynamic query. Is there something I am missing
$dayArg = array(
'tax_query' => array(
array(
'taxonomy' => 'pa_timing',
'field' => 'slug',
'terms' => array( 'day' )
),
array(
'taxonomy' => 'pa_size',
'field' => 'slug',
'terms' => array( 's' )
)
),
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => - 1,
'product_cat' => 'pads'
)
This is argument I am passing to WP_Query one generating dynamically and one hardcoding it.

Incorrect posts showing through WP-Query on WooCommerce

So basically I am using the following code which seems to be putting everything into the query perfectly however, I am still getting the wrong products. For example, I am requesting products with product category 'winter' but still receiving products in category 'all-season'
Here is my code:
add_action('pre_get_posts', 'advanced_search_query', 1000);
function advanced_search_query($query) {
if ( ! is_admin() && $query->is_main_query() && $query->is_search() ) {
global $wp_query;
// category terms search
$categories = array('winter','all-season','summer','run-flat');
$category = $_GET['category'];
$categories = array_diff($categories,array($category));
$taxonomy = 'product_cat';
if (isset($category) && !empty($category)) {
$args = array(
'relation' => 'AND',
array(
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => $category,
'operator' => 'IN'
),
array(
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => array($categories),
'operator' => 'NOT IN'
)
);
$query->set('tax_query', $args);
print_r($query);
}
return $query;
}
}
The print_r returns the following:
WP_Query Object ( [query] => Array ( [s] => 2457516 [post_type] => product ) [query_vars] => Array ( [s] => 2457516 [post_type] => product [error] => [m] => [p] => 0 [post_parent] => [subpost] => [subpost_id] => [attachment] => [attachment_id] => 0 [name] => [static] => [pagename] => [page_id] => 0 [second] => [minute] => [hour] => [day] => 0 [monthnum] => 0 [year] => 0 [w] => 0 [category_name] => [tag] => [cat] => [tag_id] => [author] => [author_name] => [feed] => [tb] => [paged] => 0 [comments_popup] => [meta_key] => total_sales [meta_value] => [preview] => [sentence] => [fields] => [menu_order] => [category__in] => Array ( ) [category__not_in] => Array ( ) [category__and] => Array ( ) [post__in] => Array ( ) [post__not_in] => Array ( ) [tag__in] => Array ( ) [tag__not_in] => Array ( ) [tag__and] => Array ( ) [tag_slug__in] => Array ( ) [tag_slug__and] => Array ( ) [post_parent__in] => Array ( ) [post_parent__not_in] => Array ( ) [author__in] => Array ( ) [author__not_in] => Array ( ) [orderby] => menu_order title [order] => ASC [meta_query] => Array ( [0] => Array ( [key] => _visibility [value] => Array ( [0] => visible [1] => search ) [compare] => IN ) [1] => Array ( [key] => _stock_status [value] => instock [compare] => = ) ) [posts_per_page] => 12 [wc_query] => product_query [tax_query] => Array ( [relation] => AND [0] => Array ( [taxonomy] => product_cat [field] => slug [terms] => winter [operator] => IN ) [1] => Array ( [taxonomy] => product_cat [field] => slug [terms] => Array ( [1] => all-season [2] => summer [3] => run-flat ) [operator] => NOT IN ) ) ) [tax_query] => WP_Tax_Query Object ( [queries] => Array ( ) [relation] => AND [table_aliases:protected] => Array ( ) [queried_terms] => Array ( ) [primary_table] => [primary_id_column] => ) [meta_query] => [date_query] => [post_count] => 0 [current_post] => -1 [in_the_loop] => [comment_count] => 0 [current_comment] => -1 [found_posts] => 0 [max_num_pages] => 0 [max_num_comment_pages] => 0 [is_single] => [is_preview] => [is_page] => [is_archive] => 1 [is_date] => [is_year] => [is_month] => [is_day] => [is_time] => [is_author] => [is_category] => [is_tag] => [is_tax] => [is_search] => 1 [is_feed] => [is_comment_feed] => [is_trackback] => [is_home] => [is_404] => [is_comments_popup] => [is_paged] => [is_admin] => [is_attachment] => [is_singular] => [is_robots] => [is_posts_page] => [is_post_type_archive] => 1 [query_vars_hash:WP_Query:private] => ac61ad4fe3856f3f91e2ca85a7e667a1 [query_vars_changed:WP_Query:private] => [thumbnails_cached] => [stopwords:WP_Query:private] => [compat_fields:WP_Query:private] => Array ( [0] => query_vars_hash [1] => query_vars_changed ) [compat_methods:WP_Query:private] => Array ( [0] => init_query_flags [1] => parse_tax_query ) )
My guess is you have a double array for terms in your tax_query. You have:
$categories = array('...');
$args = array(
//....
array(
'terms' => array( $categories )
)
//....
);
This should just be:
'terms' => $categories

Setting Tax Query in pre_get_posts still showing products with the wrong taxonomy

So basically I am using the following code which seems to be putting everything into the query perfectly however, I am still getting the wrong products. For example, I am requesting products with product category 'winter' but still receiving products in category 'all-season'
Here is my code:
add_action('pre_get_posts', 'advanced_search_query', 1000);
function advanced_search_query($query) {
if ( ! is_admin() && $query->is_main_query() && $query->is_search() ) {
global $wp_query;
// category terms search
$categories = array('winter','all-season','summer','run-flat');
$category = $_GET['category'];
$categories = array_diff($categories,array($category));
$taxonomy = 'product_cat';
if (isset($category) && !empty($category)) {
$args = array(
'relation' => 'AND',
array(
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => $category,
'operator' => 'IN'
),
array(
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => array($categories),
'operator' => 'NOT IN'
)
);
$query->set('tax_query', $args);
print_r($query);
}
return $query;
}
}
The print_r returns the following:
WP_Query Object (
[query] => Array
(
[s] => 2457516
[post_type] => product
)
[query_vars] => Array
(
[s] => 2457516
[post_type] => product
[error] =>
[m] =>
[p] => 0
[post_parent] =>
[subpost] =>
[subpost_id] =>
[attachment] =>
[attachment_id] => 0
[name] =>
[static] =>
[pagename] =>
[page_id] => 0
[second] =>
[minute] =>
[hour] =>
[day] => 0
[monthnum] => 0
[year] => 0
[w] => 0
[category_name] =>
[tag] =>
[cat] =>
[tag_id] =>
[author] =>
[author_name] =>
[feed] =>
[tb] =>
[paged] => 0
[comments_popup] =>
[meta_key] => total_sales
[meta_value] =>
[preview] =>
[sentence] =>
[fields] =>
[menu_order] =>
[category__in] => Array
(
)
[category__not_in] => Array
(
)
[category__and] => Array
(
)
[post__in] => Array
(
)
[post__not_in] => Array
(
)
[tag__in] => Array
(
)
[tag__not_in] => Array
(
)
[tag__and] => Array
(
)
[tag_slug__in] => Array
(
)
[tag_slug__and] => Array
(
)
[post_parent__in] => Array
(
)
[post_parent__not_in] => Array
(
)
[author__in] => Array
(
)
[author__not_in] => Array
(
)
[orderby] => menu_order title
[order] => ASC
[meta_query] => Array
(
[0] => Array
(
[key] => _visibility
[value] => Array
(
[0] => visible
[1] => search
)
[compare] => IN
)
[1] => Array
(
[key] => _stock_status
[value] => instock
[compare] => =
)
)
[posts_per_page] => 12
[wc_query] => product_query
[tax_query] => Array
(
[relation] => AND
[0] => Array
(
[taxonomy] => product_cat
[field] => slug
[terms] => winter
[operator] => IN
)
[1] => Array
(
[taxonomy] => product_cat
[field] => slug
[terms] => Array
(
[1] => all-season
[2] => summer
[3] => run-flat
)
[operator] => NOT IN
)
)
)
[tax_query] => WP_Tax_Query Object
(
[queries] => Array
(
)
[relation] => AND
[table_aliases:protected] => Array
(
)
[queried_terms] => Array
(
)
[primary_table] =>
[primary_id_column] =>
)
[meta_query] =>
[date_query] =>
[post_count] => 0
[current_post] => -1
[in_the_loop] =>
[comment_count] => 0
[current_comment] => -1
[found_posts] => 0
[max_num_pages] => 0
[max_num_comment_pages] => 0
[is_single] =>
[is_preview] =>
[is_page] =>
[is_archive] => 1
[is_date] =>
[is_year] =>
[is_month] =>
[is_day] =>
[is_time] =>
[is_author] =>
[is_category] =>
[is_tag] =>
[is_tax] =>
[is_search] => 1
[is_feed] =>
[is_comment_feed] =>
[is_trackback] =>
[is_home] =>
[is_404] =>
[is_comments_popup] =>
[is_paged] =>
[is_admin] =>
[is_attachment] =>
[is_singular] =>
[is_robots] =>
[is_posts_page] =>
[is_post_type_archive] => 1
[query_vars_hash:WP_Query:private] => ac61ad4fe3856f3f91e2ca85a7e667a1
[query_vars_changed:WP_Query:private] =>
[thumbnails_cached] =>
[stopwords:WP_Query:private] =>
[compat_fields:WP_Query:private] => Array
(
[0] => query_vars_hash
[1] => query_vars_changed
)
[compat_methods:WP_Query:private] => Array
(
[0] => init_query_flags
[1] => parse_tax_query
)
)
SQL queries:
SELECT SQL_CALC_FOUND_ROWS itq2_posts.ID FROM itq2_posts INNER JOIN
itq2_term_relationships ON (itq2_posts.ID =
itq2_term_relationships.object_id) INNER JOIN itq2_postmeta ON (
itq2_posts.ID = itq2_postmeta.post_id ) INNER JOIN itq2_postmeta AS
mt1 ON ( itq2_posts.ID = mt1.post_id ) INNER JOIN itq2_postmeta AS
mt2 ON ( itq2_posts.ID = mt2.post_id ) WHERE 1=1 AND (
itq2_term_relationships.term_taxonomy_id IN (300) AND
itq2_posts.ID NOT IN (
SELECT object_id
FROM itq2_term_relationships
WHERE term_taxonomy_id IN (8,1901,1902,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1917,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,1930,1931,1932,1933,1934,1935,1936,1937,1938,1939,1940,1941,1943,1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1957,1959,1960,1962,1965,1968,1971,1974,1976,1979,1981,1982,1983,1985,1988,1990,1991,1992,1995,1997,1999,2002,2004,2005,2007,2010,2012,2014,2017,2020,2023,2769,2770,2776,2780,3421,3479,3529,3540,3543,3549,3555,3592,3600,3632,3725,3729,3734,3738,3775,3789,3882,3890)
) ) AND (((itq2_posts.post_title LIKE '%2457516%') OR (post_excerpt
LIKE '%2457516%') OR (itq2_posts.post_content LIKE '%2457516%'))) AND
( itq2_postmeta.meta_key = 'total_sales' AND (
( mt1.meta_key = '_visibility' AND CAST(mt1.meta_value AS CHAR) IN ('visible','search') )
AND
( mt2.meta_key = '_stock_status' AND CAST(mt2.meta_value AS CHAR) = 'instock' ) ) ) AND itq2_posts.post_type = 'product' AND (itq2_posts.post_status = 'publish' OR itq2_posts.post_status =
'private') GROUP BY itq2_posts.ID ORDER BY itq2_postmeta.meta_value+0
DESC, itq2_posts.post_date DESC LIMIT 0, 12
I am not sure if this is woocommerce specific, but when I ran into this issue myself I found that woocommerce already builds an empty tax query into it's product query, so when you add set your tax query with $query->set( 'tax_query', $tax_query ); it's essentially adding a redundant array into the query as the tax_query inside the array has already been converted into an object for use.
The work around this, all you need to do is grab the current tax query and add to it or adjust it instead of starting with a blank array. Doing it this way allows you to build on to an object that has already got everything else needed for the tax_query.
So building off of your example, instead of just creating a new variable called $args, we're going to grab the current tax_query and save it as $args and then build further into it like this:
if (isset($category) && !empty($category)) {
$args = $query->get( 'tax_query', [] ); //this is the important part
$args['relation'] => 'AND';
$args[] = array(
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => $category,
'operator' => 'IN'
);
$args[] = array(
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => array($categories),
'operator' => 'NOT IN'
);
);
$query->set('tax_query', $args);

Categories