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

Contents of /contributions/modules/actions/actions.module

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


Revision 1.25.2.3 - (hide annotations) (download) (as text)
Thu Oct 18 22:13:19 2007 UTC (2 years, 1 month ago) by jvandyk
Branch: DRUPAL-5
CVS Tags: DRUPAL-5--1-0
Changes since 1.25.2.2: +3 -9 lines
File MIME type: text/x-php
#184032 help hook improperly implemented
1 jvandyk 1.1 <?php
2 jvandyk 1.25.2.3 /* $Id: actions.module,v 1.25.2.2 2007/03/11 21:17:46 jvandyk Exp $ */
3 jvandyk 1.1
4     /**
5     * @file
6     * Enables functions to be stored as scripts to be triggered by other modules.
7     */
8    
9     /**
10     * Implementation of hook_help().
11     */
12     function actions_help($section) {
13     switch ($section) {
14 jvandyk 1.25.2.2 case 'admin/build/actions':
15 jvandyk 1.25.2.3 return t('This page lists all actions that are available. Simple actions that do not require any configuration are listed automatically. Actions that need to be configured are listed in the <em>Add new action</em> menu. To add a configurable action, select the action and click the <em>Add new action</em> button. After completing the configuration form, the action will be available for use by Drupal.');
16 jvandyk 1.25.2.2 case 'admin/build/actions/config':
17 jvandyk 1.25.2.3 return t('This is where you configure a certain action that will be performed at some time in the future. For example, you might configure an action to send email to your friend Royce. Your entry in the description field, below, should be descriptive enough to remind you of that.');
18 jvandyk 1.1 }
19     }
20    
21     /**
22     * Implementation of hook_menu().
23     */
24     function actions_menu($may_cache) {
25     $items = array();
26     $access = user_access('administer actions');
27    
28     if ($may_cache) {
29 jvandyk 1.24 $items[] = array(
30 jvandyk 1.25.2.1 'path' => 'admin/build/actions',
31 jvandyk 1.25 'title' => t('Actions'),
32 jvandyk 1.24 'description' => t('Manage the actions defined for your site.'),
33     'access' => $access,
34     'callback' => 'actions_overview');
35    
36     $items[] = array(
37 jvandyk 1.25.2.1 'path' => 'admin/build/actions/config',
38 jvandyk 1.25 'title' => t('Configure action'),
39 jvandyk 1.24 'access' => $access,
40     'weight' => -9,
41     'callback' => 'drupal_get_form',
42     'callback arguments' => array('actions_configure'),
43     'type' => MENU_CALLBACK);
44    
45     $items[] = array(
46 jvandyk 1.25.2.1 'path' => 'admin/build/actions/delete',
47 jvandyk 1.25 'title' => t('Delete action'),
48 jvandyk 1.24 'access' => $access,
49     'callback' => 'drupal_get_form',
50     'callback arguments' => array('actions_delete_form'),
51     'weight' => -8,
52     'type' => MENU_CALLBACK);
53    
54     $items[] = array(
55 jvandyk 1.25.2.1 'path' => 'admin/build/actions/orphan',
56 jvandyk 1.25 'title' => t('Delete action'),
57 jvandyk 1.24 'access' => $access,
58     'callback' => 'actions_remove_orphans',
59     'weight' => -8,
60     'type' => MENU_CALLBACK);
61     }
62 jvandyk 1.1
63     return $items;
64     }
65    
66     /**
67     * Implementation of hook_perm().
68     */
69     function actions_perm() {
70     return array('administer actions');
71     }
72    
73     /**
74     * Menu callback.
75     * Create the main action module page giving an overview of configured actions.
76     *
77     */
78     function actions_overview() {
79     $output = '';
80     $actions = actions_list();
81     actions_synchronize($actions);
82     $actions_map = actions_actions_map($actions);
83     $options = array();
84     $unconfigurable = array();
85 jvandyk 1.15
86 jvandyk 1.1 foreach ($actions_map as $key => $array) {
87     if ($array['configurable']) {
88 jvandyk 1.15 $options[$key] = $array['description'] . '...';
89 jvandyk 1.1 }
90     else {
91     $unconfigurable[] = $array;
92     }
93     }
94 jvandyk 1.15
95 jvandyk 1.1 if ($actions_map) {
96 jvandyk 1.24 $output .= drupal_get_form('actions_overview_form', $options);
97 jvandyk 1.1 }
98 jvandyk 1.15
99 jvandyk 1.1 $row = array();
100     $instances_present = db_fetch_object(db_query("SELECT aid FROM {actions} WHERE params != ''"));
101 jvandyk 1.16 $header = array(
102     array('data' => t('Action Type'), 'field' => 'type'),
103     array('data' => t('Description'), 'field' => 'description'),
104     array('data' => $instances_present ? t('Operations') : '', 'colspan' => '2')
105     );
106 jvandyk 1.1 $sql = 'SELECT * FROM {actions}';
107     $result = pager_query($sql . tablesort_sql($header), 50);
108     while ($data = db_fetch_object($result)) {
109     $row[] = array(
110 jvandyk 1.15 array('data' => $data->type),
111     array('data' => $data->description),
112 jvandyk 1.25.2.2 array('data' => $data->params ? l(t('configure'), "admin/build/actions/config/$data->aid") : ''),
113     array('data' => $data->params ? l(t('delete'), "admin/build/actions/delete/$data->aid") : '')
114 jvandyk 1.1 );
115     if ($data->params) {
116     $instances_present = TRUE;
117     }
118     }
119 jvandyk 1.15
120 jvandyk 1.1 if ($row) {
121 jvandyk 1.18 $pager = theme('pager', NULL, 50, 0);
122 jvandyk 1.1 if (!empty($pager)) {
123     $row[] = array(array('data' => $pager, 'colspan' => '3'));
124     }
125 jvandyk 1.16 $output .= '<h3>' . t('Actions available to Drupal:') . '</h3>';
126 jvandyk 1.1 $output .= theme('table', $header, $row);
127     }
128 jvandyk 1.15
129     return $output;
130 jvandyk 1.1 }
131    
132 jvandyk 1.24 function actions_overview_form($options = array()) {
133     $form['action'] = array(
134     '#type' => 'select',
135     '#title' => t('Add new action'),
136     '#default_value' => '',
137     '#options' => $options,
138     '#description' => '',
139     );
140     $form['buttons']['submit'] = array(
141     '#type' => 'submit',
142     '#value' => t('Add new action'),
143     );
144     return $form;
145     }
146    
147     function actions_overview_form_submit($form_id, $form_values) {
148     if ($form_values['action'] != '') {
149 jvandyk 1.25.2.2 return 'admin/build/actions/config/' . $form_values['action'];
150 jvandyk 1.24 }
151     }
152    
153 jvandyk 1.1 /**
154     * Menu callback.
155     * Create the form for configuration of a single action.
156     * We provide the "Description" field. The rest of the form
157     * is provided by the action. We then provide the Save button.
158     */
159 jvandyk 1.24 function actions_configure($action = NULL) {
160     if ($action === NULL) {
161 jvandyk 1.25.2.2 drupal_goto('admin/build/actions');
162 jvandyk 1.24 }
163    
164 jvandyk 1.1 $actions_map = actions_actions_map(actions_list());
165 jvandyk 1.24 $edit = array();
166 jvandyk 1.15
167 jvandyk 1.24 if (is_numeric($action)) {
168     // if the form has been filled out, ask the action's function to validate it
169     $dummy = array();
170     $aid = $action;
171     if ($aid) {
172     // load values from database
173     $data = db_fetch_object(db_query("SELECT * FROM {actions} WHERE aid = %d", intval($aid)));
174     $edit['actions_desc'] = $data->description;
175     $edit['actions_type'] = $data->type;
176     $function = $data->func;
177     $action = md5($data->func);
178     $params = unserialize($data->params);
179     if ($params) {
180     foreach ($params as $name => $val) {
181     $edit[$name] = $val;
182     }
183 jvandyk 1.23 }
184 jvandyk 1.1 }
185     }
186 jvandyk 1.14 else {
187 jvandyk 1.24 $function = $actions_map[$action]['function'];
188     $edit['actions_desc'] = $actions_map[$action]['description'];
189 jvandyk 1.15 }
190    
191     $form = array();
192     $form['actions_desc'] = array(
193     '#type' => 'textfield',
194     '#title' => t('Description'),
195     '#default_value' => $edit['actions_desc'],
196     '#size' => '70',
197     '#maxlength' => '255',
198     '#description' => t('A unique description for this configuration of this action'),
199     '#weight' => -10
200     );
201     $form = array_merge($form, $function('form', $edit, $dummy));
202     $form['action'] = array(
203     '#type' => 'hidden',
204 jvandyk 1.24 '#value' => $action,
205 jvandyk 1.15 );
206     if ($aid) {
207     $form['aid'] = array(
208     '#type' => 'hidden',
209     '#value' => $aid,
210     );
211 jvandyk 1.14 }
212 jvandyk 1.15 $form['configured'] = array(
213     '#type' => 'hidden',
214     '#value' => '1',
215     );
216     $form['buttons']['submit'] = array(
217     '#type' => 'submit',
218     '#value' => t('Save'),
219     '#weight' => 13
220     );
221    
222 jvandyk 1.24 return $form;
223 jvandyk 1.15 }
224    
225 jvandyk 1.24 function actions_configure_validate($form_id, $form_values) {
226     $function = actions_key_lookup($form_values['action']);
227 jvandyk 1.15 $dummy = array();
228 jvandyk 1.24 $function('validate', $form_values, $dummy);
229 jvandyk 1.15 }
230    
231 jvandyk 1.24 function actions_configure_submit($form_id, $form_values) {
232     $function = actions_key_lookup($form_values['action']);
233 jvandyk 1.15 $dummy = array();
234 jvandyk 1.24 $params = $function('submit', $form_values, $dummy);
235     $metadata = $function('metadata', $form_values, $dummy);
236     $aid = $form_values['aid'];
237     actions_save($function, $metadata['type'], $params, $form_values['actions_desc'], $aid);
238 jvandyk 1.15 drupal_set_message(t('The action has been successfully saved.'));
239 jvandyk 1.24
240 jvandyk 1.25.2.2 return 'admin/build/actions';
241 jvandyk 1.1 }
242    
243     /**
244     * Menu callback.
245     * Create the form for confirmation of deleting an action.
246     *
247     */
248 jvandyk 1.24 function actions_delete_form($aid) {
249 jvandyk 1.25.2.2 if (!$aid) drupal_goto('admin/build/actions');
250 jvandyk 1.1 $action = actions_load($aid);
251 jvandyk 1.15 $form['aid'] = array(
252     '#type' => 'hidden',
253     '#value' => $aid
254 jvandyk 1.24 );
255 jvandyk 1.15
256 jvandyk 1.24 return confirm_form(
257     $form,
258     t('Really delete action !action?', array('!action' => theme('placeholder', $action->description))),
259 jvandyk 1.25.2.2 'admin/build/actions',
260 jvandyk 1.24 t('This cannot be undone.'),
261     t('Delete'),
262     t('Cancel')
263     );
264 jvandyk 1.15 }
265    
266 jvandyk 1.24 function actions_delete_form_submit($form_id, $form_values) {
267     // note that in the future we need to check for dependencies here
268     $aid = $form_values['aid'];
269     $action = actions_load($aid);
270     actions_delete($aid);
271     $description = check_plain($action->description);
272     watchdog('user', t('Deleted action %aid (%action)', array('%aid' => $aid, '%action' => $description)));
273     drupal_set_message(t('Action !action was deleted', array('!action' => theme('placeholder', $description))));
274 jvandyk 1.25.2.2 return 'admin/build/actions';
275 jvandyk 1.1 }
276    
277     /**
278     * Given the IDs of actions to perform, find out what the functions
279     * for the actions are by querying the database. Then call each function
280     * using the function call $function('do', $params, $a1, $a2, $a3, $a4)
281     * where $function is the name of a function written in compliance with
282     * the action specification. The $params parameter is an array of
283     * stored parameters that have been previously configured through the
284 jvandyk 1.16 * web using actions.module.
285 jvandyk 1.1 *
286     * @param $aids
287     * The ID of the action to perform. Can be a single action ID or an array
288     * of IDs. IDs of instances will be numeric; IDs of singletons will be
289     * function names.
290     * @param $a1
291     * Parameter that will be passed along to the callback.
292     * @param $a2
293     * Parameter that will be passed along to the callback.
294     * @param $a3
295     * Parameter that will be passed along to the callback.
296     * @param $a4
297     * Parameter that will be passed along to the callback.
298     *
299     * @return
300 jvandyk 1.15 * An associative array containing the result of the function that
301 jvandyk 1.1 * performs the action, keyed on action ID.
302     *
303     */
304     function actions_do($aids, $a1 = NULL, $a2 = NULL, $a3 = NULL, $a4 = NULL) {
305 jvandyk 1.17 static $stack;
306     $stack++;
307     if ($stack > 25) {
308     watchdog('actions', t('Stack overflow; aborting.'), WATCHDOG_ERROR);
309     return;
310     }
311 jvandyk 1.1 $actions = array();
312     $available_actions = actions_list();
313     $result = array();
314     if (is_array($aids)) {
315     $where = '';
316     foreach ($aids as $aid) {
317     if (is_numeric($aid)) {
318 jvandyk 1.15 $where .= 'OR aid = ' . $aid . ' ';
319 jvandyk 1.1 }
320     elseif (isset($available_actions[$aid])) {
321     $actions[$aid] = $available_actions[$aid];
322     }
323 jvandyk 1.15 }
324 jvandyk 1.1
325 jvandyk 1.15 if ($where) { // we must go to the database to retrieve instance data
326     // strip off leading 'OR '
327     $where = $where ? '(' . strstr($where, " ") . ')' : '';
328 jvandyk 1.1 $result_db = db_query("SELECT * FROM {actions} WHERE $where");
329     while ($data = db_fetch_object($result_db)) {
330     $aid = $data->aid;
331     $actions[$aid] = $data->params ? unserialize($data->params) : array();
332     $actions[$aid]['function'] = $data->func;
333     $actions[$aid]['type'] = $data->type;
334     $actions[$aid]['batchable'] = $available_actions[$data->func]['batchable'];
335     }
336 jvandyk 1.15 }
337    
338     // batch node functions to avoid unnecessary and costly node_load
339 jvandyk 1.1 // and node_save for each action; only the last one will do node_save
340     $batch = array();
341     foreach ($actions as $func => $metadata) {
342     if ($metadata['batchable']) {
343     $batch[$metadata['type']][] = $func;
344     }
345     }
346 jvandyk 1.15
347 jvandyk 1.1 // fire batched actions
348     // each type has its own batch
349     foreach ($batch as $type) {
350     // remove last batchable action so it will not receive 'defer'
351 jvandyk 1.3 array_pop($type);
352 jvandyk 1.1 foreach ($type as $action) {
353     if (is_numeric($action)) { // it needs parameters
354     $actions[$action]['defer'] = TRUE;
355     $result[$action] = $actions[$action]['function']('do', $actions[$action], $a1, $a2, $a3, $a4);
356     }
357     else { // singleton
358     $result[$action] = $action('do', array('defer' => TRUE), $a1, $a2, $a3, $a4);
359     }
360     // remove action we've already fired
361     unset($actions[$action]);
362     }
363     }
364 jvandyk 1.15
365 jvandyk 1.1 // fire remaining actions in no particular order
366     foreach ($actions as $aid => $params) {
367     if (is_numeric($aid)) { // it needs parameters
368     $function = $params['function'];
369     $result[$aid] = $function('do', $params, $a1, $a2, $a3, $a4);
370     }
371     else {
372     $result[$aid] = $aid('do', array(), $a1, $a2, $a3, $a4);
373 jvandyk 1.15 }
374     }
375     }
376 jvandyk 1.1 else { // optimized for single action
377     if (is_numeric($aids)) {
378     $data = db_fetch_object(db_query("SELECT * FROM {actions} WHERE aid = %d", $aids));
379     $function = $data->func;
380 jvandyk 1.9 $result[$aids] = $function('do', unserialize($data->params), $a1, $a2, $a3, $a4);
381 jvandyk 1.1 }
382 jvandyk 1.9 else { // $aids is an actual function name
383     $result[$aids] = $aids('do', array(), $a1, $a2, $a4, $a4);
384 jvandyk 1.1 }
385     }
386     return $result;
387     }
388    
389     /**
390     * Discover all action functions. These begin with 'action_'.
391 jvandyk 1.15 * An action function must be of the form
392 jvandyk 1.1 * 'action_' . module name . function name($op ...)
393     *
394     * action_example_foo($op, $context, $node) {
395     * switch($op) {
396     * case 'metadata':
397     * return array(
398     * 'type' = t('Node'),
399     * 'description' = t('Translate a node to French'),
400     * 'configurable' = false,
401     * 'batchable' = false)
402     * case 'do':
403     * $node->body = lang_translate($node->body, 'FR');
404     * node_save($node);
405     * }
406     * }
407     *
408     * The description is used in presenting possible actions to the user for
409     * configuration. The type is used to present these actions in a logical
410     * grouping.
411 jvandyk 1.15 *
412 jvandyk 1.1 *
413     * @return
414     * An associative array keyed on function name. The value of each key is
415     * an array containing information about the action, such as type of
416     * action and description of the action.
417 jvandyk 1.15 * E.g. $actions['actions_node_publish'] = ('description' => 'Publish a node' ... )
418 jvandyk 1.1 *
419     */
420     function actions_list() {
421     static $actions;
422 jvandyk 1.10 if (isset($actions)) {
423     return $actions;
424 jvandyk 1.1 }
425 jvandyk 1.15
426 jvandyk 1.11 $actions = array();
427 jvandyk 1.15
428 jvandyk 1.1 $all_func = get_defined_functions();
429 jvandyk 1.10 $functions = array_filter($all_func['user'], '_actions_isaction');
430 jvandyk 1.4 $dummy = array();
431 jvandyk 1.1 foreach ($functions as $function) {
432 jvandyk 1.15 $actions[$function] = $function('metadata', $dummy, $dummy);
433 jvandyk 1.1 }
434     return $actions;
435     }
436    
437     /**
438     * Create an associative array keyed by md5 hashes of function names.
439     * Hashes are used to prevent actual function names from going out into
440     * HTML forms and coming back.
441     *
442     * @param $actions
443     * An associative array with function names as keys and associative
444     * arrays with keys 'description', 'type', etc. as values. Generally
445 jvandyk 1.15 * the output of actions_list() or actions_get_all_actions is given
446 jvandyk 1.1 * as input to this function.
447     *
448     * @return
449 jvandyk 1.15 * An associative array keyed on md5 hash of function name. The value of
450 jvandyk 1.1 * each key is an associative array of function, description, and type
451     * for the action.
452     */
453     function actions_actions_map($actions) {
454     $actions_map = array();
455     foreach ($actions as $func => $array) {
456     $key = md5($func);
457 jvandyk 1.15 $actions_map[$key]['function'] = $func;
458     $actions_map[$key]['description'] = $array['description'];
459     $actions_map[$key]['type'] = $array['type'];
460 jvandyk 1.1 $actions_map[$key]['configurable'] = $array['configurable'];
461     $actions_map[$key]['batchable'] = $array['batchable'];
462 jvandyk 1.15 }
463 jvandyk 1.1 return $actions_map;
464     }
465    
466     /**
467     * Given an md5 hash of a function name, return the function name.
468     * Faster than actions_actions_map() when you only need the function name.
469     *
470     * @param $hash
471     * MD5 hash of a function name
472 jvandyk 1.15 *
473 jvandyk 1.1 * @return
474     * Function name
475     *
476 jvandyk 1.15 */
477 jvandyk 1.1 function actions_key_lookup($hash) {
478     foreach (actions_list() as $func => $array) {
479     if (md5($func) == $hash) {
480     return $func;
481     }
482 jvandyk 1.15 }
483    
484 jvandyk 1.1 // must be an instance; must check database
485     $result = db_query("SELECT aid FROM {actions} WHERE params != ''");
486     while ($data = db_fetch_object($result)) {
487     if (md5($data->aid) == $hash) {
488     return $data->aid;
489     }
490 jvandyk 1.15 }
491 jvandyk 1.1 }
492 jvandyk 1.15
493 jvandyk 1.1 /**
494     * Save an action and its associated user-supplied parameter values to
495     * the database.
496     *
497     * @param $function
498     * The name of the function to be called when this action is performed.
499     * @param $params
500     * An associative array with parameter names as keys and parameter values
501     * as values.
502     * @param $desc
503     * A user-supplied description of this particular action, e.g. 'Send
504     * e-mail to Jim'
505     * @param $aid
506     * The ID of this action. If omitted, a new action is created.
507     *
508     * @return
509     * The ID of the action.
510     */
511     function actions_save($function, $type, $params, $desc, $aid = NULL) {
512     $serialized = serialize($params);
513     if ($aid) {
514 jvandyk 1.7 db_query("UPDATE {actions} SET func = '%s', type = '%s', params = '%s', description = '%s' WHERE aid = %d", $function, $type, $serialized, $desc, $aid);
515 jvandyk 1.12 watchdog('user', t("Action '%action' saved.", array('%action' => check_plain($desc))));
516 jvandyk 1.1 }
517     else {
518 jvandyk 1.22 $aid = db_next_id('{actions}_aid');
519 jvandyk 1.1 db_query("INSERT INTO {actions} (aid, func, type, params, description) VALUES (%d, '%s', '%s', '%s', '%s')", $aid, $function, $type, $serialized, $desc);
520 jvandyk 1.12 watchdog('user', t("Action '%action' created.", array('%action' => check_plain($desc))));
521 jvandyk 1.1 }
522 jvandyk 1.15
523 jvandyk 1.1 return $aid;
524     }
525    
526     /**
527     * Retrieve a single action from the database.
528     *
529     * @param $aid
530     * integer The ID of the action to retrieve.
531     *
532     * @return
533     * The appropriate action row from the database as an object.
534     */
535     function actions_load($aid) {
536     return db_fetch_object(db_query("SELECT * FROM {actions} WHERE aid = %d", $aid));
537     }
538    
539     /**
540     * Delete a single action from the database.
541     *
542     * @param $aid
543     * integer The ID of the action to retrieve.
544     *
545     */
546     function actions_delete($aid) {
547 jvandyk 1.15 db_query("DELETE FROM {actions} WHERE aid = %d", $aid);
548 jvandyk 1.1 }
549    
550     /**
551     * Retrieve all action instances from the database.
552     * Compare with actions_list() which gathers actions from
553     * the PHP function namespace. The two are synchronized
554 jvandyk 1.25.2.2 * by visiting /admin/build/actions, which runs actions_synchronize().
555 jvandyk 1.1 *
556     * @return
557     * Associative array keyed by action ID. Each value is
558     * an associative array with keys 'function', 'description',
559     * and 'type'.
560     */
561     function actions_get_all_actions() {
562     $actions = array();
563     $result = db_query("SELECT * FROM {actions}");
564     while ($data = db_fetch_object($result)) {
565     $actions[$data->aid] = array('function' => $data->func, 'description' => $data->description, 'type' => $data->type);
566 jvandyk 1.15 }
567 jvandyk 1.1 return $actions;
568     }
569    
570     /**
571     * Register an action in the actions registry. This function is called
572     * by modules that are using the actions. The actions registry
573     * keeps track of in which modules actions are used. This allows us
574     * to warn the administrator when an action is about to be deleted by
575     * pointing out the action is still being used by such and such a module.
576     *
577     */
578     function actions_register($aid, $module_name, $id) {
579     if (db_fetch_object(db_query("SELECT aid FROM {actions_registry} WHERE aid = %d AND module = '%s' AND id = %d", $aid, $module_name, $id))) return;
580     db_query("INSERT INTO {actions_registry} (aid, module, id) VALUES (%d, '%s', %d)", $aid, $module_name, $id);
581     }
582    
583     /**
584     * Remove an action from the actions registry. This must be
585     * done by all modules that are using an action before an action
586     * is deleted. For example, if workflow.module is using action 14
587     * in a transition, workflow.module is responsible for calling
588     * actions_unregister when the transition is deleted.
589     *
590     * @return
591     * Associative array keyed by action ID. Each value is
592     * an associative array with keys 'function' and 'description'.
593     */
594     function actions_unregister($aid, $module_name, $id) {
595     db_query("DELETE FROM {actions_registry} WHERE aid = %d AND module = '%s' AND id = %d", $aid, $module_name, $id);
596     }
597    
598     /**
599     * Synchronize actions that are provided by modules with actions
600     * that are stored in the actions table. This is necessary so that
601     * actions that do not require configuration can receive action IDs.
602     * This is not necessarily the best approach, but it is the most
603     * straightforward.
604     *
605     */
606     function actions_synchronize($actions_in_code = array(), $delete_orphans = FALSE) {
607     if (!$actions_in_code) {
608 jvandyk 1.15 $actions_in_code = actions_list();
609 jvandyk 1.1 }
610     $actions_in_db = array();
611     $result = db_query("SELECT * FROM {actions} WHERE params = ''");
612     while ($data = db_fetch_object($result)) {
613     $actions_in_db[$data->func] = array('aid' => $data->aid, 'description' => $data->description);
614 jvandyk 1.15 }
615    
616 jvandyk 1.1 // go through all the actions provided by modules
617     foreach ($actions_in_code as $func => $array) {
618     // ignore configurable actions since their instances get put in when user adds action
619     if (!$array['configurable']) {
620     // if we already have an action ID for this action
621     if (array_key_exists($func, $actions_in_db)) {
622     unset($actions_in_db[$func]);
623     }
624     else {
625     // this is a new singleton that we don't have an aid for; assign one
626     db_query("INSERT INTO {actions} (aid, type, func, params, description) VALUES ('%s', '%s', '%s', '%s', '%s')", $func, $array['type'], $func, '', $array['description']);
627 jvandyk 1.12 drupal_set_message(t("Action '%action' added.", array('%action' => htmlspecialchars($array['description']))));
628 jvandyk 1.15 }
629 jvandyk 1.1 }
630     }
631 jvandyk 1.15
632 jvandyk 1.1 // any actions that we have left in $actions_in_db are orphaned
633     if ($actions_in_db) {
634     $orphaned = '';
635 jvandyk 1.15
636 jvandyk 1.1 foreach ($actions_in_db as $func => $array) {
637     if ($delete_orphans) {
638     db_query("DELETE FROM {actions} WHERE func = '%s'", $func);
639     drupal_set_message(t('Deleted orphaned action') . " '$func'.");
640     }
641     else {
642     $orphaned .= $func . ', ';
643     }
644     }
645 jvandyk 1.15
646 jvandyk 1.1 if (!$delete_orphans) {
647     $orphaned = rtrim(rtrim($orphaned, ' '), ',');
648 jvandyk 1.25.2.2 $link = l(t('Remove orphaned actions'), 'admin/build/actions/orphan');
649 jvandyk 1.15
650 jvandyk 1.12 drupal_set_message(t("%actionphrase in the actions table: ", array('%actionphrase' => format_plural(count($actions_in_db), 'One orphaned action exists', '%count orphaned actions exist'))) . ' (' . $orphaned . '). ' . $link, 'warning');
651 jvandyk 1.1 }
652     }
653     }
654    
655     function actions_remove_orphans() {
656     actions_synchronize(actions_list(), TRUE);
657 jvandyk 1.25.2.2 drupal_goto('admin/build/actions');
658 jvandyk 1.1 }
659    
660 jvandyk 1.10 /**
661     * Callback function for array_filter in actions_list()
662     */
663     function _actions_isaction($s) {
664     return substr($s, 0, 7) == 'action_';
665     }
666    
667 jvandyk 1.25 include_once(drupal_get_path('module', 'actions') . '/actions.inc');

  ViewVC Help
Powered by ViewVC 1.1.2