WP Cron – всё про планировщик задач WordPress

Владислав Белецкий
Владислав Белецкий .
Категория:
Комментариев: 0

WP-Cron – это планировщик в WordPress, используемый для запуска периодически выполняемых задач, либо задач, которые должны быть запущены в определённое время.

Также важно упомянуть, что задачи WP-Cron не запускаются автоматически, просто при каждой загрузке страницы происходит сопоставление всех запланированных задач с текущим временем и, если время выполнения уже наступило, задача будет запущена. Это также значит, что если у вас запланирована задача на скажем 5:31 и если посещаемость вашего сайта не очень высокая, то задача скорее всего будет выполнена позднее указанного времени.

Примеры работы WP-Cron в ядре WordPress

Ниже я приведу таблицу, в которой перечислены события WP-Cron, запланированные непосредственно в ядре WordPress.

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

WP-Cron — это очень просто, однако я помню то время, когда боялся к нему подступиться. Просто читайте эту статью последовательно и сразу же выполняйте данные здесь примеры и этого будет достаточно, чтобы освоить планировщик задач в WordPress.

Как проверить, что WP-Cron работает на сайте?

Обычно на сайтах WordPress с планировщиком всё окей, однако всё же бывают случаи, когда он не работает. Поэтому, прежде чем перейти к примерам, давайте убедимся, что с ним всё окей.

Используя «Здоровье сайта»

Начиная с версии WordPress 5.2, когда появилась функция Здоровье сайта, это стало делать очень легко – достаточно лишь перейти в Инструменты > Здоровье сайта и проверить, есть ли там рекомендация «Запланированное задание пропущено».

Используя запланированную публикацию записи

Если вдруг у вас стоит старая версия WordPress и вы не можете проверить работу планировщика в Здоровье сайта, то достаточно создать пост и в качестве даты публикации установить время в будущем, ну и понятное дело, чтобы долго ждать не пришлось, можно поставить время на 2 или 5 минут позже текущего.

Если WP_Cron работает на вашем сайте, то пост просто опубликуется через пару минут, а если не работает, то вот что вы получите:

Как починить WP_Cron?

Итак, что же делать, если планировщик отказывается работать на вашем сайте? Сейчас я не буду слишком подробно на этом останавливаться, но дам несколько базовых советов, которые возможно помогут вам разобраться с проблемой.

define( 'DISABLE_WP_CRON', true );
define( 'ALTERNATE_WP_CRON', true );
define( 'DISABLE_WP_CRON', true );
wget -O /dev/null http://misha.agency/wp-cron.php?doing_wp_cron

Всё ещё ничего не получается? Тогда рекомендую попробовать разобраться с супортом хостинга, если не могут помочь, но возможно следует рассмотреть переезд на другой хостинг, например на мой. Дело в том, что проблемы с виртуальным WP_Cron – это проблемы именно с сервером, а значит супорт вам обязан помочь.

Как отключить WP_Cron?

В целом в предыдущем шаге я уже упомянул, как это сделать, но расскажу ещё раз. Чтобы отключить планироващик WP-Cron на вашем сайте, зайдите в файл wp-config.php, который лежит в корне вашего сайта и поместите туда строчку

define( 'DISABLE_WP_CRON', true );

Но не в самый конец файла, а до require_once ABSPATH . 'wp-settings.php';.

Создание запланированной задачи

Задача, которая выполнится один раз в определённое время

Для этих целей в WordPress существует функция wp_schedule_single_event().

wp_schedule_single_event( time() + 60, 'misha_action_hook' );

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

Поэтому код непосредственно с запуском этой функции лучше всего добавлять в обработчики форм например. Форма отправлена – событие запланировано. Всё просто.

Однако я воспользуюсь тем, что при смене темы WordPress на страницу передаётся параметр GET activated, равный true — в таком случае я смогу вставить код прямо в functions.php в следующем виде:

if( 'true' == $_GET[ 'activated' ] ) {
	wp_schedule_single_event( time() + 60, 'misha_action_hook' );
}

Это означает, что как только переключиться на текущую тему, событие запланируется.

Хорошо, что же теперь делать с misha_action_hook? Повторяю — это не функция! Просто очень частой ошибкой бывает, что люди начинают писать функцию function misha_action_hook( лалала ) — это неправильно, а правильно будет так:

// вот он хук и мы вешаем на него произвольную функцию
add_action( 'misha_action_hook', 'test' );
// конечно можно повесить и несколько функций на один хук!
 
function test() {
	// банально поменяю емайл администратора на сайте, проще всего протестировать
	update_option( 'admin_email', 'misha@truemisha.ru' );
}

Незнакомая функция? Читайте подробнее про update_option().

Вставляем всё это пошагово в functions.php, переключаемся сначала на какую-нибудь левую тему, а потом обратно на текущую, замечаем минуту и потом смотрим емайл в настройках.

Для вашего удобства вот полностью готовый код из примера.

if( 'true' == $_GET[ 'activated' ] ) {
	wp_schedule_single_event( time() + 60, 'misha_action_hook' );
}
 
add_action( 'misha_action_hook', 'test' );
 
function test() {
	update_option( 'admin_email', 'misha@truemisha.ru' );
}

И напоследок — у функции wp_schedule_single_event() есть ещё один, третий аргумент, который содержит параметры, передаваемые в хук, и тут я предлагаю вам два варианта — вы можете перейти по ссылке на функцию, чтобы почитать о ней подробнее там, либо переходите к следующему примеру, хоть он уже и про другую функцию, но параметр с аргументами работает у них одинаково.

Планируем задачу, которая будет выполняться регулярно через определенные интервалы времени

В этом нам поможет функция wp_schedule_event().

wp_schedule_event( time(), 'hourly', 'misha_hook_1', array( 'no-reply@misha.agency', 'Тест тема', 'Тест сообщение' ) );

Куда вставлять?

Вне зависимости от того, куда вы её вставите, сделайте проверку, что точно такая же задача уже не запланирована. В этом вам поможет функция wp_next_scheduled().

$parametri = array( 'no-reply@misha.agency', 'Тест тема', 'Тест сообщение' );
 
// если ещё не запланировано - планируем
if( ! wp_next_scheduled( 'misha_hook_1', $parametri ) ) {
	wp_schedule_event( time(), 'hourly', 'misha_hook_1', $parametri );
}

Ну а дальше — функция и хук. Код будет ежечасно отправлять мне сообщения с сайта.

// вот он хук и мы вешаем на него произвольную функцию, цифра 3 - количество передаваемых параметров
add_action( 'misha_hook_1', 'misha_send', 10, 3 );
// конечно можно повесить и несколько функций на один хук!
 
function misha_send( $to, $subject, $msg ) {
	// отправляем емайл каждый час
	wp_mail( $to, $subject, $msg );
}

Для отправки писем я использую стандартную функцию WordPress — wp_mail(). Обратите внимание, что необязательно создавать функцию misha_send(), а можно сразу повесить wp_mail() на хук.

Ну и конечно же готовый код для вашего удобства.

$parametri = array( 'no-reply@misha.agency', 'Тест тема', 'Тест сообщение' );
 
// если ещё не запланировано - планируем
if( ! wp_next_scheduled( 'misha_hook_1', $parametri ) ) {
	wp_schedule_event( time(), 'hourly', 'misha_hook_1', $parametri );
}
 
add_action( 'misha_hook_1', 'misha_send', 10, 3 );
 
function misha_send( $to, $subject, $msg ) {
	wp_mail( $to, $subject, $msg );
}

Как задать свой собственный интервал?

По умолчанию в WordPress 4 зарегистрированных интервала времени:

$schedules = array(
	'hourly' => array( // каждый час
		'interval' => HOUR_IN_SECONDS,
		'display'  => __( 'Once Hourly' ),
	),
	'twicedaily' => array( // каждые 12 часов
		'interval' => 12 * HOUR_IN_SECONDS,
		'display'  => __( 'Twice Daily' ),
	),
	'daily' => array( // каждые 24 часа, раз в день
		'interval' => DAY_IN_SECONDS,
		'display'  => __( 'Once Daily' ),
	),
	'weekly' => array( // раз в неделю
		'interval' => WEEK_IN_SECONDS,
		'display'  => __( 'Once Weekly' ),
	),
);

Кстати, в этом коде мы видим временные константы в WordPress, про них я отдельно рассказывал в этом уроке.

Если вас не устраивают стандартные вордпрессовские интервалы времени, вы с лёгкостью можете добавить в этот массив свой собственный.

Делается это предельно просто при помощи следующего хука:

add_filter( 'cron_schedules', 'true_moi_interval'); 
 
function true_moi_interval( $raspisanie ) {
	// $raspisanie - это массив, состоящий из всех зарегистрированных интервалов
	// наша задача - добавить в него свой собственный интервал, к примеру пусть будет 3 минуты
	$raspisanie[ 'kajd_3_min' ] = array(
		'interval' => 180, // в одной минуте 60 секунд, в трёх минутах - 180
		'display' => 'Каждые три минуты' // отображаемое имя
	);
	return $raspisanie;
}

Если не знаете, куда вставлять этот код, читайте.

Всё, интервал зарегистрирован, теперь можно использовать его имя kajd_3_min при планировке повторяющихся событий.

Просмотр запланированных задач

Делается это довольно просто двумя способами — либо через плагин, либо через код. Если вам часто приходится мониторить, то конечно лучше и удобнее воспользоваться плагином, но обо всём по порядку.

Просмотр и отладка через код

Cron-задачи хранятся в виде массива прямо в таблице wp_options базы данных. А значит их можно получить при помощи функции get_option(). И вот как это делается.

// получаем все задачи из базы данных
$cron_zadachi = get_option( 'cron' );
 
// можно использовать функции print_r() или var_dump() для вывода всех задач
echo '<pre>';
print_r( $cron_zadachi );
exit;

Или же при помощи функции _get_cron_array().

echo '<pre>';
print_r( _get_cron_array() );
exit;

В результате они выведутся примерно в таком формате:

При помощи плагина Advanced Cron Manager

Зная из предыдущей главы, как выводятся задачи, вы теперь с лёгкостью и сами сможете написать плагин для мониторинга, а я поделюсь с вами тем плагином, который использую сам и в общем-то пока он меня устраивает — бесплатный Advanced Cron Manager (добавляйте прямо через админку). Если вы знаете плагины получше, прошу поделиться в комментариях 🙂

Заходим в Инструменты > Список задач планировщика и все задачи перед нами:

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

Удаление задач происходит при помощи одной из двух функций — wp_clear_scheduled_hook() или wp_unschedule_event(), отличие второй от первой заключается в том, что она может удалить более конкретную задачу, если вам интересны подробности, переходите по ссылкам и читайте описания этих функций.

Что же касается наших примеров 1 и 2, для удаления этих событий нам подойдёт любая из них, поэтому давайте первое событие с хуком misha_hook_1 удалим функцией wp_clear_scheduled_hook(), а второе с хуком misha_action_hook функцией wp_unschedule_event().

// удаляем первое событие
wp_clear_scheduled_hook( 'misha_hook_1', array( 'no-reply@misha.agency', 'Тест тема', 'Тест сообщение') );
 
// удаляем второе событие
wp_unschedule_event( wp_next_scheduled( 'misha_action_hook' ), 'misha_action_hook' );

Первый параметр функции wp_unschedule_event() — это штамп времени, который вы можете получить при помощи wp_next_scheduled(), либо глянуть его при выводе всех задач через код, тут это будет 1469678041.

Подписаться
Уведомить о
guest
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии