diff --git a/core/lib/Drupal/Core/Access/AccessResult.php b/core/lib/Drupal/Core/Access/AccessResult.php index efbb835..7adc8f4 100644 --- a/core/lib/Drupal/Core/Access/AccessResult.php +++ b/core/lib/Drupal/Core/Access/AccessResult.php @@ -8,6 +8,9 @@ use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\CacheableDependencyInterface; +use Drupal\Core\Cache\CacheableMetadata; +use Drupal\Core\Cache\RefinableCacheableDependencyInterface; +use Drupal\Core\Cache\RefinableCacheableDependencyTrait; use Drupal\Core\Config\ConfigBase; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; @@ -29,31 +32,9 @@ * @todo Use RefinableCacheableDependencyInterface and the corresponding trait in * https://www.drupal.org/node/2526326. */ -abstract class AccessResult implements AccessResultInterface, CacheableDependencyInterface { +abstract class AccessResult implements AccessResultInterface, CacheableDependencyInterface, RefinableCacheableDependencyInterface { - /** - * The cache context IDs (to vary a cache item ID based on active contexts). - * - * @see \Drupal\Core\Cache\Context\CacheContextInterface - * @see \Drupal\Core\Cache\Context\CacheContextsManager::convertTokensToKeys() - * - * @var string[] - */ - protected $contexts; - - /** - * The cache tags. - * - * @var array - */ - protected $tags; - - /** - * The maximum caching time in seconds. - * - * @var int - */ - protected $maxAge; + use RefinableCacheableDependencyTrait; /** * Constructs a new AccessResult object. @@ -215,35 +196,22 @@ public function isNeutral() { * {@inheritdoc} */ public function getCacheContexts() { - sort($this->contexts); - return $this->contexts; + sort($this->cacheContexts); + return $this->cacheContexts; } /** * {@inheritdoc} */ public function getCacheTags() { - return $this->tags; + return $this->cacheTags; } /** * {@inheritdoc} */ public function getCacheMaxAge() { - return $this->maxAge; - } - - /** - * Adds cache contexts associated with the access result. - * - * @param string[] $contexts - * An array of cache context IDs, used to generate a cache ID. - * - * @return $this - */ - public function addCacheContexts(array $contexts) { - $this->contexts = array_unique(array_merge($this->contexts, $contexts)); - return $this; + return $this->getCacheMaxAge; } /** @@ -252,20 +220,7 @@ public function addCacheContexts(array $contexts) { * @return $this */ public function resetCacheContexts() { - $this->contexts = array(); - return $this; - } - - /** - * Adds cache tags associated with the access result. - * - * @param array $tags - * An array of cache tags. - * - * @return $this - */ - public function addCacheTags(array $tags) { - $this->tags = Cache::mergeTags($this->tags, $tags); + $this->cacheContexts = array(); return $this; } @@ -275,7 +230,7 @@ public function addCacheTags(array $tags) { * @return $this */ public function resetCacheTags() { - $this->tags = array(); + $this->cacheTags = array(); return $this; } @@ -288,7 +243,7 @@ public function resetCacheTags() { * @return $this */ public function setCacheMaxAge($max_age) { - $this->maxAge = $max_age; + $this->cacheMaxAge = $max_age; return $this; } @@ -319,14 +274,15 @@ public function cachePerUser() { * The entity whose cache tag to set on the access result. * * @return $this + * + * @deprecated Use this::addCacheableDependency() instead. */ public function cacheUntilEntityChanges(EntityInterface $entity) { - $this->addCacheTags($entity->getCacheTags()); - // @discuss Currently only the cache tags are copied from the entity, but - // the contexts are ignored. Shouldn't we include these, since we might - // vary on a parameter that affects accessibility? A good example would be - // block visibility. - // $this->addCacheContexts($entity->getCacheContexts()); + $metadata = CacheableMetadata::createFromObject($this); + $metadata->addCacheTags($entity->getCacheTags()); + $metadata->addCacheContexts($entity->getCacheContexts()); + $this->addCacheableDependency($metadata); + return $this; } @@ -337,9 +293,33 @@ public function cacheUntilEntityChanges(EntityInterface $entity) { * The configuration object whose cache tag to set on the access result. * * @return $this + * + * @deprecated Use this::addCacheableDependency() instead. */ public function cacheUntilConfigurationChanges(ConfigBase $configuration) { - $this->addCacheTags($configuration->getCacheTags()); + $metadata = CacheableMetadata::createFromObject($this); + $metadata->addCacheTags($configuration->getCacheTags()); + $this->addCacheableDependency($metadata); + + return $this; + } + + /** + * Adds a dependency on another cacheable object. + * + * When an access result depends on some other cacheable object such as an + * entity or a configuration object we must declare that dependency. + * + * @param \Drupal\Core\Cache\CacheableMetadata $metadata + * The dependency metadata to add. + * + * @return $this + */ + public function addCacheableDependency(CacheableMetadata $metadata) { + $this->addCacheContexts($metadata->getCacheContexts()); + $this->addCacheTags($metadata->getCacheTags()); + $this->mergeCacheMaxAge($metadata->getCacheMaxAge()); + return $this; }