Come aggiungere lo SKU WooCommerce alla query di ricerca?
Ho un problema nell'aggiungere il meta_value
nella query di ricerca per lo SKU di WooCommerce. Di default, la ricerca per SKU funziona solo nell'admin.
Vorrei far accettare la ricerca SKU anche nel frontend.
Nota: Gli SKU non sono presenti nel titolo del prodotto. Quindi devo creare una query personalizzata.
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');
Il problema: Quando inserisco questo codice e stampo la richiesta SQL corrente, mi restituisce qualcosa del genere.
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
Come potete vedere, cerca di recuperare la "parte classica" nella tabella x_posts
per post_title
O post_excerpt
O post_content
E deve avere un meta_value
del mio SKU.
Come detto sopra, i titoli dei miei prodotti non contengono lo sku.
Obiettivo: Poter cercare nei titoli, excerpt, contenuto o nel meta_value OPPURE cercare esclusivamente con il meta_value.

Se stai utilizzando la ricerca di WordPress puoi aggiungere questo codice per farla funzionare
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 );

Grazie per aver condiviso questo codice. Volevo solo farti sapere che ho provato a utilizzarlo ma genera un avviso PHP: "Parameter 2 to search_by_sku() expected to be a reference, value given"

Non ho abbastanza reputazione, quindi non ho potuto commentare, ma ecco la modifica;
Il codice di @ahsankhan sembra funzionare, ma come segnalato, dava un errore "parameter 2".
Se rimuovi il "&" dalla prima riga dove c'è "&$query_vars" e lo sostituisci con semplicemente "$query_vars", sembra funzionare senza generare errori.
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 );

// modificato per la ricerca tramite SKU nelle varianti ;)
function search_by_sku($search, &$query_vars)
{
global $wpdb;
if (isset($query_vars->query['s']) && !empty($query_vars->query['s'])) {
// prodotti semplici
$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;
}
// varianti
$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);
