¿Cómo hacer una búsqueda WP_Query con tipos de contenido personalizados?
He registrado un tipo de contenido personalizado llamado "node".
Cuando creo una WP_Query básica para obtener entradas de ese tipo, funciona perfectamente. Ejemplo:
$args = array(
'post_status' => 'publish',
'post_type' => 'node');
$query = new WP_Query($args);
Esto obtendrá todas las entradas publicadas del tipo "node".
Sin embargo, tan pronto como combino esto con una búsqueda, no se devuelve nada. Ejemplo:
$args = array(
'post_status' => 'publish',
'post_type' => 'node',
's' => 'Mi término de búsqueda');
$query = new WP_Query($args);
Esto no devolverá nada, aunque debería obtener varias entradas del tipo 'node' que contengan 'Mi término de búsqueda'.
Por lo que puedo ver, los tipos de contenido se establecen automáticamente en "post" y "page" tan pronto como incluyo el parámetro "s" en $args. Si imprimo un var_dump de $query, muestra lo siguiente:
Sin "s":
object(WP_Query)
public 'query' =>
array (size=2)
'post_status' => string 'publish' (length=7)
'post_type' => string 'node' (length=4)
public 'query_vars' =>
array (size=63)
'post_status' => string 'publish' (length=7)
'post_type' => string 'node' (length=4)
...
Con "s":
object(WP_Query)
public 'query' =>
array (size=2)
'post_status' => string 'publish' (length=7)
's' => string 'Mi término de búsqueda' (length=14)
'post_type' => string 'node' (length=4)
public 'query_vars' =>
array (size=66)
'post_status' => string 'publish' (length=7)
's' => string 'Mi término de búsqueda' (length=14)
'post_type' =>
array (size=2)
0 => string 'post' (length=4)
1 => string 'page' (length=4)
...
Parece que WordPress sobrescribe los tipos de contenido tan pronto como se involucra una búsqueda.
¿Cómo puedo arreglar esto?

En una instalación estándar de WordPress, WP_Query por defecto usará post_type
= 'post'
.
Considera este sencillo ejemplo:
$args = array(
"posts_per_page"=>5,
"ignore_sticky_posts"=>true
);
$itposts = new WP_Query( $args );
Esto resultará en la siguiente consulta ejecutada:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 5
LA MEJOR SOLUCIÓN
La solución es añadir un argumento post_type
configurado como 'any'
. De esta manera WordPress buscará automáticamente entre todos los tipos excepto revisiones y tipos con exclude_from_search
establecido como true
. El problema es que, por defecto, los archivos adjuntos no están excluidos de la búsqueda. Mientras no tengas un argumento post_status
configurado como 'inherit'
, no deberías tener problemas porque los archivos adjuntos siempre tienen post_status
establecido como 'inherit'
.
De esta manera la consulta cambiará a:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type IN ('post', 'page', 'attachment') AND (wp_posts.post_status = 'publish' OR wp_posts.post_author = 1 AND wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 5
Si es necesario, puedes excluir archivos adjuntos de la búsqueda usando este código:
add_action('init', 'exclude_attachments_from_search');
function exclude_attachments_from_search() {
global $wp_post_types;
$wp_post_types['attachment']->exclude_from_search = true;
}

Sé que esta es una pregunta muy antigua pero llegué aquí porque tenía el mismo problema. No puedo comentar por falta de reputación, pero quiero ayudar a personas como @Stefano para que no tengan que revisar todos sus plugins y ver cuál causa el cambio en la consulta.
En mi caso fue un plugin llamado "Custom Search by BestWebSoft". Pero no era culpa del plugin, simplemente no había marcado la casilla para mi tipo de contenido personalizado en sus ajustes.
