Новый параметр date_query для WP_Query в WordPress. Офигенные фильтры постов по дате.

До версии движка 3.7, WP_Query имел весьма скудные параметры для получения постов по датам, ну правда ещё была небольшая хитрость, которая позволяла вывести посты, опубликованные в определенный промежуток времени.

Версия WordPress 3.7 принесла нам потрясающий date_query, по сути это аналог meta_query и tax_query, но только для дат, который полностью развязывает нам руки в отношении фильтрации постов по дате/времени.

1. Заменяем старые параметры даты на date_query.

Так же, как и раньше, вы можете выводить посты, опубликованные в определенный год, месяц, день, час, минуту и так далее. Кроме того, старый вариант задания даты никуда не делся, вы спокойно можете использовать и его:

$params = array(
	'year' => 2014, // год
	'monthnum' => 12, // номер месяца, декабрь
	'day'	=> 31 // число
);
$dateq = new WP_Query( $params );

Но можете и перейти на новый формат задания даты через date_query:

$params = array(
	'date_query' => array(
		array(
			'year'  => 2014,
			'month' => 12, // обратите внимание, раньше было monthnum, теперь просто month
			'day'   => 31,
		),
	),
);
$dateq = new WP_Query( $params );

2. Вывод постов за определенный промежуток времени.

Пример 1. Посты по дням недели.

Вот тут определенно есть, где разгуляться. И начну я с простого примера — как выводить скажем посты, опубликованные с понедельника по пятницу, или наоборот, в выходные.

$params = array(
	'date_query' => array(
		array(
			'dayofweek' => array( 1, 5 ), // дни недели, 1 - понедельник, 5 - пятница
			'compare'   => 'BETWEEN'
		)
	)
);
$dateq = new WP_Query( $params );

Параметр compare, равный BETWEEN означает, что нужно взять промежуток между, в данном случае между понедельником и пятницей.

Также, если вы уберете BETWEEN, а также замените значение параметра dayofweek на числовое (от 1 до 7), то тогда у вас будут выводиться посты за какой-то определенный день недели.

Если вам нужно вывести посты за несколько не идущих друг за другом дней недели, то не надейтесь указать массив в dayofweek — он всё равно работать не будет, тем не менее ваша задача реализуема, вам лишь понадобится несколько условий, о них — в следующем примере.

Пример 2. Посты по дням недели и по временному промежутку

Окей, теперь давайте помимо условия выборки постов, опубликованных в будни, поставим также условие, чтобы эти посты были опубликованы в определенный промежуток времени.

Вы наверное уже заметили, что date_query это массив массивов, так вот, каждый массив внутри date_query — это условие, и сейчас нам как раз потребуется задать несколько таких условий.

$params = array(
	'date_query' => array(
		array(
			'hour'      => 8, // с 8 часов утра (24-часовой формат времени)
			'compare'   => '>=', // больше либо равно
		),
		array(
			'hour'      => 16,
			'compare'   => '<=', // меньше либо равно
		),
		array(
			'dayofweek' => array( 1, 5 ), // дни недели, 1 - понедельник, 5 - пятница
			'compare'   => 'BETWEEN'
		),
		'relation' => 'AND' // этот параметр равен AND по умолчанию и поэтому его можно не указывать
	)
);
$dateq = new WP_Query( $params );

По умолчанию, WP_Query будет возвращать посты, удовлетворяющие каждому из заданных условий. Если вам достаточно, чтобы хотя бы одно условие выполнялось, добавьте в конец date_query параметр relation, равный OR.

Пример 3. Посты между двумя датами

Задать промежуток между скажем 8 январем 2016 года и 20 мартом 2016 проще простого, при помощи параметров before и after.

$params = array(
	'date_query' => array(
		array(
			'after'     => array( // после этой даты
				'year'  => 2016,
				'month' => 1,
				'day'   => 8,
			),
			'before'    => array( // до этой даты
				'year'  => 2016,
				'month' => 3,
				'day'   => 20,
			),
			// 'inclusive'=> true
		)
	)
);
$dateq = new WP_Query( $params );

Обратите внимание, в примере выше посты по умолчанию будут выводиться только в промежутке между указанными датами, сами же указанные даты в этот промежуток не входят. Если же вы хотите включить их в промежуток, то добавьте в date_query параметр inclusive равный true.

Параметры before и after также позволяют задавать время в таком формате 2015-02-17 23:59:59.

Пример 4. Вывод постов, опубликованных столько-то времени спустя

Что это значит?

Хорошо, давайте для начала выведем записи, опубликованные более двух лет назад (before):

$params = array(
	'date_query' => array(
		array(
			'before' => '2 year ago' // можете указать и множественное число - 1 years ago, 2 years ago
		)
	)
);
$dateq = new WP_Query( $params );

Подойдут также значения параметров: 2 week ago, 3 hours ago, 1 minute ago, 5 month ago.

Теперь к условию добавим ещё одно — из выбранных постов нам нужно выбрать те, которые обновлялись за последние 3 дня (after).

$params = array(
	'date_query' => array(
		array(
			'before' => '2 year ago',
		),
		array(
			'column' => 'post_modified', // фильтруем не по дате публикации, а по дате обновления поста
			'after'  => '3 day ago',
		)
	)
);
$dateq = new WP_Query( $params );

Все параметры

date_query
(массив)

year
Год, 4х-значное целое число, например 2015.
month
Номер месяца (целое, от 1 до 12).
week
Номер недели года (целое число, от 0 до 53).
day
День месяца, число (целочисленное, от 1 до 31).
hour
Час (значение от 0 до 23).
minute
Минута (0 — 59).
second
Секунда (0 — 59).
dayofweek
День недели. Целое число от 1 до 7, либо массив при использовании в качестве промежутка (когда compare равен BETWEEN).
after
Когда нужно вывести посты, опубликованные после указанного в этом параметре времени.
before
Когда нужно вывести посты, опубликованные до указанного в этом параметре времени. Значение можно задать в виде массива или строки, смотрите примеры выше.
inclusive
Только для параметров before и after, нужно ли включать конечные даты в промежуток. Логическое значение
compare
(строка) оператор сопоставления, возможные значения: ‘=’ (по умолчанию), ‘!=’, ‘>’, ‘>=’, ‘<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'EXISTS' и 'NOT EXISTS'.
column
Благодаря этому параметры вы можете работать не только с обычной датой публикации постов (post_date, по умолчанию), но и с датой публикацией по GMT (post_date_gmt), а также и с датой последнего обновления поста (post_modified, post_modified_gmt).
relation
Логическое соотношение между условиями, может принимать два значения — AND (И — все условия должны выполняться), OR (ИЛИ — достаточно, чтобы хотя бы одно условие выполнялось).
Подпишитесь, чтобы раз в неделю получать свежие статьи с блога по email.

Смотрите также

Оставить комментарий / вопрос

phpjsHTMLCSSSQLПросто код
  Для того, чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или авторизуйтесь на сайте.
Получайте новости блога по email или следите за мной в социальных сетях.
  • Миша: Да, точно)

  • Владимир: и на третьей строке не хватает скобки ) закрывающей if :)

  • Миша: Добрый вечер! Рекомендую получить ID пользователя через функцию get_current_user_id().

  • Дмитрий: Миша, подскажите пожалуйста, я использую такой редирект, но он не срабатывает: add_action( 'template_redirect', funct...

  • Миша: Ну как не определена - это аргумент функции. Или я просто вас не до конца понимаю.