core/modules/block/lib/Drupal/block/BlockBase.php | 26 ++++++++++++-
.../book/Plugin/Block/BookNavigationBlock.php | 36 ++----------------
.../lib/Drupal/search/Form/SearchBlockForm.php | 9 +++++
.../Drupal/system/Plugin/Block/SystemHelpBlock.php | 22 +++++------
.../Drupal/system/Plugin/Block/SystemMenuBlock.php | 29 ++------------
.../UserLoginBlockConfigChangeSubscriber.php | 40 ++++++++++++++++++++
.../Drupal/user/Plugin/Block/UserLoginBlock.php | 9 +++++
core/modules/user/user.services.yml | 4 ++
8 files changed, 104 insertions(+), 71 deletions(-)
diff --git a/core/modules/block/lib/Drupal/block/BlockBase.php b/core/modules/block/lib/Drupal/block/BlockBase.php
index 99150cf..2dd5cde 100644
--- a/core/modules/block/lib/Drupal/block/BlockBase.php
+++ b/core/modules/block/lib/Drupal/block/BlockBase.php
@@ -161,6 +161,18 @@ public function buildConfigurationForm(array $form, array &$form_state) {
),
),
);
+ if (count($this->getRequiredCacheContexts()) > 0) {
+ // 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));
+ }
+
// Add plugin-specific settings for this block type.
$form += $this->blockForm($form, $form_state);
return $form;
@@ -242,10 +254,22 @@ public function getMachineNameSuggestion() {
}
/**
+ * Returns the cache contexts required for this block.
+ *
+ * @return array
+ * The required cache contexts IDs.
+ */
+ protected function getRequiredCacheContexts() {
+ return array();
+ }
+
+ /**
* {@inheritdoc}
*/
public function getCacheKeys() {
- return $this->configuration['cache']['contexts'];
+ // Return the required cache contexts, merged with the user-configured cache
+ // contexts, if any.
+ return array_merge($this->getRequiredCacheContexts(), $this->configuration['cache']['contexts']);
}
/**
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 333a255..6a9cfff 100644
--- a/core/modules/book/lib/Drupal/book/Plugin/Block/BookNavigationBlock.php
+++ b/core/modules/book/lib/Drupal/book/Plugin/Block/BookNavigationBlock.php
@@ -155,40 +155,10 @@ 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 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() {
+ // The "Book navigation" block must be cached per URL and per role: the
+ // "active" menu link may differ per URL and different roles may have access
+ // to different menu links.
return array('cache_context.url', 'cache_context.user.roles');
}
diff --git a/core/modules/search/lib/Drupal/search/Form/SearchBlockForm.php b/core/modules/search/lib/Drupal/search/Form/SearchBlockForm.php
index ad96735..0635eb0 100644
--- a/core/modules/search/lib/Drupal/search/Form/SearchBlockForm.php
+++ b/core/modules/search/lib/Drupal/search/Form/SearchBlockForm.php
@@ -103,4 +103,13 @@ public function submitForm(array &$form, array &$form_state) {
}
}
+ /**
+ * {@inheritdoc}
+ */
+ public function defaultConfiguration() {
+ // This is a block containing a simple form without state, which is safe to
+ // cache forever.
+ return array('cache' => array('max_age' => \Drupal\Core\Cache\Cache::PERMANENT));
+ }
+
}
diff --git a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemHelpBlock.php b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemHelpBlock.php
index 89a859d..c594b98 100644
--- a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemHelpBlock.php
+++ b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemHelpBlock.php
@@ -120,23 +120,21 @@ public function build() {
/**
* {@inheritdoc}
*/
- public function buildConfigurationForm(array $form, array &$form_state) {
- $form = parent::buildConfigurationForm($form, $form_state);
-
- // The help block is never cacheable, because it is path-specific.
- $form['cache']['#disabled'] = TRUE;
- $form['cache']['#description'] = t('This block is never cacheable, it is not configurable.');
- $form['cache']['max_age']['#value'] = 0;
-
- return $form;
+ public function defaultConfiguration() {
+ // Modify the default max age for the System Help block: help text is static
+ // for a given URL, except when a module is updated, in which case
+ // update.php must be run, which clears all caches. Thus it's safe to cache
+ // the output for this block forever on a per-URL basis.
+ return array('cache' => array('max_age' => \Drupal\Core\Cache\Cache::PERMANENT));
}
/**
* {@inheritdoc}
*/
- public function isCacheable() {
- // The help block is never cacheable, because it is path-specific.
- return FALSE;
+ protected function getRequiredCacheContexts() {
+ // The "System Help" block must be cached per URL: help is defined for a
+ // given path, and does not come with any access restrictions.
+ return array('cache_context.url');
}
}
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 c3b5463..b6d1316 100644
--- a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php
+++ b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php
@@ -48,25 +48,6 @@ 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 the required cache contexts, merged with the user-configured cache
// contexts, if any.
@@ -86,14 +67,12 @@ public function getCacheTags() {
}
/**
- * 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.
+ * {@inheritdoc}
*/
protected function getRequiredCacheContexts() {
+ // Menu blocks must be cached per URL and per role: the "active" menu link
+ // may differ per URL and different roles may have access to different menu
+ // links.
return array('cache_context.url', 'cache_context.user.roles');
}
diff --git a/core/modules/user/lib/Drupal/user/EventSubscriber/UserLoginBlockConfigChangeSubscriber.php b/core/modules/user/lib/Drupal/user/EventSubscriber/UserLoginBlockConfigChangeSubscriber.php
new file mode 100644
index 0000000..d307dee
--- /dev/null
+++ b/core/modules/user/lib/Drupal/user/EventSubscriber/UserLoginBlockConfigChangeSubscriber.php
@@ -0,0 +1,40 @@
+getConfig()->getName() === 'user.settings' && $event->isChanged('register')) {
+ Cache::invalidateTags(array('block_plugin' => array('user_login_block')));
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ static function getSubscribedEvents() {
+ $events[ConfigEvents::SAVE][] = array('onConfigSave', 0);
+ return $events;
+ }
+
+}
diff --git a/core/modules/user/lib/Drupal/user/Plugin/Block/UserLoginBlock.php b/core/modules/user/lib/Drupal/user/Plugin/Block/UserLoginBlock.php
index c087889..19266ab 100644
--- a/core/modules/user/lib/Drupal/user/Plugin/Block/UserLoginBlock.php
+++ b/core/modules/user/lib/Drupal/user/Plugin/Block/UserLoginBlock.php
@@ -64,4 +64,13 @@ public function build() {
);
}
+ /**
+ * {@inheritdoc}
+ */
+ public function defaultConfiguration() {
+ // This is a block containing a simple form without state, which is safe to
+ // cache forever.
+ return array('cache' => array('max_age' => \Drupal\Core\Cache\Cache::PERMANENT));
+ }
+
}
diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml
index 7f73ccc..45af7f1 100644
--- a/core/modules/user/user.services.yml
+++ b/core/modules/user/user.services.yml
@@ -35,6 +35,10 @@ services:
class: Drupal\user\EventSubscriber\MaintenanceModeSubscriber
tags:
- { name: event_subscriber }
+ user_login_block_config_change_subscriber:
+ class: Drupal\user\EventSubscriber\UserLoginBlockConfigChangeSubscriber
+ tags:
+ - { name: event_subscriber }
theme.negotiator.admin_theme:
class: Drupal\user\Theme\AdminNegotiator
arguments: ['@current_user', '@config.factory', '@entity.manager']