You are here

function workflow_execute_transition in Workflow 6

Same name and namespace in other branches
  1. 8 workflow.module \workflow_execute_transition()
  2. 5.2 workflow.module \workflow_execute_transition()
  3. 5 workflow.module \workflow_execute_transition()
  4. 6.2 workflow.module \workflow_execute_transition()
  5. 7.2 workflow.module \workflow_execute_transition()
  6. 7 workflow.module \workflow_execute_transition()

Execute a transition (change state of a node).

Parameters

$node:

$sid: Target state ID.

$comment: A comment for the node's workflow history.

$force: If set to TRUE, workflow permissions will be ignored.

Return value

int ID of new state.

4 calls to workflow_execute_transition()
workflow_cron in ./workflow.module
Implementation of hook_cron().
workflow_select_given_state_action in workflow_actions/workflow_actions.module
Implementation of a Drupal action. Move a node to a specified state.
workflow_select_next_state_action in workflow_actions/workflow_actions.module
Implementation of a Drupal action. Move a node to the next state in the workfow.
workflow_transition in ./workflow.module
Validate target state and either execute a transition immediately or schedule a transition to be executed later by cron.

File

./workflow.module, line 395
Support workflows made up of arbitrary states.

Code

function workflow_execute_transition($node, $sid, $comment = NULL, $force = FALSE) {
  global $user;
  $old_sid = workflow_node_current_state($node);
  if ($old_sid == $sid) {

    // Stop if not going to a different state.
    // Write comment into history though.
    if ($comment && !$node->_workflow_scheduled_comment) {
      $node->workflow_stamp = time();
      db_query("UPDATE {workflow_node} SET stamp = %d WHERE nid = %d", $node->workflow_stamp, $node->nid);
      $result = module_invoke_all('workflow', 'transition pre', $old_sid, $sid, $node);
      _workflow_write_history($node, $sid, $comment);
      unset($node->workflow_comment);
      $result = module_invoke_all('workflow', 'transition post', $old_sid, $sid, $node);

      // Rules integration
      if (module_exists('rules')) {
        rules_invoke_event('workflow_comment_added', $node, $old_sid, $sid);
      }
    }
    return;
  }
  $tid = workflow_get_transition_id($old_sid, $sid);
  if (!$tid && !$force) {
    watchdog('workflow', 'Attempt to go to nonexistent transition (from %old to %new)', array(
      '%old' => $old_sid,
      '%new' => $sid,
      WATCHDOG_ERROR,
    ));
    return;
  }

  // Make sure this transition is valid and allowed for the current user.
  // Check allowability of state change if user is not superuser (might be cron).
  if ($user->uid != 1 && !$force) {
    if (!workflow_transition_allowed($tid, array_merge(array_keys($user->roles), array(
      'author',
    )))) {
      watchdog('workflow', 'User %user not allowed to go from state %old to %new', array(
        '%user' => $user->name,
        '%old' => $old_sid,
        '%new' => $sid,
        WATCHDOG_NOTICE,
      ));
      return;
    }
  }

  // Invoke a callback indicating a transition is about to occur. Modules
  // may veto the transition by returning FALSE.
  $result = module_invoke_all('workflow', 'transition pre', $old_sid, $sid, $node);

  // Stop if a module says so.
  if (in_array(FALSE, $result)) {
    watchdog('workflow', 'Transition vetoed by module.');
    return;
  }

  // If the node does not have an existing $node->_workflow property, save
  // the $old_sid there so _workflow_write_history() can log it.
  if (!isset($node->_workflow)) {
    $node->_workflow = $old_sid;
  }

  // Change the state.
  _workflow_node_to_state($node, $sid, $comment);
  $node->_workflow = $sid;

  // Register state change with watchdog.
  $state_name = workflow_get_state_name($sid);
  $type = node_get_types('name', $node->type);
  watchdog('workflow', 'State of @type %node_title set to %state_name', array(
    '@type' => $type,
    '%node_title' => $node->title,
    '%state_name' => $state_name,
  ), WATCHDOG_NOTICE, l('view', 'node/' . $node->nid));

  // Notify modules that transition has occurred. Actions should take place
  // in response to this callback, not the previous one.
  module_invoke_all('workflow', 'transition post', $old_sid, $sid, $node);

  // Clear any references in the scheduled listing.
  db_query('DELETE FROM {workflow_scheduled_transition} WHERE nid = %d', $node->nid);

  // Rules integration
  if (module_exists('rules')) {
    rules_invoke_event('workflow_state_changed', $node, $old_sid, $sid);
  }
  return $sid;
}