function node_access

Access callback: Checks a user's permission for performing a node operation.

@todo Add langcode support to node_access schema / queries. http://drupal.org/node/1658846

Parameters

$op: The operation to be performed on the node. Possible values are:

  • "view"
  • "update"
  • "delete"
  • "create"

Drupal\node\Node|string|stdClass $node: The node entity on which the operation is to be performed, or the node type object, or node type string (e.g., 'forum') for the 'create' operation.

$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()

Related topics

27 calls to node_access()
book_block_view in drupal/core/modules/book/book.module
Implements hook_block_view().
book_node_view_link in drupal/core/modules/book/book.module
Adds relevant book links to the node's links.
comment_file_download_access in drupal/core/modules/comment/comment.module
Implements hook_file_download_access().
forum_menu_local_tasks_alter in drupal/core/modules/forum/forum.module
Implements hook_menu_local_tasks_alter().
hook_file_download_access in drupal/core/modules/file/file.api.php
Control download access to files.

... See full list

25 string references to 'node_access'
book_block_view in drupal/core/modules/book/book.module
Implements hook_block_view().
book_get_books in drupal/core/modules/book/book.module
Returns an array of all books.
comment_admin_overview in drupal/core/modules/comment/comment.admin.inc
Form constructor for the comment overview administration form.
comment_get_recent in drupal/core/modules/comment/comment.module
Finds the most recent comments that are available to the current user.
comment_menu in drupal/core/modules/comment/comment.module
Implements hook_menu().

... See full list

File

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

Code

function node_access($op, $node, $account = NULL, $langcode = NULL) {
  $rights =& drupal_static(__FUNCTION__, array());
  if (!$node || !in_array($op, array(
    'view',
    'update',
    'delete',
    'create',
  ), TRUE)) {

    // 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 no user object is supplied, the access check is for the current user.
  if (empty($account)) {
    $account = $GLOBALS['user'];
  }

  // $node may be a node object, a node type object, or a node type string.
  // Use the node ID as the primary cache ID, or the node type name otherwise.
  $cid = is_object($node) ? isset($node->nid) ? $node->nid : $node->type : $node;

  // If no language code was provided, default to the node's langcode or
  // to an empty langcode if a node type was requested. The latter is purely
  // for caching purposes.
  if (empty($langcode)) {
    $langcode = is_object($node) && isset($node->nid) ? $node->langcode : '';
  }

  // If we've already checked access for this node, user and op, return from
  // cache.
  if (isset($rights[$account->uid][$cid][$langcode][$op])) {
    return $rights[$account->uid][$cid][$langcode][$op];
  }
  if (user_access('bypass node access', $account)) {
    $rights[$account->uid][$cid][$langcode][$op] = TRUE;
    return TRUE;
  }
  if (!user_access('access content', $account)) {
    $rights[$account->uid][$cid][$langcode][$op] = FALSE;
    return FALSE;
  }

  // We grant access to the node if both of the following conditions are met:
  // - No modules say to deny access.
  // - At least one module says to grant access.
  // If no module specified either allow or deny, we fall back to the
  // node_access table.
  $access = module_invoke_all('node_access', $node, $op, $account, $langcode);
  if (in_array(NODE_ACCESS_DENY, $access, TRUE)) {
    $rights[$account->uid][$cid][$langcode][$op] = FALSE;
    return FALSE;
  }
  elseif (in_array(NODE_ACCESS_ALLOW, $access, TRUE)) {
    $rights[$account->uid][$cid][$langcode][$op] = TRUE;
    return TRUE;
  }

  // Check if authors can view their own unpublished nodes.
  if ($op == 'view' && !$node
    ->get('status', $langcode) && user_access('view own unpublished content', $account) && $account->uid == $node
    ->get('uid', $langcode) && $account->uid != 0) {
    $rights[$account->uid][$cid][$langcode][$op] = TRUE;
    return TRUE;
  }

  // If the module did not override the access rights, use those set in the
  // node_access table.
  if ($op != 'create' && $node->nid) {
    if (module_implements('node_grants')) {
      $query = db_select('node_access');
      $query
        ->addExpression('1');
      $query
        ->condition('grant_' . $op, 1, '>=');
      $nids = db_or()
        ->condition('nid', $node->nid);
      if ($node->status) {
        $nids
          ->condition('nid', 0);
      }
      $query
        ->condition($nids);
      $query
        ->range(0, 1);
      $grants = db_or();
      foreach (node_access_grants($op, $account) as $realm => $gids) {
        foreach ($gids as $gid) {
          $grants
            ->condition(db_and()
            ->condition('gid', $gid)
            ->condition('realm', $realm));
        }
      }
      if (count($grants) > 0) {
        $query
          ->condition($grants);
      }
      $result = (bool) $query
        ->execute()
        ->fetchField();
      $rights[$account->uid][$cid][$langcode][$op] = $result;
      return $result;
    }
    elseif (is_object($node) && $op == 'view' && $node
      ->get('status', $langcode)) {

      // If no modules implement hook_node_grants(), the default behavior is to
      // allow all users to view published nodes, so reflect that here.
      $rights[$account->uid][$cid][$langcode][$op] = TRUE;
      return TRUE;
    }
  }
  return FALSE;
}