class NodeAccessController

Defines the access controller for the node entity type.

Hierarchy

Expanded class hierarchy of NodeAccessController

File

drupal/core/modules/node/lib/Drupal/node/NodeAccessController.php, line 19
Contains \Drupal\node\NodeAccessController.

Namespace

Drupal\node
View source
class NodeAccessController extends EntityAccessController {

  /**
   * {@inheritdoc}
   */
  public function access(EntityInterface $entity, $operation, $langcode = Language::LANGCODE_DEFAULT, AccountInterface $account = NULL) {
    if (user_access('bypass node access', $account)) {
      return TRUE;
    }
    if (!user_access('access content', $account)) {
      return FALSE;
    }
    return parent::access($entity, $operation, $langcode, $account);
  }

  /**
   * {@inheritdoc}
   */
  protected function checkAccess(EntityInterface $node, $operation, $langcode, AccountInterface $account) {

    // Fetch information from the node object if possible.
    $status = isset($node->status) ? $node->status : NULL;
    $uid = isset($node->uid) ? $node->uid : NULL;

    // If it is a proper EntityNG object, use the proper methods.
    if ($node instanceof EntityNG) {
      $status = $node
        ->getTranslation($langcode, FALSE)->status->value;
      $uid = $node
        ->getTranslation($langcode, FALSE)->uid->value;
    }

    // Check if authors can view their own unpublished nodes.
    if ($operation === 'view' && !$status && user_access('view own unpublished content', $account)) {
      if ($account
        ->id() != 0 && $account
        ->id() == $uid) {
        return TRUE;
      }
    }

    // If no module specified either allow or deny, we fall back to the
    // node_access table.
    if (($grants = $this
      ->accessGrants($node, $operation, $langcode, $account)) !== NULL) {
      return $grants;
    }

    // If no modules implement hook_node_grants(), the default behavior is to
    // allow all users to view published nodes, so reflect that here.
    if ($operation === 'view') {
      return $status;
    }
  }

  /**
   * Determines access to nodes based on node grants.
   *
   * @param \Drupal\Core\Entity\EntityInterface $node
   *   The entity for which to check 'create' access.
   * @param string $operation
   *   The entity operation. Usually one of 'view', 'edit', 'create' or
   *   'delete'.
   * @param string $langcode
   *   The language code for which to check access.
   * @param \Drupal\Core\Session\AccountInterface $account
   *   The user for which to check access.
   *
   * @return bool|null
   *   TRUE if access was granted, FALSE if access was denied or NULL if no
   *   module implements hook_node_grants(), the node does not (yet) have an id
   *   or none of the implementing modules explicitly granted or denied access.
   */
  protected function accessGrants(EntityInterface $node, $operation, $langcode, AccountInterface $account) {

    // If no module implements the hook or the node does not have an id there is
    // no point in querying the database for access grants.
    if (!module_implements('node_grants') || !$node
      ->id()) {
      return;
    }

    // Check the database for potential access grants.
    $query = db_select('node_access');
    $query
      ->addExpression('1');

    // Only interested for granting in the current operation.
    $query
      ->condition('grant_' . $operation, 1, '>=');

    // Check for grants for this node and the correct langcode.
    $nids = db_and()
      ->condition('nid', $node
      ->id())
      ->condition('langcode', $langcode);

    // If the node is published, also take the default grant into account. The
    // default is saved with a node ID of 0.
    $status = $node instanceof EntityNG ? $node->status : $node
      ->get('status', $langcode)->value;
    if ($status) {
      $nids = db_or()
        ->condition($nids)
        ->condition('nid', 0);
    }
    $query
      ->condition($nids);
    $query
      ->range(0, 1);
    $grants = db_or();
    foreach (node_access_grants($operation, $account instanceof User ? $account
      ->getBCEntity() : $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);
    }
    return $query
      ->execute()
      ->fetchField();
  }

}

Members

Namesort descending Modifiers Type Description Overrides
EntityAccessController::$accessCache protected property Stores calculcated access check results.
EntityAccessController::getCache protected function Tries to retrieve a previously cached access value from the static cache.
EntityAccessController::resetCache public function Clears all cached access checks. Overrides EntityAccessControllerInterface::resetCache
EntityAccessController::setCache protected function Statically caches whether the given user has access.
NodeAccessController::access public function Checks access to an operation on a given entity or entity translation. Overrides EntityAccessController::access
NodeAccessController::accessGrants protected function Determines access to nodes based on node grants.
NodeAccessController::checkAccess protected function Performs access checks. Overrides EntityAccessController::checkAccess