Question

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

Was it helpful?

Solution

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!

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top