4

I'm trying to alter the search functionality of a WooCommerce store so when a user makes a query that matches a product_tag slug it returns the products that don't have that product tag assigned.

The logic behind this is showing all the products without gluten to a user who searches for "gluten".

My code is almost working except for the operator parameter.

I'm throwing this query:

http://example.com/?s=gluten

This function returns all the products tagged as the search query:

function menta_pre_get_posts( $query ) {
if ( !is_admin() && $query->is_search() && $query->is_main_query() ) {
    $term = get_term_by('slug', get_query_var('s'), 'product_tag');
    if ( $term && !is_wp_error( $term ) ) {
        $tax_query = array(
                'taxonomy'  => 'product_tag',
                'field'     => 'slug',
                'terms'     => $term->slug,
                'operator'  => 'IN'
        );
        $query->tax_query->queries[] = $tax_query;
        $query->query_vars['tax_query'] = $query->tax_query->queries;
     }
}}
add_action( 'pre_get_posts', 'menta_pre_get_posts', 1 );

But if I change the operator to NOT IN, I get no results:

function menta_pre_get_posts( $query ) {
if ( !is_admin() && $query->is_search() && $query->is_main_query() ) {
    $term = get_term_by('slug', get_query_var('s'), 'product_tag');
    if ( $term && !is_wp_error( $term ) ) {
        $tax_query = array(
                'taxonomy'  => 'product_tag',
                'field'     => 'slug',
                'terms'     => $term->slug,
                'operator'  => 'NOT IN'
        );
        $query->tax_query->queries[] = $tax_query;
        $query->query_vars['tax_query'] = $query->tax_query->queries;
     }
}}
add_action( 'pre_get_posts', 'menta_pre_get_posts', 1 );

The products are correctly tagged, and there are products without the gluten tag

2 Answers 2

7

I suspect you need an array for the terms - although I'm not sure why it would work with "IN" and not with "NOT IN"... But I'd try this:

function menta_pre_get_posts( $query ) {
if ( !is_admin() && $query->is_search() && $query->is_main_query() ) {
    $term = get_term_by('slug', get_query_var('s'), 'product_tag');
    if ( $term && !is_wp_error( $term ) ) {
        $tax_query = array(
                'taxonomy'  => 'product_tag',
                'field'     => 'slug',
                'terms'     => array($term->slug),
                'operator'  => 'NOT IN'
        );
        $query->tax_query->queries[] = $tax_query;
        $query->query_vars['tax_query'] = $query->tax_query->queries;
        $query->set('tax_query', $query->tax_query->queries);
     }
}}
add_action( 'pre_get_posts', 'menta_pre_get_posts', 1 );

Hope this helps!

4
  • Thank you, but I've just tried that and the query still doesn't return results
    – NiloVelez
    Feb 14, 2017 at 7:41
  • Hmmm. Ok. Well in the past, I've also sometimes had to add $query->set('tax_query', $query->tax_query->queries); -- see my updated answer.
    – nibnut
    Feb 14, 2017 at 10:42
  • You could also debug the query to see what WP builds off your filter: codex.wordpress.org/…
    – nibnut
    Feb 14, 2017 at 10:43
  • I'm getting unconsistent results, but at least I have a base for debugging queries. I'm marking your answer as accepted as further problems might be caused by external factors, thank you for your help.
    – NiloVelez
    Feb 15, 2017 at 14:28
0

Just to complement the answer by @nibnut, I recommend to check first if there is some tax_query in the Query, so you do not overwrite them:

$query->tax_query->queries      = (array) $query->get( 'tax_query' );
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.