You are here

function state_flow_promote_node_revision in State Machine 7.2

Same name and namespace in other branches
  1. 7 modules/state_flow/state_flow.module \state_flow_promote_node_revision()

Promote a node revision to be the most current by loading and re-saving it. If the given node revision is not the most recent, then re-save it as a new revision. Also update related metadata from the node, node_revision, node_revision_states, and node_revision_states_history tables. Finally, delete the original revision if a new revision is created.

2 calls to state_flow_promote_node_revision()
StateFlow::set_node_revision in modules/state_flow/plugins/state_flow.inc
state_flow_prevent_live_revision in modules/state_flow/state_flow.module
Checks whether the version of the node being saved is in the published state, and if not, re-saves the latest published revision.

File

modules/state_flow/state_flow.module, line 472
An implementation of node revision workflow for Drupal based on the State Machine system.

Code

function state_flow_promote_node_revision($rev_state_rec, $nid, $current_vid) {

  // Load data about the current revision
  $current_rev = node_load($nid, $current_vid);
  $current_timestamp = !empty($current_rev->revision_timestamp) ? $current_rev->revision_timestamp : REQUEST_TIME;

  // From workbench_moderation:
  // Path module is stupid and doesn't load its data in node_load.
  if (module_exists('path') && isset($current_rev->nid)) {
    $path = array();
    $conditions = array(
      'source' => 'node/' . $current_rev->nid,
      'language' => isset($current_rev->language) ? $current_rev->language : LANGUAGE_NONE,
    );
    $path = path_load($conditions);
    if ($path === FALSE) {
      $path = array();
    }
    if (module_exists('pathauto')) {
      if (isset($current_rev->path) && isset($path['pathauto'])) {
        $path['pathauto'] += $current_rev->path['pathauto'];
      }
    }
    if (isset($current_rev->path)) {
      $path += $current_rev->path;
    }
    if (!empty($path)) {
      $current_rev->path = $path;
    }
  }

  // Determine the latest revision of this node
  $latest_vid = db_query('
    SELECT nr.vid
    FROM {node_revision} nr
    WHERE nr.nid = :nid
    ORDER BY nr.vid DESC
    LIMIT 0, 1', array(
    ':nid' => $nid,
  ))
    ->fetchField();

  // Re-save the node. Create a new revision if the given revision is not the
  // most recent.
  $current_rev->revision = $latest_vid > $current_vid ? TRUE : FALSE;
  $current_rev->stateflow_ignore_state = TRUE;
  node_save($current_rev);

  // node_save() has updated the $current_rev object, so it is the new revision.
  $new_rev = $current_rev;

  // Set the node.changed and the node_revision.timestamp value to the
  // timestamp of the published revision
  db_update('node')
    ->fields(array(
    'changed' => $current_timestamp,
  ))
    ->condition('vid', $new_rev->vid)
    ->execute();
  db_update('node_revision')
    ->fields(array(
    'timestamp' => $current_timestamp,
  ))
    ->condition('vid', $new_rev->vid)
    ->execute();

  // If a new revision was created, update state_flow records for the revision.
  if ($new_rev->revision) {

    // Update the node_revision_states record for the new published revision
    // to match the old revision
    db_update('node_revision_states')
      ->fields(array(
      'state' => $rev_state_rec->state,
      'status' => $rev_state_rec->status,
      'timestamp' => $rev_state_rec->timestamp,
    ))
      ->condition('vid', $new_rev->vid)
      ->execute();

    // Delete any node_revision_states_history records associated with the new
    // revision (created during hook_node_insert) which will refer to the new
    // version as a draft
    db_delete('node_revision_states_history')
      ->condition('vid', $new_rev->vid)
      ->execute();

    // Change all node_revision_states_history records for the old revision
    // to be associated with the new revision
    db_update('node_revision_states_history')
      ->fields(array(
      'vid' => $new_rev->vid,
    ))
      ->condition('vid', $current_vid)
      ->execute();

    // Notify other modules about the vid change
    module_invoke_all('state_flow_change_vid', $current_vid, $new_rev);

    // Delete the old published revision (that has been cloned)
    node_revision_delete($current_vid);
  }
}