Mercurial > hg > isophonics-drupal-site
diff core/modules/node/src/Cache/NodeAccessGrantsCacheContext.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/modules/node/src/Cache/NodeAccessGrantsCacheContext.php Wed Nov 29 16:09:58 2017 +0000 @@ -0,0 +1,101 @@ +<?php + +namespace Drupal\node\Cache; + +use Drupal\Core\Cache\CacheableMetadata; +use Drupal\Core\Cache\Context\CalculatedCacheContextInterface; +use Drupal\Core\Cache\Context\UserCacheContextBase; + +/** + * Defines the node access view cache context service. + * + * Cache context ID: 'user.node_grants' (to vary by all operations' grants). + * Calculated cache context ID: 'user.node_grants:%operation', e.g. + * 'user.node_grants:view' (to vary by the view operation's grants). + * + * This allows for node access grants-sensitive caching when listing nodes. + * + * @see node_query_node_access_alter() + * @ingroup node_access + */ +class NodeAccessGrantsCacheContext extends UserCacheContextBase implements CalculatedCacheContextInterface { + + /** + * {@inheritdoc} + */ + public static function getLabel() { + return t("Content access view grants"); + } + + /** + * {@inheritdoc} + */ + public function getContext($operation = NULL) { + // If the current user either can bypass node access then we don't need to + // determine the exact node grants for the current user. + if ($this->user->hasPermission('bypass node access')) { + return 'all'; + } + + // When no specific operation is specified, check the grants for all three + // possible operations. + if ($operation === NULL) { + $result = []; + foreach (['view', 'update', 'delete'] as $op) { + $result[] = $this->checkNodeGrants($op); + } + return implode('-', $result); + } + else { + return $this->checkNodeGrants($operation); + } + } + + /** + * Checks the node grants for the given operation. + * + * @param string $operation + * The operation to check the node grants for. + * + * @return string + * The string representation of the cache context. + */ + protected function checkNodeGrants($operation) { + // When checking the grants for the 'view' operation and the current user + // has a global view grant (i.e. a view grant for node ID 0) — note that + // this is automatically the case if no node access modules exist (no + // hook_node_grants() implementations) then we don't need to determine the + // exact node view grants for the current user. + if ($operation === 'view' && node_access_view_all_nodes($this->user)) { + return 'view.all'; + } + + $grants = node_access_grants($operation, $this->user); + $grants_context_parts = []; + foreach ($grants as $realm => $gids) { + $grants_context_parts[] = $realm . ':' . implode(',', $gids); + } + return $operation . '.' . implode(';', $grants_context_parts); + } + + /** + * {@inheritdoc} + */ + public function getCacheableMetadata($operation = NULL) { + $cacheable_metadata = new CacheableMetadata(); + + if (!\Drupal::moduleHandler()->getImplementations('node_grants')) { + return $cacheable_metadata; + } + + // The node grants may change if the user is updated. (The max-age is set to + // zero below, but sites may override this cache context, and change it to a + // non-zero value. In such cases, this cache tag is needed for correctness.) + $cacheable_metadata->setCacheTags(['user:' . $this->user->id()]); + + // If the site is using node grants, this cache context can not be + // optimized. + return $cacheable_metadata->setCacheMaxAge(0); + } + +}