/[drupal]/contributions/modules/nodetriggers/nodetriggers.module
ViewVC logotype

Contents of /contributions/modules/nodetriggers/nodetriggers.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download) (as text)
Wed Nov 14 22:45:42 2007 UTC (2 years ago) by pfournier
Branch: MAIN
CVS Tags: DRUPAL-5--1-0, HEAD
Branch point for: DRUPAL-5
File MIME type: text/x-php
Initial checkin of the nodetriggers module
1 <?php
2 /* $Id$ */
3
4 /**
5 * @file
6 * Triggers actions using node events.
7 */
8
9 function nodetriggers_perm() {
10 return array('administer node triggers');
11 }
12
13 /**
14 * Implementation of hook_menu().
15 */
16 function nodetriggers_menu($may_cache) {
17 $items = array();
18 $access = user_access('administer node triggers');
19
20 if (!$may_cache) {
21 $items[] = array(
22 'path' => 'admin/build/nodetriggers',
23 'title' => t('Node Triggers'),
24 'description' => t('Manage the node triggers defined for your site.'),
25 'access' => $access,
26 'callback' => 'nodetriggers_overview');
27
28 $items[] = array(
29 'path' => 'admin/build/nodetriggers/list',
30 'title' => t('List node triggers'),
31 'access' => $access,
32 'weight' => 0,
33 'type' => MENU_DEFAULT_LOCAL_TASK);
34
35 $items[] = array(
36 'path' => 'admin/build/nodetriggers/add',
37 'title' => t('Add node triggers'),
38 'access' => $access,
39 'weight' => 1,
40 'callback' => 'drupal_get_form',
41 'callback arguments' => array('nodetriggers_configure'),
42 'type' => MENU_LOCAL_TASK);
43
44 $items[] = array(
45 'path' => 'admin/build/nodetriggers/edit',
46 'title' => t('Configure node triggers'),
47 'access' => $access,
48 'weight' => -9,
49 'callback' => 'drupal_get_form',
50 'callback arguments' => array('nodetriggers_configure'),
51 'type' => MENU_CALLBACK);
52
53 $items[] = array(
54 'path' => 'admin/build/nodetriggers/delete',
55 'title' => t('Delete node triggers'),
56 'access' => $access,
57 'weight' => -8,
58 'callback' => 'drupal_get_form',
59 'callback arguments' => array('nodetriggers_delete'),
60 'type' => MENU_CALLBACK);
61 }
62
63 return $items;
64 }
65
66 /**
67 * Menu callback.
68 * Create the main action module page giving an overview of configured actions.
69 *
70 */
71 function nodetriggers_overview() {
72 $output = '<p>' . t('The node triggers module is used to trigger actions when something happens to a node. You do this by creating a Trigger Set, that defines the actions to be triggered and which node types will trigger the actions.') . '</p>';
73 $row = array();
74 $header = array(
75 array('data' => t('Trigger Set'), 'field' => 'name'),
76 array('data' => t('Description'), 'field' => 'description'),
77 array('data' => t('Weight'), 'field' => 'priority'),
78 array('data' => t('Operations'), 'colspan' => '2')
79 );
80 $sql = 'SELECT * FROM {nodetriggers_configs}';
81 $result = pager_query($sql . tablesort_sql($header), 50);
82 while ($data = db_fetch_object($result)) {
83 $row[] = array(
84 array('data' => $data->name),
85 array('data' => $data->description),
86 array('data' => $data->priority),
87 array('data' => l(t('edit'), "admin/build/nodetriggers/edit/$data->id")),
88 array('data' => l(t('delete'), "admin/build/nodetriggers/delete/$data->id"))
89 );
90 }
91
92 if ($row) {
93 $pager = theme('pager', NULL, 50, 0);
94 if (!empty($pager)) {
95 $row[] = array(array('data' => $pager, 'colspan' => '3'));
96 }
97 $output .= t('Node Triggers Sets:');
98 $output .= theme('table', $header, $row);
99 }
100
101 return $output;
102 }
103 /**
104 * Returns the form to add or modify a trigger set.
105 *
106 * @param $trigger The trigger set to modify, NULL if we should create one.
107 * @return the form
108 */
109 function nodetriggers_configure_form($trigger = NULL) {
110 if ($trigger) {
111 $output = t('Modify the trigger set.');
112 }
113 else {
114 $output = t('Create a new trigger set.');
115 }
116 $output .= drupal_get_form('nodetriggers_configure');
117 return $output;
118 }
119
120 function nodetriggers_configure($trigger = NULL) {
121
122 if ($trigger) {
123 $edit = _nodetriggers_load_configuration($trigger);
124 }
125 else {
126 $edit = array();
127 }
128
129 $form = array();
130 $form['nodetriggers_name'] = array(
131 '#type' => 'textfield',
132 '#title' => t('Name'),
133 '#default_value' => $edit['name'],
134 '#size' => '40',
135 '#maxlength' => '255',
136 '#description' => t('A name for this trigger set'),
137 '#weight' => -13
138 );
139 $form['nodetriggers_desc'] = array(
140 '#type' => 'textarea',
141 '#title' => t('Description'),
142 '#default_value' => $edit['description'],
143 '#cols' => '40',
144 '#rows' => '3',
145 '#resizable' => TRUE,
146 '#description' => t('A short description of the trigger set.'),
147 '#weight' => -12
148 );
149 $form['nodetriggers_weight'] = array(
150 '#type' => 'weight',
151 '#title' => t('Weight'),
152 '#default_value' => $edit['priority'],
153 '#delta' => '10',
154 '#description' => t('Heavier trigger set will be executed after lighter ones.'),
155 '#weight' => -11
156 );
157
158 $types = drupal_map_assoc(node_get_types('names'));
159 $form['nodetriggers_node_types'] = array(
160 '#type' => 'checkboxes',
161 '#title' => t('Node types'),
162 '#default_value' => $edit['node_types'],
163 '#options' => $types,
164 '#description' => t('Events on these node types will trigger the actions defined in this trigger set.'),
165 '#weight' => -10
166 );
167
168 // List actions if Actions module is installed.
169 $actions = array();
170 if (function_exists(actions_get_all_actions)) {
171 $actions_data = actions_get_all_actions();
172 foreach ($actions_data as $name => $metadata) {
173 if (isset($actions[$metadata['type']])) {
174 $actions[$metadata['type']][md5($name)] = $metadata['description'];
175 }
176 else {
177 $actions[$metadata['type']] = array(md5($name) => $metadata['description']);
178 }
179 }
180 }
181
182 $form['nodetriggers_oncreate'] = array(
183 '#type' => 'fieldset',
184 '#title' => t('On create'),
185 '#collapsible' => TRUE,
186 '#collapsed' => FALSE,
187 '#weight' => -9
188 );
189 $form['nodetriggers_oncreate']['nodetriggers_create_activate'] = array(
190 '#type' => 'checkboxes',
191 '#default_value' => $edit['insert']['active'] ? 'nodetriggers_create_activate' : 0,
192 '#options' => array('nodetriggers_create_activate' => t('Node creation triggers this action.')),
193 '#weight' => -9
194 );
195 $form['nodetriggers_oncreate']['nodetriggers_create_action'] = array(
196 '#type' => 'select',
197 '#title' => t('Action'),
198 '#default_value' => $edit['insert']['action_ids'][0],
199 '#options' => $actions,
200 '#weight' => -8
201 );
202
203 $form['nodetriggers_onupdate'] = array(
204 '#type' => 'fieldset',
205 '#title' => t('On update'),
206 '#collapsible' => TRUE,
207 '#collapsed' => FALSE,
208 '#weight' => -8
209 );
210 $form['nodetriggers_onupdate']['nodetriggers_update_activate'] = array(
211 '#type' => 'checkboxes',
212 '#default_value' => $edit['update']['active'] ? 'nodetriggers_update_activate' : 0,
213 '#options' => array('nodetriggers_update_activate' => t('Node update triggers this action.')),
214 '#weight' => -9
215 );
216 $form['nodetriggers_onupdate']['nodetriggers_update_action'] = array(
217 '#type' => 'select',
218 '#title' => t('Action'),
219 '#default_value' => $edit['update']['action_ids'][0],
220 '#options' => $actions,
221 '#weight' => -8
222 );
223
224 $form['nodetriggers_ondelete'] = array(
225 '#type' => 'fieldset',
226 '#title' => t('On delete'),
227 '#collapsible' => TRUE,
228 '#collapsed' => FALSE,
229 '#weight' => -7
230 );
231 $form['nodetriggers_ondelete']['nodetriggers_delete_activate'] = array(
232 '#type' => 'checkboxes',
233 '#default_value' => $edit['delete']['active'] ? 'nodetriggers_delete_activate' : 0,
234 '#options' => array('nodetriggers_delete_activate' => t('Node deletion triggers this action.')),
235 '#weight' => -9
236 );
237 $form['nodetriggers_ondelete']['nodetriggers_delete_action'] = array(
238 '#type' => 'select',
239 '#title' => t('Action'),
240 '#default_value' => $edit['delete']['action_ids'][0],
241 '#options' => $actions,
242 '#weight' => -8
243 );
244
245 $form['#validate'] = array(
246 'nodetriggers_configure_validate' => array(),
247 );
248
249 if ($trigger) {
250 $form['nodetriggers_submit'] = array(
251 '#type' => 'submit',
252 '#value' => t('Update'),
253 '#weight' => 10
254 );
255
256 $form['#submit'] = array(
257 'nodetriggers_configure_submit' => array($edit['id']),
258 );
259 }
260 else {
261 $form['nodetriggers_submit'] = array(
262 '#type' => 'submit',
263 '#value' => t('Submit'),
264 '#weight' => 10
265 );
266
267 $form['#submit'] = array(
268 'nodetriggers_configure_submit' => array(),
269 );
270 }
271
272 return $form;
273 }
274
275 function nodetriggers_configure_validate($form_id, $form_values) {
276 return TRUE;
277 }
278
279 function nodetriggers_configure_submit($form_id, $form_values, $update_id = NULL) {
280 $result = _nodetriggers_save_configuration($update_id, $form_values);
281 if ($result) {
282 drupal_set_message(t('The configuration has been successfully saved.'));
283 }
284 else {
285 drupal_set_message(t('There was an error while saving the configuration.'));
286 }
287
288 return 'admin/build/nodetriggers/list';
289 }
290
291 /**
292 * Form requesting confirmation of trigger set deletion.
293 *
294 * @param $config_id the trigger set id
295 * @return the form
296 */
297 function nodetriggers_delete($config_id) {
298 if (!$config_id) {
299 drupal_goto('admin/build/nodetriggers/list');
300 }
301
302 $config_name = _nodetriggers_get_configuration_name($config_id);
303
304 $form['#submit'] = array(
305 'nodetriggers_delete_submit' => array($config_id),
306 );
307
308 return confirm_form(
309 $form,
310 t('Really delete configuration !config?', array('!config' => theme('placeholder', $config_name))),
311 'admin/build/nodetriggers/list',
312 t('This cannot be undone.'),
313 t('Delete'),
314 t('Cancel')
315 );
316 }
317
318 function nodetriggers_delete_submit($form_id, $form_values, $config_id) {
319 if (_nodetriggers_delete_configuration($config_id)) {
320 drupal_set_message(t('The configuration was deleted.'));
321 }
322 return 'admin/build/nodetriggers/list';
323 }
324
325 /**
326 * Get trigger set name from trigger set id.
327 *
328 * @param unknown_type $id
329 * @return the trigger set name
330 */
331 function _nodetriggers_get_configuration_name($id) {
332 $config = db_query("SELECT name FROM {nodetriggers_configs} WHERE id = '%d'", $id);
333 if ($config) {
334 $c = db_fetch_array($config);
335 return $c['name'];
336 }
337
338 return '';
339 }
340
341 /**
342 * Read a trigger set form database.
343 *
344 * @param $config_id the trigger set id we should read.
345 * @return the trigger set
346 */
347 function _nodetriggers_load_configuration($config_id) {
348 $conf = array();
349 $conf['node_types'] = array();
350
351 // load config data
352 $config = db_query("SELECT * FROM {nodetriggers_configs} WHERE id = '%d'", $config_id);
353 // load node types that trigger the actions
354 $nodes = db_query("SELECT * FROM {nodetriggers_nodes} WHERE config_id = '%d'", $config_id);
355 // load events that trigger the actions
356 $events = db_query("SELECT * FROM {nodetriggers_events} WHERE config_id = '%d'", $config_id);
357
358 if ($config) {
359 $conf = db_fetch_array($config);
360 while ($n = db_fetch_array($nodes)) {
361 $conf['node_types'][] = $n['node_type'];
362 }
363
364 while ($e = db_fetch_array($events)) {
365 $conf[$e['event_name']]['active'] = $e['active'];
366 $conf[$e['event_name']]['action_ids'] = array();
367
368 // for each node/event combination, load the actions triggered
369 $actions = db_query("SELECT * FROM {nodetriggers_actions} WHERE event_id = '%d' ORDER BY action_order", $e['event_id']);
370 while ($a = db_fetch_array($actions)) {
371 $conf[$e['event_name']]['action_ids'][] = md5($a['action_id']);
372 }
373 }
374 }
375
376 return $conf;
377 }
378
379 /**
380 * Save a trigger set to the database.
381 *
382 * @param $config_id if we are updating a trigger set, its id; NULL if we are creating a new one
383 * @param $form_values data entered in the tigger set form
384 * @return TRUE on success, FALSE otherwise
385 */
386 function _nodetriggers_save_configuration($config_id = NULL, $form_values) {
387 $result = TRUE;
388 $updating = ($config_id != NULL);
389
390 if ($updating) {
391 /*
392 * Update the configuration description and delete related entries in other tables: we'll rewrite them.
393 */
394 $result &= db_query("UPDATE {nodetriggers_configs} SET name = '%s', description = '%s', priority = %d WHERE id = %d",
395 $form_values['nodetriggers_name'], $form_values['nodetriggers_desc'], $form_values['nodetriggers_weight'], $config_id);
396
397 $events = db_query("SELECT * FROM {nodetriggers_events} WHERE config_id = '%d'", $config_id);
398
399 while ($e = db_fetch_array($events)) {
400 $result &= db_query("DELETE FROM {nodetriggers_actions} WHERE event_id=%d", $e['event_id']);
401 }
402
403 $result &= db_query("DELETE FROM {nodetriggers_events} WHERE config_id=%d", $config_id);
404 $result &= db_query("DELETE FROM {nodetriggers_nodes} WHERE config_id=%d", $config_id);
405 }
406 else {
407 $config_id = db_next_id('{nodetriggers_configs}_id');
408 $result = db_query("INSERT INTO {nodetriggers_configs} (id, name, description, priority) VALUES (%d, '%s', '%s', %d)",
409 $config_id, $form_values['nodetriggers_name'], $form_values['nodetriggers_desc'], $form_values['nodetriggers_weight']);
410 }
411
412 if ($result) {
413 foreach ($form_values['nodetriggers_node_types'] as $key => $node_type) {
414 /* Save node types affected by trigger */
415 if ($node_type) {
416 $result &= db_query("INSERT INTO {nodetriggers_nodes} (config_id, node_type) VALUES (%d, '%s')", $config_id, $node_type);
417 }
418 }
419 }
420
421 if ($result) {
422 /* Save events that trigger actions. */
423 $insert_event_id = db_next_id('{nodetriggers_events}_id');
424 $active = (strcmp($form_values['nodetriggers_create_activate']['nodetriggers_create_activate'], 'nodetriggers_create_activate') == 0);
425 $result &= db_query("INSERT INTO {nodetriggers_events} (event_id, config_id, event_name, active) VALUES (%d, %d, 'insert', %d)",
426 $insert_event_id, $config_id, $active);
427
428 $update_event_id = db_next_id('{nodetriggers_events}_id');
429 $active = (strcmp($form_values['nodetriggers_update_activate']['nodetriggers_update_activate'], 'nodetriggers_update_activate') == 0);
430 $result &= db_query("INSERT INTO {nodetriggers_events} (event_id, config_id, event_name, active) VALUES (%d, %d, 'update', %d)",
431 $update_event_id, $config_id, $active);
432
433 $delete_event_id = db_next_id('{nodetriggers_events}_id');
434 $active = (strcmp($form_values['nodetriggers_delete_activate']['nodetriggers_delete_activate'], 'nodetriggers_delete_activate') == 0);
435 $result &= db_query("INSERT INTO {nodetriggers_events} (event_id, config_id, event_name, active) VALUES (%d, %d, 'delete', %d)",
436 $delete_event_id, $config_id, $active);
437
438 /* Save actions. Eventually there will be more than one action per event. */
439 $action = actions_key_lookup($form_values['nodetriggers_create_action']);
440 $result &= db_query("INSERT INTO {nodetriggers_actions} (event_id, action_id, action_order) VALUES (%d, '%s', 0)", $insert_event_id, $action);
441
442 $action = actions_key_lookup($form_values['nodetriggers_update_action']);
443 $result &= db_query("INSERT INTO {nodetriggers_actions} (event_id, action_id, action_order) VALUES (%d, '%s', 0)", $update_event_id, $action);
444
445 $action = actions_key_lookup($form_values['nodetriggers_delete_action']);
446 $result &= db_query("INSERT INTO {nodetriggers_actions} (event_id, action_id, action_order) VALUES (%d, '%s', 0)", $delete_event_id, $action);
447 }
448
449 if ($result) {
450 watchdog('user', t("Node trigger set @conf saved.", array('@conf' => $config_id)));
451 }
452
453 return $result;
454 }
455
456 /**
457 * Delete a trigger set from the database.
458 *
459 * @param $config_id
460 * @return TRUE on success, FALSE otherwise
461 */
462 function _nodetriggers_delete_configuration($config_id) {
463
464 $result = TRUE;
465
466 $events = db_query("SELECT * FROM {nodetriggers_events} WHERE config_id = '%d'", $config_id);
467
468 while ($e = db_fetch_array($events)) {
469 $result &= db_query("DELETE FROM {nodetriggers_actions} WHERE event_id=%d", $e['event_id']);
470 }
471
472 $result &= db_query("DELETE FROM {nodetriggers_events} WHERE config_id=%d", $config_id);
473 $result &= db_query("DELETE FROM {nodetriggers_nodes} WHERE config_id=%d", $config_id);
474 $result &= db_query("DELETE FROM {nodetriggers_configs} WHERE id=%d", $config_id);
475
476 if ($result) {
477 watchdog('user', t("Trigger set @conf deleted.", array('@conf' => $config_id)));
478 }
479
480 return $result;
481 }
482
483 /**
484 * hook_nodeapi implementation: retrieve the appropriate actions for the $node/$op
485 * combination and trigger them.
486 *
487 */
488 function nodetriggers_nodeapi(&$node, $op, $teaser, $page) {
489 /* Action module must be installed */
490 if (!function_exists('actions_do')) {
491 return;
492 }
493
494 /* Quick exit */
495 if (!in_array($op, array('insert', 'update', 'delete'))) {
496 return;
497 }
498
499 /* Prevent infinite trigerring */
500 static $processing = FALSE;
501 if ($processing) {
502 return;
503 }
504 else {
505 $processing = TRUE;
506 }
507
508 // @FIXME: We surely can optimise queries with some JOIN here.
509 $configs = db_query("SELECT id, priority FROM {nodetriggers_configs} ORDER BY priority");
510
511 while ($c = db_fetch_array($configs)) {
512 $type = node_get_types('name', $node);
513 $node_type = db_query("SELECT * FROM {nodetriggers_nodes} WHERE config_id = %d AND node_type = '%s'", $c['id'], $type);
514
515 if (db_num_rows($node_type) > 0) {
516 $event = db_query("SELECT event_id, active FROM {nodetriggers_events} WHERE event_name = '%s' AND config_id = %d", $op, $c['id']);
517
518 if (db_num_rows($event) > 0) {
519 $e = db_fetch_array($event);
520 if ($e['active']) {
521 $actions = db_query("SELECT action_id, action_order FROM {nodetriggers_actions} WHERE event_id = %d ORDER BY action_order", $e['event_id']);
522
523 while ($a = db_fetch_array($actions)) {
524 actions_do($a['action_id'], $node);
525 }
526 }
527 }
528 }
529 }
530
531 $processing = FALSE;
532 }

  ViewVC Help
Powered by ViewVC 1.1.2