1
|
<?php
|
2
|
|
3
|
/**
|
4
|
* @file
|
5
|
* Rules integration for the rules scheduler module.
|
6
|
*
|
7
|
* @addtogroup rules
|
8
|
*
|
9
|
* @{
|
10
|
*/
|
11
|
|
12
|
/**
|
13
|
* Implements hook_rules_action_info().
|
14
|
*/
|
15
|
function rules_scheduler_rules_action_info() {
|
16
|
$items['schedule'] = array(
|
17
|
'label' => t('Schedule component evaluation'),
|
18
|
'group' => t('Rules scheduler'),
|
19
|
'base' => 'rules_scheduler_action_schedule',
|
20
|
'named parameter' => TRUE,
|
21
|
'parameter' => array(
|
22
|
'component' => array(
|
23
|
'type' => 'text',
|
24
|
'label' => t('Component'),
|
25
|
'options list' => 'rules_scheduler_component_options_list',
|
26
|
'restriction' => 'input',
|
27
|
'description' => 'Select the component to schedule. Only components containing actions are available – no condition sets.',
|
28
|
),
|
29
|
'date' => array(
|
30
|
'type' => 'date',
|
31
|
'label' => t('Scheduled evaluation date'),
|
32
|
),
|
33
|
'identifier' => array(
|
34
|
'type' => 'text',
|
35
|
'label' => t('Identifier'),
|
36
|
'description' => t('A string used for identifying this task. Any existing tasks for this component with the same identifier will be replaced.'),
|
37
|
'optional' => TRUE,
|
38
|
),
|
39
|
// Further needed parameter by the component are added during processing.
|
40
|
),
|
41
|
);
|
42
|
// Add action to delete scheduled tasks.
|
43
|
$items['schedule_delete'] = array(
|
44
|
'label' => t('Delete scheduled tasks'),
|
45
|
'group' => t('Rules scheduler'),
|
46
|
'base' => 'rules_scheduler_action_delete',
|
47
|
'parameter' => array(
|
48
|
'component' => array(
|
49
|
'type' => 'text',
|
50
|
'label' => t('Component'),
|
51
|
'options list' => 'rules_scheduler_component_options_list',
|
52
|
'description' => t('The component for which scheduled tasks will be deleted.'),
|
53
|
'optional' => TRUE,
|
54
|
),
|
55
|
'task' => array(
|
56
|
'type' => 'text',
|
57
|
'label' => t('Task identifier'),
|
58
|
'description' => t('All tasks that are annotated with the given identifier will be deleted.'),
|
59
|
'optional' => TRUE,
|
60
|
),
|
61
|
),
|
62
|
);
|
63
|
return $items;
|
64
|
}
|
65
|
|
66
|
/**
|
67
|
* Options list callback returning a list of action components.
|
68
|
*/
|
69
|
function rules_scheduler_component_options_list() {
|
70
|
return rules_get_components(TRUE, 'action');
|
71
|
}
|
72
|
|
73
|
/**
|
74
|
* Base action implementation for scheduling components.
|
75
|
*/
|
76
|
function rules_scheduler_action_schedule($args, $element) {
|
77
|
$state = $args['state'];
|
78
|
if ($component = rules_get_cache('comp_' . $args['component'])) {
|
79
|
// Manually create a new evaluation state for scheduling the evaluation.
|
80
|
$new_state = new RulesState();
|
81
|
|
82
|
// Register all parameters as variables.
|
83
|
foreach ($element->pluginParameterInfo() as $name => $info) {
|
84
|
if (strpos($name, 'param_') === 0) {
|
85
|
// Remove the parameter name prefix 'param_'.
|
86
|
$var_name = substr($name, 6);
|
87
|
$new_state->addVariable($var_name, $state->currentArguments[$name], $info);
|
88
|
}
|
89
|
}
|
90
|
rules_scheduler_schedule_task(array(
|
91
|
'date' => $args['date'],
|
92
|
'config' => $args['component'],
|
93
|
'data' => $new_state,
|
94
|
'identifier' => $args['identifier'],
|
95
|
));
|
96
|
}
|
97
|
else {
|
98
|
throw new RulesEvaluationException('Unable to get the component %name', array('%name' => $args['component']), $element, RulesLog::ERROR);
|
99
|
}
|
100
|
}
|
101
|
|
102
|
/**
|
103
|
* Info alteration callback for the schedule action.
|
104
|
*/
|
105
|
function rules_scheduler_action_schedule_info_alter(&$element_info, RulesPlugin $element) {
|
106
|
if (isset($element->settings['component'])) {
|
107
|
// If run during a cache rebuild the cache might not be instantiated yet,
|
108
|
// so fail back to loading the component from database.
|
109
|
if (($component = rules_get_cache('comp_' . $element->settings['component'])) || $component = rules_config_load($element->settings['component'])) {
|
110
|
// Add in the needed parameters.
|
111
|
foreach ($component->parameterInfo() as $name => $info) {
|
112
|
$element_info['parameter']['param_' . $name] = $info;
|
113
|
}
|
114
|
}
|
115
|
}
|
116
|
}
|
117
|
|
118
|
/**
|
119
|
* Validate callback for the schedule action.
|
120
|
*
|
121
|
* Makes sure the component exists and is not dirty.
|
122
|
*
|
123
|
* @see rules_element_invoke_component_validate()
|
124
|
*/
|
125
|
function rules_scheduler_action_schedule_validate(RulesPlugin $element) {
|
126
|
$info = $element->info();
|
127
|
$component = rules_config_load($element->settings['component']);
|
128
|
if (!$component) {
|
129
|
throw new RulesIntegrityException(t('The component %config does not exist.', array('%config' => $element->settings['component'])), $element);
|
130
|
}
|
131
|
// Check if the component is marked as dirty.
|
132
|
rules_config_update_dirty_flag($component);
|
133
|
if (!empty($component->dirty)) {
|
134
|
throw new RulesIntegrityException(t('The utilized component %config fails the integrity check.', array('%config' => $element->settings['component'])), $element);
|
135
|
}
|
136
|
}
|
137
|
|
138
|
/**
|
139
|
* Help for the schedule action.
|
140
|
*/
|
141
|
function rules_scheduler_action_schedule_help() {
|
142
|
return t("Note that component evaluation is triggered by <em>cron</em> – make sure cron is configured correctly by checking your site's !status. The scheduling time accuracy depends on your configured cron interval. See <a href='@url'>the online documentation</a> for more information on how to schedule evaluation of components.",
|
143
|
array('!status' => l(t('Status report'), 'admin/reports/status'),
|
144
|
'@url' => rules_external_help('scheduler')));
|
145
|
}
|
146
|
|
147
|
/**
|
148
|
* Form alter callback for the schedule action.
|
149
|
*/
|
150
|
function rules_scheduler_action_schedule_form_alter(&$form, &$form_state, $options, RulesAbstractPlugin $element) {
|
151
|
$first_step = empty($element->settings['component']);
|
152
|
$form['reload'] = array(
|
153
|
'#weight' => 5,
|
154
|
'#type' => 'submit',
|
155
|
'#name' => 'reload',
|
156
|
'#value' => $first_step ? t('Continue') : t('Reload form'),
|
157
|
'#limit_validation_errors' => array(array('parameter', 'component')),
|
158
|
'#submit' => array('rules_action_type_form_submit_rebuild'),
|
159
|
'#ajax' => rules_ui_form_default_ajax(),
|
160
|
);
|
161
|
// Use ajax and trigger as the reload button.
|
162
|
$form['parameter']['component']['settings']['type']['#ajax'] = $form['reload']['#ajax'] + array(
|
163
|
'event' => 'change',
|
164
|
'trigger_as' => array('name' => 'reload'),
|
165
|
);
|
166
|
|
167
|
if ($first_step) {
|
168
|
// In the first step show only the component select.
|
169
|
foreach (element_children($form['parameter']) as $key) {
|
170
|
if ($key != 'component') {
|
171
|
unset($form['parameter'][$key]);
|
172
|
}
|
173
|
}
|
174
|
unset($form['submit']);
|
175
|
unset($form['provides']);
|
176
|
}
|
177
|
else {
|
178
|
// Hide the reload button in case js is enabled and it's not the first step.
|
179
|
$form['reload']['#attributes'] = array('class' => array('rules-hide-js'));
|
180
|
}
|
181
|
}
|
182
|
|
183
|
/**
|
184
|
* Action: Delete scheduled tasks.
|
185
|
*/
|
186
|
function rules_scheduler_action_delete($component_name = NULL, $task_identifier = NULL) {
|
187
|
$query = db_delete('rules_scheduler');
|
188
|
if (!empty($component_name)) {
|
189
|
$query->condition('config', $component_name);
|
190
|
}
|
191
|
if (!empty($task_identifier)) {
|
192
|
$query->condition('identifier', $task_identifier);
|
193
|
}
|
194
|
$query->execute();
|
195
|
}
|
196
|
|
197
|
/**
|
198
|
* Cancels scheduled task action validation callback.
|
199
|
*/
|
200
|
function rules_scheduler_action_delete_validate($element) {
|
201
|
if (empty($element->settings['task']) && empty($element->settings['task:select']) &&
|
202
|
empty($element->settings['component']) && empty($element->settings['component:select'])) {
|
203
|
|
204
|
throw new RulesIntegrityException(t('You have to specify at least either a component or a task identifier.'), $element);
|
205
|
}
|
206
|
}
|
207
|
|
208
|
/**
|
209
|
* Help for the cancel action.
|
210
|
*/
|
211
|
function rules_scheduler_action_delete_help() {
|
212
|
return t('This action allows you to delete scheduled tasks that are waiting for future execution.') . ' ' . t('They can be addressed by an identifier or by the component name, whereas if both are specified only tasks fulfilling both requirements will be deleted.');
|
213
|
}
|
214
|
|
215
|
/**
|
216
|
* @}
|
217
|
*/
|