Вопрос или проблема
Первый пост на этом форуме, прошу прощения, если деталей недостаточно.
Я пытаюсь использовать WP_Query, чтобы собрать CPT, у которых есть Advanced Custom Field (плагин WP) “Дата окончания”, это поле выбирается с помощью календаря. Я хочу, чтобы запрос возвращал все посты, которые находятся до их индивидуальной “Даты окончания”, и все посты, у которых нет “Даты окончания”, на случай, если пользователь не знает или не хочет добавлять ее. В общем, я не хочу, чтобы посты проходили через запрос, если “Дата окончания” уже прошла.
Ниже приведено то, что я пробовал до сих пор с небольшим успехом
$meta_query = array(
'relation' => 'OR',
array(
'key' => 'vacancy_end_date',
'value' => date('Ymd'),
'type' => 'DATE',
'compare' => '>='
),
array(
'key' => 'vacancy_end_date',
'value' => '',
'type' => 'DATE',
'compare' => '='
)
);
$args = [
'post_type' => 'vacancy',
// изначально 9
'posts_per_page' => -1,
'meta_key' => 'vacancy_end_date',
'meta_query' => $meta_query,
];
$posts = new \WP_Query($args);
В каком виде vacancy_end_date
хранится в вашей базе данных ACF? Убедитесь, что вы запрашиваете тот же формат. То есть date('Ymd')
выдает 20200421
, но ваша vacancy_end_date
может храниться в виде unix временной метки, что будет строкой вроде 1619028671
, так что вы никогда не получите совпадения.
Я не думаю, что вам нужна строка 'meta_key' => 'vacancy_end_date',
в $args
дополнительно к meta_query
.
https://generatewp.com/wp_meta_query/ предлагает вам сделать следующее:
$meta_query = array(
'relation' => 'OR',
array(
'key' => 'vacancy_end_date',
'value' => $date,
'compare' => '>=',
),
array(
'key' => 'vacancy_end_date',
'value' => '',
'compare' => '=',
),
);
$args = array(
'post_type' => 'vacancy',
'meta_query' => $meta_query,
);
$query = new WP_Query( $args );
Вам просто нужно точно определить $date
, как было упомянуто выше.
Это сработало. Ymd был правильным форматом даты. Чтобы получить посты, где не было добавлено значения, мне просто нужно было сделать ссылку на CPT без значения и установить его в NOT EXISTS.
$meta_query = [
'relation' => 'OR',
[
'key' => 'vacancy_end_date',
'value' => date('Ymd'),
'compare' => '>=',
],
[
'key' => 'vacancy_end_date',
'compare' => 'NOT EXISTS'
],
];
$args = [
'post_type' => 'vacancy',
'meta_query' => $meta_query,
'posts_per_page' => -1,
];
$posts = new \WP_Query($args);
Ваш код в основном выглядит правильно, но вы используете meta_query
для фильтрации posts
на основе поля “Дата окончания"
, и вы комбинируете условия с помощью отношения OR
, что подходит для вашего случая.
внесите корректировки в код, чтобы он работал правильно в вашем условии
Формат даты: Убедитесь, что формат даты в поле ACF соответствует формату, который вы используете в запросе. Похоже, вы используете формат ‘Ymd’, который предназначен для дат, подобных 20240214 (год-месяц-день). Убедитесь, что это совпадает с форматом, в котором ACF хранит дату.
Оператор сравнения: Корректируйте оператор сравнения для постов без “Даты окончания”. Вместо того чтобы использовать '='
, используйте 'NOT EXISTS'
. Это включит посты, где поле “Дата окончания” не существует
$meta_query = array(
'relation' => 'OR',
array(
'key' => 'vacancy_end_date',
'value' => date('Ymd'), // Корректируйте формат при необходимости
'type' => 'DATE',
'compare' => '>=',
),
array(
'key' => 'vacancy_end_date',
'compare' => 'NOT EXISTS', // Включите посты без Даты окончания
),
);
$args = array(
'post_type' => 'vacancy',
'posts_per_page' => -1,
'meta_query' => $meta_query,
);
$posts_query = new WP_Query($args);
Ответ или решение
Для выбора пользовательских типов записей (Custom Post Types, CPT) в WordPress с использованием WP_Query и фильтрации по полям, созданным с помощью плагина Advanced Custom Fields (ACF), необходимо учесть некоторые тонкости, связанные с хранением и обработкой данных. В данной ситуации мы будем рассматривать поле "End Date", которое хранится в формате даты.
1. Цели Запроса
Необходимо вернуть все записи, которые:
- Имеют дату "End Date" позже текущей даты.
- Или не имеют установленной даты "End Date".
2. Формат Даты
Перед созданием запроса важно убедиться, что формат даты, используемый в поле ACF, соответствует формату, который будет использоваться в запросе. В ACF формат хранения даты может быть задан как ‘Ymd’, что приведет к формату вида 20240421
(год-месяц-день).
3. Использование WP_Query
Для выполнения данного запроса будет использоваться meta_query
, который позволяет фильтровать записи по значению пользовательских полей.
Пример Закода
Вот как будет выглядеть конечный код запроса:
$meta_query = array(
'relation' => 'OR',
array(
'key' => 'vacancy_end_date',
'value' => date('Ymd'), // Текущая дата
'compare' => '>=', // Сравнение: больше либо равно
'type' => 'DATE', // Тип данных
),
array(
'key' => 'vacancy_end_date',
'compare' => 'NOT EXISTS', // Записи без установленной даты
),
);
$args = array(
'post_type' => 'vacancy', // Ваш пользовательский тип записи
'posts_per_page' => -1, // Получить все записи
'meta_query' => $meta_query, // Применяемый мета-запрос
);
$posts_query = new WP_Query($args);
// Обработка результатов
if ($posts_query->have_posts()) {
while ($posts_query->have_posts()) {
$posts_query->the_post();
// Здесь выводите информацию о записи
}
wp_reset_postdata(); // Сброс результатов запроса
} else {
// Обработка случая, если записи не найдены
}
4. Разбор Запроса
relation
: Установленное значение ‘OR’ указывает, что запись будет возвращена, если удовлетворяет хотя бы одному из условий.- Первый массив: Сравнивает значения поля
vacancy_end_date
с текущей датой. Если дата больше или равна текущей, запись будет включена в результаты. - Второй массив: Проверяет наличие значения в поле. Если поле не существует, запись также будет включена в результаты.
5. Итог
Данный запрос позволит извлечь из базы данных записи с выбранным пользовательским типом, которые либо еще актуальны (по дате), либо не имеют установленной даты окончания. Убедитесь, что ваш формат даты в ACF и в запросе совпадают для корректной работы.
Следуя описанным шагам, вы сможете эффективно использовать WP_Query для работы с пользовательскими полями, обеспечивая корректную фильтрацию записей на вашем сайте.