diff --git a/core/lib/Drupal/Core/Cache/Context/CacheContextsManager.php b/core/lib/Drupal/Core/Cache/Context/CacheContextsManager.php index dc05e29..dde854e 100644 --- a/core/lib/Drupal/Core/Cache/Context/CacheContextsManager.php +++ b/core/lib/Drupal/Core/Cache/Context/CacheContextsManager.php @@ -115,10 +115,7 @@ public function convertTokensToKeys(array $context_tokens) { throw new \InvalidArgumentException(SafeMarkup::format('"@context" is not a valid cache context ID.', ['@context' => $context_id])); } $context = $this->getService($context_id); - // To make it possible to return NULL instead of CacheableMetadata. - if ($metadata = $context->getCacheableMetadata($parameter)) { - $cacheable_metadata = $cacheable_metadata->merge($metadata); - } + $cacheable_metadata = $cacheable_metadata->merge($context->getCacheableMetadata($parameter)); } sort($optimized_tokens); @@ -176,9 +173,15 @@ public function optimizeTokens(array $context_tokens) { if (strpos($context_token, '.') === FALSE && strpos($context_token, ':') === FALSE) { $optimized_content_tokens[] = $context_token; } + // Check cacheability. If the context defines a max-age of 0, then it + // can not be optimized away. + elseif ($this->getService($context_token)->getCacheableMetadata()->getCacheMaxAge() == 0) { + $optimized_content_tokens[] = $context_token; + } // The context token has a period or a colon. Iterate over all ancestor // cache contexts. If one exists, omit the context token. else { + $ancestor_found = FALSE; // Treat a colon like a period, that allows us to consider 'a' the // ancestor of 'a:foo', without any additional code for the colon. diff --git a/core/lib/Drupal/Core/Cache/Context/CookiesCacheContext.php b/core/lib/Drupal/Core/Cache/Context/CookiesCacheContext.php index 961209d..babbd37 100644 --- a/core/lib/Drupal/Core/Cache/Context/CookiesCacheContext.php +++ b/core/lib/Drupal/Core/Cache/Context/CookiesCacheContext.php @@ -37,11 +37,4 @@ public function getContext($cookie = NULL) { } } - /** - * {@inheritdoc} - */ - public function getCacheableMetadata() { - return NULL; - } - } diff --git a/core/lib/Drupal/Core/Cache/Context/HeadersCacheContext.php b/core/lib/Drupal/Core/Cache/Context/HeadersCacheContext.php index 7cb14f2..8286b36 100644 --- a/core/lib/Drupal/Core/Cache/Context/HeadersCacheContext.php +++ b/core/lib/Drupal/Core/Cache/Context/HeadersCacheContext.php @@ -35,11 +35,4 @@ public function getContext($header = NULL) { } } - /** - * {@inheritdoc} - */ - public function getCacheableMetadata($header = NULL) { - return NULL; - } - } diff --git a/core/lib/Drupal/Core/Cache/Context/IpCacheContext.php b/core/lib/Drupal/Core/Cache/Context/IpCacheContext.php index 313806d..9cc6713 100644 --- a/core/lib/Drupal/Core/Cache/Context/IpCacheContext.php +++ b/core/lib/Drupal/Core/Cache/Context/IpCacheContext.php @@ -28,11 +28,4 @@ public function getContext() { return $this->requestStack->getCurrentRequest()->getClientIp(); } - /** - * {@inheritdoc} - */ - public function getCacheableMetadata() { - return NULL; - } - } diff --git a/core/lib/Drupal/Core/Cache/Context/IsSuperUserCacheContext.php b/core/lib/Drupal/Core/Cache/Context/IsSuperUserCacheContext.php index 051b443..1f4c5ac 100644 --- a/core/lib/Drupal/Core/Cache/Context/IsSuperUserCacheContext.php +++ b/core/lib/Drupal/Core/Cache/Context/IsSuperUserCacheContext.php @@ -7,6 +7,8 @@ namespace Drupal\Core\Cache\Context; +use Drupal\Core\Cache\CacheableMetadata; + /** * Defines the IsSuperUserCacheContext service, for "super user or not" caching. * @@ -28,11 +30,4 @@ public function getContext() { return ((int) $this->user->id()) === 1 ? '1' : '0'; } - /** - * {@inheritdoc} - */ - public function getCacheableMetadata() { - return NULL; - } - } diff --git a/core/lib/Drupal/Core/Cache/Context/LanguagesCacheContext.php b/core/lib/Drupal/Core/Cache/Context/LanguagesCacheContext.php index cdc3bad..6df0af6 100644 --- a/core/lib/Drupal/Core/Cache/Context/LanguagesCacheContext.php +++ b/core/lib/Drupal/Core/Cache/Context/LanguagesCacheContext.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Cache\Context; +use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Language\LanguageManagerInterface; /** @@ -78,7 +79,7 @@ public function getContext($type = NULL) { * {@inheritdoc} */ public function getCacheableMetadata($type = NULL) { - return NULL; + return new CacheableMetadata(); } } diff --git a/core/lib/Drupal/Core/Cache/Context/MenuActiveTrailsCacheContext.php b/core/lib/Drupal/Core/Cache/Context/MenuActiveTrailsCacheContext.php index 1b5b9c7..fc72bcb 100644 --- a/core/lib/Drupal/Core/Cache/Context/MenuActiveTrailsCacheContext.php +++ b/core/lib/Drupal/Core/Cache/Context/MenuActiveTrailsCacheContext.php @@ -29,6 +29,10 @@ public static function getLabel() { * {@inheritdoc} */ public function getContext($menu_name = NULL) { + if (!$menu_name) { + throw new \InvalidArgumentException('No menu name provided for menu.active_trail cache context.'); + } + $active_trail = $this->container->get('menu.active_trail') ->getActiveTrailIds($menu_name); return 'menu_trail.' . $menu_name . '|' . implode('|', $active_trail); @@ -38,6 +42,9 @@ public function getContext($menu_name = NULL) { * {@inheritdoc} */ public function getCacheableMetadata($menu_name = NULL) { + if (!$menu_name) { + throw new \InvalidArgumentException('No menu name provided for menu.active_trail cache context.'); + } $cacheable_metadata = new CacheableMetadata(); return $cacheable_metadata->setCacheTags(["config:system.menu.$menu_name"]); } diff --git a/core/lib/Drupal/Core/Cache/Context/PagersCacheContext.php b/core/lib/Drupal/Core/Cache/Context/PagersCacheContext.php index 4a537dd..f53d464 100644 --- a/core/lib/Drupal/Core/Cache/Context/PagersCacheContext.php +++ b/core/lib/Drupal/Core/Cache/Context/PagersCacheContext.php @@ -38,11 +38,4 @@ public function getContext($pager_id = NULL) { return 'pager.' . $pager_id . '.' . pager_find_page($pager_id); } - /** - * {@inheritdoc} - */ - public function getCacheableMetadata($pager_id = NULL) { - return NULL; - } - } diff --git a/core/lib/Drupal/Core/Cache/Context/QueryArgsCacheContext.php b/core/lib/Drupal/Core/Cache/Context/QueryArgsCacheContext.php index f9106bd..faceb07 100644 --- a/core/lib/Drupal/Core/Cache/Context/QueryArgsCacheContext.php +++ b/core/lib/Drupal/Core/Cache/Context/QueryArgsCacheContext.php @@ -35,11 +35,4 @@ public function getContext($query_arg = NULL) { } } - /** - * {@inheritdoc} - */ - public function getCacheableMetadata($query_arg = NULL) { - return NULL; - } - } diff --git a/core/lib/Drupal/Core/Cache/Context/RequestStackCacheContextBase.php b/core/lib/Drupal/Core/Cache/Context/RequestStackCacheContextBase.php index 9909399..f4c960f 100644 --- a/core/lib/Drupal/Core/Cache/Context/RequestStackCacheContextBase.php +++ b/core/lib/Drupal/Core/Cache/Context/RequestStackCacheContextBase.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Cache\Context; +use Drupal\Core\Cache\CacheableMetadata; use Symfony\Component\HttpFoundation\RequestStack; /** @@ -35,7 +36,7 @@ public function __construct(RequestStack $request_stack) { * {@inheritdoc} */ public function getCacheableMetadata() { - return NULL; + return new CacheableMetadata(); } } diff --git a/core/lib/Drupal/Core/Cache/Context/RouteCacheContext.php b/core/lib/Drupal/Core/Cache/Context/RouteCacheContext.php index 3059a44..4b4f21b 100644 --- a/core/lib/Drupal/Core/Cache/Context/RouteCacheContext.php +++ b/core/lib/Drupal/Core/Cache/Context/RouteCacheContext.php @@ -52,7 +52,7 @@ public function getContext() { * {@inheritdoc} */ public function getCacheableMetadata() { - return NULL; + return new CacheableMetadata(); } } diff --git a/core/lib/Drupal/Core/Cache/Context/ThemeCacheContext.php b/core/lib/Drupal/Core/Cache/Context/ThemeCacheContext.php index 46ff397..7e451af 100644 --- a/core/lib/Drupal/Core/Cache/Context/ThemeCacheContext.php +++ b/core/lib/Drupal/Core/Cache/Context/ThemeCacheContext.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Cache\Context; +use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Theme\ThemeManagerInterface; /** @@ -51,7 +52,7 @@ public function getContext() { * {@inheritdoc} */ public function getCacheableMetadata() { - return NULL; + return new CacheableMetadata(); } } diff --git a/core/lib/Drupal/Core/Cache/Context/TimeZoneCacheContext.php b/core/lib/Drupal/Core/Cache/Context/TimeZoneCacheContext.php index 84321ce..71dab96 100644 --- a/core/lib/Drupal/Core/Cache/Context/TimeZoneCacheContext.php +++ b/core/lib/Drupal/Core/Cache/Context/TimeZoneCacheContext.php @@ -7,6 +7,8 @@ namespace Drupal\Core\Cache\Context; +use Drupal\Core\Cache\CacheableMetadata; + /** * Defines the TimeZoneCacheContext service, for "per time zone" caching. * @@ -36,7 +38,7 @@ public function getContext() { * {@inheritdoc} */ public function getCacheableMetadata() { - return NULL; + return new CacheableMetadata(); } } diff --git a/core/lib/Drupal/Core/Cache/Context/UserCacheContext.php b/core/lib/Drupal/Core/Cache/Context/UserCacheContext.php index 5ed0c1e..983f8a3 100644 --- a/core/lib/Drupal/Core/Cache/Context/UserCacheContext.php +++ b/core/lib/Drupal/Core/Cache/Context/UserCacheContext.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Cache\Context; +use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Session\AccountInterface; /** @@ -44,7 +45,7 @@ public function getContext() { * {@inheritdoc} */ public function getCacheableMetadata() { - return NULL; + return new CacheableMetadata(); } } diff --git a/core/lib/Drupal/Core/Cache/Context/UserRolesCacheContext.php b/core/lib/Drupal/Core/Cache/Context/UserRolesCacheContext.php index eed0d01..4221f14 100644 --- a/core/lib/Drupal/Core/Cache/Context/UserRolesCacheContext.php +++ b/core/lib/Drupal/Core/Cache/Context/UserRolesCacheContext.php @@ -45,11 +45,4 @@ public function getContext($role = NULL) { } } - /** - * {@inheritdoc} - */ - public function getCacheableMetadata($role = NULL) { - return NULL; - } - } diff --git a/core/modules/comment/src/Tests/CommentRssTest.php b/core/modules/comment/src/Tests/CommentRssTest.php index 93c0282..aed6be8 100644 --- a/core/modules/comment/src/Tests/CommentRssTest.php +++ b/core/modules/comment/src/Tests/CommentRssTest.php @@ -53,6 +53,15 @@ function testCommentRss() { $this->postComment($this->node, $this->randomMachineName(), $this->randomMachineName()); $this->drupalGet('rss.xml'); + $cache_contexts = [ + 'languages:language_interface', + 'theme', + 'user.node_grants:view', + 'user.permissions', + 'timezone', + ]; + $this->assertCacheContexts($cache_contexts); + $cache_context_tags = \Drupal::service('cache_contexts_manager')->convertTokensToKeys($cache_contexts)->getCacheableMetadata()->getCacheTags(); $this->assertCacheTags(Cache::mergeTags($cache_context_tags, [ 'config:views.view.frontpage', @@ -61,14 +70,6 @@ function testCommentRss() { 'user:3', ])); - $this->assertCacheContexts([ - 'languages:language_interface', - 'theme', - 'user.node_grants:view', - 'user.permissions', - 'timezone', - ]); - $raw = '' . $this->node->url('canonical', array('fragment' => 'comments', 'absolute' => TRUE)) . ''; $this->assertRaw($raw, 'Comments as part of RSS feed.'); diff --git a/core/modules/node/src/Cache/NodeAccessGrantsCacheContext.php b/core/modules/node/src/Cache/NodeAccessGrantsCacheContext.php index 8f64cbe..10c09f4 100644 --- a/core/modules/node/src/Cache/NodeAccessGrantsCacheContext.php +++ b/core/modules/node/src/Cache/NodeAccessGrantsCacheContext.php @@ -87,7 +87,15 @@ protected function checkNodeGrants($operation) { * {@inheritdoc} */ public function getCacheableMetadata($operation = NULL) { - return NULL; + $cacheable_metadata = new CacheableMetadata(); + + if (!\Drupal::moduleHandler()->getImplementations('node_grants')) { + return $cacheable_metadata; + } + + // If the site is using node grants, this cache context can not be + // optimized. + return $cacheable_metadata->setCacheMaxAge(0); } } diff --git a/core/modules/system/tests/modules/entity_test/src/Cache/EntityTestViewGrantsCacheContext.php b/core/modules/system/tests/modules/entity_test/src/Cache/EntityTestViewGrantsCacheContext.php index f2e3bb2..9d49470 100644 --- a/core/modules/system/tests/modules/entity_test/src/Cache/EntityTestViewGrantsCacheContext.php +++ b/core/modules/system/tests/modules/entity_test/src/Cache/EntityTestViewGrantsCacheContext.php @@ -7,6 +7,7 @@ namespace Drupal\entity_test\Cache; +use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Cache\Context\CacheContextInterface; /** @@ -38,7 +39,7 @@ public function getContext() { * {@inheritdoc} */ public function getCacheableMetadata() { - return NULL; + return new CacheableMetadata(); } } diff --git a/core/modules/views/tests/modules/views_test_data/src/Cache/ViewsTestCacheContext.php b/core/modules/views/tests/modules/views_test_data/src/Cache/ViewsTestCacheContext.php index 88d7559..e9ddc08 100644 --- a/core/modules/views/tests/modules/views_test_data/src/Cache/ViewsTestCacheContext.php +++ b/core/modules/views/tests/modules/views_test_data/src/Cache/ViewsTestCacheContext.php @@ -7,6 +7,7 @@ namespace Drupal\views_test_data\Cache; +use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Cache\Context\CacheContextInterface; /** @@ -34,7 +35,7 @@ public function getContext() { * {@inheritdoc} */ public function getCacheableMetadata() { - return NULL; + return new CacheableMetadata(); } } diff --git a/core/tests/Drupal/Tests/Core/Cache/Context/CacheContextsManagerTest.php b/core/tests/Drupal/Tests/Core/Cache/Context/CacheContextsManagerTest.php index c6c06a5..818aec4 100644 --- a/core/tests/Drupal/Tests/Core/Cache/Context/CacheContextsManagerTest.php +++ b/core/tests/Drupal/Tests/Core/Cache/Context/CacheContextsManagerTest.php @@ -7,6 +7,7 @@ namespace Drupal\Tests\Core\Cache\Context; +use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Cache\Context\CacheContextsManager; use Drupal\Core\Cache\Context\CacheContextInterface; use Drupal\Core\Cache\Context\CalculatedCacheContextInterface; @@ -238,7 +239,7 @@ public function getContext() { * {@inheritdoc} */ public function getCacheableMetadata() { - return NULL; + return new CacheableMetadata(); } } @@ -269,7 +270,7 @@ public function getContext($parameter = NULL) { * {@inheritdoc} */ public function getCacheableMetadata($parameter = NULL) { - return NULL; + return new CacheableMetadata(); } }