WP_Query — это мощный класс WordPress для выборки записей из базы данных. Но часто базовых параметров недостаточно, и возникает задача добавить дополнительные условия: например, фильтровать по нескольким метаполям, проводить сложные сравнения или манипулировать SQL-запросом напрямую. В этой статье разберём, как расширить WP_Query, чтобы создавать гибкие запросы под любые задачи.
Основы добавления условий в WP_Query
WP_Query принимает множество параметров, в том числе meta_query, tax_query, date_query и другие. Эти параметры позволяют строить сложные условия без прямого вмешательства в SQL. Например, для выборки записей с определённым метаполем и значением:
$args = [
'post_type' => 'post',
'meta_query' => [
[
'key' => 'wpinc_custom_field',
'value' => 'value1',
'compare' => '='
]
]
];
$query = new WP_Query($args);Но иногда нужно добавить условия, которых нет в стандартных параметрах, например, сравнить два метаполя между собой, или использовать сложные операторы SQL. Для таких случаев существуют хуки.
Использование хуков для расширения WP_Query
WordPress предоставляет несколько фильтров для изменения SQL-запроса, который формирует WP_Query. Вот основные из них:
posts_where— позволяет добавить свои условия в часть WHERE.posts_join— позволяет добавить JOIN к таблицам.posts_orderby— изменить часть ORDER BY.
Например, чтобы выбрать записи, у которых значение метаполя field_one больше значения метаполя field_two, нужно подключиться к таблице постмета дважды и добавить условие сравнения:
add_filter('posts_join', 'wpinc_posts_join_fields_compare');
function wpinc_posts_join_fields_compare($join) {
global $wpdb;
$join .= "
INNER JOIN {$wpdb->postmeta} AS pm1 ON ({$wpdb->posts}.ID = pm1.post_id AND pm1.meta_key = 'field_one')
INNER JOIN {$wpdb->postmeta} AS pm2 ON ({$wpdb->posts}.ID = pm2.post_id AND pm2.meta_key = 'field_two') ";
return $join;
}
add_filter('posts_where', 'wpinc_posts_where_fields_compare');
function wpinc_posts_where_fields_compare($where) {
global $wpdb;
$where .= " AND CAST(pm1.meta_value AS UNSIGNED) > CAST(pm2.meta_value AS UNSIGNED) ";
return $where;
}
add_action('pre_get_posts', 'wpinc_modify_query_for_fields_compare');
function wpinc_modify_query_for_fields_compare($query) {
if (is_admin() || !$query->is_main_query()) {
return;
}
// Добавим метаполя для подгрузки, чтобы фильтры сработали
$query->set('meta_query', []);
}В этом примере мы дважды присоединяем таблицу postmeta с разными алиасами, чтобы сравнить значения двух разных метаполей. Такое нельзя сделать стандартными параметрами WP_Query.
Пример: выборка по нескольким условиям с OR и AND
Для сложных условий с вложенными логическими операторами можно использовать массивы в meta_query с параметром relation. Рассмотрим пример, когда нужно выбрать записи, у которых метаполе status равно "published" ИЛИ дата создания позже 2024-01-01 И категория — «Новости».
$args = [
'post_type' => 'post',
'tax_query' => [
[
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'novosti',
],
],
'meta_query' => [
'relation' => 'OR',
[
'key' => 'status',
'value' => 'published',
'compare' => '=',
],
[
'key' => 'date_created',
'value' => '2024-01-01',
'compare' => '>',
'type' => 'DATE',
],
],
'date_query' => [
[
'after' => '2024-01-01',
],
],
];
$query = new WP_Query($args);Обратите внимание, что meta_query и tax_query можно комбинировать, а также для более сложных условий можно использовать отдельные фильтры.
Как избежать ошибок при кастомизации WP_Query
Расширение WP_Query с помощью фильтров — мощный инструмент, но требует аккуратности. Несколько советов:
- Всегда проверяйте, что ваш фильтр применяется только к нужному запросу, например, через проверку
$query->is_main_query()и!is_admin(). - Используйте глобальный объект
$wpdbдля корректного указания таблиц и алиасов. - Не забывайте очищать фильтры после выполнения, если они нужны только для одного запроса.
- Проверяйте типы данных, особенно при сравнении числовых значений в SQL — используйте
CASTдля преобразования.
Использование плагина Clearfy Pro для расширения WP_Query
Для тех, кто не хочет писать код вручную, полезен плагин Clearfy Pro. Он позволяет улучшить работу с запросами и оптимизировать производительность, а также встроить дополнительные возможности фильтрации без кодинга.
Для интеграции с WP_Query Clearfy Pro предоставляет интерфейс для настройки дополнительных условий, которые затем автоматически добавляются к запросам.
Заключение
WP_Query — фундаментальный инструмент WordPress, и умение расширять его функционал позволяет решать нестандартные задачи выборки данных. Использование фильтров posts_join, posts_where и других, а также правильная организация параметров запроса позволит создавать гибкие и мощные выборки под любые проекты. При этом не забывайте об осторожности — неправильное вмешательство в SQL запросы может ухудшить производительность и привести к ошибкам. Используйте плагины, такие как Clearfy Pro, для упрощения и безопасности.