Функция wp_schedule_single_event()
позволяет запланировать задачу, которая выполнится в определённое время. Для этого используется планировщик задач WordPress – WP Cron.
Любые функции для создания запланированных задач в 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( $timestamp, $hook, $args = array(), $wp_error = false )
wp_schedule_single_event()
. То есть wp_schedule_single_event()
обратилась к указанному хуку — и сразу выполнились все функции, которые были на него повешены. И ещё кое-что, функция будет возвращать false
и отказываться планировать следующий хук с таким же названием, если до выполнения последнего запланированного такого же хука осталось больше, чем 10 минут. Другими словами, если хук ещё не выполнялся, вы можете запланировать ещё один такой же, но только при условии, что предыдущий выполнится в ближайшие 10 минут. Однако данное правило не срабатывает, если третьим аргументом в хук были переданы какие-либо уникальные параметры.wp_schedule_single_event()
возвращает false
, например, если в первый параметр передать нечисловое значение, либо если такое событие уже запланировано. Поставив параметр $wp_error
в значение true
, у нас появляется возможность получать полноценный объект WP_Error в таких ситуациях вместо обычного логического false
.Не знаю, кому это может понадобится, но сейчас моя главная цель — показать весь процесс в действии.
// функция, которая поменяет 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
в тему – только для этой определённой темы.
Для воспроизведения этого примера вам понадобятся два поста, которых не жалко, хотя любые подойдут, так как мы не будем удалять их полностью, а перенесём в корзину (если только корзина у вас не отключена). Ну и вторая 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 ) ); // для разнообразия я задал время немного по-другому }
Если вам приходится часто работать с WP_Cron, то очень удобно держать всё это дело под контролем.
Если вы уже использовали код из предыдущего примера и ждёте 10 минут, то давайте глянем на наши задачи, пока они не выполнились и не исчезли из очереди! Это можно сделать при помощи кода:
$cron_zadachi = get_option( 'cron' ); var_dump( $cron_zadachi );
Или при помощи плагина Advanced Cron Manager (добавляйте прямо через админку). Захожу в Инструменты > Cron Manager… а вот и они:
Значение single
в колонке Schedule как раз означает, что задача выполнится только 1 раз.
Если те 10 минут всё ещё не прошли… то можно попробовать отменить удаление второго поста из вышеприведённого примера при помощи функции wp_clear_scheduled_hook(). Конечно, в нашем случае функция не сделает ничего, если мы не укажем вторым параметром ID поста.
wp_clear_scheduled_hook( 'true_my_hook_2', array( 5 ) );
Не хочу лишний раз напоминать, если вы вставляете эту функцию прямиком в functions.php
, то только в целях тестирования! Вы ведь не хотите запускать её каждый раз при обновлении страницы.
При помощи хуков, описанных ниже, вы можете изменять то, как ведёт себя функция wp_schedule_single_event()
по умолчанию.
Позволяет либо запланировать событие альтернативным способом, либо прекратить планирование события вовсе.
Если мы возвращаем этим хуком любое значение, отличающееся от null
, например true
, false
или объект WP_Error, то происходит моментальный выход из функции wp_schedule_single_event()
.
$pre = apply_filters( 'pre_schedule_event', null, $event, $wp_error );
wp_schedule_single_event()
планирует НЕ повторяющееся событие, то значение параметра всегда будет равно false
.Например таким способом можно снять планирование определённой задачи.
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
позволяет внести изменения в планируемое событие вот прямо непосредственно перед его планированием.
$event = apply_filters( 'schedule_event', $event );
wp_schedule_single_event()
планирует НЕ повторяющееся событие, то значение параметра всегда будет равно false
.
Чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или войдите.