Búsqueda en tipo de entrada personalizada por metadatos
Tengo un tipo de entrada personalizada 'Property' que mis usuarios necesitan poder buscar por metadatos.
Tengo 3 funciones de búsqueda - 2 en el frontend y 1 en el área de administración - 2 de las cuales funcionan correctamente y una que no parece filtrar los resultados.
Creo que puede haber un problema con mi definición o uso de custom query_vars.
En mi functions.php tengo lo siguiente:
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');
Buscar por el código de propiedad funciona sin problemas tanto en el frontend como en el backend, sin embargo intentar filtrar resultados por las query vars personalizadas - location, type y bedrooms - no funciona.
Un ejemplo de cadena de búsqueda que se crea es el siguiente:
/property/?post_type=nc_property&which_form=meta_form&bedrooms=Two&type=Apartment&location=Bahceli
Hay una propiedad en el sitio que coincide con esos detalles pero WordPress devuelve todos los resultados cada vez.
¿Me he olvidado de algo?
EDIT: Resulta que como mi formulario de búsqueda para las consultas de metadatos no estaba usando un elemento con 's'
como nombre, la condición $query->is_search
de mi sentencia if devolvía false, lo que significa que mi meta_query simplemente no se estaba llamando.
¡Créditos a fischi por darse cuenta de esto por mí! :D

En este caso, al mezclar enlaces permanentes con parámetros de solicitud, usaría las variables $_GET
en tu consulta.
$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'
)
)
);
Asegúrate de utilizar la sanitización adecuada, dependiendo de tus necesidades, o usando una función que verifique valores permitidos en los datos $_GET
.
También verifica la función de los condicionales - solo modificas la consulta si es una solicitud de búsqueda (usando s
como parámetro de búsqueda), o modifica la declaración if
.

He realizado los cambios que recomendaste, sin embargo, los resultados de búsqueda aún no parecen filtrarse de ninguna manera, aunque sé que las variables $_GET
se están recogiendo correctamente cuando hago var_dump
...

¿Puedes revisar qué consulta está ejecutando tu WordPress? <?php echo $GLOBALS['wp_query']->request; ?>

La consulta es la siguiente 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
así que parece que mi meta query simplemente está siendo ignorada? :/

ups, vi otra cosa - si no usas el parámetro s
tu condición if (!is_admin() && $query->is_search )
no se cumple, ya que WordPress no sabe que es una búsqueda. Intenta cambiar eso también.

¡Eres un héroe de WordPress! ¡Hacer que uno de los campos de búsqueda tenga el nombre 's' ha resuelto el problema!
