actions_do

Definition

actions_do($action_ids, $object = NULL, $context = NULL, $a1 = NULL, $a2 = NULL)
drupal/includes/actions.inc, line 39

Description

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.

$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.

Code

function actions_do($action_ids, $object = NULL, $context = NULL, $a1 = NULL, $a2 = NULL) {
  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 = %d';
        $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'];
        $context = array_merge($context, $params);
        $result[$action_id] = $function($object, $context, $a1, $a2);
      }
      // 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 = %d", $action_ids));
      $function = $action->callback;
      $context = array_merge($context, unserialize($action->parameters));
      $result[$action_ids] = $function($object, $context, $a1, $a2);
    }
    // Singleton action; $action_ids is the function name.
    else {
      $result[$action_ids] = $action_ids($object, $context, $a1, $a2);
    }
  }
  return $result;
}