Projet

Général

Profil

Paste
Télécharger (5,94 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / rules / rules_scheduler / rules_scheduler.module @ 74f6bef0

1
<?php
2

    
3
/**
4
 * @file
5
 * Rules scheduler module.
6
 */
7

    
8
define('RULES_SCHEDULER_PATH', 'admin/config/workflow/rules/schedule');
9

    
10
/**
11
 * Implements hook_cron().
12
 */
13
function rules_scheduler_cron() {
14
  if (rules_scheduler_queue_tasks()) {
15
    // hook_exit() is not invoked for cron runs, so register it as shutdown
16
    // callback for logging the rules log to the watchdog.
17
    drupal_register_shutdown_function('rules_exit');
18
    // Clear the log before running tasks via the queue to avoid logging
19
    // unrelated logs from previous cron-operations.
20
    RulesLog::logger()->clear();
21
  }
22
}
23

    
24
/**
25
 * Implements hook_cron_queue_info().
26
 */
27
function rules_scheduler_cron_queue_info() {
28
  $queues['rules_scheduler_tasks'] = array(
29
    'worker callback' => 'rules_scheduler_run_task',
30
    'time' => 15,
31
  );
32
  return $queues;
33
}
34

    
35
/**
36
 * Queue worker callback for running a single task.
37
 *
38
 * @param array $task
39
 *   The task to process.
40
 */
41
function rules_scheduler_run_task(array $task) {
42
  try {
43
    rules_scheduler_task_handler($task)->runTask();
44
  }
45
  catch (RulesEvaluationException $e) {
46
    rules_log($e->msg, $e->args, $e->severity);
47
    rules_log('Unable to execute task with identifier %id scheduled on date %date.', array('%id' => $task['identifier'], '%date' => format_date($task['date'])), RulesLog::ERROR);
48
  }
49
}
50

    
51
/**
52
 * Returns the task handler for a given task.
53
 *
54
 * @param array $task
55
 *   A task (queue item) array.
56
 *
57
 * @throws RulesEvaluationException
58
 *   If the task handler class is missing.
59
 *
60
 * @return RulesSchedulerTaskHandlerInterface
61
 *   The task handler.
62
 */
63
function rules_scheduler_task_handler(array $task) {
64
  $class = !empty($task['handler']) ? $task['handler'] : 'RulesSchedulerDefaultTaskHandler';
65
  if (!class_exists($class)) {
66
    throw new RulesEvaluationException('Missing task handler implementation %class.', array('%class' => $class), NULL, RulesLog::ERROR);
67
  }
68
  return new $class($task);
69
}
70

    
71
/**
72
 * Implements hook_rules_ui_menu_alter().
73
 *
74
 * Adds a menu item for the 'schedule' operation.
75
 */
76
function rules_scheduler_rules_ui_menu_alter(&$items, $base_path, $base_count) {
77
  $items[$base_path . '/manage/%rules_config/schedule'] = array(
78
    'title callback' => 'rules_get_title',
79
    'title arguments' => array('Schedule !plugin "!label"', $base_count + 1),
80
    'page callback' => 'drupal_get_form',
81
    'page arguments' => array('rules_scheduler_schedule_form', $base_count + 1, $base_path),
82
    'access callback' => 'rules_config_access',
83
    'access arguments' => array('update', $base_count + 1),
84
    'file' => 'rules_scheduler.admin.inc',
85
    'file path' => drupal_get_path('module', 'rules_scheduler'),
86
  );
87
}
88

    
89
/**
90
 * Implements hook_menu().
91
 */
92
function rules_scheduler_menu() {
93
  $items = array();
94
  $items[RULES_SCHEDULER_PATH] = array(
95
    'title' => 'Schedule',
96
    'type' => MENU_LOCAL_TASK,
97
    'page callback' => 'rules_scheduler_schedule_page',
98
    'access arguments' => array('administer rules'),
99
    'file' => 'rules_scheduler.admin.inc',
100
  );
101
  $items[RULES_SCHEDULER_PATH .'/%rules_scheduler_task/delete'] = array(
102
    'title' => 'Delete a scheduled task',
103
    'type' => MENU_CALLBACK,
104
    'page callback' => 'drupal_get_form',
105
    'page arguments' => array('rules_scheduler_delete_task', 5),
106
    'access arguments' => array('administer rules'),
107
    'file' => 'rules_scheduler.admin.inc',
108
  );
109
  return $items;
110
}
111

    
112
/**
113
 * Load a task by a given task ID.
114
 */
115
function rules_scheduler_task_load($tid) {
116
  $result = db_select('rules_scheduler', 'r')
117
    ->fields('r')
118
    ->condition('tid', (int) $tid)
119
    ->execute();
120
  return $result->fetchAssoc();
121
}
122

    
123
/**
124
 * Delete a task by a given task ID.
125
 */
126
function rules_scheduler_task_delete($tid) {
127
  db_delete('rules_scheduler')
128
    ->condition('tid', $tid)
129
    ->execute();
130
}
131

    
132
/**
133
 * Schedule a task to be executed later on.
134
 *
135
 * @param $task
136
 *   An array representing the task with the following keys:
137
 *   - config: The machine readable name of the to be scheduled component.
138
 *   - date: Timestamp when the component should be executed.
139
 *   - state: (deprecated) Rules evaluation state to use for scheduling.
140
 *   - data: Any additional data to store with the task.
141
 *   - handler: The name of the task handler class.
142
 *   - identifier: User provided string to identify the task per scheduled
143
 *   configuration.
144
 */
145
function rules_scheduler_schedule_task($task) {
146
  // Map the deprecated 'state' property into 'data'.
147
  if (isset($task['state'])) {
148
    $task['data'] = $task['state'];
149
    unset($task['state']);
150
  }
151
  if (!empty($task['identifier'])) {
152
    // If there is a task with the same identifier and component, we replace it.
153
    db_delete('rules_scheduler')
154
      ->condition('config', $task['config'])
155
      ->condition('identifier', $task['identifier'])
156
      ->execute();
157
  }
158
  drupal_write_record('rules_scheduler', $task);
159
}
160

    
161
/**
162
 * Queue tasks that are ready for execution.
163
 *
164
 * @return boolean
165
 *   Returns TRUE if any queue items where created, otherwise FALSE.
166
 */
167
function rules_scheduler_queue_tasks() {
168
  $items_created = FALSE;
169
  // Limit adding tasks to 1000 per cron run.
170
  $result = db_select('rules_scheduler', 'r', array('fetch' => PDO::FETCH_ASSOC))
171
    ->fields('r')
172
    ->condition('date', time(), '<=')
173
    ->orderBy('date')
174
    ->range(0, 1000)
175
    ->execute();
176

    
177
  $queue = DrupalQueue::get('rules_scheduler_tasks');
178
  foreach ($result as $task) {
179
    // Add the task to the queue and remove the entry afterwards.
180
    if ($queue->createItem($task)) {
181
      $items_created = TRUE;
182
      rules_scheduler_task_handler($task)->afterTaskQueued();
183
    }
184
  }
185
  return $items_created;
186
}
187

    
188
/**
189
 * Implements hook_rules_config_delete().
190
 */
191
function rules_scheduler_rules_config_delete($rules_config) {
192
  // Delete all tasks scheduled for this config.
193
  db_delete('rules_scheduler')
194
    ->condition('config', $rules_config->name)
195
    ->execute();
196
}
197

    
198
/**
199
 * Implements hook_views_api().
200
 */
201
function rules_scheduler_views_api() {
202
  return array(
203
    'api' => '3.0-alpha1',
204
    'path' => drupal_get_path('module', 'rules_scheduler') .'/includes',
205
  );
206
}