Как выполнить поиск WP_Query с пользовательскими типами записей?
Я зарегистрировал пользовательский тип записи под названием "node".
Когда я создаю базовый WP_Query для получения записей этого типа, он работает нормально. Пример:
$args = array(
'post_status' => 'publish',
'post_type' => 'node');
$query = new WP_Query($args);
Это получит все опубликованные записи типа "node".
Однако, как только я комбинирую это с поиском, ничего не возвращается. Пример:
$args = array(
'post_status' => 'publish',
'post_type' => 'node',
's' => 'My search term');
$query = new WP_Query($args);
Это не вернет ничего, хотя должно получить несколько записей типа 'node', которые содержат 'My search term'.
Насколько я могу видеть, типы записей автоматически устанавливаются на "post" и "page", как только я включаю параметр "s" в $args. Если я выведу var_dump от $query, он показывает следующее:
Без "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)
...
С "s":
object(WP_Query)
public 'query' =>
array (size=2)
'post_status' => string 'publish' (length=7)
's' => string 'My search term' (length=14)
'post_type' => string 'node' (length=4)
public 'query_vars' =>
array (size=66)
'post_status' => string 'publish' (length=7)
's' => string 'My search term' (length=14)
'post_type' =>
array (size=2)
0 => string 'post' (length=4)
1 => string 'page' (length=4)
...
Таким образом, WordPress, похоже, переопределяет типы записей, как только появляется поиск.
Как это можно исправить?

В стандартной установке WordPress, WP_Query по умолчанию использует post_type
= 'post'
.
Рассмотрим простой пример:
$args = array(
"posts_per_page"=>5,
"ignore_sticky_posts"=>true
);
$itposts = new WP_Query( $args );
Это приведёт к выполнению следующего запроса:
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
ЛУЧШЕЕ РЕШЕНИЕ
Решение заключается в добавлении аргумента post_type
со значением 'any'
. Таким образом WordPress автоматически будет искать среди всех типов записей, за исключением ревизий и типов с установленным параметром exclude_from_search
в true
. Проблема в том, что по умолчанию вложения (attachments) не исключаются из поиска. Пока у вас не установлен аргумент post_status
в 'inherit'
, это не должно мешать, так как вложения всегда имеют post_status
равный 'inherit'
.
В таком случае запрос изменится на:
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
При необходимости можно исключить вложения из поиска с помощью этого кода:
add_action('init', 'exclude_attachments_from_search');
function exclude_attachments_from_search() {
global $wp_post_types;
$wp_post_types['attachment']->exclude_from_search = true;
}

Я знаю, что это очень старый вопрос, но я наткнулся на него, потому что у меня была такая же проблема. Я не могу оставить комментарий из-за репутации, но хочу помочь людям, таким как @Stefano, чтобы вам не пришлось перебирать все плагины и проверять, какой из них влияет на запрос.
В моем случае это был плагин под названием "Custom Search by BestWebSoft". Но это была не ошибка плагина — я просто не отметил галочкой свой пользовательский тип записи в его настройках.
