View source
<?php
include dirname(__FILE__) . '/ultimate_cron.poorman.inc';
define('ULTIMATE_CRON_LOG_TYPE_NORMAL', 0);
define('ULTIMATE_CRON_LOG_TYPE_ADMIN', 1);
define('ULTIMATE_CRON_LOG_TYPE_ALL', -1);
function _ultimate_cron_define_log_type_all() {
return array(
ULTIMATE_CRON_LOG_TYPE_NORMAL,
ULTIMATE_CRON_LOG_TYPE_ADMIN,
);
}
$GLOBALS['__RESERVED_MEMORY'] = str_repeat('0', variable_get('ultimate_cron_reserve_memory', 1024 * 1024 * 2));
$GLOBALS['ultimate_cron_shutdown_functions'] = array();
if (!function_exists('_ultimate_cron_out_of_memory_protection')) {
function _ultimate_cron_out_of_memory_protection() {
unset($GLOBALS['__RESERVED_MEMORY']);
foreach ($GLOBALS['ultimate_cron_shutdown_functions'] as $function) {
call_user_func_array($function['callback'], $function['arguments']);
}
}
$callbacks =& drupal_register_shutdown_function();
if (empty($callbacks)) {
register_shutdown_function('_ultimate_cron_out_of_memory_protection');
}
else {
array_unshift($callbacks, array(
'callback' => '_ultimate_cron_out_of_memory_protection',
'arguments' => array(),
));
reset($callbacks);
}
}
function ultimate_cron_register_shutdown_function($callback) {
$args = func_get_args();
array_shift($args);
$GLOBALS['ultimate_cron_shutdown_functions'][] = array(
'callback' => $callback,
'arguments' => $args,
);
}
function ultimate_cron_ctools_plugin_api($module, $api) {
if ($module == 'ultimate_cron' && $api == 'plugins') {
return array(
'version' => 3,
);
}
if ($module == 'ultimate_cron' && $api == 'ultimate_cron') {
return array(
'version' => 3,
);
}
}
function ultimate_cron_ctools_plugin_directory($module, $type) {
if (!module_invoke('ctools', 'api_version', '1.7')) {
return;
}
$supported = array(
'ctools' => array(
'export_ui' => 'export_ui',
),
'ultimate_cron' => array(
'settings' => 'settings',
'scheduler' => 'scheduler',
'launcher' => 'launcher',
'logger' => 'logger',
),
);
if (isset($supported[$module][$type])) {
return "plugins/{$module}/" . $supported[$module][$type];
}
}
function ultimate_cron_ctools_plugin_type() {
return array(
'settings' => array(
'use hooks' => FALSE,
'defaults' => array(
'static' => array(
'default plugin' => '',
'title singular' => t('settings'),
'title plural' => t('settings'),
'title singular proper' => t('Settings'),
'title plural proper' => t('Settings'),
'class' => 'UltimateCronSettings',
'multiple' => TRUE,
),
),
'classes' => array(
'handler',
),
'cache' => TRUE,
),
'scheduler' => array(
'use hooks' => FALSE,
'defaults' => array(
'static' => array(
'default plugin' => 'simple',
'title singular' => t('scheduler'),
'title plural' => t('schedulers'),
'title singular proper' => t('Scheduler'),
'title plural proper' => t('Schedulers'),
'class' => 'UltimateCronScheduler',
),
),
'classes' => array(
'handler',
),
'cache' => TRUE,
),
'launcher' => array(
'use hooks' => FALSE,
'defaults' => array(
'static' => array(
'default plugin' => 'serial',
'title singular' => t('launcher'),
'title plural' => t('launchers'),
'title singular proper' => t('Launcher'),
'title plural proper' => t('Launchers'),
'class' => 'UltimateCronLauncher',
),
),
'classes' => array(
'handler',
),
'cache' => TRUE,
),
'logger' => array(
'use hooks' => FALSE,
'defaults' => array(
'static' => array(
'default plugin' => 'database',
'title singular' => t('logger'),
'title plural' => t('loggers'),
'title singular proper' => t('Logger'),
'title plural proper' => t('Loggers'),
'class' => 'UltimateCronLogger',
),
),
'classes' => array(
'handler',
),
'cache' => TRUE,
),
);
}
function ultimate_cron_ctools_plugin_instance($type, $plugin) {
static $cache;
if (!isset($cache[$plugin['name']])) {
$cache[$plugin['name']] = ctools_plugin_get_class($plugin, 'handler');
}
if (isset($cache[$plugin['name']]) && class_exists($cache[$plugin['name']])) {
$class = $cache[$plugin['name']];
return $class::factory($class, $type, $plugin);
}
else {
return NULL;
}
}
function _ultimate_cron_plugin_require($type, $name) {
$object = _ultimate_cron_plugin_load($type, $name);
if (!is_object($object)) {
throw new \RuntimeException(t('Ultimate Cron failed to require ctools "!type" plugin "!name"', array(
'!type' => $type,
'!name' => $name,
)));
}
return $object;
}
function _ultimate_cron_plugin_load($type, $name) {
$cache =& drupal_static('ultimate_cron_plugin_load_all', array());
if (!isset($cache[$type][$name])) {
_ultimate_cron_plugin_load_all($type);
}
if (isset($cache[$type][$name])) {
return $cache[$type][$name];
}
else {
return NULL;
}
}
function _ultimate_cron_plugin_load_all($type, $reset = FALSE) {
$cache =& drupal_static('ultimate_cron_plugin_load_all', array());
if (!$reset && isset($cache[$type])) {
return $cache[$type];
}
if ($reset) {
drupal_static_reset('ctools_plugins');
drupal_static_reset('ctools_plugin_setup');
}
ctools_include('plugins');
$plugin_infos = ctools_get_plugins('ultimate_cron', $type);
$plugins = array();
foreach ($plugin_infos as $name => $plugin) {
if ($object = ultimate_cron_ctools_plugin_instance($name, $plugin)) {
$plugins[$name] = $object;
}
}
$cache[$type] = $plugins;
return $cache[$type];
}
function _ultimate_cron_job_load_all_raw($reset = FALSE) {
ctools_include('export');
$table = 'ultimate_cron_job';
if ($reset) {
ctools_export_load_object_reset($table);
}
$class = _ultimate_cron_get_class('job');
$results = ctools_export_load_object($table);
foreach ($results as $name => &$result) {
$result->disabled = ultimate_cron_job_get_status($name);
$result->settings = !empty($result->settings) ? $result->settings : array();
if (!$result instanceof $class) {
$result = $class::factory($result);
}
}
return $results;
}
function _ultimate_cron_job_load($name, $reset = FALSE) {
$jobs = _ultimate_cron_job_load_all($reset);
return isset($jobs[$name]) ? $jobs[$name] : FALSE;
}
function _ultimate_cron_job_load_multiple($names, $reset = FALSE) {
$jobs = array();
foreach (_ultimate_cron_job_load_all($reset) as $name => $job) {
if (in_array($name, $names)) {
$jobs[$name] = $job;
}
}
return $jobs;
}
function _ultimate_cron_job_load_all($reset = FALSE) {
static $cache = NULL;
if (!$reset && isset($cache)) {
return $cache;
}
$raw_jobs = _ultimate_cron_job_load_all_raw($reset);
$jobs = array();
foreach (ultimate_cron_get_hooks($reset) as $name => $hook) {
$jobs[$name] = ultimate_cron_prepare_job($name, $hook, isset($raw_jobs[$name]) ? $raw_jobs[$name] : NULL);
}
$cache = $jobs;
UltimateCronPlugin::hook_cron_alter($cache);
return $cache;
}
function ultimate_cron_prepare_job($name, $hook, $job = NULL) {
$schema = ctools_export_get_schema('ultimate_cron_job');
$export = $schema['export'];
if (!$job) {
$job = ctools_export_crud_new('ultimate_cron_job');
$job->name = $name;
$job->title = $hook['title'];
$job->description = $hook['description'];
$job->table = 'ultimate_cron_job';
$job->export_type = EXPORT_IN_CODE;
$job->{$export['export type string']} = t('Default');
$job->disabled = ultimate_cron_job_get_status($name);
if (!isset($job->disabled)) {
$job->disabled = !$hook['enabled'];
}
}
else {
if ($job->export_type & EXPORT_IN_DATABASE) {
$job->{$export['export type string']} = t('Overridden');
$job->export_type |= EXPORT_IN_CODE;
}
}
ctools_include('plugins');
$plugin_types = ctools_plugin_get_plugin_type_info();
foreach ($plugin_types['ultimate_cron'] as $plugin_type => $info) {
$class = $info['defaults']['static']['class'];
if ($class::$multiple) {
$plugins = _ultimate_cron_plugin_load_all($plugin_type);
foreach ($plugins as $plugin) {
if (!isset($job->settings[$plugin_type][$plugin->name])) {
$job->settings[$plugin_type][$plugin->name] = array();
}
}
}
else {
if (!isset($job->settings[$plugin_type])) {
$job->settings[$plugin_type] = array();
}
}
}
$job->hook = $hook;
return $job;
}
function _ultimate_cron_job_set_status($object, $status) {
if (!is_object($object)) {
$object = _ultimate_cron_job_load($object);
}
if (empty($object->dont_log)) {
$log_entry = $object
->startLog(uniqid($object->name, TRUE), 'modification', ULTIMATE_CRON_LOG_TYPE_ADMIN);
$log_entry
->log($object->name, 'Job @status by ' . $log_entry
->formatUser(), array(
'@status' => $status ? t('disabled') : t('enabled'),
), WATCHDOG_INFO);
$log_entry
->finish();
}
variable_set('default_ultimate_cron_job_' . $object->name, $status ? TRUE : FALSE);
$object->disabled = $status;
}
function _ultimate_cron_job_save(&$object) {
$table = 'ultimate_cron_job';
$schema = ctools_export_get_schema($table);
$export = $schema['export'];
if (empty($export['primary key'])) {
return FALSE;
}
$key = $export['primary key'];
if ($object->export_type & EXPORT_IN_DATABASE) {
$update = array(
$key,
);
}
else {
$update = array();
$object->export_type = EXPORT_IN_DATABASE;
}
$result = drupal_write_record($table, $object, $update);
if (empty($object->dont_log)) {
$log = $object
->startLog(uniqid($object->name, TRUE), 'modification', ULTIMATE_CRON_LOG_TYPE_ADMIN);
$log
->log($object->name, 'Job modified by ' . $log
->formatUser(), array(), WATCHDOG_INFO);
$log
->finish();
}
return $result;
}
function _ultimate_cron_job_delete($object) {
$table = 'ultimate_cron_job';
$schema = ctools_export_get_schema($table);
$export = $schema['export'];
if (!is_object($object)) {
$name = $object;
if (!($object = _ultimate_cron_job_load($name))) {
throw new Exception(t('Unable to revert unknown job: @name', array(
'@name' => $name,
)));
}
}
db_delete($table)
->condition($export['key'], $object->{$export['key']})
->execute();
if (empty($object->dont_log)) {
$log = $object
->startLog(uniqid($object->name, TRUE), 'modification', ULTIMATE_CRON_LOG_TYPE_ADMIN);
$log
->log($object->name, 'Job reverted by ' . $log
->formatUser(), array(), WATCHDOG_INFO);
$log
->finish();
}
}
function ultimate_cron_job_get_status($name) {
return variable_get('default_ultimate_cron_job_' . $name, NULL);
}
function _ultimate_cron_job_export_settings($object, $field, $value, $indent = '') {
return ctools_var_export($value, $indent);
}
function _ultimate_cron_job_export($object, $indent = '') {
$object = (object) (array) $object;
return ctools_export_object('ultimate_cron_job', $object, $indent);
}
function _ultimate_cron_job_import($code) {
$table = 'ultimate_cron_job';
$schema = ctools_export_get_schema($table);
$export = $schema['export'];
ob_start();
eval($code);
ob_end_clean();
if (empty(${$export['identifier']})) {
$errors = ob_get_contents();
if (empty($errors)) {
$errors = t('No item found.');
}
return $errors;
}
$item = ${$export['identifier']};
$jobs = _ultimate_cron_job_load_all();
if (isset($jobs[$item->name])) {
$job = clone $jobs[$item->name];
$job->disabled = $item->disabled;
$job->api_version = $item->api_version;
$job->name = $item->name;
$job->title = $item->title;
$job->settings = $item->settings;
$item = $job;
}
else {
return t('Job "@name" doesn\'t exist. You can only import jobs already defined by the system.', array(
'@name' => $item->name,
));
}
$item->export_type = NULL;
$item->{$export['export type string']} = t('Overridden');
return $item;
}
function ultimate_cron_ultimate_cron_job_list() {
$table = 'ultimate_cron_job';
$list = array();
$items = _ultimate_cron_job_load_all_raw();
$schema = ctools_export_get_schema($table);
$export_key = $schema['export']['key'];
foreach ($items as $item) {
$keys = array(
'admin_title',
'title',
);
if (isset($schema['export']['admin_title'])) {
array_unshift($keys, $schema['export']['admin_title']);
}
$string = '';
foreach ($keys as $key) {
if (!empty($item->{$key})) {
$string = $item->{$key} . " (" . $item->{$export_key} . ")";
break;
}
}
if (empty($string)) {
$string = $item->{$export_key};
}
$list[$item->{$export_key}] = check_plain($string);
}
return $list;
}
function ultimate_cron_flush_caches() {
return array(
'cache_ultimate_cron',
);
}
function ultimate_cron_hook_info() {
$hooks = array();
$easy_hooks = ultimate_cron_get_easy_hooks();
$easy_hooks += array(
'cron' => array(),
'cron_alter' => array(),
'cronapi' => array(),
);
foreach (array_keys($easy_hooks) as $name) {
$hooks[$name] = array(
'group' => 'cron',
);
}
$hooks['cron_easy_hooks'] = array(
'group' => 'cron',
);
$hooks['cron_easy_hooks_alter'] = array(
'group' => 'cron',
);
$hooks['cron_pre_schedule'] = array(
'group' => 'cron',
);
$hooks['cron_post_schedule'] = array(
'group' => 'cron',
);
$hooks['cron_pre_launch'] = array(
'group' => 'cron',
);
$hooks['cron_post_launch'] = array(
'group' => 'cron',
);
$hooks['cron_pre_run'] = array(
'group' => 'cron',
);
$hooks['cron_post_run'] = array(
'group' => 'cron',
);
$hooks['cron_pre_invoke'] = array(
'group' => 'cron',
);
$hooks['cron_post_invoke'] = array(
'group' => 'cron',
);
$hooks['ultimate_cron_plugin_build_operations_alter'] = array(
'group' => 'cron',
);
return $hooks;
}
function ultimate_cron_hook_info_alter(&$hooks) {
if (module_exists('background_process')) {
$info = system_get_info('module', 'background_process');
if (!empty($info['dependencies']) && in_array('progress', $info['dependencies'])) {
$hooks['background_process_shutdown']['group'] = 'background_process';
}
}
}
function ultimate_cron_init() {
if (!variable_get('ultimate_cron_bypass_transactional_safe_connection')) {
$info = Database::getConnectionInfo('default');
Database::addConnectionInfo('default', 'ultimate_cron', $info['default']);
}
$GLOBALS['ultimate_cron_original_session_saving'] = drupal_save_session();
$GLOBALS['ultimate_cron_original_user'] = $GLOBALS['user'];
_ultimate_cron_variable_load('cron_last');
}
function ultimate_cron_help($path, $arg) {
switch ($path) {
case 'admin/help#ultimate_cron':
$readme = dirname(__FILE__) . '/README.txt';
if (is_readable($readme)) {
return '<pre>' . file_get_contents($readme) . '</pre>';
}
else {
$output = '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The Ultimate Cron handling for Drupal. Runs cron jobs individually in parallel using configurable rules, pool management and load balancing.') . '</p>';
$output .= '<h3>' . t('Features') . '</h3>';
$output .= '<ul>';
$output .= '<li>' . t('Works out-of-the box in most cases (or aims to)') . '</li>';
$output .= '<li>' . t('Parallel exection of cron jobs') . '</li>';
$output .= '<li>' . t('Configuration per job (enable/disable, rules, etc.)') . '</li>';
$output .= '<li>' . t('Multiple rules per cron job') . '</li>';
$output .= '<li>' . t('Pool management and load balancing using Background process') . '</li>';
$output .= '<li>' . t('Support for Drupal Queues') . '</li>';
$output .= '<li>' . t('Overview of cron jobs') . '</li>';
$output .= '<li>' . t('Log history of cron jobs') . '</li>';
$output .= '<li>' . t('Status/error messages per cron job, providing easy debugging of troublesome cron jobs') . '</li>';
$output .= '<li>' . t('hook_cron_alter() for easy adding/manipulating cron jobs') . '</li>';
$output .= '<li>' . t('Poormans cron with keepalive a granularity of 1 minute') . '</li>';
$output .= '<li>' . t('<a href="@url" rel="nofollow">Drush</a> support (list, start, enable/disable jobs from the command line)', array(
'@url' => 'https://www.drupal.org/project/drush',
)) . '</li>';
$output .= '</ul>';
$output .= '<h3>' . t('Useful links') . '</h3>';
$output .= '<ul>';
$output .= '<li>' . t('<a href="@url">Ultimate Cron project on Drupal.org</a>', array(
'@url' => 'https://www.drupal.org/project/ultimate_cron',
)) . '</li>';
$output .= '</ul>';
return $output;
}
}
}
function ultimate_cron_modules_enabled() {
cache_clear_all('plugins:ultimate_cron:', 'cache', TRUE);
menu_rebuild();
}
function ultimate_cron_modules_disabled() {
cache_clear_all('plugins:ultimate_cron:', 'cache', TRUE);
menu_rebuild();
}
function ultimate_cron_menu() {
$items = array();
$items['admin/config/system/cron/poorman'] = array(
'title' => 'Poormans cron',
'description' => 'Trigger poormans cron',
'page callback' => 'ultimate_cron_poorman_page',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
'file' => 'ultimate_cron.poorman.inc',
);
ctools_include('plugins');
$plugin_types = ctools_plugin_get_plugin_type_info(TRUE);
$weight = 0;
foreach ($plugin_types['ultimate_cron'] as $plugin_type => $info) {
$static = $info['defaults']['static'];
$class = $static['class'];
$items["admin/config/system/cron/{$plugin_type}"] = array(
'type' => MENU_LOCAL_TASK,
'title' => $static['title plural proper'],
'description' => "Administer " . $static['title plural'],
'page callback' => 'drupal_get_form',
'page arguments' => array(
'ultimate_cron_plugin_form',
$plugin_type,
),
'access arguments' => array(
'administer ultimate cron',
),
'file' => 'ultimate_cron.admin.inc',
'weight' => 2 + $weight,
);
$items["admin/config/system/cron/{$plugin_type}/settings"] = array(
'type' => MENU_DEFAULT_LOCAL_TASK,
'title' => $class::$multiple ? 'List' : 'Settings',
'weight' => -1 + $weight,
);
$weight++;
foreach (_ultimate_cron_plugin_load_all($plugin_type, TRUE) as $name => $plugin) {
if (!$plugin
->isValid()) {
continue;
}
$items["admin/config/system/cron/{$plugin_type}/{$name}"] = array(
'type' => MENU_LOCAL_TASK,
'title' => $plugin->title,
'description' => $plugin->description,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'ultimate_cron_plugin_settings',
$plugin_type,
$name,
),
'access arguments' => array(
'administer ultimate cron',
),
'file' => 'ultimate_cron.admin.inc',
'weight' => $weight++,
);
}
}
return $items;
}
function ultimate_cron_menu_alter(&$items) {
if (isset($items['admin/config/system/cron/jobs'])) {
$items['admin/config/system/cron'] = $items['admin/config/system/cron/jobs'];
$items['admin/config/system/cron/jobs'] = array(
'title' => 'Jobs',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 20,
);
unset($items['admin/config/system/cron']['type']);
}
$steal =& $items['admin/reports/status/run-cron'];
$steal['page callback'] = 'ultimate_cron_run_scheduled_page';
$steal['page arguments'] = array(
'admin/reports/status',
);
$steal['module'] = 'ultimate_cron';
$steal['file'] = 'ultimate_cron.module';
}
function ultimate_cron_permission() {
return array(
'administer ultimate cron' => array(
'title' => t('Administer Ultimate Cron'),
'description' => t('Lets you configure everything in Ultimate Cron'),
),
'view cron jobs' => array(
'title' => t('View cron jobs'),
'description' => t('Lets you view cron jobs and their logs'),
),
'run cron jobs' => array(
'title' => t('Run cron jobs'),
'description' => t('Lets you run cron jobs'),
),
);
}
function ultimate_cron_cron_queue_info() {
$debug = debug_backtrace();
$cron_debug_level = 3;
if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
$cron_debug_level--;
}
if (!empty($debug[$cron_debug_level]['function']) && $debug[$cron_debug_level]['function'] == 'drupal_cron_run') {
if (!empty($debug[$cron_debug_level + 1])) {
try {
if ($debug[$cron_debug_level + 1]['function'] == 'install_finished') {
watchdog('ultimate_cron', 'Running cron in compatibility mode during site install.', array(), WATCHDOG_DEBUG);
}
else {
watchdog('ultimate_cron', 'drupal_cron_run() called unexpectedly by @file:@line function @function. Running core in compatibility mode.', array(
'@function' => $debug[$cron_debug_level + 1]['function'],
'@line' => $debug[$cron_debug_level]['line'],
'@file' => $debug[$cron_debug_level]['file'],
), WATCHDOG_DEBUG);
}
ultimate_cron_cron_run_compatibility();
} catch (Throwable $e) {
$GLOBALS['user'] = $GLOBALS['ultimate_cron_original_user'];
drupal_save_session($GLOBALS['ultimate_cron_original_session_saving']);
throw $e;
} catch (Exception $e) {
$GLOBALS['user'] = $GLOBALS['ultimate_cron_original_user'];
drupal_save_session($GLOBALS['ultimate_cron_original_session_saving']);
throw $e;
}
return array();
}
ultimate_cron_cron_run();
exit;
}
return array();
}
function ultimate_cron_plugin_cleanup($job, $arguments) {
$type = $arguments['type'];
$name = $arguments['name'];
$plugin = _ultimate_cron_plugin_require($type, $name);
$plugin
->cleanup();
}
function ultimate_cron_watchdog(array $log_entry) {
if (class_exists('UltimateCronLogger')) {
UltimateCronLogger::hook_watchdog($log_entry);
}
}
function ultimate_cron_cron_run() {
if (variable_get('install_task', FALSE) != 'done') {
return;
}
if (drupal_is_cli()) {
return;
}
ultimate_cron_run_scheduled(FALSE);
exit;
}
function ultimate_cron_cron_run_compatibility() {
foreach (_ultimate_cron_job_load_all() as $job) {
if (in_array('core', $job->hook['tags'])) {
$core_jobs[] = $job;
}
else {
if (!variable_get('ultimate_cron_check_schedule_on_core_cron', FALSE) || $job
->isScheduled()) {
if ($lock_id = $job
->lock()) {
$log_entry = $job
->startLog($lock_id, 'Launched by Drupal core');
$job
->run();
$log_entry
->finish();
$job
->unlock();
}
}
}
}
foreach ($core_jobs as $job) {
$lock_id = $job
->lock();
if (!$lock_id) {
throw new Exception(t('Could not acquire lock for @name', array(
'@name' => $job->name,
)));
}
$job
->startLog($lock_id, 'Launched by Drupal core');
}
}
function _ultimate_cron_variable_load($name, $default = NULL) {
if ($value = db_query("SELECT value FROM {variable} WHERE name = :name", array(
':name' => $name,
))
->fetchField()) {
$value = unserialize($value);
}
else {
$value = $default;
}
global $conf;
$conf[$name] = $value;
return $value;
}
function _ultimate_cron_variable_load_multiple($names, $default = NULL) {
$values = array();
$result = db_query("SELECT name, value FROM {variable} WHERE name IN (:names)", array(
':names' => $names,
))
->fetchAllKeyed();
global $conf;
foreach ($names as $name) {
$conf[$name] = $values[$name] = isset($result[$name]) ? unserialize($result[$name]) : $default;
}
return $values;
}
function _ultimate_cron_variable_save($name, $value) {
global $conf;
db_merge('variable')
->key(array(
'name' => $name,
))
->fields(array(
'value' => serialize($value),
))
->execute();
$conf[$name] = $value;
}
function ultimate_cron_get_easy_hooks() {
static $easy_hooks;
if (isset($easy_hooks)) {
return $easy_hooks;
}
$easy_hooks = array(
'cron' => array(
'title' => 'Default cron job',
),
'cron_hourly' => array(
'title' => 'Hourly cron job',
'scheduler' => array(
'name' => 'crontab',
'crontab' => array(
'rules' => array(
'0+@ * * * *',
),
),
),
),
'cron_daily' => array(
'title' => 'Daily cron job',
'scheduler' => array(
'name' => 'crontab',
'crontab' => array(
'rules' => array(
'0+@ 12 * * *',
),
),
),
),
'cron_nightly' => array(
'title' => 'Nightly cron job',
'scheduler' => array(
'name' => 'crontab',
'crontab' => array(
'rules' => array(
'0+@ 0 * * *',
),
),
),
),
'cron_weekly' => array(
'title' => 'Weekly cron job',
'scheduler' => array(
'name' => 'crontab',
'crontab' => array(
'rules' => array(
'0+@ 0 * * 1',
),
),
),
),
'cron_monthly' => array(
'title' => 'Monthly cron job',
'scheduler' => array(
'name' => 'crontab',
'crontab' => array(
'rules' => array(
'0+@ 0 1 * *',
),
),
),
),
'cron_yearly' => array(
'title' => 'Yearly cron job',
'scheduler' => array(
'name' => 'crontab',
'crontab' => array(
'rules' => array(
'0+@ 0 1 1 *',
),
),
),
),
);
$easy_hooks += module_invoke_all('cron_easy_hooks');
drupal_alter('cron_easy_hooks', $easy_hooks);
return $easy_hooks;
}
function ultimate_cron_get_hook($name, $reset = FALSE) {
$hooks = ultimate_cron_get_hooks($reset);
return $hooks[$name];
}
function ultimate_cron_get_module_hooks($module) {
$items = array();
if (module_hook($module, 'cronapi')) {
$items = module_invoke($module, 'cronapi', NULL);
if (!is_array($items)) {
$items = array();
$list = module_invoke($module, 'cronapi', 'list');
if (!$list) {
$list = array();
}
foreach ($list as $name => $title) {
$items[$name] = array(
'title' => $title,
);
}
foreach ($items as $name => &$item) {
$item['api_version'] = 'ultimate_cron-1';
$rules = module_invoke($module, 'cronapi', 'rule', $name);
$rules = $rules ? $rules : array();
$settings = (array) module_invoke($module, 'cronapi', 'settings', $name);
if (empty($settings['rules']) && $rules) {
$settings['rules'] = is_array($rules) ? $rules : array(
$rules,
);
}
if (!empty($settings['rules'])) {
$settings['scheduler'] = array(
'name' => 'crontab',
'crontab' => array(
'rules' => $settings['rules'],
),
);
unset($settings['rules']);
}
$settings += array(
'configure' => module_invoke($module, 'cronapi', 'configure', $name),
);
$item += $settings;
}
}
else {
foreach ($items as &$item) {
if (!empty($item['rule'])) {
$item['scheduler'] = array(
'name' => 'crontab',
'crontab' => array(
'rules' => array(
$item['rule'],
),
),
);
$item['api_version'] = 'elysia_cron-2';
$item['title'] = $item['description'];
}
}
}
}
if (module_hook($module, 'cron')) {
if (empty($items["{$module}_cron"])) {
$items["{$module}_cron"] = array();
}
$info = system_get_info('module', $module);
$items["{$module}_cron"] += array(
'module' => $module,
'title' => 'Default cron handler',
'configure' => empty($info['configure']) ? NULL : $info['configure'],
'tags' => array(),
'pass job argument' => FALSE,
);
$items["{$module}_cron"]['tags'][] = 'core';
}
foreach (ultimate_cron_get_easy_hooks() as $name => $easy_hook) {
$hook_name = "{$module}_{$name}";
if (module_hook($module, $name)) {
if (empty($items[$hook_name])) {
$items[$hook_name] = array();
}
$items[$hook_name] += $easy_hook;
$info = system_get_info('module', $module);
$items[$hook_name] += array(
'module' => $module,
'title' => 'Easy hook ' . $name,
);
}
}
foreach ($items as &$item) {
$item += array(
'module' => $module,
);
}
return $items;
}
function ultimate_cron_get_plugin_hooks() {
$items = array();
$plugin_types = ctools_plugin_get_plugin_type_info();
foreach ($plugin_types['ultimate_cron'] as $plugin_type => $info) {
$plugins = _ultimate_cron_plugin_load_all($plugin_type);
foreach ($plugins as $plugin) {
if ($plugin
->isValid()) {
$items += $plugin
->cronapi();
}
}
}
return $items;
}
function ultimate_cron_prepare_hooks(&$hooks) {
static $plugin_types;
static $plugins;
if (!isset($plugin_types)) {
ctools_include('plugins');
$plugin_types = ctools_plugin_get_plugin_type_info();
$plugins = array();
foreach ($plugin_types['ultimate_cron'] as $plugin_type => $info) {
$plugins[$plugin_type] = _ultimate_cron_plugin_load_all($plugin_type);
}
}
foreach ($hooks as $name => &$item) {
foreach ($plugin_types['ultimate_cron'] as $plugin_type => $info) {
$static = $info['defaults']['static'];
$class = $static['class'];
$item += array(
$plugin_type => array(),
);
if (!$class::$multiple) {
$item[$plugin_type] += array(
'name' => variable_get('ultimate_cron_plugin_' . $plugin_type . '_default', $static['default plugin']),
);
}
foreach ($plugins[$plugin_type] as $plugin_name => $plugin) {
if (!$plugin
->isValid()) {
continue;
}
$item[$plugin_type] += array(
$plugin_name => array(),
);
}
}
$item += array(
'title' => $name,
'description' => isset($item['title']) ? $item['title'] : $name,
'file path' => drupal_get_path('module', $item['module']),
'callback arguments' => array(),
'callback' => $name,
'enabled' => TRUE,
'tags' => array(),
'api_version' => 'ultimate_cron-2',
'pass job argument' => TRUE,
);
}
}
function ultimate_cron_get_hooks($reset = FALSE) {
static $cache = NULL;
if (!$reset && isset($cache)) {
return $cache;
}
$cache = cache_get('ultimate_cron_hooks');
if ($cache && $cache->data) {
$cache = $cache->data;
return $cache;
}
$hooks = array();
$modules = module_list();
foreach ($modules as $module) {
$hooks += ultimate_cron_get_module_hooks($module);
}
$hooks += ultimate_cron_get_plugin_hooks();
ultimate_cron_prepare_hooks($hooks);
drupal_alter('cron', $hooks);
$registered = variable_get('ultimate_cron_hooks_registered', array());
$new = array();
foreach ($hooks as $name => $hook) {
$new[$name] = empty($registered[$name]) ? REQUEST_TIME : $registered[$name];
}
if ($registered != $new) {
variable_set('ultimate_cron_hooks_registered', $new);
}
$cache = $hooks;
cache_set('ultimate_cron_hooks', $cache);
return $cache;
}
function ultimate_cron_plugin_crontab_element_validate_rule($element, &$form_state) {
$rules = array();
$value = $element['#value'];
if (!empty($value)) {
$rules = explode(';', $value);
$rules = array_map('trim', $rules);
}
foreach ($rules as $rule) {
if (!ultimate_cron_validate_rule($rule)) {
form_error($element, t('%name: %rule is not a valid rule.', array(
'%name' => $element['#title'],
'%rule' => $rule,
)));
}
}
}
function ultimate_cron_validate_rule($rule) {
$cron = CronRule::factory($rule);
if (!$cron
->isValid()) {
return FALSE;
}
else {
return TRUE;
}
}
function ultimate_cron_blank_values($array) {
$result = array();
foreach ($array as $key => $value) {
switch (gettype($value)) {
case 'array':
$result[$key] = array();
break;
default:
$result[$key] = '';
}
}
return $result;
}
function ultimate_cron_run_scheduled_page($dest = NULL) {
ultimate_cron_run_scheduled(TRUE);
$dest = $dest ? $dest : 'admin/config/system/cron';
drupal_goto($dest);
}
function ultimate_cron_run_scheduled($set_message = TRUE) {
if (variable_get('ultimate_cron_disable_scheduled', 0)) {
ultimate_cron_watchdog_message('ultimate_cron', 'Cannot launch scheduled jobs while ultimate_cron_disable_scheduled variable is set!', array(), WATCHDOG_NOTICE, 'error', $set_message);
return;
}
if (variable_get('maintenance_mode', 0)) {
ultimate_cron_watchdog_message('ultimate_cron', 'Cannot launch scheduled jobs while in maintenance mode!', array(), WATCHDOG_NOTICE, 'error', $set_message);
return;
}
ultimate_cron_run_launchers();
}
function ultimate_cron_run_launchers($launchers = NULL) {
_ultimate_cron_variable_save('cron_last', time());
$launcher_jobs = array();
foreach (_ultimate_cron_job_load_all() as $job) {
$launcher = $job
->getPlugin('launcher');
if (!isset($launchers) || in_array($launcher->name, $launchers)) {
$launcher_jobs[$launcher->name]['launcher'] = $launcher;
$launcher_jobs[$launcher->name]['sort'] = array(
$launcher->weight,
);
$launcher_jobs[$launcher->name]['jobs'][$job->name] = $job;
$launcher_jobs[$launcher->name]['jobs'][$job->name]->sort = array(
$job
->loadLatestLogEntry()->start_time,
);
}
}
uasort($launcher_jobs, '_ultimate_cron_multi_column_sort');
foreach ($launcher_jobs as $name => $launcher_job) {
uasort($launcher_job['jobs'], '_ultimate_cron_multi_column_sort');
$launcher_job['launcher']
->launchJobs($launcher_job['jobs']);
}
}
function ultimate_cron_watchdog_message($type, $message, $variables, $severity, $status, $set_message) {
if ($set_message) {
drupal_set_message(t($message, $variables), $status);
}
else {
watchdog($type, $message, $variables, $severity);
}
}
function _ultimate_cron_sort_jobs_by_start_time($a, $b) {
return $a->log_entry->start_time == $b->log_entry->start_time ? 0 : ($a->log_entry->start_time > $b->log_entry->start_time ? 1 : -1);
}
function _ultimate_cron_multi_column_sort($a, $b) {
$a = (array) $a;
$b = (array) $b;
foreach ($a['sort'] as $i => $sort) {
if ($a['sort'][$i] == $b['sort'][$i]) {
continue;
}
return $a['sort'][$i] < $b['sort'][$i] ? -1 : 1;
}
return 0;
}
function _ultimate_cron_get_transactional_safe_connection() {
return !variable_get('ultimate_cron_bypass_transactional_safe_connection') && Database::getConnection()
->inTransaction() ? 'ultimate_cron' : 'default';
}
function _ultimate_cron_get_class($name) {
static $defaults = array(
'job' => 'UltimateCronJob',
'lock' => 'UltimateCronLock',
'progress' => 'UltimateCronProgress',
'signal' => 'UltimateCronSignal',
);
return variable_get('ultimate_cron_class_' . $name, $defaults[$name]);
}
function ultimate_cron_watchdog_throwable($type, Throwable $exception, $message = NULL, $variables = array(), $severity = WATCHDOG_ERROR, $link = NULL) {
if (empty($message)) {
$message = '%type: !message in %function (line %line of %file).';
}
if (!is_array($variables)) {
$variables = array();
}
require_once DRUPAL_ROOT . '/includes/errors.inc';
$variables += _drupal_decode_exception($exception);
watchdog($type, $message, $variables, $severity, $link);
}