function _node_revision_access

Access callback: Checks node revision access.

Parameters

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

Return value

TRUE if the operation may be performed, FALSE otherwise.

See also

node_menu()

1 call to _node_revision_access()
NodeRevisionPermissionsTestCase::testNodeRevisionAccess in modules/node/node.test
Tests the _node_revision_access() function.
1 string reference to '_node_revision_access'
node_menu in modules/node/node.module
Implements hook_menu().

File

modules/node/node.module, line 1897

Code

function _node_revision_access($node, $op = 'view', $account = NULL) {
    $access =& drupal_static(__FUNCTION__, array());
    $map = array(
        'view' => 'view revisions',
        'update' => 'revert revisions',
        'delete' => 'delete revisions',
    );
    if (!$node || !isset($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'];
    }
    // Statically cache access by revision ID, user account ID, and operation.
    $cid = $node->vid . ':' . $account->uid . ':' . $op;
    if (!isset($access[$cid])) {
        // Perform basic permission checks first.
        if (!user_access($map[$op], $account) && !user_access('administer nodes', $account)) {
            return $access[$cid] = FALSE;
        }
        $node_current_revision = node_load($node->nid);
        $is_current_revision = $node_current_revision->vid == $node->vid;
        // There should be at least two revisions. If the vid of the given node and
        // the vid of the current 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 current revision, that's not
        // good.
        if ($is_current_revision && (db_query('SELECT COUNT(vid) FROM {node_revision} WHERE nid = :nid', 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 current revision and finally, if the node
            // passed in is not the current revision then access to that, too.
            $access[$cid] = node_access($op, $node_current_revision, $account) && ($is_current_revision || node_access($op, $node, $account));
        }
    }
    return $access[$cid];
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.