/** * {@inheritdoc} */ public function orIf(AccessResultInterface $other) { $merge_other = FALSE; // $other's cacheability metadata is merged if $merge_other gets set to TRUE // and this happens in three cases: // 1. $other's access result is the one that determines the combined access // result. // 2. This access result is not cacheable and $other's access result is the // same. i.e. attempt to return a cacheable access result. // 3. Neither access result is 'forbidden' and both are cacheable: inherit // the other's cacheability metadata because it may turn into a // 'forbidden' for another value of the cache contexts in the // cacheability metadata. In other words: this is necessary to respect // the contagious nature of the 'forbidden' access result. // e.g. we have two access results A and B. Neither is forbidden. A is // globally cacheable (no cache contexts). B is cacheable per role. If we // don't have merging case 3, then A->orIf(B) will be globally cacheable, // which means that even if a user of a different role logs in, the // cached access result will be used, even though for that other role, B // is forbidden! if ($this->isForbidden() || $other->isForbidden()) { $result = static::forbidden(); if (!$this->isForbidden() || $this->getCacheMaxAge() === 0 && $other->isForbidden()) { $merge_other = TRUE; } } elseif ($this->isAllowed() || $other->isAllowed()) { $result = static::allowed(); if (!$this->isAllowed() || $this->getCacheMaxAge() === 0 && $other->isAllowed() || $this->getCacheMaxAge() !== 0 && $other instanceof CacheableDependencyInterface && $other->getCacheMaxAge() !== 0) { $merge_other = TRUE; } } else { $result = static::neutral(); if (!$this->isNeutral() || $this->getCacheMaxAge() === 0 && $other->isNeutral() || $this->getCacheMaxAge() !== 0 && $other instanceof CacheableDependencyInterface && $other->getCacheMaxAge() !== 0) { $merge_other = TRUE; } } $result->inheritCacheability($this); if ($merge_other) { $result->inheritCacheability($other); } return $result; }
/** * Inherits the cacheability of the other access result, if any. * * @param \Drupal\Core\Access\AccessResultInterface $other * The other access result, whose cacheability (if any) to inherit. * * @return $this */ public function inheritCacheability(AccessResultInterface $other) { if ($other instanceof CacheableInterface) { $this->setCacheable($other->isCacheable()); $this->addCacheContexts($other->getCacheKeys()); $this->addCacheTags($other->getCacheTags()); // Use the lowest max-age. if ($this->getCacheMaxAge() === Cache::PERMANENT) { // The other max-age is either lower or equal. $this->setCacheMaxAge($other->getCacheMaxAge()); } else { $this->setCacheMaxAge(min($this->getCacheMaxAge(), $other->getCacheMaxAge())); } } else { $this->setCacheable(FALSE); } return $this; }
/** * Inherits the cacheability of the other access result, if any. * * @param \Drupal\Core\Access\AccessResultInterface $other * The other access result, whose cacheability (if any) to inherit. * * @return $this */ public function inheritCacheability(AccessResultInterface $other) { if ($other instanceof CacheableDependencyInterface) { if ($this->getCacheMaxAge() !== 0 && $other->getCacheMaxAge() !== 0) { $this->setCacheMaxAge(Cache::mergeMaxAges($this->getCacheMaxAge(), $other->getCacheMaxAge())); } else { $this->setCacheMaxAge($other->getCacheMaxAge()); } $this->addCacheContexts($other->getCacheContexts()); $this->addCacheTags($other->getCacheTags()); } else { $this->setCacheMaxAge(0); } return $this; }
/** * Inherits the cacheability of the other access result, if any. * * @param \Drupal\Core\Access\AccessResultInterface $other * The other access result, whose cacheability (if any) to inherit. * * @return $this */ public function inheritCacheability(AccessResultInterface $other) { if ($other instanceof CacheableInterface) { $this->setCacheable($other->isCacheable()); $this->addCacheContexts($other->getCacheContexts()); $this->addCacheTags($other->getCacheTags()); $this->setCacheMaxAge(Cache::mergeMaxAges($this->getCacheMaxAge(), $other->getCacheMaxAge())); } else { $this->setCacheable(FALSE); } return $this; }