Ricerca di custom post type tramite metadati in WordPress
Ho un custom post type 'Property' che gli utenti devono poter cercare tramite metadati.
Ho 3 funzioni di ricerca - 2 nel frontend e 1 nell'area admin - 2 delle quali funzionano correttamente mentre una non sembra filtrare i risultati.
Penso ci possa essere un problema con la definizione o l'uso dei custom query_vars.
Nel mio functions.php ho il seguente codice:
function add_query_vars($public_query_vars) {
$public_query_vars[] = 'bedrooms';
$public_query_vars[] = 'type';
$public_query_vars[] = 'location';
return $public_query_vars;
}
add_filter('query_vars', 'add_query_vars');
function meta_search_query($query) {
$query_args_code = array(
'posts_per_page' => 5,
'post_type' => 'nc_property',
'meta_key' => 'nc_code',
'meta_value' => $query->query_vars['s'],
'meta_compare' => 'LIKE'
);
$query_args_meta = array(
'posts_per_page' => -1,
'post_type' => 'nc_property',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'nc_bedrooms',
'value' => $query->query_vars['bedrooms'],
'compare' => 'LIKE'
),
array(
'key' => 'nc_type',
'value' => $query->query_vars['type'],
'compare' => 'LIKE'
),
array(
'key' => 'nc_location',
'value' => $query->query_vars['location'],
'compare' => 'LIKE'
)
)
);
if (is_admin() && $query->is_search ) {
query_posts($query_args_code);
} elseif (!is_admin() && $query->is_search ) {
if ($_REQUEST["which_form"] == 'meta_form') {
query_posts($query_args_meta);
} elseif ($_REQUEST["which_form"] == 'code_form'){
query_posts($query_args_code);
}
}
}
add_filter( 'pre_get_posts', 'meta_search_query');
La ricerca tramite codice proprietà funziona perfettamente sia nel frontend che nel backend, ma il filtro tramite i custom query vars - location, type e bedrooms - non produce alcun risultato.
Un esempio di query string generata è:
/property/?post_type=nc_property&which_form=meta_form&bedrooms=Two&type=Apartment&location=Bahceli
C'è una proprietà nel sito che corrisponde a quei criteri ma WordPress restituisce sempre tutti i risultati.
Mi sono perso qualcosa?
EDIT: Ho scoperto che poiché il mio form di ricerca per i metadati non utilizzava un elemento con nome 's'
, la condizione $query->is_search
del mio if restituiva false, quindi la meta_query non veniva mai chiamata.
Riconoscimento a fischi per averlo notato! :D

In questo caso, visto che stai combinando permalink puliti con parametri di richiesta, utilizzerei le variabili $_GET
nella tua query.
$query_args_meta = array(
'posts_per_page' => -1,
'post_type' => 'nc_property',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'nc_bedrooms',
'value' => sanitize_text_field( $_GET['bedrooms'] ),
'compare' => 'LIKE'
),
array(
'key' => 'nc_type',
'value' => sanitize_text_field( $_GET['type'] ),
'compare' => 'LIKE'
),
array(
'key' => 'nc_location',
'value' => sanitize_text_field( $_GET['location'] ),
'compare' => 'LIKE'
)
)
);
Assicurati di utilizzare la corretta sanitizzazione, in base alle tue esigenze, oppure usa una funzione che verifichi i valori consentiti (whitelist) dei dati $_GET
.
Verifica anche le condizioni della tua funzione - modificherai la query solo se si tratta di una richiesta di ricerca (utilizzando s
come parametro di ricerca), oppure modifica l'istruzione if
.

Ho implementato le modifiche che mi hai consigliato, tuttavia i risultati della ricerca non sembrano essere filtrati in alcun modo, anche se so che le variabili $_GET
vengono rilevate correttamente quando faccio var_dump
...

Puoi verificare quale query esegue il tuo WordPress? <?php echo $GLOBALS['wp_query']->request; ?>

La query è la seguente SELECT SQL_CALC_FOUND_ROWS north_posts.ID FROM north_posts WHERE 1=1 AND north_posts.post_type = 'nc_property' AND (north_posts.post_status = 'publish' OR north_posts.post_status = 'private') ORDER BY north_posts.post_date DESC LIMIT 0, 10
quindi sembra che la mia meta query venga semplicemente ignorata? :/

ops, ho notato un'altra cosa - se non usi il parametro s
la tua condizione if (!is_admin() && $query->is_search )
non viene soddisfatta, poiché WordPress non riconosce che si tratta di una ricerca. Prova a modificare anche quello.

Sei un eroe di WordPress! Fare in modo che uno dei campi di ricerca abbia il nome 's' ha risolto il problema!
