Есть ли способ использовать $query->set('tax_query') в фильтре pre_get_posts?
Есть ли способ использовать $query->set('tax_query', ...)
в фильтре pre_get_posts
? Например, следующий код не изменяет запрос. Обратите внимание, что я создаю $taxonomies из пользовательского поиска.
function custom_search_filter($query) {
...
// array('taxonomy' => 'category', 'field' => 'id', 'terms' => array( 41,42 ), 'operator' => 'IN')
$taxonomies = implode(',', $taxonomy_arr);
// https://wordpress.stackexchange.com/questions/25076/how-to-filter-wordpress-search-excluding-post-in-some-custom-taxonomies
$taxonomy_query = array('relation' => 'AND', $taxonomies);
$query->set('tax_query', $taxonomy_query);
}
return $query;
}
add_filter( 'pre_get_posts', 'custom_search_filter', 999 );
Заранее спасибо.

Переменная $query
в фильтре представляет собой объект WP_Query
, поэтому не следует передавать новый объект WP_Query
в метод для установки его свойств.
Вопрос, из которого вы скопировали код, некорректно использовал действие, что могло быть причиной вашей проблемы.
Да, tax_query
можно использовать внутри действия pre_get_posts
или аналогично, подключив parse_request
, request
или parse_query
.
Вот пример:
Указание пользовательской таксономии для поисковых запросов
function search_filter_get_posts( $query ) {
if( !$query->is_search || is_admin() )
return;
$taxquery = array(
array(
'taxonomy' => 'career_event_type',
'field' => 'term_id',
'terms' => array( 35, 19, 6 ),
'operator'=> 'IN'
)
);
$query->set( 'tax_query', $taxquery );
}
add_action( 'pre_get_posts', 'search_filter_get_posts' );
Хотя стоит отметить, что более точные условия могут помочь избежать изменений в запросах, которые вы не собирались модифицировать.
Например, если вы используете пользовательскую форму поиска для поиска по пользовательскому типу записи, добавление скрытого поля (или даже выпадающего списка) для установки post_type
поможет обеспечить дополнительную специфичность условий.
<input type="hidden" name="post_type" id="post_type" value="my_post_type" />
Тогда в действии/фильтре pre_get_posts
(или его эквиваленте) будет больше информации для проверки того, что мы модифицируем правильный тип запроса.
'my_post_type' === $query->query['post_type']
или
'my_post_type' === get_query_var( 'my_post_type' )
Можно пойти дальше и использовать параметр запроса, который не ожидается в поисковом запросе, но поддерживается WordPress, просто как флаг для вашего действия/фильтра.
<input type="hidden" name="author_name" id="author_name" value="my_special_guy" />
Это предоставляет еще один условный параметр для вашего действия, и вы можете просто сбросить значение перед тем, как оно попадет в запрос.
set_query_var( 'author_name', '' );

можете привести рабочий пример установки tax_query внутри действия pre_get_posts?

$tax_query - это объект, содержащий вложенный массив. Вы не можете переопределить объект вложенным массивом.

$tax_query
не является объектом, хотя $query
является (это экземпляр WP_Query
).

Разве это не перезаписывает tax_query полностью? Не следует ли добавить $taxquery к текущим данным в аргументе tax_query?

@hot_barbara В текущем виде это перезапишет tax_query. Вот версия, которая добавит к текущему запросу: $taxquery = array( 'relation' => 'OR', array( 'taxonomy' => 'career_event_type', 'field' => 'id', 'terms' => array( 52 ), 'operator'=> 'NOT IN' ) );

@t31os Не должны ли значения ключа массива "field" быть "term_id" вместо "id"? Согласно https://developer.wordpress.org/reference/classes/wp_query/#taxonomy-parameters, возможные значения: 'term_id', 'name', 'slug' или 'term_taxonomy_id'. Значение по умолчанию - 'term_id'. Значение 'id' там вообще не упоминается.

Запросы к таксономиям требуют, чтобы вы также установили объект tax_query в запросе, так как запрос уже был обработан. Смотрите мой ответ на Изменение страниц таксономий для исключения элементов в дочерних таксономиях.
