Функция wp_schedule_single_event()
позволяет запланировать задачу, которая выполнится в определённое время. Для этого используется планировщик задач WordPress – WP Cron.
Про UNIX-формат времени
Любые функции для создания запланированных задач в WordPress используют именно UNIX-формат времени. Суть его в том, что каждая любая точка во времени измеряется в секундах, прошедших с 1 января 1970 года. Например, в момент написания данного урока это в основном десятизначные числа типо 1454835955
.
Несколько примеров:
/* * 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' ); // прошлый понедельник
Исходя из этих примеров, можно сделать вывод, что нам достаточно всего лишь пары PHP-функций для передачи UNIX-времени в WP Cron. Например, чтобы запланировать задачу через час, мы можем использовать time() + 3600
(текущее время плюс 1 час в секундах). Или же и вовсе time() + HOUR_IN_SECONDS
, но про временные константы в WordPress можете почитать в отдельном уроке.
Параметры функции wp_schedule_single_event()
wp_schedule_single_event( $timestamp, $hook, $args = array(), $wp_error = false )
- $timestamp
- (целое число) Дата и время, когда функция будет запущена. А теперь внимание: Чем меньше посещаемость вашего сайта, тем меньше шанс того, что запланированная задача будет выполнена точно по расписанию. Работает это так — кто-то (или вы) зашёл на ваш сайт, и если на данный момент имелись запланированные задачи, время выполнения которых уже наступило, то они будут выполнены.
- $hook
- (строка) Название хука, к которому обратится
wp_schedule_single_event()
. То естьwp_schedule_single_event()
обратилась к указанному хуку — и сразу выполнились все функции, которые были на него повешены. И ещё кое-что, функция будет возвращатьfalse
и отказываться планировать следующий хук с таким же названием, если до выполнения последнего запланированного такого же хука осталось больше, чем 10 минут. Другими словами, если хук ещё не выполнялся, вы можете запланировать ещё один такой же, но только при условии, что предыдущий выполнится в ближайшие 10 минут. Однако данное правило не срабатывает, если третьим аргументом в хук были переданы какие-либо уникальные параметры. - $args
- (массив) Массив параметров, которые можно передать в хук, а соответственно и во все функции, которые на него повешены. На один и тот же хук спокойно можно запланировать много задач с разными параметрами.
- $wp_error
- (логическое) (с версии WordPress 5.7.0). В некоторых ситуациях функция
wp_schedule_single_event()
возвращаетfalse
, например, если в первый параметр передать нечисловое значение, либо если такое событие уже запланировано. Поставив параметр$wp_error
в значениеtrue
, у нас появляется возможность получать полноценный объект WP_Error в таких ситуациях вместо обычного логическогоfalse
.
Примеры
1. Изменяем email, указанный в настройках сайта через 10 минут после активации темы
Не знаю, кому это может понадобится, но сейчас моя главная цель — показать весь процесс в действии.
// функция, которая поменяет 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( 'true' == $_GET[ 'activated' ] ) { wp_schedule_single_event( time() + 600, 'true_hook_1' ); // 600 секунд это 10 минут, если кто не знал :) }
Не знаете, куда вставлять код? Кстати, обратите внимание, что если вы вставите этот код в плагин, то он будет срабатывать при активации любой темы, если в functions.php
в тему – только для этой определённой темы.
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( 'true' == $_GET['activated'] ) { // создаем две задачи на один хук, но с разными аргументами (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… а вот и они:
Значение single
в колонке Schedule как раз означает, что задача выполнится только 1 раз.
4. Как снять запланированную задачу
Если те 10 минут всё ещё не прошли… то можно попробовать отменить удаление второго поста из вышеприведённого примера при помощи функции wp_clear_scheduled_hook(). Конечно, в нашем случае функция не сделает ничего, если мы не укажем вторым параметром ID поста.
wp_clear_scheduled_hook( 'true_my_hook_2', array( 5 ) );
Не хочу лишний раз напоминать, если вы вставляете эту функцию прямиком в functions.php
, то только в целях тестирования! Вы ведь не хотите запускать её каждый раз при обновлении страницы.
Хуки внутри функции
При помощи хуков, описанных ниже, вы можете изменять то, как ведёт себя функция wp_schedule_single_event()
по умолчанию.
pre_schedule_event
Позволяет либо запланировать событие альтернативным способом, либо прекратить планирование события вовсе.
Если мы возвращаем этим хуком любое значение, отличающееся от null
, например true
, false
или объект WP_Error, то происходит моментальный выход из функции wp_schedule_single_event()
.
$pre = apply_filters( 'pre_schedule_event', null, $event, $wp_error );
- $pre
- (null|логическое|WP_Error) Возвращаемое хуком значение. По умолчанию это null, что означает, что мы можем продолжить планировать событие внутри функции.
- $event
- (объект) Объект, в котором содержится информации о планируемом событии.
- hook
- (строка) Хук события
- timestamp
- (целое число) Время в UNIX-формате, когда в следующий раз выполнится событие.
- schedule
- (строка|false) Как часто событие должно выполняться, например hourly, daily или любой другой зарегистрированный интервал. Так как функция
wp_schedule_single_event()
планирует НЕ повторяющееся событие, то значение параметра всегда будет равноfalse
. - args
- (массив) Параметры, переданные в функцию.
- $wp_error
- (логическое) Значение параметра $wp_error в функции.
- hook
- (строка) Хук события
- timestamp
- (целое число) Время в UNIX-формате, когда в следующий раз выполнится событие.
- schedule
- (строка|false) Как часто событие должно выполняться, например hourly, daily или любой другой зарегистрированный интервал. Так как функция
wp_schedule_single_event()
планирует НЕ повторяющееся событие, то значение параметра всегда будет равноfalse
. - args
- (массив) Параметры, переданные в функцию.
Например таким способом можно снять планирование определённой задачи.
add_filter( 'pre_schedule_event', 'true_skip_this_event', 25, 3 ); function true_skip_this_event( $pre, $event, $wp_error ) { if( 'some_hook_to_skip' === $event->hook ) { return false; } return $pre; }
schedule_event
Фильтр-хук schedule_event
позволяет внести изменения в планируемое событие вот прямо непосредственно перед его планированием.
$event = apply_filters( 'schedule_event', $event );
- $event
- (объект) Объект, в котором содержится информации о планируемом событии.
- hook
- (строка) Хук события
- timestamp
- (целое число) Время в UNIX-формате, когда в следующий раз выполнится событие.
- schedule
- (строка|false) Как часто событие должно выполняться, например hourly, daily или любой другой зарегистрированный интервал. Так как функция
wp_schedule_single_event()
планирует НЕ повторяющееся событие, то значение параметра всегда будет равноfalse
. - args
- (массив) Параметры, переданные в функцию.
- hook
- (строка) Хук события
- timestamp
- (целое число) Время в UNIX-формате, когда в следующий раз выполнится событие.
- schedule
- (строка|false) Как часто событие должно выполняться, например hourly, daily или любой другой зарегистрированный интервал. Так как функция
wp_schedule_single_event()
планирует НЕ повторяющееся событие, то значение параметра всегда будет равноfalse
. - args
- (массив) Параметры, переданные в функцию.