Reputation: 21
I've just built a specialist bookshop website using Woocommerce (2.1.11) with their free Mystile theme. The products (books) have several custom fields added including isbn, author, publisher etc.
I would like now to amend the default product search facility to ONLY search the custom fields (as opposed to just including custom fields in the search). Does anyone know how to do that?
Thanks
Upvotes: 1
Views: 14690
Reputation: 21
Custom code to search using name and product description (just paste this code in function.php)
// Join in your where condition
function cf_search_join( $join ) {
global $wpdb;
if ( is_search() ) {
$join .=' LEFT JOIN '.$wpdb->postmeta. ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
}
return $join;
}
add_filter('posts_join', 'cf_search_join' );
function cf_search_distinct( $where ) {
global $wpdb;
if ( is_search() ) {
return "DISTINCT";
}
return $where;
}
add_filter( 'posts_distinct', 'cf_search_distinct' );
// Search by Post Title
function search_by_id_only( $search, &$wp_query )
{
//remove_filter( 'posts_search', 'vc_search_by_title_only', 500, 2 );
global $wpdb,$wp_the_query,$wp;
if ( empty( $search ) ){
return $search; // skip processing - no search term in query
}
$q = $wp_query->query_vars;
$n = ! empty( $q['exact'] ) ? '' : '%';
$search = $searchand = '';
foreach ( (array) $q['search_terms'] as $term ) {
$term = $wpdb->esc_like( $term );
$n = '%';
$like = $n . $term . $n;
$search .= $wpdb->prepare( "{$searchand}($wpdb->posts.ID LIKE %s)", $like );
$searchand = ' OR ';
$search .= $wpdb->prepare( "{$searchand}($wpdb->posts.post_title LIKE %s)", $like );
$searchand = ' OR ';
$search .= $wpdb->prepare( "{$searchand}($wpdb->postmeta.meta_key = '_sku' AND CAST($wpdb->postmeta.meta_value AS CHAR) LIKE %s)", $like );
//$search .= $wpdb->prepare("{$searchand} (select * from {$wpdb->postmeta} where post_id={$wpdb->posts}.ID and meta_key in ('_sku') and meta_value like %s )",$like);
$searchand = ' OR ';
//$search .= $wpdb->prepare( "{$searchand}($wpdb->posts.post_content LIKE %s)", $like );
// $searchand = ' OR ';
}
if ( ! empty( $search ) ) {
$search = " AND ({$search}) ";
}
return $search;
}
if( !is_admin() ){
add_filter( 'posts_search', 'search_by_id_only', 500, 2 );
}
Upvotes: 0
Reputation: 21
Thanks again Dinesh - got there in the end - results below
WP templating is one thing - happy with that - just slightly baffled by Woocommerce.
End Result: As Woocommerce search results are fed into their plugin specific 'archive-product.php' page I had to add your code there. archive-pruduct.php is also the main category listing page so need to catch the search with a is_search condition before using your above override:
I did it as follows:
<?php
if ( is_search() ) :
$args = array(
'post_type' => 'product',
'posts_per_page' => -1,
'order' => 'ASC',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'meta:_isbn_field', //your meta key
'value' => $_REQUEST['meta:_isbn_field'], //your search post value
'compare' => 'LIKE'
)
), array(
'key' => 'meta:_published_field', //your meta key
'value' => $_REQUEST['meta:_published_field'], //your search post value
'compare' => 'LIKE'
),
array(
'key' => 'meta:_publisher_field', //your meta key
'value' => $_REQUEST['meta:_publisher_field'], // your search post value for author
'compare' => 'LIKE'
),
array(
'key' => 'post_title',
'value' => $_REQUEST['post_title'],
'compare' => 'LIKE'
)
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) {
echo '<h2>Your search Results</h2>';
while ( $the_query->have_posts() ) {
$the_query->the_post();
echo wc_get_template_part( 'content', 'single-productsimple' );
}
}else{
echo 'sorry nothing found';
}
else:
//leave default archive-product.php code here
endif;
?>
Upvotes: 1
Reputation: 4110
You can try meta_query to make this searching, as you know custom field get save in wp_postmeta table.
So just do something like this:
<?php
$args = array(
'post_type' => 'product',
'posts_per_page' => -1,
'order' => 'ASC',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => ' isbn', //your meta key
'value' => $_REQUEST['isbn'], //your search post value
'compare' => 'LIKE'
),
array(
'key' => ' author', //your meta key
'value' => $_REQUEST['author'], // your search post value for author
'compare' => 'LIKE'
),
array(
'key' => ' publisher ',
'value' => $_REQUEST['publisher '],
'compare' => 'LIKE'
)
)
);
$query = new WP_Query( $args );
if (have_posts()) : while (have_posts()) : the_post();
// your result go here
?>
Upvotes: 0