function NodeGrantDatabaseStorage::access
Same name in other branches
- 9 core/modules/node/src/NodeGrantDatabaseStorage.php \Drupal\node\NodeGrantDatabaseStorage::access()
- 8.9.x core/modules/node/src/NodeGrantDatabaseStorage.php \Drupal\node\NodeGrantDatabaseStorage::access()
- 11.x core/modules/node/src/NodeGrantDatabaseStorage.php \Drupal\node\NodeGrantDatabaseStorage::access()
File
-
core/
modules/ node/ src/ NodeGrantDatabaseStorage.php, line 61
Class
- NodeGrantDatabaseStorage
- Defines a storage handler class that handles the node grants system.
Namespace
Drupal\nodeCode
public function access(NodeInterface $node, $operation, AccountInterface $account) {
// Grants only support these operations.
if (!in_array($operation, [
'view',
'update',
'delete',
])) {
return AccessResult::neutral();
}
// 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
->hasImplementations('node_grants') || !$node->id()) {
// Return the equivalent of the default grant, defined by
// self::writeDefault().
if ($operation === 'view') {
return AccessResult::allowedIf($node->isPublished());
}
else {
return AccessResult::neutral();
}
}
// Check the database for potential access grants.
$query = $this->database
->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. New translations
// do not yet have a langcode and must check the fallback node record.
$nids = $query->andConditionGroup()
->condition('nid', $node->id());
if (!$node->isNewTranslation()) {
$nids->condition('langcode', $node->language()
->getId());
}
else {
$nids->condition('fallback', 1);
}
// If the node is published, also take the default grant into account. The
// default is saved with a node ID of 0.
$status = $node->isPublished();
if ($status) {
$nids = $query->orConditionGroup()
->condition($nids)
->condition('nid', 0);
}
$query->condition($nids);
$query->range(0, 1);
$grants = $this->buildGrantsQueryCondition(node_access_grants($operation, $account));
if (count($grants) > 0) {
$query->condition($grants);
}
// 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 ($query->execute()
->fetchField()) {
return $set_cacheability(AccessResult::allowed());
}
else {
return $set_cacheability(AccessResult::neutral());
}
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.