Вопрос или проблема
У меня есть пользовательский тип записи, для которого я пытаюсь ограничить результаты в поиске.
Пользовательский тип записи – это сделка/купон, с датой начала и окончания для каждой из сделок.
Что я пытаюсь сделать, так это показывать эти записи в поиске:
- Для нерегулярных событий… Показать записи, где дата окончания сегодня или после.
ИЛИ
- Для регулярных событий ограничить показ только тех событий, дата окончания которых между сегодняшним днем и не превышающей 7 дней.
Каждый из этих запросов работает идеально по отдельности, но я не могу объединить их…
function search_pre_get_posts( $query ) {
if ( $query->is_search() && $query->is_main_query() ) {
$recurring_count = am_get_recurring_count($post->ID);
// Показать нерегулярные события с датой окончания сегодня или позже
if ($recurring_count == 0){
$currentdate = date('Y-m-d');
$query->set(
'meta_query',
array(
'relation' => 'OR',
array(
'key' => 'am_enddate',
'compare' => '>=',
'value' => $currentdate,
),
array(
'key' => 'am_enddate',
'compare' => 'NOT EXISTS',
)
)
);
$query->set( 'orderby', 'meta_value' );
$query->set( 'order', 'ASC' );
} else {
// Показать регулярные события с датой окончания сегодня или позже, которые не превышают 7 дней.
$currentdate = date('Y-m-d');
$enddate = strtotime(date('Y-m-d') . "+7 days");
$enddate = date('Y-m-d',$enddate);
$query->set(
'meta_query',
array(
'relation' => 'OR',
array(
'key' => 'am_enddate',
'compare' => 'NOT EXISTS',
),
array(
'relation' => 'AND',
array(
'key' => 'am_enddate',
'compare' => '>=',
'value' => $currentdate,
),
array(
'key' => 'am_enddate',
'compare' => '<=',
'value' => $enddate,
)
)
)
);
$query->set( 'orderby', 'meta_value' );
$query->set( 'order', 'ASC' );
}
}
}
add_action( 'pre_get_posts', 'search_pre_get_posts' );
Как насчет того, чтобы убрать условие if и объединить запросы во что-то вроде этого:
'meta_query',
array(
'relation' => 'OR',
array(
array(
'relation' => 'AND',
array(
'key' => 'am_get_recurring_count',
'compare' => '=',
'value' => '0',
),
array(
'relation' => 'OR',
array(
'key' => 'am_enddate',
'compare' => '>=',
'value' => $currentdate,
),
array(
'key' => 'am_enddate',
'compare' => 'NOT EXISTS',
)
)
)
)
array(
array(
'relation' => 'AND',
array(
'key' => 'am_get_recurring_count',
'compare' => '!=',
'value' => '0',
),
array(
'relation' => 'OR',
array(
'key' => 'am_enddate',
'compare' => 'NOT EXISTS',
),
array(
'relation' => 'AND',
array(
'key' => 'am_enddate',
'compare' => '>=',
'value' => $currentdate,
),
array(
'key' => 'am_enddate',
'compare' => '<=',
'value' => $enddate,
)
)
)
)
)
)
Я еще не успел это протестировать. Пожалуйста, дайте мне знать, если это сработает.
Попробуйте это
function search_pre_get_posts( $query ) {
if ( $query->is_search() && $query->is_main_query() ) {
$currentdate = date('Y-m-d');
$enddate = strtotime(date('Y-m-d') . "+7 days");
$enddate = date('Y-m-d',$enddate);
$query->set(
'meta_query',
array(
'relation' => 'OR',
array(
'key' => 'am_enddate',
'compare' => 'NOT EXISTS',
),
array(
'relation' => 'OR',
array(
'key' => 'am_enddate',
'compare' => '>=',
'value' => $currentdate,
),
array(
'key' => 'am_recurrence_id',
'compare' => 'NOT EXISTS',
)
),
array(
'relation' => 'AND',
array(
'key' => 'am_enddate',
'compare' => '>=',
'value' => $currentdate,
),
array(
'key' => 'am_enddate',
'compare' => '<=',
'value' => $enddate,
),
array(
'key' => 'am_recurrence_id',
'compare' => 'EXISTS',
)
)
)
);
$query->set( 'orderby', 'meta_value' );
$query->set( 'order', 'ASC' );
}
}
add_action( 'pre_get_posts', 'search_pre_get_posts' );
Ответ или решение
Условные Запросы в WP_Query для Поиска
Вам необходимо ограничить результаты поиска для пользовательского типа записей (CPT), связанным с купонами или предложениями, в зависимости от наличия даты окончания. Рассмотрим, как можно реализовать это через WP_Query
, чтобы фильтровать посты по указанным условиям.
Задача
У вас есть два критерия фильтрации:
-
Для одноразовых событий: Показать посты, у которых дата окончания сегодня или позже.
-
Для повторяющихся событий: Показать посты, у которых дата окончания находится в диапазоне от сегодняшней даты до 7 дней вперёд.
Необходимо объединить эти два запроса в одну конструкцию, чтобы они работали совместно.
Реализация
Для решения данной задачи мы будем использовать хук pre_get_posts
, который позволяет модифицировать запрос перед его выполнением. Ниже приведённый код с детальным объяснением будет выполнять требуемую логику:
function search_pre_get_posts( $query ) {
// Проверяем, что это основной запрос для страницы поиска
if ( $query->is_search() && $query->is_main_query() ) {
$currentdate = date('Y-m-d');
$enddate = date('Y-m-d', strtotime("+7 days"));
$query->set(
'meta_query',
array(
'relation' => 'OR',
// Условия для одноразовых событий
array(
'relation' => 'AND',
array(
'key' => 'am_get_recurring_count',
'value' => '0',
'compare' => '='
),
array(
'relation' => 'OR',
array(
'key' => 'am_enddate',
'value' => $currentdate,
'compare' => '>='
),
array(
'key' => 'am_enddate',
'compare' => 'NOT EXISTS'
)
)
),
// Условия для повторяющихся событий
array(
'relation' => 'AND',
array(
'key' => 'am_get_recurring_count',
'value' => '0',
'compare' => '!='
),
array(
'relation' => 'OR',
array(
'key' => 'am_enddate',
'compare' => 'NOT EXISTS'
),
array(
'relation' => 'AND',
array(
'key' => 'am_enddate',
'value' => $currentdate,
'compare' => '>='
),
array(
'key' => 'am_enddate',
'value' => $enddate,
'compare' => '<='
)
)
)
)
)
);
$query->set( 'orderby', 'meta_value' );
$query->set( 'order', 'ASC' );
}
}
add_action( 'pre_get_posts', 'search_pre_get_posts' );
Объяснение кода
-
Проверка условий запроса: Мы проверяем, что это основной запрос и это поиск, чтобы не вмешиваться в другие типы запросов.
-
Дата и диапазон: Мы устанавливаем текущую дату и конечную дату через 7 дней, что позволяет нам использовать эти значения в метапоисках.
-
Мета-запрос: Мы строим сложный мета-запрос с использованием
'relation'
какOR
, чтобы объединить требования для каждого из событий:- Для одноразовых событий мы ищем посты с
am_get_recurring_count
равным 0 и, далее, определяем даты окончания. - Для повторяющихся событий мы отсекаем посты с
am_get_recurring_count
, не равным 0 и определяем как и для одноразовых события, ограничения для их дат окончания.
- Для одноразовых событий мы ищем посты с
-
Сортировка: Наконец, мы устанавливаем параметры сортировки по мета-значению, что позволяет управлять порядком отображения результатов.
Заключение
Этот подход позволяет эффективно комбинировать условия и оптимизировать вывод данных, обеспечивая нужный результат в поиске. Вы можете протестировать этот код и убедиться, что он соответствует вашим требованиям. Не забудьте проверить корректность выполнения каждого условия и при необходимости настроить метапараметры под вашу конкретную структуру данных.