You are here

public function MongodbNodeGrantStorage::access in MongoDB 8

Determines access to nodes based on node grants.

Parameters

\Drupal\node\NodeInterface $node: The entity for which to check 'create' access.

string $operation: The entity operation. Usually one of 'view', 'edit', 'create' or 'delete'.

\Drupal\Core\Session\AccountInterface $account: The user for which to check access.

Return value

\Drupal\Core\Access\AccessResultInterface The access result, either allowed or neutral. If there are no node grants, the default grant defined by writeDefault() is applied.

Overrides NodeGrantDatabaseStorageInterface::access

See also

hook_node_grants()

hook_node_access_records()

\Drupal\node\NodeGrantDatabaseStorageInterface::writeDefault()

File

mongodb_node/src/MongodbNodeGrantStorage.php, line 61
Contains \Drupal\node\NodeGrantDatabaseStorage.

Class

MongodbNodeGrantStorage
Defines a controller class that handles the node grants system.

Namespace

Drupal\mongodb_node

Code

public function access(NodeInterface $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 (!$this->moduleHandler
    ->getImplementations('node_grants') || !$node
    ->id()) {

    // No opinion.
    return AccessResult::neutral();
  }
  $query['nid'] = (int) $node
    ->id();
  $query['grant'][$operation]['$exists'] = TRUE;
  $node_access_grants = node_access_grants($operation, $account);
  $fallbacks = [
    $langcode == $node
      ->language()
      ->getId(),
  ];
  if ($grant_conditions = $this
    ->buildGrantsQueryCondition($node_access_grants, $langcode, $fallbacks)) {
    $query['grant'][$operation]['$in'] = $grant_conditions;
  }
  if ($node
    ->isPublished()) {
    $new_query['$or'] = [
      [
        '_id' => 0,
      ],
      $query,
    ];
    $query = $new_query;
  }

  // Only the 'view' node grant can currently be cached; the others currently
  // don't have any cacheability metadata. Hopefully, we can add that in the
  // future, which would allow this access check result to be cacheable in all
  // cases. For now, this must remain marked as uncacheable, even when it is
  // theoretically cacheable, because we don't have the necessary metadata to
  // know it for a fact.
  $set_cacheability = function (AccessResult $access_result) use ($operation) {
    $access_result
      ->addCacheContexts([
      'user.node_grants:' . $operation,
    ]);
    if ($operation !== 'view') {
      $access_result
        ->setCacheMaxAge(0);
    }
    return $access_result;
  };
  if ($this->mongo
    ->get('entity.node')
    ->findOne($query)) {
    return $set_cacheability(AccessResult::allowed());
  }
  else {
    return $set_cacheability(AccessResult::forbidden());
  }
}