core/core.services.yml | 10 +--
core/includes/common.inc | 8 +-
core/lib/Drupal/Core/Cache/Cache.php | 4 +-
.../Drupal/Core/Cache/CacheContextInterface.php | 34 ++++++++
core/lib/Drupal/Core/Cache/CacheContexts.php | 82 ++++++++++----------
core/lib/Drupal/Core/Cache/CacheContextsPass.php | 9 +--
core/lib/Drupal/Core/Cache/UrlCacheContext.php | 41 ++++++++++
core/lib/Drupal/Core/Http/RequestCacheContexts.php | 36 ---------
core/modules/block/lib/Drupal/block/BlockBase.php | 39 +++++-----
.../block/lib/Drupal/block/BlockViewBuilder.php | 6 +-
.../lib/Drupal/block/Tests/BlockCacheTest.php | 40 ++++++----
.../lib/Drupal/block/Tests/BlockInterfaceTest.php | 23 +++---
.../Drupal/block/Tests/BlockStorageUnitTest.php | 2 +-
.../book/Plugin/Block/BookNavigationBlock.php | 35 ++++++++-
.../Drupal/forum/Plugin/Block/ForumBlockBase.php | 2 +-
.../Drupal/system/Plugin/Block/SystemMenuBlock.php | 35 ++++++++-
.../lib/Drupal/user/Cache/UserCacheContext.php | 42 ++++++++++
.../Drupal/user/Cache/UserRolesCacheContext.php | 42 ++++++++++
.../modules/user/lib/Drupal/user/CacheContexts.php | 38 ---------
core/modules/user/user.services.yml | 9 ++-
.../Drupal/Tests/Core/Cache/CacheContextsTest.php | 55 ++++++++-----
21 files changed, 386 insertions(+), 206 deletions(-)
diff --git a/core/core.services.yml b/core/core.services.yml
index 1de4ce9..2169617 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -7,6 +7,11 @@ services:
cache_contexts:
class: Drupal\Core\Cache\CacheContexts
arguments: ['@service_container', '%cache_contexts%' ]
+ cache_context.url:
+ class: Drupal\Core\Cache\UrlCacheContext
+ arguments: ['@request']
+ tags:
+ - { name: cache.context}
cache.backend.database:
class: Drupal\Core\Cache\DatabaseBackendFactory
arguments: ['@database']
@@ -643,11 +648,6 @@ services:
date:
class: Drupal\Core\Datetime\Date
arguments: ['@entity.manager', '@language_manager', '@string_translation', '@config.factory']
- http.request_cache_contexts:
- class: Drupal\Core\Http\RequestCacheContexts
- arguments: ['@request']
- tags:
- - { name: cache.context}
feed.bridge.reader:
class: Drupal\Component\Bridge\ZfExtensionManagerSfContainer
calls:
diff --git a/core/includes/common.inc b/core/includes/common.inc
index 524e304..73edc78 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -4612,9 +4612,11 @@ function drupal_render_cid_create($elements) {
return $elements['#cache']['cid'];
}
elseif (isset($elements['#cache']['keys'])) {
- // Add cache context keys when constants are used in the 'keys' parameter.
- $cacheable_helper = \Drupal::service("cache_contexts");
- $keys = $cacheable_helper->addContextsToKeys($elements['#cache']['keys']);
+ // Cache keys may either be static (just strings) or tokens (placeholders
+ // that are converted to static keys by the @cache_contexts service,
+ // depending on the request).
+ $cache_contexts = \Drupal::service("cache_contexts");
+ $keys = $cache_contexts->convertTokensToKeys($elements['#cache']['keys']);
$granularity = isset($elements['#cache']['granularity']) ? $elements['#cache']['granularity'] : NULL;
// Merge in additional cache ID parts based provided by drupal_render_cid_parts().
diff --git a/core/lib/Drupal/Core/Cache/Cache.php b/core/lib/Drupal/Core/Cache/Cache.php
index 25e15bb..38ca1b1 100644
--- a/core/lib/Drupal/Core/Cache/Cache.php
+++ b/core/lib/Drupal/Core/Cache/Cache.php
@@ -73,9 +73,9 @@ public static function getBins() {
}
/**
- * Generates a hash from a query object, to be used as part of the cache key
+ * Generates a hash from a query object, to be used as part of the cache key.
*
- * @param $query
+ * @param \Drupal\Core\Database\Query\SelectInterface $query
* A select query object.
*
* @return string
diff --git a/core/lib/Drupal/Core/Cache/CacheContextInterface.php b/core/lib/Drupal/Core/Cache/CacheContextInterface.php
new file mode 100644
index 0000000..fd9783a
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/CacheContextInterface.php
@@ -0,0 +1,34 @@
+ array(
- * "service" => "provider_service_id",
- * "callback" => "getSomeContext",
- * )
- * )
- *
+ * An array of key-value pairs, where the keys are service names (which also
+ * serve as the corresponding cache context token) and the values are the
+ * cache context labels.
*/
public function __construct(ContainerInterface $container, array $contexts) {
$this->container = $container;
@@ -44,33 +54,39 @@ public function __construct(ContainerInterface $container, array $contexts) {
* An array of available cache contexts.
*/
public function getAll() {
- return array_keys($this->contexts);
+ return $this->contexts;
}
/**
- * Provides an array of available cache context labels, to be used used in a
- * cache configuration form.
+ * Provides an array of available cache context labels.
+ *
+ * To be used in a cache configuration form.
*
* @return array
- * An array of available cache context labels.
+ * An array of available cache contexts and corresponding labels.
*/
public function getLabels() {
$with_labels = array();
- foreach ($this->contexts as $name => $params) {
- $with_labels[$name] = $params["label"];
+ foreach ($this->contexts as $context) {
+ $with_labels[$context] = $this->getService($context)->getLabel();
}
return $with_labels;
}
/**
- * Converts cache contexts to string representations of the context.
+ * Converts cache context tokens to string representations of the context.
+ *
+ * Cache keys may either be static (just strings) or tokens (placeholders
+ * that are converted to static keys by the @cache_contexts service, depending
+ * depending on the request). This is the default cache contexts service.
+ *
+ * @param array $keys
+ * An array of cache keys that may or may not contain cache context tokens.
*
- * @param $keys
- * An array of cache keys that may or may not contain cache contexts.
* @return array
- * A copy of the input, with cache contexts converted.
+ * A copy of the input, with cache context tokens converted.
*/
- public function addContextsToKeys($keys) {
+ public function convertTokensToKeys(array $keys) {
$context_keys = array_intersect($keys, $this->getAll());
$new_keys = $keys;
@@ -85,27 +101,14 @@ public function addContextsToKeys($keys) {
/**
* Provides the string representaton of a cache context.
*
- * @todo Document this properly once the input arguments are decided on,
- * assuming the reuse of existing cache constants is temporary.
+ * @param string $context
+ * A cache context token of an available cache context service.
*
* @return string
* The string representaton of a cache context.
*/
protected function getContext($context) {
- $context_info = $this->contexts[$context];
- return call_user_func($this->getCallable($context_info));
- }
-
- /**
- * @param array $context
- * @return callable
- * A callable that returns the resolved cache context.
- */
- protected function getCallable($context) {
- return array(
- $this->getService($context["service"]),
- $context["callback"]
- );
+ return $this->getService($context)->getContext();
}
/**
@@ -113,6 +116,7 @@ protected function getCallable($context) {
*
* @param string $service
* The ID of the service to retrieve.
+ *
* @return mixed
* The specified service.
*/
diff --git a/core/lib/Drupal/Core/Cache/CacheContextsPass.php b/core/lib/Drupal/Core/Cache/CacheContextsPass.php
index d5f87f0..a5f666f 100644
--- a/core/lib/Drupal/Core/Cache/CacheContextsPass.php
+++ b/core/lib/Drupal/Core/Cache/CacheContextsPass.php
@@ -21,14 +21,7 @@ class CacheContextsPass implements CompilerPassInterface {
* Collects the cache contexts into the cache_contexts parameter.
*/
public function process(ContainerBuilder $container) {
- $cache_contexts = array();
- foreach ($container->findTaggedServiceIds('cache.context') as $service_name => $attrs) {
- $service = $container->getDefinition($service_name);
- $class = $service->getClass();
- foreach ($class::getCacheContexts() as $context => $params) {
- $cache_contexts[$context] = $params + array("service" => $service_name);
- }
- }
+ $cache_contexts = array_keys($container->findTaggedServiceIds('cache.context'));
$container->setParameter('cache_contexts', $cache_contexts);
}
}
diff --git a/core/lib/Drupal/Core/Cache/UrlCacheContext.php b/core/lib/Drupal/Core/Cache/UrlCacheContext.php
new file mode 100644
index 0000000..8d9141e
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/UrlCacheContext.php
@@ -0,0 +1,41 @@
+request = $request;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getLabel() {
+ return t('URL');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getContext() {
+ return $this->request->getUri();
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Http/RequestCacheContexts.php b/core/lib/Drupal/Core/Http/RequestCacheContexts.php
deleted file mode 100644
index fada2c7..0000000
--- a/core/lib/Drupal/Core/Http/RequestCacheContexts.php
+++ /dev/null
@@ -1,36 +0,0 @@
-request = $request;
- }
-
- static function getCacheContexts() {
- return array(
- "http.request_path" => array(
- "callback" => "getCurrentPath",
- "label" => "Request path",
- ),
- );
- }
-
- /**
- * @return string
- * The current path.
- */
- public function getCurrentPath() {
- // @todo: Make this use the request.
- global $base_root;
- return $base_root . request_uri();
- }
-
-}
diff --git a/core/modules/block/lib/Drupal/block/BlockBase.php b/core/modules/block/lib/Drupal/block/BlockBase.php
index e3834a1..de7916b 100644
--- a/core/modules/block/lib/Drupal/block/BlockBase.php
+++ b/core/modules/block/lib/Drupal/block/BlockBase.php
@@ -65,7 +65,7 @@ protected function baseConfigurationDefaults() {
'label_display' => BlockInterface::BLOCK_LABEL_VISIBLE,
'cache' => array(
'max_age' => 0,
- 'cache_contexts' => array(),
+ 'contexts' => array(),
),
);
}
@@ -135,26 +135,28 @@ public function buildConfigurationForm(array $form, array &$form_state) {
$period[0] = '<' . t('no caching') . '>';
$period[\Drupal\Core\Cache\Cache::PERMANENT] = t('Forever');
$form['cache'] = array(
- '#type' => 'fieldset',
- '#title' => t('Cache'),
+ '#type' => 'details',
+ '#title' => t('Cache settings'),
);
$form['cache']['max_age'] = array(
'#type' => 'select',
'#title' => t('Maximum age'),
- '#description' => t('The maximum time a block can be cached.'),
+ '#description' => t('The maximum time this block may be cached.'),
'#default_value' => $this->configuration['cache']['max_age'],
'#options' => $period,
- '#fieldset' => 'cache',
);
- $cache_contexts = \Drupal::service("cache_contexts");
- $form['cache']['cache_contexts'] = array(
+ $form['cache']['contexts'] = array(
'#type' => 'select',
- '#multiple' => true,
- '#title' => t('Keys'),
- '#description' => t('Additional keys to vary the cache by.'),
- '#default_value' => $this->configuration['cache']['cache_contexts'],
- '#options' => $cache_contexts->getLabels(),
- '#fieldset' => 'cache',
+ '#multiple' => TRUE,
+ '#title' => t('Vary by context'),
+ '#description' => t('The contexts this cached block must be varied by.'),
+ '#default_value' => $this->configuration['cache']['contexts'],
+ '#options' => \Drupal::service("cache_contexts")->getLabels(),
+ '#states' => array(
+ 'disabled' => array(
+ ':input[name="settings[cache][max_age]"]' => array('value' => (string) 0),
+ ),
+ ),
);
// Add plugin-specific settings for this block type.
$form += $this->blockForm($form, $form_state);
@@ -237,7 +239,7 @@ public function getMachineNameSuggestion() {
* {@inheritdoc}
*/
public function getCacheKeys() {
- return array();
+ return $this->configuration['cache']['contexts'];
}
/**
@@ -272,13 +274,8 @@ public function isCacheable() {
// Similar to the page cache, a block is cacheable if it has a max age.
// Blocks that should never be cached can override this method to simply
// return FALSE.
- return $this->configuration['cache']['max_age'] > 0;
- }
-
- /**
- */
- public function getCacheContexts() {
- return $this->configuration['cache']['cache_contexts'];
+ $max_age = $this->configuration['cache']['max_age'];
+ return $max_age === Cache::PERMANENT || $max_age > 0;
}
}
diff --git a/core/modules/block/lib/Drupal/block/BlockViewBuilder.php b/core/modules/block/lib/Drupal/block/BlockViewBuilder.php
index 2554e7d..6fe8abc 100644
--- a/core/modules/block/lib/Drupal/block/BlockViewBuilder.php
+++ b/core/modules/block/lib/Drupal/block/BlockViewBuilder.php
@@ -85,11 +85,7 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la
$default_cache_keys = array('entity_view', 'block', $entity->id(), $entity->langcode);
$max_age = $plugin->getCacheMaxAge();
$build[$entity_id]['#cache'] += array(
- 'keys' => array_merge(
- $default_cache_keys,
- $plugin->getCacheKeys(),
- $plugin->getCacheContexts()
- ),
+ 'keys' => array_merge($default_cache_keys, $plugin->getCacheKeys()),
'bin' => $plugin->getCacheBin(),
'expire' => ($max_age === Cache::PERMANENT) ? Cache::PERMANENT : REQUEST_TIME + $max_age,
);
diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockCacheTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockCacheTest.php
index 0d4e2dd..ce78720 100644
--- a/core/modules/block/lib/Drupal/block/Tests/BlockCacheTest.php
+++ b/core/modules/block/lib/Drupal/block/Tests/BlockCacheTest.php
@@ -61,10 +61,13 @@ function setUp() {
}
/**
- * Test "user.current_user_roles" cache context.
+ * Test "cache_context.user.roles" cache context.
*/
function testCachePerRole() {
- $this->setCacheMode('user.current_user_roles');
+ $this->setBlockCacheConfig(array(
+ 'max_age' => 600,
+ 'contexts' => array('cache_context.user.roles'),
+ ));
// Enable our test block. Set some content for it to display.
$current_content = $this->randomName();
@@ -111,8 +114,10 @@ function testCachePerRole() {
* Test a cacheable block without any cache context.
*/
function testCacheGlobal() {
- $this->block->getPlugin()->setConfigurationValue('cache', array('max_age' => 600));
- $this->block->save();
+ $this->setBlockCacheConfig(array(
+ 'max_age' => 600,
+ ));
+
$current_content = $this->randomName();
\Drupal::state()->set('block_test.content', $current_content);
@@ -132,8 +137,9 @@ function testCacheGlobal() {
* Test non-cacheable block.
*/
function testNoCache() {
- $this->block->getPlugin()->setConfigurationValue('cache', array('max_age' => 0));
- $this->block->save();
+ $this->setBlockCacheConfig(array(
+ 'max_age' => 0,
+ ));
$current_content = $this->randomName();
\Drupal::state()->set('block_test.content', $current_content);
@@ -150,10 +156,14 @@ function testNoCache() {
}
/**
- * Test "user.current_user" cache context.
+ * Test "cache_context.user" cache context.
*/
function testCachePerUser() {
- $this->setCacheMode('user.current_user');
+ $this->setBlockCacheConfig(array(
+ 'max_age' => 600,
+ 'contexts' => array('cache_context.user'),
+ ));
+
$current_content = $this->randomName();
\Drupal::state()->set('block_test.content', $current_content);
$this->drupalLogin($this->normal_user);
@@ -178,10 +188,14 @@ function testCachePerUser() {
}
/**
- * Test "http.request_path" cache context.
+ * Test "cache_context.url" cache context.
*/
function testCachePerPage() {
- $this->setCacheMode('http.request_path');
+ $this->setBlockCacheConfig(array(
+ 'max_age' => 600,
+ 'contexts' => array('cache_context.url'),
+ ));
+
$current_content = $this->randomName();
\Drupal::state()->set('block_test.content', $current_content);
@@ -199,11 +213,11 @@ function testCachePerPage() {
}
/**
- * Private helper method to set the test block's cache mode.
+ * Private helper method to set the test block's cache configuration.
*/
- private function setCacheMode($cache_mode) {
+ private function setBlockCacheConfig($cache_config) {
$block = $this->block->getPlugin();
- $block->setConfigurationValue('cache', array('max_age' => 600, 'cache_contexts' => array($cache_mode)));
+ $block->setConfigurationValue('cache', $cache_config);
$this->block->save();
}
diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockInterfaceTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockInterfaceTest.php
index 7166ce0..240fc39 100644
--- a/core/modules/block/lib/Drupal/block/Tests/BlockInterfaceTest.php
+++ b/core/modules/block/lib/Drupal/block/Tests/BlockInterfaceTest.php
@@ -49,7 +49,7 @@ public function testBlockInterface() {
'label_display' => BlockInterface::BLOCK_LABEL_VISIBLE,
'cache' => array(
'max_age' => 0,
- 'cache_contexts' => array(),
+ 'contexts' => array(),
),
'display_message' => 'no message set',
);
@@ -91,24 +91,27 @@ public function testBlockInterface() {
'#return_value' => 'visible',
),
'cache' => array(
- '#type' => 'fieldset',
- '#title' => t('Cache'),
+ '#type' => 'details',
+ '#title' => t('Cache settings'),
'max_age' => array(
'#type' => 'select',
'#title' => t('Maximum age'),
- '#description' => t('The maximum time a block can be cached.'),
+ '#description' => t('The maximum time this block may be cached.'),
'#default_value' => 0,
'#options' => $period,
- '#fieldset' => 'cache',
),
- 'cache_contexts' => array(
+ 'contexts' => array(
'#type' => 'select',
- '#multiple' => true,
- '#title' => t('Keys'),
- '#description' => t('Additional keys to vary the cache by.'),
+ '#multiple' => TRUE,
+ '#title' => t('Vary by context'),
+ '#description' => t('The contexts this cached block must be varied by.'),
'#default_value' => array(),
'#options' => \Drupal::service("cache_contexts")->getLabels(),
- '#fieldset' => 'cache',
+ '#states' => array(
+ 'disabled' => array(
+ ':input[name="settings[cache][max_age]"]' => array('value' => (string) 0),
+ ),
+ ),
),
),
'display_message' => array(
diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockStorageUnitTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockStorageUnitTest.php
index 3e510b6..d95edca 100644
--- a/core/modules/block/lib/Drupal/block/Tests/BlockStorageUnitTest.php
+++ b/core/modules/block/lib/Drupal/block/Tests/BlockStorageUnitTest.php
@@ -104,7 +104,7 @@ protected function createTests() {
'label_display' => BlockInterface::BLOCK_LABEL_VISIBLE,
'cache' => array(
'max_age' => 0,
- 'cache_contexts' => array(),
+ 'contexts' => array(),
),
),
'visibility' => NULL,
diff --git a/core/modules/book/lib/Drupal/book/Plugin/Block/BookNavigationBlock.php b/core/modules/book/lib/Drupal/book/Plugin/Block/BookNavigationBlock.php
index e2cf674..333a255 100644
--- a/core/modules/book/lib/Drupal/book/Plugin/Block/BookNavigationBlock.php
+++ b/core/modules/book/lib/Drupal/book/Plugin/Block/BookNavigationBlock.php
@@ -155,8 +155,41 @@ public function build() {
/**
* {@inheritdoc}
*/
+ public function buildConfigurationForm(array $form, array &$form_state) {
+ $form = parent::buildConfigurationForm($form, $form_state);
+
+ // Remove the required cache contexts from the list of contexts a user can
+ // choose to modify by: they must always be applied.
+ $context_labels = array();
+ foreach ($this->getRequiredCacheContexts() as $context) {
+ $context_labels[] = $form['cache']['contexts']['#options'][$context];
+ unset($form['cache']['contexts']['#options'][$context]);
+ }
+ $required_context_list = implode(', ', $context_labels);
+ $form['cache']['contexts']['#description'] .= ' ' . t('This block is always varied by the following contexts: %required-context-list.', array('%required-context-list' => $required_context_list));
+
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
public function getCacheKeys() {
- return array(DRUPAL_CACHE_PER_PAGE, DRUPAL_CACHE_PER_ROLE);
+ // Return the required cache contexts, merged with the user-configured cache
+ // contexts, if any.
+ return array_merge($this->getRequiredCacheContexts(), parent::getCacheKeys());
+ }
+
+ /**
+ * Returns the cache contexts required for this block.
+ *
+ * Two cache contexts are required: cache by URL and by user's roles.
+ *
+ * @return array
+ * The required cache contexts IDs.
+ */
+ protected function getRequiredCacheContexts() {
+ return array('cache_context.url', 'cache_context.user.roles');
}
}
diff --git a/core/modules/forum/lib/Drupal/forum/Plugin/Block/ForumBlockBase.php b/core/modules/forum/lib/Drupal/forum/Plugin/Block/ForumBlockBase.php
index 972d2a8..6b760a9 100644
--- a/core/modules/forum/lib/Drupal/forum/Plugin/Block/ForumBlockBase.php
+++ b/core/modules/forum/lib/Drupal/forum/Plugin/Block/ForumBlockBase.php
@@ -84,7 +84,7 @@ public function blockSubmit($form, &$form_state) {
* {@inheritdoc}
*/
public function getCacheKeys() {
- return array(Cache::keyFromQuery($this->buildForumQuery()));
+ return array_merge(parent::getCacheKeys(), Cache::keyFromQuery($this->buildForumQuery()));
}
}
diff --git a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php
index 7d91859..52d7a02 100644
--- a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php
+++ b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php
@@ -47,8 +47,41 @@ public function defaultConfiguration() {
/**
* {@inheritdoc}
*/
+ public function buildConfigurationForm(array $form, array &$form_state) {
+ $form = parent::buildConfigurationForm($form, $form_state);
+
+ // Remove the required cache contexts from the list of contexts a user can
+ // choose to modify by: they must always be applied.
+ $context_labels = array();
+ foreach ($this->getRequiredCacheContexts() as $context) {
+ $context_labels[] = $form['cache']['contexts']['#options'][$context];
+ unset($form['cache']['contexts']['#options'][$context]);
+ }
+ $required_context_list = implode(', ', $context_labels);
+ $form['cache']['contexts']['#description'] .= ' ' . t('This block is always varied by the following contexts: %required-context-list.', array('%required-context-list' => $required_context_list));
+
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
public function getCacheKeys() {
- return array(DRUPAL_CACHE_PER_PAGE, DRUPAL_CACHE_PER_ROLE);
+ // Return the required cache contexts, merged with the user-configured cache
+ // contexts, if any.
+ return array_merge($this->getRequiredCacheContexts(), parent::getCacheKeys());
+ }
+
+ /**
+ * Returns the cache contexts required for this block.
+ *
+ * Two cache contexts are required: cache by URL and by user's roles.
+ *
+ * @return array
+ * The required cache contexts IDs.
+ */
+ protected function getRequiredCacheContexts() {
+ return array('cache_context.url', 'cache_context.user.roles');
}
}
diff --git a/core/modules/user/lib/Drupal/user/Cache/UserCacheContext.php b/core/modules/user/lib/Drupal/user/Cache/UserCacheContext.php
new file mode 100644
index 0000000..77b833e
--- /dev/null
+++ b/core/modules/user/lib/Drupal/user/Cache/UserCacheContext.php
@@ -0,0 +1,42 @@
+user = $user;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getLabel() {
+ return t('User');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getContext() {
+ return "u." . $this->user->id();
+ }
+
+}
diff --git a/core/modules/user/lib/Drupal/user/Cache/UserRolesCacheContext.php b/core/modules/user/lib/Drupal/user/Cache/UserRolesCacheContext.php
new file mode 100644
index 0000000..fb98c1a
--- /dev/null
+++ b/core/modules/user/lib/Drupal/user/Cache/UserRolesCacheContext.php
@@ -0,0 +1,42 @@
+user = $user;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getLabel() {
+ return t("User's roles");
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getContext() {
+ return 'r.' . implode(',', $this->user->getRoles());
+ }
+
+}
diff --git a/core/modules/user/lib/Drupal/user/CacheContexts.php b/core/modules/user/lib/Drupal/user/CacheContexts.php
deleted file mode 100644
index 027b4be..0000000
--- a/core/modules/user/lib/Drupal/user/CacheContexts.php
+++ /dev/null
@@ -1,38 +0,0 @@
-user = $user;
- }
-
- static function getCacheContexts() {
- return array(
- "user.current_user" => array(
- "callback" => "getCurrentUser",
- "label" => "Current user id",
- ),
- "user.current_user_roles" => array(
- "callback" => "getCurrentUserRoles",
- "label" => "Current user's roles",
- ),
- );
- }
-
- public function getCurrentUser() {
- return "u." . $this->user->id();
- }
-
- public function getCurrentUserRoles() {
- return 'r.' . implode(',', $this->user->getRoles());
- }
-
-}
diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml
index e444cf9..8a0db43 100644
--- a/core/modules/user/user.services.yml
+++ b/core/modules/user/user.services.yml
@@ -15,8 +15,13 @@ services:
class: Drupal\user\Access\LoginStatusCheck
tags:
- { name: access_check, applies_to: _user_is_logged_in }
- user.cache.contexts:
- class: Drupal\user\CacheContexts
+ cache_context.user:
+ class: Drupal\user\Cache\UserCacheContext
+ arguments: ['@current_user']
+ tags:
+ - { name: cache.context}
+ cache_context.user.roles:
+ class: Drupal\user\Cache\UserRolesCacheContext
arguments: ['@current_user']
tags:
- { name: cache.context}
diff --git a/core/tests/Drupal/Tests/Core/Cache/CacheContextsTest.php b/core/tests/Drupal/Tests/Core/Cache/CacheContextsTest.php
index f1bc656..2ed2cd6 100644
--- a/core/tests/Drupal/Tests/Core/Cache/CacheContextsTest.php
+++ b/core/tests/Drupal/Tests/Core/Cache/CacheContextsTest.php
@@ -2,23 +2,38 @@
/**
* @file
- * Contains Drupal\Tests\Core\Cache\CacheContextsTest.
+ * Contains \Drupal\Tests\Core\Cache\CacheContextsTest.
*/
namespace Drupal\Tests\Core\Cache;
use Drupal\Core\Cache\CacheContexts;
+use Drupal\Core\Cache\CacheContextInterface;
/**
* Fake cache context class.
*/
-class SomeClass {
- function someMethod() {
- return "foo";
+class FooCacheContext implements CacheContextInterface {
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getLabel() {
+ return 'Foo';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getContext() {
+ return 'bar';
}
+
}
/**
+ * Tests the CacheContexts service.
+ *
* @group Cache
*
* @see \Drupal\Core\Cache\CacheContexts
@@ -33,44 +48,44 @@ public static function getInfo() {
);
}
- public function testContextPlaceholdersAreReplaced() {
+ public function atestContextPlaceholdersAreReplaced() {
$container = $this->getMockContainer();
$container->expects($this->once())
->method("get")
- ->with("some_service")
- ->will($this->returnValue(new SomeClass));
+ ->with("cache_context.foo")
+ ->will($this->returnValue(new FooCacheContext()));
$cache_contexts = new CacheContexts($container, $this->getContextsFixture());
- $new_keys = $cache_contexts->addContextsToKeys(
- array("non-cache-context", "somemodule.some_context")
+ $new_keys = $cache_contexts->convertTokensToKeys(
+ array("non-cache-context", "cache_context.foo")
);
- $expected = array("non-cache-context", "foo");
+ $expected = array("non-cache-context", "bar");
$this->assertEquals($expected, $new_keys);
}
public function testAvailableContextStrings() {
$cache_contexts = new CacheContexts($this->getMockContainer(), $this->getContextsFixture());
$contexts = $cache_contexts->getAll();
- $this->assertEquals(array("somemodule.some_context"), $contexts);
+ $this->assertEquals(array("cache_context.foo"), $contexts);
}
- public function testAvailableContextLabels() {
+ public function atestAvailableContextLabels() {
+ $container = $this->getMockContainer();
+ $container->expects($this->once())
+ ->method("get")
+ ->with("cache_context.foo")
+ ->will($this->returnValue(new FooCacheContext()));
+
$cache_contexts = new CacheContexts($this->getMockContainer(), $this->getContextsFixture());
$labels = $cache_contexts->getLabels();
- $expected = array("somemodule.some_context" => "Some label");
+ $expected = array("cache_context.foo" => "Foo");
$this->assertEquals($expected, $labels);
}
protected function getContextsFixture() {
- return array(
- "somemodule.some_context" => array(
- "service" => "some_service",
- "callback" => "someMethod",
- "label" => "Some label",
- )
- );
+ return array('cache_context.foo');
}
protected function getMockContainer() {