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:

Read More
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

Related posts

1 comment

  1. 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);
    

Comments are closed.