Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error in searching specific post_type form post_type column using WooCommerce product search

I am using this code to search products from a Wordpress/WooCommerce website.
My requirment is URL will be like "http://localhost/wp/?s=D34&post_type=product" While s=D34 is search string.

When user will search for a string. Data will be searched from All default fields+ product's custom filed. The below code work fine with http://localhost/wp/?s=D34 but when &post_type=product is concatenated with url then it say enter image description here

Code is given below

function cf_search_where( $where ) {
global $pagenow, $wpdb;


    if ( is_search() ) {
$where = preg_replace("/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
            "(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where );
        $where .= " AND ($wpdb->posts.post_type = 'product') ";
    }

    return $where;
}
add_filter( 'posts_where', 'cf_search_where' );

This is to prevent distinct values

  function cf_search_distinct( $where ) {
        global $wpdb;
if ( is_search() ) {
    return "DISTINCT"; //to prevent duplicates
}

return $where;

}
add_filter( 'posts_distinct', 'cf_search_distinct' );

So What modification is required?

URL http://localhost/wp/?orderby=price&post_type=product work fine

but what is wrong with http://localhost/wp/?s=D34&post_type=product

like image 924
Adnan Ali Avatar asked Dec 18 '15 06:12

Adnan Ali


1 Answers

try this

function cf_search_where( $where ) {
    global $pagenow, $wpdb;

    // a little debugging will help you..
    //print_r ($where);
    //die();

    if ( is_search() ) {

        $where = preg_replace("/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
            "(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where );
        $where .= " AND ($wpdb->posts.post_type = 'product') ";
    }

    return $where;
}
add_filter( 'posts_where', 'cf_search_where' );

Based on your updated question.

if only you've used print_r ($where); to check what value does $where contains, you will see something like these...

with http://localhost/wp/?s=D34

AND (((wp1_posts.post_title LIKE '%D34%') OR (wp1_postmeta.meta_value LIKE '%D34%') OR (wp1_posts.post_content LIKE '%D34%'))) 
AND (wp1_posts.post_password = '') 
AND wp1_posts.post_type IN ('post', 'page', 'attachment', 'product') 
AND (wp1_posts.post_status = 'publish')

with http://localhost/wp/?s=D34&post_type=product

AND (((wp1_posts.post_title LIKE '%D34%') OR (wp1_postmeta.meta_value LIKE '%D34%') OR (wp1_posts.post_content LIKE '%D34%'))) 
AND (wp1_posts.post_password = '') 
AND ( ( wp1_postmeta.meta_key = '_visibility' AND CAST(wp1_postmeta.meta_value AS CHAR) IN ('visible','search') ) ) 
AND wp1_posts.post_type = 'product' 
AND (wp1_posts.post_status = 'publish')

take note of wp1_posts.post_type and get a hint.. be flexible on yourself and try to debug. above are results without the $where .= " AND ($wpdb->posts.post_type = 'product') "; though.

like image 186
Reigel Avatar answered Sep 30 '22 04:09

Reigel