function _node_revision_access

Access callback: Checks node revision access.

Parameters

\Drupal\Core\Entity\EntityInterface $node: The node to check.

$op: (optional) The specific operation being checked. Defaults to 'view.'

object $account: (optional) A user object representing the user for whom the operation is to be performed. Determines access for a user other than the current user. Defaults to NULL.

$langcode: (optional) Language code for the variant of the node. Different language variants might have different permissions associated. If NULL, the original langcode of the node is used. Defaults to NULL.

Return value

TRUE if the operation may be performed, FALSE otherwise.

See also

node_menu()

2 calls to _node_revision_access()
NodeRevisionPermissionsTest::testNodeRevisionAccessAnyType in drupal/core/modules/node/lib/Drupal/node/Tests/NodeRevisionPermissionsTest.php
Tests general revision access permissions.
NodeRevisionPermissionsTest::testNodeRevisionAccessPerType in drupal/core/modules/node/lib/Drupal/node/Tests/NodeRevisionPermissionsTest.php
Tests revision access permissions for a specific content type.
1 string reference to '_node_revision_access'
node_menu in drupal/core/modules/node/node.module
Implements hook_menu().

File

drupal/core/modules/node/node.module, line 1507
The core module that allows content to be submitted to the site.

Code

function _node_revision_access(EntityInterface $node, $op = 'view', $account = NULL, $langcode = NULL) {
  $access =& drupal_static(__FUNCTION__, array());
  $map = array(
    'view' => 'view all revisions',
    'update' => 'revert all revisions',
    'delete' => 'delete all revisions',
  );
  $type_map = array(
    'view' => "view {$node->type} revisions",
    'update' => "revert {$node->type} revisions",
    'delete' => "delete {$node->type} revisions",
  );
  if (!$node || !isset($map[$op]) || !isset($type_map[$op])) {

    // If there was no node to check against, or the $op was not one of the
    // supported ones, we return access denied.
    return FALSE;
  }
  if (!isset($account)) {
    $account = $GLOBALS['user'];
  }

  // If no language code was provided, default to the node revision's langcode.
  if (empty($langcode)) {
    $langcode = $node->langcode;
  }

  // Statically cache access by revision ID, language code, user account ID,
  // and operation.
  $cid = $node->vid . ':' . $langcode . ':' . $account->uid . ':' . $op;
  if (!isset($access[$cid])) {

    // Perform basic permission checks first.
    if (!user_access($map[$op], $account) && !user_access($type_map[$op], $account) && !user_access('administer nodes', $account)) {
      return $access[$cid] = FALSE;
    }

    // There should be at least two revisions. If the vid of the given node
    // and the vid of the default revision differ, then we already have two
    // different revisions so there is no need for a separate database check.
    // Also, if you try to revert to or delete the default revision, that's
    // not good.
    if ($node
      ->isDefaultRevision() && (db_query('SELECT COUNT(*) FROM {node_field_revision} WHERE nid = :nid AND default_langcode = 1', array(
      ':nid' => $node->nid,
    ))
      ->fetchField() == 1 || $op == 'update' || $op == 'delete')) {
      $access[$cid] = FALSE;
    }
    elseif (user_access('administer nodes', $account)) {
      $access[$cid] = TRUE;
    }
    else {

      // First check the access to the default revision and finally, if the
      // node passed in is not the default revision then access to that, too.
      $access[$cid] = node_access($op, node_load($node->nid), $account, $langcode) && ($node
        ->isDefaultRevision() || node_access($op, $node, $account, $langcode));
    }
  }
  return $access[$cid];
}