Есть ли способ использовать $query->set('tax_query') в фильтре pre_get_posts?

30 нояб. 2011 г., 22:10:42
Просмотры: 66.3K
Голосов: 20

Есть ли способ использовать $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 );

Заранее спасибо.

2
Комментарии

Почему вы передаете объект WP_Query в метод установки аргументов?

t31os t31os
1 дек. 2011 г. 03:06:26

Да, я был неправ, теперь я понял, используя eval для преобразования строки в массив (и я абсолютно уверен, что строка безопасна). Спасибо.

José Pablo Orozco Marín José Pablo Orozco Marín
1 дек. 2011 г. 14:14:13
Все ответы на вопрос 2
7
43

Переменная $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', '' );
1 дек. 2011 г. 15:32:04
Комментарии

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

helgatheviking helgatheviking
22 февр. 2012 г. 22:05:44

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

AlxVallejo AlxVallejo
17 апр. 2013 г. 22:11:06

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

t31os t31os
18 апр. 2013 г. 00:29:10

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

hot_barbara hot_barbara
25 мая 2018 г. 22:33:43

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

rambillo rambillo
21 янв. 2020 г. 00:20:20

@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' там вообще не упоминается.

Alexander Behling Alexander Behling
22 февр. 2022 г. 11:38:59

Конечно, так и должно было быть, я обновил ответ, чтобы внести некоторые исправления/дополнения.

t31os t31os
20 окт. 2022 г. 08:08:12
Показать остальные 2 комментариев
0

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

3 мая 2013 г. 02:17:30