Kama_Cron
Небольшой класс для удобного добавления крон событий (задач) в WordPress.
Класс позволяет быстро и удобно создавать cron задачи, чтобы не перепутать ничего, все настройки указываются в параметре при вызове класса, всю рутину по правильной регистрации крон задач и их интервалов класс берет на себя. Функции-обработчики задач нужно писать отдельно!
Код класса Kama_Cron
GitHub<?php
/**
* Convenient way to add cron tasks in WordPress.
*
* Changelog: https://github.com/doiftrue/Kama_Cron/blob/master/changelog.md
*
* @author Kama (wp-kama.ru)
*
* @version 0.4.4
*/
class Kama_Cron {
static $DEBUG = 0; // must be 0 on production. For debug go to: http://mysite.com/wp-cron.php
static $opts;
protected $id; // internal (not used for cron)
/**
* Constructor.
*
* @param array $args {
* Args.
*
* @type string $id Уникальный идентификатор, по которому потом можно обращаться к настройкам.
* По умолчанию: ключи параметра $events.
* @type bool $auto_activate true - автоматически создаст указанное событие, при посещении админ-панели.
* В этом случае отдельно вызывать метод activate() не нужно.
* @type array $events {
* Массив событий, которые нужно добавить в крон. Ключ элемента будет использоваться в хуке крона.
* Значение элемента - это массив параметров события, который может содержать следующие ключи:
*
* @type callable $callback Название функции крон-задачи.
* @type mixed $args Какие параметры передать в фукнцию крон-задачи.
* @type string $interval_name Название интервала, например: 'half_an_hover'.
* Можно указать название вида N_(min|hour|day|month): 10_min, 2_hours, 5_days, 2_month,
* тогда время интервала будет выставлено соотвествующеее.
* Можно указать уже имеющийся интервал WP: hourly, twicedaily, daily,
* тогда время интервала выставлять необзательно.
* @type int $interval_sec Время интервала, например HOUR_IN_SECONDS / 2. Не нужно указывать, когда
* $interval_name = N_(min|hour|day|month), hourly, twicedaily, daily.
* @type string $interval_desc Описание интервала, например 'Каждые пол часа'. Не нужно указывать, когда
* $interval_name = hourly, twicedaily, daily.
* @type int $start_time UNIX - time() метка времени. С какого момента начать событие. По умолчанию: time().
* }
*
* }
*/
function __construct( $args ){
if( empty($args['events']) )
wp_die( 'ERROR: Kama_Cron `events` parameter not set. '. print_r(debug_backtrace(), 1) );
$args_def = [
'id' => implode( '--', array_keys($args['events']) ),
'auto_activate' => true,
'events' => [
'hook_name' => [
'callback' => [ __CLASS__, 'default_callback' ],
'args' => [],
'interval_name' => '',
'interval_sec' => 0,
'interval_desc' => '',
'start_time' => 0,
],
],
];
$event_def = $args_def['events']['hook_name'];
unset( $args_def['events'] );
// complete parameters using defaults
$args = array_merge( $args_def, $args );
foreach( $args['events'] as & $events )
$events = array_merge( $event_def, $events );
unset( $events );
$args = (object) $args;
$this->id = $args->id;
self::$opts[ $this->id ] = $args;
// after self::$opts
add_filter( 'cron_schedules', [ $this, 'add_intervals' ] );
// after 'cron_schedules'
if( !empty($args->auto_activate) && is_admin() )
self::activate( $this->id );
foreach( $args->events as $hook => $data )
add_action( $hook, $data['callback'] );
if( self::$DEBUG && defined('DOING_CRON') && DOING_CRON ){
add_action( 'wp_loaded', function(){
echo 'Current time: '. time() ."\n\n\n".'Existing Intervals:'."\n".
print_r( wp_get_schedules(), 1 ) ."\n\n\n". print_r( _get_cron_array(), 1 );
} );
}
}
function add_intervals( $schedules ){
foreach( self::$opts[ $this->id ]->events as $hook => $data ){
$_name = $data['interval_name'];
if( isset($schedules[ $_name ]) || in_array($_name, [ 'hourly','twicedaily','daily' ]) )
continue;
// allow set only `interval_name` parameter like: 10_min, 2_hours, 5_days, 2_month
if( empty($data['interval_sec']) ){
if( preg_match('/(\d+)[_-](min|hour|day|month)s?/', $_name, $mm) ){
$min = 60;
$hour = $min * 60;
$day = $hour * 24;
$month = $day * 30;
$data['interval_sec'] = $mm[1] * ${$mm[2]};
}
else
wp_die( 'ERROR: Kama_Cron required event parameter `interval_sec` not set. '. print_r(debug_backtrace(), 1) );
}
$schedules[ $_name ] = [
'interval' => $data['interval_sec'],
'display' => $data['interval_desc'],
];
}
return $schedules;
}
# Add cron task.
# Вызывается при активации плагина, можно где-то еще, например при обновлении настроек.
static function activate( $id = '' ){
$opts = $id ? [ $id => self::$opts[ $id ] ] : self::$opts;
foreach( $opts as $opt ){
foreach( $opt->events as $hook => $data ){
if( ! wp_next_scheduled( $hook, $data['args'] ) ){
wp_schedule_event( ( $data['start_time'] ?: time() ), $data['interval_name'], $hook, $data['args'] );
}
}
}
}
# Removes cron task.
# Вызывается при дезактивации плагина.
static function deactivate( $id = '' ){
$opts = $id ? [ $id => self::$opts[ $id ] ] : self::$opts;
foreach( $opts as $opt ){
foreach( $opt->events as $hook => $data )
wp_clear_scheduled_hook( $hook, $data['args'] );
}
}
# Default function for `$data['callback']` parameter.
static function default_callback(){
echo "ERROR: One of Kama_Cron callback function not set.\n\nKama_Cron::\$opts = ".
print_r( self::$opts, 1 ) ."\n\n\n\n_get_cron_array() =".
print_r( _get_cron_array(), 1 );
}
}
Примеры использования класса Kama_Cron
Для начала, скопируйте код класса и вставьте его в плагин или functions.php
темы.
Пример 1: Создадим 3 крон задачи
Создадим 3 крон задачи с разными интервалами. Задачи регистрируются автоматически при посещении админ-панели (это работает очень быстро). Код добавляем куда угодно, например в functions.php
.
new Kama_Cron([
'id' => 'my_cron_jobs', // не обязательный параметр
'events' => array(
// первая задача
'wpkama_cron_func' => array(
'callback' => 'wpkama_cron_func', // название функции крон-задачи
'interval_name' => '10_min', // можно указать уже имеющийся интервал: hourly, twicedaily, daily
'interval_desc' => 'Каждые 10 минут', // не нужен, если задан уже имеющийся интервал
),
// вторая задача
'wpkama_cron_func_2' => array(
'callback' => 'wpkama_cron_func_2',
'start_time' => time() + DAY_IN_SECONDS, // начать через 1 день
'interval_name' => 'two_hours',
'interval_sec' => HOUR_IN_SECONDS * 2,
'interval_desc' => 'Каждые 2 часа',
),
// третья задача
'wpkama_cron_func_3' => array(
'callback' => 'wpkama_cron_func_3',
'interval_name' => 'hourly', // это уже известный WP интервал
),
),
]);
//Kama_Cron::$DEBUG = 1; // для дебага
//Kama_Cron::deactivate('my_cron_jobs'); // для удаления
// Функция крона
function wpkama_cron_func(){
file_put_contents( dirname(ABSPATH) .'/cron_check.txt', current_time('mysql') ."\n", FILE_APPEND );
}
// Функция крона
function wpkama_cron_func_2(){
// операции
}
// Функция крона
function wpkama_cron_func_3(){
// операции
}
Пример 2: Регистрация задач при активации плагина
Код ниже показывает, как активировать и деактивировать задачи при активации/деактивации плагина.
// Пример активации и деактивации, если не указан параметр auto_activate
register_activation_hook( __FILE__, function(){
Kama_Cron::activate( 'my_cron_jobs_2' );
} );
register_deactivation_hook( __FILE__, function(){
Kama_Cron::deactivate( 'my_cron_jobs_2' );
} );
new Kama_Cron([
'id' => 'my_cron_jobs_2',
'auto_activate' => false, // false чтобы повесить активацию задач на register_activation_hook()
'events' => array(
// первая задача
'wpkama_cron_func_4' => array(
'callback' => 'wpkama_cron_func_4', // название функции крон-задачи
'interval_name' => 'twicedaily', // можно указать уже имеющийся интервал: hourly, twicedaily, daily
),
// вторая задача
'wpkama_cron_func_5' => array(
'callback' => 'wpkama_cron_func_5',
'interval_name' => 'two_hours',
'interval_sec' => HOUR_IN_SECONDS * 2,
'interval_desc' => 'Каждые 2 часа',
),
),
]);
function wpkama_cron_func_4(){
// операции
}
function wpkama_cron_func_5(){
// операции
}
Очень удобное решение, надо сказать, реально добавлять задачи с ним удобнее. Рекомендую
В примере 2 для активации плагина указаны методы "activation" и "deactivation". Хотя в классе они называются "activate" и "deactivate".
Поправил, спасибо