wp_schedule_single_event() — как, используя WP_Cron, запланировать задачу, которая выполнится в определённое время.

Этой функцией я начинаю серию постов про планировщик WordPressWP Cron. Никакой обобщающей статьи у меня не будет, поэтому постараюсь излагать последовательно и ничего не забыть, при необходимости буду ссылаться на другие статьи.

Вступление. Пара слов про формат UNIX времени.

Пожалуй нужно хоть вкратце осветить этот вопрос, потому как WP_Cron только такое время и использует. Итак, для незнающих — UNIX-формат времени измеряется в секундах и равен количеству секунд, прошедших с момента зарождения мира с 1 января 1970 года.

Если вы захотите узнать больше об этом формате, то википедия вам в помощь, я же покажу лишь несколько примеров, которые могут быть полезны и тогда уже перейдём к WP Cron.

/*
 * time() выводит текущее время в UNIX-формате
 * так как оно в секундах, то при каждом обновлении страницы значение будет отличаться
 */
echo time(); // 1454835955
 
/*
 * используя функцию date(), вы можете перевести время в более удобный формат
 * кстати говоря, второй параметр date() по умолчанию является значением time() - текущим временем
 */
echo date('Y-m-d', 1454835955); // 2016-02-07 (год-месяц-день)
echo date('F j, Y H:i', 1454835955); // February 7, 2016 13:10
 
/*
 * очень удобна функция strtotime(), которая позволяет наоборот вернуться к UNIX-времени
 */
echo strtotime( '2016-02-07' ); // 1454788800 (если всё это поместим в date(), то изменим отображаемый формат)
echo strtotime( '+1 day' ) // завтра в это же время, если + не указан, он опускается
echo strtotime( '-2 day' ) // вчера в это же время, знаю, что 2 - это уже множественное число, но "s" на конце можно указывать, а можно нет
echo strtotime( '+1 year 3 months 1 week 3 days 2 hours 30 minutes 55 seconds' ); // всё, что душе угодно
echo strtotime( 'next Sunday' ); // следующее воскресенье
echo strtotime( 'last Monday' ); // прошлый понедельник

Думаю мы вполне можем ограничиться этими 2-3 функциями, чтобы без труда начать планировать задачи в WP Cron.

wp_schedule_single_event()

wp_schedule_single_event( $timestamp, $hook, $args = array() )
$timestamp
(целое число) Дата и время, когда функция будет запущена.

А теперь внимание: Чем меньше посещаемость вашего сайта, тем меньше шанс того, что запланированная задача будет выполнена точно по расписанию. Работает это так — кто-то (или вы) зашёл на ваш сайт, и если на данный момент имелись запланированные задачи, время выполнения которых уже наступило, то они будут выполнены.

$hook
(строка) Название хука, к которому обратится wp_schedule_single_event(). То есть wp_schedule_single_event() обратилась к указанному хуку — и сразу выполнились все функции, которые были на него повешены.

И ещё кое-что, функция будет возвращать false и отказываться планировать следующий хук с таким же названием, если до выполнения последнего запланированного такого же хука осталось больше, чем 10 минут. Другими словами, если хук ещё не выполнялся, вы можете запланировать ещё один такой же, но только при условии, что предыдущий выполнится в ближайшие 10 минут.

Однако данное правило не срабатывает, если третьим аргументом в хук были переданы какие-либо уникальные параметры.

$args
(массив) Массив параметров, которые можно передать в хук, а соответственно и во все функции, которые на него повешены.

На один и тот же хук спокойно можно запланировать много задач с разными параметрами.

Примеры

1. Изменяем email, указанный в настройках сайта через 10 минут после активации темы

Не знаю, кому это может понадобится, но сейчас моя главная цель — показать весь процесс в действии и чтобы для этого было достаточно вставить код в functions.php вашей темы.

// функция, которая поменяет email в настройках
function true_cherez_10_min() {
	update_option('admin_email','no-reply@truemisha.ru');
}
 
// этот хук и будет запускаться через 10 минут, я повесил на него только одну функцию (смены емайла), но можно и несколько
add_action( 'true_hook_1', 'true_cherez_10_min' );
 
// так как мы не хотим, чтобы ивент пытался планироваться каждый раз при обновлении страницы, то давайте повесим его на активацию темы
if( $_GET['activated'] == 'true' )
	wp_schedule_single_event( time() + 600, 'true_hook_1' ); // 600 секунд это 10 минут, если кто не знал :)

Ок, вставили в functions.php? Теперь нам нужно сменить тему на другую, а потом снова на эту же. После заходим на сайт через 10 минут и радуемся результату (возможно придётся лишний раз обновить страницу).

2. Удаляем пост с конкретным ID через 5 минут, а потом ещё через 5 минут удаляем пост с другим ID.

Для воспроизведения этого примера вам понадобятся два поста, которых не жалко, хотя любые подойдут, так как мы не будем удалять их полностью, а перенесём в корзину (если только корзина у вас не отключена). Ну и вторая WP тема, так как планировать мы будем при смене темы.

Здесь я хочу обратить ваше внимание, что не всегда нужно создавать свою функцию, ведь вполне возможно, что в WordPress уже есть функция, которая выполняет нужную нам задачу. В данном случае это wp_trash_post().

// последний параметр хука - количествово аргументов - у нас он один, у функции wp_trash_post() (какое счастье!) тоже
add_action( 'true_my_hook_2', 'wp_trash_post', 10, 1 );
 
if( $_GET['activated'] == 'true' ) {
	// создаем две задачи на один хук, но с разными аргументами (IDы постов)
	wp_schedule_single_event( time() + 300, 'true_my_hook_2', array( 2 ) );
	wp_schedule_single_event( strtotime('+10 minutes'), 'true_my_hook_2', array( 5 ) ); // для разнообразия я задал время немного по-другому
}

3. Как отследить запланированные задачи?

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

Если вы уже использовали код из предыдущего примера и ждёте 10 минут, то давайте глянем на наши задачи, пока они не выполнились и не исчезли из очереди! Это можно сделать при помощи кода:

$cron_zadachi = get_option( 'cron' );
var_dump( $cron_zadachi );

Или при помощи плагина Advanced Cron Manager (добавляйте прямо через админку). Захожу в Инструменты > Cron Manager… а вот и они:

Плагин Advanced Cron Manager позволяет очень удобно просмотреть все задачи, висящие в очереди на выполнение.

Значение single в колонке Schedule как раз означает, что задача выполнится только 1 раз.

4. Как снять запланированную задачу

Если те 10 минут всё ещё не прошли… то можно попробовать отменить удаление второго поста из вышеприведённого примера при помощи функции wp_clear_scheduled_hook(). Конечно, в нашем случае функция не сделает ничего, если мы не укажем вторым параметром ID поста.

wp_clear_scheduled_hook( 'true_my_hook_2', array( 5 ) );

Не хочу лишний раз напоминать, если вы вставляете эту функцию прямиком в functions.php, то только в целях тестирования! Вы ведь не хотите запускать её каждый раз при обновлении страницы.

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

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

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

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

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

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