function actions_do

You are here

7 actions.inc actions_do($action_ids, $object = NULL, $context = NULL, $a1 = NULL, $a2 = NULL)
6 actions.inc actions_do($action_ids, &$object, $context = NULL, $a1 = NULL, $a2 = NULL)

Perform a given list of actions by executing their callback functions.

Given the IDs of actions to perform, find out what the callbacks for the actions are by querying the database. Then call each callback using the function call $function($object, $context, $a1, $a2) where $function is the name of a function written in compliance with the action specification; that is, foo($object, $context).

Parameters

$action_ids: The ID of the action to perform. Can be a single action ID or an array of IDs. IDs of instances will be numeric; IDs of singletons will be function names.

$object: Parameter that will be passed along to the callback. Typically the object that the action will act on; a node, user or comment object. If the action does not act on an object, pass a dummy object. This is necessary to support PHP 4 object referencing.

$context: Parameter that will be passed along to the callback. $context is a keyed array containing extra information about what is currently happening at the time of the call. Typically $context['hook'] and $context['op'] will tell which hook-op combination resulted in this call to actions_do().

$a1: Parameter that will be passed along to the callback.

$a2: Parameter that will be passed along to the callback.

Return value

An associative array containing the result of the function that performs the action, keyed on action ID.

5 calls to actions_do()
trigger_comment in modules/trigger/trigger.module
Implementation of hook_comment().
trigger_cron in modules/trigger/trigger.module
Implementation of hook_cron().
trigger_nodeapi in modules/trigger/trigger.module
Implementation of hook_nodeapi().
trigger_taxonomy in modules/trigger/trigger.module
Implementation of hook_taxonomy().
trigger_user in modules/trigger/trigger.module
Implementation of hook_user().

File

includes/actions.inc, line 60
This is the actions engine for executing stored actions.

Code

function actions_do($action_ids, &$object, $context = NULL, $a1 = NULL, $a2 = NULL) {
  // $stack tracks the number of recursive calls.
  static $stack;
  $stack++;
  if ($stack > variable_get('actions_max_stack', 35)) {
    watchdog('actions', 'Stack overflow: too many calls to actions_do(). Aborting to prevent infinite recursion.', array(), WATCHDOG_ERROR);
    return;
  }
  $actions = array();
  $available_actions = actions_list();
  $result = array();
  if (is_array($action_ids)) {
    $where = array();
    $where_values = array();
    foreach ($action_ids as $action_id) {
      if (is_numeric($action_id)) {
        $where[] = "OR aid = '%s'";
        $where_values[] = $action_id;
      }
      elseif (isset($available_actions[$action_id])) {
        $actions[$action_id] = $available_actions[$action_id];
      }
    }

    // When we have action instances we must go to the database to
    // retrieve instance data.
    if ($where) {
      $where_clause = implode(' ', $where);
      // Strip off leading 'OR '.
      $where_clause = '(' . strstr($where_clause, " ") . ')';
      $result_db = db_query('SELECT * FROM {actions} WHERE ' . $where_clause, $where_values);
      while ($action = db_fetch_object($result_db)) {
        $actions[$action->aid] = $action->parameters ? unserialize($action->parameters) : array();
        $actions[$action->aid]['callback'] = $action->callback;
        $actions[$action->aid]['type'] = $action->type;
      }
    }

    // Fire actions, in no particular order.
    foreach ($actions as $action_id => $params) {
      if (is_numeric($action_id)) { // Configurable actions need parameters.
        $function = $params['callback'];
        if (function_exists($function)) {
          $context = array_merge($context, $params);
          $actions_result[$action_id] = $function($object, $context, $a1, $a2);
        }
        else {
          $actions_result[$action_id] = FALSE;
        }
      }
      // Singleton action; $action_id is the function name.
      else {
        $result[$action_id] = $action_id($object, $context, $a1, $a2);
      }
    }
  }
  // Optimized execution of single action.
  else {
    // If it's a configurable action, retrieve stored parameters.
    if (is_numeric($action_ids)) {
      $action = db_fetch_object(db_query("SELECT * FROM {actions} WHERE aid = '%s'", $action_ids));
      $function = $action->callback;
      if (function_exists($function)) {
        $context = array_merge($context, unserialize($action->parameters));
        $actions_result[$action_ids] = $function($object, $context, $a1, $a2);
      }
      else {
        $actions_result[$action_ids] = FALSE;
      }
    }
    // Singleton action; $action_ids is the function name.
    else {
      $result[$action_ids] = $action_ids($object, $context, $a1, $a2);
    }
  }
  $stack--;
  return $result;
}

Comments

You might want to consider calling the function _trigger_get_hook_aids($hook, $op) to get the information for the $action_ids array.

Example:

<?php
$aids
= _trigger_get_hook_aids('cron', 'run');
actions_do(array_keys($aids), $object, $context);
?>

See the trigger.module source for more examples.

If you are using context variables on a custom node action, like %title or %node_url, you should include the $node variable on the $context argument array, and not only as the $object variable on actions_do.

Otherwise, context variables will not be properly retrieved by your custom action.

if you create a custom action like 'Send email...' that includes context variables on the body message and needs to be executed when some event occurs, you will use a snippet of code like this:

$context = array(
  'hook' => 'nodeapi',
  'op' => 'insert',
  'node' => $node     /* The $node variable is passed in the $context array ( actions_do, 3rd parameter ) */
);

actions_do($your_action_id, $node, $context);  /* The $node variable is also passed as the $object parameter on actions_do */

I hope this information is useful.

Please include dani_strab's information about the node value in the $context variable, its very important.