core/lib/Drupal/Core/Cache/Cache.php | 2 +- core/lib/Drupal/Core/Cache/CacheContexts.php | 88 ++++++++++++---------- .../views/src/Entity/Render/RendererBase.php | 3 +- .../views/src/Tests/Entity/FieldEntityTest.php | 1 - .../Drupal/Tests/Core/Cache/CacheContextsTest.php | 10 +-- .../Drupal/Tests/Core/Render/RendererTestBase.php | 1 + 6 files changed, 59 insertions(+), 46 deletions(-) diff --git a/core/lib/Drupal/Core/Cache/Cache.php b/core/lib/Drupal/Core/Cache/Cache.php index f282a77..5541a68 100644 --- a/core/lib/Drupal/Core/Cache/Cache.php +++ b/core/lib/Drupal/Core/Cache/Cache.php @@ -37,7 +37,7 @@ public static function mergeContexts() { $cache_contexts = array_merge($cache_contexts, $contexts); } $cache_contexts = array_unique($cache_contexts); - \Drupal::service('cache_contexts')->validate($cache_contexts); + \Drupal::service('cache_contexts')->validateTokens($cache_contexts); sort($cache_contexts); return $cache_contexts; } diff --git a/core/lib/Drupal/Core/Cache/CacheContexts.php b/core/lib/Drupal/Core/Cache/CacheContexts.php index 2d08eb4..665ee79 100644 --- a/core/lib/Drupal/Core/Cache/CacheContexts.php +++ b/core/lib/Drupal/Core/Cache/CacheContexts.php @@ -54,44 +54,6 @@ public function __construct(ContainerInterface $container, array $contexts) { $this->contexts = $contexts; } - public function validate(array $context_tokens = []) { - if (empty($context_tokens)) { - return; - } - - // Initialize the set of valid context tokens with the container's contexts. - if (!isset($this->validContextTokens)) { - $this->validContextTokens = array_flip($this->contexts); - } - - foreach ($context_tokens as $context_token) { - if (!is_string($context_token)) { - throw new \LogicException('Cache contexts must be strings, ' . gettype($context_token) . ' given.'); - } - - if (isset($this->validContextTokens[$context_token])) { - continue; - } - - // If it's a valid context token, then the ID must be stored in the set - // of valid context tokens (since we initialized it with the list of cache - // context IDs using the container). In case of an invalid context token, - // throw an exception, otherwise cache it, including the parameter, to - // minimize the amount of work in future ::validateContexts() calls. - $context_id = $context_token; - $colon_pos = strpos($context_id, ':'); - if ($colon_pos !== FALSE) { - $context_id = substr($context_id, 0, $colon_pos); - } - if (isset($this->validContextTokens[$context_id])) { - $this->validContextTokens[$context_token] = TRUE; - } - else { - throw new \LogicException('"' . $context_id . '" is not a valid cache context ID.'); - } - } - } - /** * Provides an array of available cache contexts. * @@ -259,4 +221,54 @@ public static function parseTokens(array $context_tokens) { return $contexts_with_parameters; } + /** + * Validates an array of cache context tokens. + * + * Can be called before using cache tags in operations, to ensure validity. + * + * @param string[] $context_tokens + * An array of cache context tokens. + * + * @throws \LogicException + * + * @see \Drupal\Core\Cache\CacheContexts::parseTokens() + */ + public function validateTokens(array $context_tokens = []) { + if (empty($context_tokens)) { + return; + } + + // Initialize the set of valid context tokens with the container's contexts. + if (!isset($this->validContextTokens)) { + $this->validContextTokens = array_flip($this->contexts); + } + + foreach ($context_tokens as $context_token) { + if (!is_string($context_token)) { + throw new \LogicException('Cache contexts must be strings, ' . gettype($context_token) . ' given.'); + } + + if (isset($this->validContextTokens[$context_token])) { + continue; + } + + // If it's a valid context token, then the ID must be stored in the set + // of valid context tokens (since we initialized it with the list of cache + // context IDs using the container). In case of an invalid context token, + // throw an exception, otherwise cache it, including the parameter, to + // minimize the amount of work in future ::validateContexts() calls. + $context_id = $context_token; + $colon_pos = strpos($context_id, ':'); + if ($colon_pos !== FALSE) { + $context_id = substr($context_id, 0, $colon_pos); + } + if (isset($this->validContextTokens[$context_id])) { + $this->validContextTokens[$context_token] = TRUE; + } + else { + throw new \LogicException('"' . $context_id . '" is not a valid cache context ID.'); + } + } + } + } diff --git a/core/modules/views/src/Entity/Render/RendererBase.php b/core/modules/views/src/Entity/Render/RendererBase.php index d4694d2..63d163d 100644 --- a/core/modules/views/src/Entity/Render/RendererBase.php +++ b/core/modules/views/src/Entity/Render/RendererBase.php @@ -8,6 +8,7 @@ namespace Drupal\views\Entity\Render; use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Language\LanguageManagerInterface; use Drupal\views\Plugin\CacheablePluginInterface; use Drupal\views\Plugin\views\query\QueryPluginBase; @@ -74,7 +75,7 @@ public function isCacheable() { * {@inheritdoc} */ public function getCacheContexts() { - return ['language']; + return ['languages']; } /** diff --git a/core/modules/views/src/Tests/Entity/FieldEntityTest.php b/core/modules/views/src/Tests/Entity/FieldEntityTest.php index 715a36b..770f7f0 100644 --- a/core/modules/views/src/Tests/Entity/FieldEntityTest.php +++ b/core/modules/views/src/Tests/Entity/FieldEntityTest.php @@ -47,7 +47,6 @@ protected function setUp($import_test_views = TRUE) { ViewTestData::createTestViews(get_class($this), array('views_test_config')); } - /** * Tests the getEntity method. */ diff --git a/core/tests/Drupal/Tests/Core/Cache/CacheContextsTest.php b/core/tests/Drupal/Tests/Core/Cache/CacheContextsTest.php index 430be3b..76251a1 100644 --- a/core/tests/Drupal/Tests/Core/Cache/CacheContextsTest.php +++ b/core/tests/Drupal/Tests/Core/Cache/CacheContextsTest.php @@ -171,7 +171,7 @@ protected function getMockContainer() { * * @return array */ - public function validateContextsProvider() { + public function validateTokensProvider() { return [ [[], FALSE], [['foo'], FALSE], @@ -199,9 +199,9 @@ public function validateContextsProvider() { } /** - * @covers ::validate + * @covers ::validateTokens * - * @dataProvider validateContextsProvider + * @dataProvider validateTokensProvider */ public function testValidateContexts(array $contexts, $expected_exception_message) { $container = new ContainerBuilder(); @@ -209,8 +209,8 @@ public function testValidateContexts(array $contexts, $expected_exception_messag if ($expected_exception_message !== FALSE) { $this->setExpectedException('LogicException', $expected_exception_message); } - // If it doesn't throw an exception, validate() returns NULL. - $this->assertNull($cache_contexts->validate($contexts)); + // If it doesn't throw an exception, validateTokens() returns NULL. + $this->assertNull($cache_contexts->validateTokens($contexts)); } } diff --git a/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php b/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php index b4320c9..15a3b05 100644 --- a/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php +++ b/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php @@ -86,6 +86,7 @@ protected function setUp() { $this->renderer = new Renderer($this->controllerResolver, $this->themeManager, $this->elementInfo, $this->requestStack, $this->cacheFactory, $this->cacheContexts); $container = new ContainerBuilder(); + $container->set('cache_contexts', $this->cacheContexts); $container->set('renderer', $this->renderer); \Drupal::setContainer($container); }