Cum adaugi SKU WooCommerce în căutare?
Am o problemă la adăugarea câmpului meta_value
în interogarea de căutare pentru SKU-ul WooCommerce. Implicit, căutarea după SKU funcționează doar în admin.
Aș dori să fac căutarea din frontend să accepte și SKU în căutare.
Notă: SKU-urile nu sunt în titlul produsului. Deci trebuie să creez o interogare personalizată.
function SearchFilter($query) {
if ($query->is_search) {
$meta_query_args = array(
'relation' => 'OR',
array(
'key' => '_sku',
'value' => $query->query_vars['s'],
'compare' => '=',
)
);
$query->set('post_type', array('post','page', 'product'));
$query->set('post_status', array('publish'));
$query->set('meta_query', $meta_query_args);
}
return $query;
}
add_filter('pre_get_posts','SearchFilter');
Problema: Când pun acest cod și afișez interogarea SQL curentă, îmi returnează ceva de genul acesta.
SELECT SQL_CALC_FOUND_ROWS bhd_posts.ID FROM bhd_posts INNER JOIN bhd_postmeta ON ( bhd_posts.ID = bhd_postmeta.post_id ) WHERE 1=1 AND (((bhd_posts.post_title LIKE '%96242-20VH%') OR (bhd_posts.post_excerpt LIKE '%96242-20VH%') OR (bhd_posts.post_content LIKE '%96242-20VH%'))) AND (bhd_posts.post_password = '') AND (
( bhd_postmeta.meta_key = '_sku' AND bhd_postmeta.meta_value = '96242-20VH' )
) AND bhd_posts.post_type IN ('post', 'page', 'product') AND ((bhd_posts.post_status = 'publish')) GROUP BY bhd_posts.ID ORDER BY bhd_posts.post_title LIKE '%96242-20VH%' DESC, bhd_posts.post_date DESC LIMIT 0, 10
După cum se poate vedea, încearcă să caute partea "clasică" în tabelul x_posts
pentru post_title
SAU post_excerpt
SAU post_content
ȘI trebuie să aibă o valoare meta_value
a SKU-ului meu.
După cum am menționat mai sus, titlurile produselor mele nu conțin SKU-ul.
Obiectiv: Să pot căuta în titluri, extras, conținut sau în meta_value SAU să caut exclusiv cu meta_value.

Dacă utilizați funcția de căutare din WordPress, puteți adăuga acest cod pentru a o face să funcționeze
function search_by_sku( $search, &$query_vars ) {
global $wpdb;
if(isset($query_vars->query['s']) && !empty($query_vars->query['s'])){
$args = array(
'posts_per_page' => -1,
'post_type' => 'product',
'meta_query' => array(
array(
'key' => '_sku',
'value' => $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_by_sku', 999, 2 );

Mulțumesc pentru partajarea acestui cod. Doar pentru informare, am încercat codul dar generează un avertisment PHP: "Parameter 2 to search_by_sku() expected to be a reference, value given"

Nu am suficient reputație, așa că nu am putut comenta, dar iată modificarea;
Codul lui @ahsankhan pare să funcționeze, dar după cum s-a raportat, dădea o eroare la "parametrul 2".
Dacă eliminați "&" din prima linie unde se află "&$query_vars" și înlocuiți cu doar "$query_vars", acesta pare să funcționeze fără a arunca erori.
function search_by_sku( $search, $query_vars ) {
global $wpdb;
if(isset($query_vars->query['s']) && !empty($query_vars->query['s'])){
$args = array(
'posts_per_page' => -1,
'post_type' => 'product',
'meta_query' => array(
array(
'key' => '_sku',
'value' => $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_by_sku', 999, 2 );

// modificat pentru căutare după SKU în variații ;)
function search_by_sku($search, &$query_vars)
{
global $wpdb;
if (isset($query_vars->query['s']) && !empty($query_vars->query['s'])) {
// produse simple
$args = array(
'posts_per_page' => -1,
'post_type' => 'product',
'meta_query' => array(
array(
'key' => '_sku',
'value' => $query_vars->query['s'],
'compare' => 'LIKE'
)
)
);
$posts = get_posts($args);
$get_post_ids = array();
foreach ($posts as $post) {
$get_post_ids[] = $post->ID;
}
// variații
$args = array(
'posts_per_page' => -1,
'post_type' => 'product_variation',
'meta_query' => array(
array(
'key' => '_sku',
'value' => $query_vars->query['s'],
'compare' => 'LIKE'
)
)
);
$posts_variation = get_posts($args);
if (empty($posts_variation) && empty($posts)) return $search;
foreach ($posts_variation as $post) {
$get_post_ids[] = $post->post_parent;
}
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_by_sku', 999, 2);
