Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enable custom taxonomies in WooCommerce product search

What I want: modify the query of the WooCommerce search form (in frontend) to display the products by searching in the name, description and product_tag of the products.

What I have: I'm trying with this code inspired from this answer that return a result for the name and description of the product. But if i make a search with the tags names, no results. The search query don't search in tags of the product.

How to reproduce this issue (put the code below in functions.php file of your active theme):

function search_product_by_tag( $search, &$query_vars ) {
    global $wpdb, $pagenow;

    if ( 'edit.php' == $pagenow || empty($search) ) {
        return $search;
    }

    $args = array(
        'posts_per_page'  => -1,
        'post_type'       => 'product',
       'meta_query' => array(
            array(
                'key' => 'taxonomy',
                'value' => 'product_tag',
                'field' => 'name',
                'terms' => array($query_vars->query['s']),
                'compare' => 'LIKE',
    )));
    $posts = get_posts( $args );
    if ( empty( $posts ) ) return $search;
    $get_post_ids = array();
    foreach($posts as $post){
        $get_post_ids[] = $post->ID;
    }
    if ( sizeof( $get_post_ids ) > 0 ) {
        $search = str_replace( 'AND (((', "AND ((({$wpdb->posts}.ID IN (" . implode( ',', $get_post_ids ) . ")) OR (", $search);
    }
    return $search;
}
add_filter( 'posts_search', 'search_product_by_tag', 999, 2 );

Example: I've one product : Black Chocolate with the product tag "confection". With this code, if i search "Chocolate" in the search form, the product will be returned. But if i search "confection" : no results. Frontend search result

like image 510
Benoit FOUCHER Avatar asked Jan 24 '23 20:01

Benoit FOUCHER


1 Answers

There are a lot of mistakes and errors in your code (a tax query is required for example).

To include WooCommmerce product tag terms in WooCommerce product search only (front end) use the following:

add_filter( 'posts_search', 'woocommerce_search_product_tag_extended', 999, 2 );
function woocommerce_search_product_tag_extended( $search, $query ) {
    global $wpdb, $wp;

    $qvars = $wp->query_vars;

    if ( is_admin() || empty($search) ||  ! ( isset($qvars['s'])
    && isset($qvars['post_type']) && ! empty($qvars['s'])
    && $qvars['post_type'] === 'product' ) ) {
        return $search;
    }
    
    // Here set your custom taxonomy
    $taxonomy = 'product_tag'; // WooCommerce product tag

    // Get the product Ids
    $ids = get_posts( array(
        'posts_per_page'  => -1,
        'post_type'       => 'product',
        'post_status'     => 'publish',
        'fields'          => 'ids',
        'tax_query'       => array( array(
            'taxonomy' => $taxonomy,
            'field'    => 'name',
            'terms'    => esc_attr($qvars['s']),
        )),
    ));

    if ( count( $ids ) > 0 ) {
        $search = str_replace( 'AND (((', "AND ((({$wpdb->posts}.ID IN (" . implode( ',', $ids ) . ")) OR (", $search);
    }
    return $search;
}

Code goes in functions.php file of your active child theme (or active theme). Tested and works.

To make it work On WordPress search too replace:

    if ( is_admin() || empty($search) ||  ! ( isset($qvars['s'])
    && isset($qvars['post_type']) && ! empty($qvars['s'])
    && $qvars['post_type'] === 'product' ) ) {

By the following:

    if ( is_admin() || empty($search) ||  ! ( isset($qvars['s']) && ! empty($qvars['s']) ) ) {

For WooCommerce product category you will replace:

$taxonomy = 'product_tag'; // WooCommerce product tag

with:

$taxonomy = 'product_cat'; // WooCommerce product category

For WooCommerce product brands you will replace:

$taxonomy = 'product_tag'; // WooCommerce product tag

with:

$taxonomy = 'product_brand'; // WooCommerce product Brands

For multiple taxonomies.

To enable the search for both product category terms and product tag terms, you will use:

add_filter( 'posts_search', 'woocommerce_search_product_tag_extended', 999, 2 );
function woocommerce_search_product_tag_extended( $search, $query ) {
    global $wpdb, $wp;

    $qvars = $wp->query_vars;

    if ( is_admin() || empty($search) ||  ! ( isset($qvars['s'])
    && isset($qvars['post_type']) && ! empty($qvars['s'])
    && $qvars['post_type'] === 'product' ) ) {
        return $search;
    }

    // Here set your custom taxonomies in the array
    $taxonomies = array('product_tag', 'product_cat');

    $tax_query  = array('relation' => 'OR'); // Initializing tax query

    // Loop through taxonomies to set the tax query
    foreach( $taxonomies as $taxonomy ) {
        $tax_query[] = array(
            'taxonomy' => $taxonomy,
            'field'    => 'name',
            'terms'    => esc_attr($qvars['s']),
        );
    }

    // Get the product Ids
    $ids = get_posts( array(
        'posts_per_page'  => -1,
        'post_type'       => 'product',
        'post_status'     => 'publish',
        'fields'          => 'ids',
        'tax_query'       => $tax_query,
    ) );

    if ( sizeof( $ids ) > 0 ) {
        $search = str_replace( 'AND (((', "AND ((({$wpdb->posts}.ID IN (" . implode( ',', $ids ) . ")) OR (", $search);
    }
    return $search;
}

Code goes in functions.php file of your active child theme (or active theme). Tested and works.

To make it work On WordPress search too replace:

    if ( is_admin() || empty($search) ||  ! ( isset($qvars['s'])
    && isset($qvars['post_type']) && ! empty($qvars['s'])
    && $qvars['post_type'] === 'product' ) ) {

By the following:

    if ( is_admin() || empty($search) ||  ! ( isset($qvars['s']) && ! empty($qvars['s']) ) ) {

New Thread: Extend WooCommerce product search to custom taxonomies and custom fields

like image 106
LoicTheAztec Avatar answered Jan 28 '23 11:01

LoicTheAztec