Использование запросов WP_Query в WordPress — часть 4 (хуки и фильтры)
Этим уроком мы продолжаем серию уроков по работе с запросами в базу данных WP_Query в ВордПресс. Сегодня мы сосредоточимся на связанных с запросом фильтрах (filters) и хуках (действия, actions). Это должно придать вам еще больше уверенности в своих силах в качестве WP-программиста.
Как вы уже знаете, при работе с классом WP_Query мы можем задействовать не только специальные функции, но и дополнительные хуки и фильтры. И сегодняшний практический урок посвящен именно этому.
Специальные фильтры, связанные с классом WP_Query
Давайте подробнее рассмотрим фильтры WordPress, специально «настроенные» под класс WP_Query. В предыдущем уроке мы рассмотрели 10 специальных функций этого класса, а сегодня продолжим и рассмотрим основные фильтры и хуки WP_Query в WordPress.
Фильтрация количества найденных публикаций запроса: found_posts
Этот фильтр позволяет изменять количество найденных элементов, несмотря на ограничения, установленные аргументом posts_per_page запроса WP_Query.
Использование этого фильтра будет особенно полезным, если необходимо создать, например, специальную разбивку результатов на отдельные страницы.
Фильтрация запроса для возврата найденных публикаций: found_posts_query
Количество найденных элементов в результате запроса вычисляется с помощью команды SQL SELECT FOUND_ROWS(). С помощью этого фильтра вы можете изменить данную команду.
Фильтрация всего SQL запроса: posts_request
Если вы хотите внести изменения в уже сформированный SQL-запрос, то можете воспользоваться данным фильтром. Другими словами, этот фильтр полностью «перерабатывает» SQL-запрос, сформированный классом WP_Query.
Фильтрование результирующего массива: posts_results
Если вам нужно изменить результирующий PHP массив, полученный в результате запроса WP_Query (SQL-команды), воспользуйтесь этим фильтром. Обратите внимание, что данный фильтр работает с необработанным (row) массивом, полученным SQL запросом.
Фильтрование результирующего (обработанного) массива: the_posts
В отличие от предыдущего фильтра posts_results, фильтр the_posts срабатывает после внутренней обработки массива. Это может быть полезно, например, если вам нужна проверка неопубликованных и закрепленных публикаций.
Фильтрация условия SELECT в запросе: posts_fields
Команда SELECT в запросе SQL определяет, какие поля базы данных будут выбраны из результирующих записей, а этот фильтр поможет «отфильтровать» ее.
Фильтрация условия LIMIT в запросе: post_limits
Команда LIMIT запроса SQL устанавливает ограничения запроса, и этот фильтр поможет «отфильтровать» ее.
Фильтрация условия DISTINCT запроса: posts_distinct
Команда DISTINCT в запросе SQL указывает, что запрос должен возвращать только уникальные результаты, а этот фильтр поможет «отфильтровать» ее. Первоначально WP_Query не возвращает только уникальные результаты, но при использовании этого фильтра запрос будет скорректирован и возвращены только уникальные результаты.
Фильтрация условия WHERE в запросе: posts_where
Команда WHERE в запросе SQL используется для операторов SELECT, INSERT, UPDATE или DELETE. Хотя в классе WP_Query сделана вся необходимая работа для фильтрации результатов, для большего контроля вы можете использовать этот фильтр.
ДОПОЛНИТЕЛЬНО: для фильтрации условия WHERE в запросе после вычисления пейджинга используйте фильтр posts_where_paged. Этот фильтр является итерацией к фильтру posts_where, который можно использовать с запросами разбивки на страницы (пейджинг, paging).
ДОПОЛНИТЕЛЬНО: для фильтрации условия WHERE в поисковом запросе используйте фильтр posts_search, который можно использовать для изменения SQL запроса при получении результатов поиска в WordPress.
Фильтрация условия JOIN запроса: posts_join
Оператор JOIN SQL запрос позволяет работать с несколькими таблицами базы данных, а этот фильтр поможет «отфильтровать» его. Но нужно использовать его очень осторожно.
ДОПОЛНИТЕЛЬНО: для фильтрации условия JOIN запроса после вычисления пейджинга, используйте фильтр posts_join_paged, который подобно posts_where_paged работает с запросами разбивки на страницы.
Фильтрация предложения ORDER BY в запросе: posts_orderby
Предложение (оператор) ORDER BY в SQL запросе используется для упорядочения запроса (сортировки), а этот фильтр поможет «отфильтровать» его.
Фильтрация оператора GROUP BY в запросе: posts_groupby
Оператор (предложение) GROUP BY запроса SQL заставляет запрос возвращать «сгруппированные» результаты за столбцами базы данных, а этот фильтр поможет «отфильтровать» его и указать, как вам нужно группировать результаты.
Фильтрация всех элементов запроса: posts_clauses
Если вы хотите иметь дело со всеми операторами одновременно, для этого случая есть соответствующий фильтр: posts_clauses. С помощью этого фильтра у вас будет контроль над элементами запроса SELECT, WHERE, DISTINCT, JOIN, GROUP BY, ORDER BY и LIMIT.
Хуки (действия, экшены, actions), связанные с запросом WP_Query
А теперь давайте перейдем от рассмотрения фильтров, связанных с классом WP_Query, к рассмотрению другого вида «зацепок»: хуков.
Если нужно «вклиниться» в запрос перед его исполнением: pre_get_posts
Прежде чем запрос будет проанализирован, у вас есть возможность взаимодействовать с ним (например, чтобы добавить дополнительные переменные) с помощью этого хука. Ниже приведен практический пример возможного применения (если есть необходимость исключить определенную категорию из основного цикла):
<?php
add_action( 'pre_get_posts', 'sebweo_exclude_some_category' );
function sebweo_exclude_some_category( $wp_query ) {
// добавьте категорию к массиву категорий для исключения
$excluded = array( 25 ); // если нужно исключить из цикла категорию под ID 25
// $excluded = array('-1' ); // если нужно исключить самую первую категорию из цикла
set_query_var( 'category__not_in', $excluded );
// $wp_query->set( 'category__not_in', $excluded ); // другой вариант написания предыдущего предложения
}
?>
Если требуется больше контроля над обработкой запроса: parse_query
В отличие от предыдущего pre_get_posts, который вмешивается в запрос до установки переменных запроса, хук parse_query будет «вмешиваться» в процесс уже после установки всех переменных для запроса. Его можно использовать, например, если вам нужно проверить текущие переменные и при необходимости откорректировать это.
Если вам нужно изменить объект публикации: the_post
Термин the_post может немного озадачить, поскольку это может быть названием хука действия, или связанной с классом WP_Query функции, или же методом WP_Query класса.
В данном случае речь пойдет о хуке, позволяющем изменять объект публикации сразу после формирования запроса и его установки. То есть, используя этот хук, вы можете напрямую изменить результат. Ниже показан простой практический пример этого:
<?php
add_action('the_post', 'sebweo_novinky_badge');
function sebweo_novinky_badge($post)
{
if (is_single() && in_category('novinky')) {
// если это одиночный пост и в категории с ID (или слагом) novinky – показать этот бейдж
echo '<div class="novinky-badge">' . __('НОВИНКИ', 'i18n') . '</div>';
}
}
?>
Вот и все, тема сегодняшнего урока исчерпана. Вы только поверхностно познакомились с хуками и фильтрами, ведь это не только интересная тема, но и очень комплексная, о которой можно много говорить и писать. Но это выходит за рамки текущего урока серии. В дальнейших уроках данная тема будет подробнее рассмотрена и раскрыта.
В следующей части уроков мы поговорим о свойствах и методах класса WP_Query, которые позволят вам иметь больше контроля над запросом.