annotate core/modules/node/src/Cache/NodeAccessGrantsCacheContext.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 4c8ae668cc8c
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\node\Cache;
Chris@0 4
Chris@0 5 use Drupal\Core\Cache\CacheableMetadata;
Chris@0 6 use Drupal\Core\Cache\Context\CalculatedCacheContextInterface;
Chris@0 7 use Drupal\Core\Cache\Context\UserCacheContextBase;
Chris@0 8
Chris@0 9 /**
Chris@0 10 * Defines the node access view cache context service.
Chris@0 11 *
Chris@0 12 * Cache context ID: 'user.node_grants' (to vary by all operations' grants).
Chris@0 13 * Calculated cache context ID: 'user.node_grants:%operation', e.g.
Chris@0 14 * 'user.node_grants:view' (to vary by the view operation's grants).
Chris@0 15 *
Chris@0 16 * This allows for node access grants-sensitive caching when listing nodes.
Chris@0 17 *
Chris@0 18 * @see node_query_node_access_alter()
Chris@0 19 * @ingroup node_access
Chris@0 20 */
Chris@0 21 class NodeAccessGrantsCacheContext extends UserCacheContextBase implements CalculatedCacheContextInterface {
Chris@0 22
Chris@0 23 /**
Chris@0 24 * {@inheritdoc}
Chris@0 25 */
Chris@0 26 public static function getLabel() {
Chris@0 27 return t("Content access view grants");
Chris@0 28 }
Chris@0 29
Chris@0 30 /**
Chris@0 31 * {@inheritdoc}
Chris@0 32 */
Chris@0 33 public function getContext($operation = NULL) {
Chris@0 34 // If the current user either can bypass node access then we don't need to
Chris@0 35 // determine the exact node grants for the current user.
Chris@0 36 if ($this->user->hasPermission('bypass node access')) {
Chris@0 37 return 'all';
Chris@0 38 }
Chris@0 39
Chris@0 40 // When no specific operation is specified, check the grants for all three
Chris@0 41 // possible operations.
Chris@0 42 if ($operation === NULL) {
Chris@0 43 $result = [];
Chris@0 44 foreach (['view', 'update', 'delete'] as $op) {
Chris@0 45 $result[] = $this->checkNodeGrants($op);
Chris@0 46 }
Chris@0 47 return implode('-', $result);
Chris@0 48 }
Chris@0 49 else {
Chris@0 50 return $this->checkNodeGrants($operation);
Chris@0 51 }
Chris@0 52 }
Chris@0 53
Chris@0 54 /**
Chris@0 55 * Checks the node grants for the given operation.
Chris@0 56 *
Chris@0 57 * @param string $operation
Chris@0 58 * The operation to check the node grants for.
Chris@0 59 *
Chris@0 60 * @return string
Chris@0 61 * The string representation of the cache context.
Chris@0 62 */
Chris@0 63 protected function checkNodeGrants($operation) {
Chris@0 64 // When checking the grants for the 'view' operation and the current user
Chris@0 65 // has a global view grant (i.e. a view grant for node ID 0) — note that
Chris@0 66 // this is automatically the case if no node access modules exist (no
Chris@0 67 // hook_node_grants() implementations) then we don't need to determine the
Chris@0 68 // exact node view grants for the current user.
Chris@0 69 if ($operation === 'view' && node_access_view_all_nodes($this->user)) {
Chris@0 70 return 'view.all';
Chris@0 71 }
Chris@0 72
Chris@0 73 $grants = node_access_grants($operation, $this->user);
Chris@0 74 $grants_context_parts = [];
Chris@0 75 foreach ($grants as $realm => $gids) {
Chris@0 76 $grants_context_parts[] = $realm . ':' . implode(',', $gids);
Chris@0 77 }
Chris@0 78 return $operation . '.' . implode(';', $grants_context_parts);
Chris@0 79 }
Chris@0 80
Chris@0 81 /**
Chris@0 82 * {@inheritdoc}
Chris@0 83 */
Chris@0 84 public function getCacheableMetadata($operation = NULL) {
Chris@0 85 $cacheable_metadata = new CacheableMetadata();
Chris@0 86
Chris@0 87 if (!\Drupal::moduleHandler()->getImplementations('node_grants')) {
Chris@0 88 return $cacheable_metadata;
Chris@0 89 }
Chris@0 90
Chris@0 91 // The node grants may change if the user is updated. (The max-age is set to
Chris@0 92 // zero below, but sites may override this cache context, and change it to a
Chris@0 93 // non-zero value. In such cases, this cache tag is needed for correctness.)
Chris@0 94 $cacheable_metadata->setCacheTags(['user:' . $this->user->id()]);
Chris@0 95
Chris@0 96 // If the site is using node grants, this cache context can not be
Chris@0 97 // optimized.
Chris@0 98 return $cacheable_metadata->setCacheMaxAge(0);
Chris@0 99 }
Chris@0 100
Chris@0 101 }