PDO::FETCH_ASSOC)) ->fields('r') ->condition('date', time(), '<=') ->range(0, 1000) ->execute(); $queue = DrupalQueue::get('rules_scheduler_tasks'); foreach ($result as $task) { // Add the task to the queue and remove the entry afterwards. if ($queue->createItem($task)) { db_delete('rules_scheduler') ->condition('tid', $task['tid']) ->execute(); $task_created = TRUE; } } if (!empty($task_created)) { // hook_exit() is not invoked for cron runs, so register it as shutdown // callback for logging the rules log to the watchdog. drupal_register_shutdown_function('rules_exit'); // Clear the log before running tasks via the queue to avoid logging // unrelated logs from previous cron-operations. RulesLog::logger()->clear(); } } /** * Implements hook_cron_queue_info(). */ function rules_scheduler_cron_queue_info() { $queues['rules_scheduler_tasks'] = array( 'worker callback' => 'rules_scheduler_run_task', 'time' => 15, ); return $queues; } /** * Queue worker callback for running a single task. */ function rules_scheduler_run_task(array $task) { if ($component = rules_get_cache('comp_' . $task['config'])) { $replacements = array('%label' => $component->label(), '%plugin' => $component->plugin()); $replacements['%identifier'] = $task['identifier'] ? $task['identifier'] : t('without identifier'); rules_log('Scheduled evaluation of %plugin %label, task %identifier.', $replacements, RulesLog::INFO, $component, TRUE); $state = unserialize($task['state']); $state->restoreBlocks(); // Finally evaluate the component with the given state. $component->evaluate($state); rules_log('Finished evaluation of %plugin %label, task %identifier.', $replacements, RulesLog::INFO, $component, FALSE); $state->cleanUp(); } } /** * Implements hook_rules_ui_menu_alter(). * * Adds a menu item for the 'schedule' operation. */ function rules_scheduler_rules_ui_menu_alter(&$items, $base_path, $base_count) { $items[$base_path . '/manage/%rules_config/schedule'] = array( 'title callback' => 'rules_get_title', 'title arguments' => array('Schedule !plugin "!label"', $base_count + 1), 'page callback' => 'drupal_get_form', 'page arguments' => array('rules_scheduler_schedule_form', $base_count + 1, $base_path), 'access callback' => 'rules_config_access', 'access arguments' => array('update', $base_count + 1), 'file' => 'rules_scheduler.admin.inc', 'file path' => drupal_get_path('module', 'rules_scheduler'), ); } /** * Implements hook_menu(). */ function rules_scheduler_menu() { $items = array(); $items[RULES_SCHEDULER_PATH] = array( 'title' => 'Schedule', 'type' => MENU_LOCAL_TASK, 'page callback' => 'rules_scheduler_schedule_page', 'access arguments' => array('administer rules'), 'file' => 'rules_scheduler.admin.inc', ); $items[RULES_SCHEDULER_PATH .'/%rules_scheduler_task/delete'] = array( 'title' => 'Delete a scheduled task', 'type' => MENU_CALLBACK, 'page callback' => 'drupal_get_form', 'page arguments' => array('rules_scheduler_delete_task', 5), 'access arguments' => array('administer rules'), 'file' => 'rules_scheduler.admin.inc', ); return $items; } /** * Load a task by a given task ID. */ function rules_scheduler_task_load($tid) { $result = db_select('rules_scheduler', 'r') ->fields('r') ->condition('tid', (int) $tid) ->execute(); return $result->fetchAssoc(); } /** * Delete a task by a given task ID. */ function rules_scheduler_task_delete($tid) { db_delete('rules_scheduler') ->condition('tid', $tid) ->execute(); } /** * Schedule a task to be executed later on. * * @param $task * An array representing the task with the following keys: * - config: The machine readable name of the to be scheduled component. * - date: Timestamp when the component should be executed. * - state: An rules evaluation state to use for scheduling. * - identifier: User provided string to identify the task per scheduled * configuration. */ function rules_scheduler_schedule_task($task) { if (!empty($task['identifier'])) { // If there is a task with the same identifier and component, we replace it. db_delete('rules_scheduler') ->condition('config', $task['config']) ->condition('identifier', $task['identifier']) ->execute(); } drupal_write_record('rules_scheduler', $task); } /** * Implements hook_rules_config_delete(). */ function rules_scheduler_rules_config_delete($rules_config) { // Delete all tasks scheduled for this config. db_delete('rules_scheduler') ->condition('config', $rules_config->name) ->execute(); } /** * Implements hook_views_api(). */ function rules_scheduler_views_api() { return array( 'api' => '3.0-alpha1', 'path' => drupal_get_path('module', 'rules_scheduler') .'/includes', ); }