From 0f8684f79bba742c767073ecd96473770ae42a19 Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Thu, 10 Dec 2015 15:31:33 +0000 Subject: [PATCH] Issue #2619332 by joelpittet, jmarkel, Wim Leers, Berdir, chintan.vyas, netsensei: Color scheme config changes aren't reflected in cached pages --- core/modules/color/color.module | 12 ++-- core/modules/color/color.services.yml | 6 ++ .../ColorConfigCacheInvalidator.php | 61 +++++++++++++++++++ core/modules/color/src/Tests/ColorTest.php | 41 ++++++++++++- .../Tests/PageCacheTagsIntegrationTest.php | 2 + 5 files changed, 115 insertions(+), 7 deletions(-) create mode 100644 core/modules/color/color.services.yml create mode 100644 core/modules/color/src/EventSubscriber/ColorConfigCacheInvalidator.php diff --git a/core/modules/color/color.module b/core/modules/color/color.module index dd48e4ac0eab..15619ff4c023 100644 --- a/core/modules/color/color.module +++ b/core/modules/color/color.module @@ -9,7 +9,7 @@ use Drupal\Component\Utility\Bytes; use Drupal\Component\Utility\Environment; use Drupal\Core\Block\BlockPluginInterface; -use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Render\Element\Textfield; @@ -118,9 +118,13 @@ function color_block_view_system_branding_block_alter(array &$build, BlockPlugin */ function color_block_view_pre_render(array $build) { $theme_key = \Drupal::theme()->getActiveTheme()->getName(); + $config = \Drupal::config('color.theme.' . $theme_key); + CacheableMetadata::createFromRenderArray($build) + ->addCacheableDependency($config) + ->applyTo($build); // Override logo. - $logo = \Drupal::config('color.theme.' . $theme_key)->get('logo'); + $logo = $config->get('logo'); if ($logo && $build['content']['site_logo'] && preg_match('!' . $theme_key . '/logo.svg$!', $build['content']['site_logo']['#uri'])) { $build['content']['site_logo']['#uri'] = file_create_url($logo); } @@ -193,7 +197,6 @@ function color_get_palette($theme, $default = FALSE) { * @see color_scheme_form_submit() */ function color_scheme_form($complete_form, FormStateInterface $form_state, $theme) { - $base = drupal_get_path('module', 'color'); $info = color_get_info($theme); $info['schemes'][''] = array('title' => t('Custom'), 'colors' => array()); @@ -500,9 +503,6 @@ function color_scheme_form_submit($form, FormStateInterface $form_state) { ->set('stylesheets', $css) ->set('files', $paths['files']) ->save(); - - // Clear the library cache. - Cache::invalidateTags(['library_info']); } /** diff --git a/core/modules/color/color.services.yml b/core/modules/color/color.services.yml new file mode 100644 index 000000000000..9575785b6bb3 --- /dev/null +++ b/core/modules/color/color.services.yml @@ -0,0 +1,6 @@ +services: + color.config_cache_invalidator: + class: Drupal\color\EventSubscriber\ColorConfigCacheInvalidator + arguments: ['@cache_tags.invalidator'] + tags: + - { name: event_subscriber } diff --git a/core/modules/color/src/EventSubscriber/ColorConfigCacheInvalidator.php b/core/modules/color/src/EventSubscriber/ColorConfigCacheInvalidator.php new file mode 100644 index 000000000000..3af8d404239e --- /dev/null +++ b/core/modules/color/src/EventSubscriber/ColorConfigCacheInvalidator.php @@ -0,0 +1,61 @@ +<?php + +/** + * @file + * Contains \Drupal\color\EventSubscriber\ColorConfigCacheInvalidator. + */ + +namespace Drupal\color\EventSubscriber; + +use Drupal\Core\Cache\CacheTagsInvalidatorInterface; +use Drupal\Core\Config\ConfigCrudEvent; +use Drupal\Core\Config\ConfigEvents; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * A subscriber invalidating cache tags when color config objects are saved. + */ +class ColorConfigCacheInvalidator implements EventSubscriberInterface { + + /** + * The cache tags invalidator. + * + * @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface + */ + protected $cacheTagsInvalidator; + + /** + * Constructs a ColorConfigCacheInvalidator object. + * + * @param \Drupal\Core\Cache\CacheTagsInvalidatorInterface $cache_tags_invalidator + * The cache tags invalidator. + */ + public function __construct(CacheTagsInvalidatorInterface $cache_tags_invalidator) { + $this->cacheTagsInvalidator = $cache_tags_invalidator; + } + + /** + * Invalidate cache tags when a color theme config object changes. + * + * @param \Drupal\Core\Config\ConfigCrudEvent $event + * The Event to process. + */ + public function onChange(ConfigCrudEvent $event) { + // Changing a theme's color settings causes the theme's asset library + // containing the color CSS file to be altered to use a different file. + if (strpos($event->getConfig()->getName(), 'color.theme.') === 0) { + $this->cacheTagsInvalidator->invalidateTags(['library_info']); + } + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events[ConfigEvents::SAVE][] = ['onChange']; + $events[ConfigEvents::DELETE][] = ['onChange']; + + return $events; + } + +} diff --git a/core/modules/color/src/Tests/ColorTest.php b/core/modules/color/src/Tests/ColorTest.php index 1d1b72e334e8..b5ed67aba60a 100644 --- a/core/modules/color/src/Tests/ColorTest.php +++ b/core/modules/color/src/Tests/ColorTest.php @@ -22,7 +22,7 @@ class ColorTest extends WebTestBase { * * @var array */ - public static $modules = array('color', 'color_test'); + public static $modules = array('color', 'color_test', 'block'); /** * A user with administrative permissions. @@ -194,4 +194,43 @@ function testLogoSettingOverride() { $this->assertIdentical($GLOBALS['base_url'] . '/' . 'core/misc/druplicon.png', $this->getDrupalSettings()['color']['logo']); } + /** + * Test whether the scheme can be set, viewed anonymously and reset. + */ + function testOverrideAndResetScheme() { + $settings_path = 'admin/appearance/settings/bartik'; + $this->config('system.theme') + ->set('default', 'bartik') + ->save(); + + // Place branding block with site name and slogan into header region. + $this->drupalPlaceBlock('system_branding_block', ['region' => 'header']); + + $this->drupalGet(''); + $this->assertNoRaw('files/color/bartik-', 'Make sure the color logo is not being used.'); + $this->assertRaw('bartik/logo.svg', 'Make sure the original bartik logo exists.'); + + // Log in and set the color scheme to 'slate'. + $this->drupalLogin($this->bigUser); + $edit['scheme'] = 'slate'; + $this->drupalPostForm($settings_path, $edit, t('Save configuration')); + + // Visit the homepage and ensure color changes. + $this->drupalLogout(); + $this->drupalGet(''); + $this->assertRaw('files/color/bartik-', 'Make sure the color logo is being used.'); + $this->assertNoRaw('bartik/logo.svg', 'Make sure the original bartik logo does not exist.'); + + // Log in and set the color scheme back to default (delete config). + $this->drupalLogin($this->bigUser); + $edit['scheme'] = 'default'; + $this->drupalPostForm($settings_path, $edit, t('Save configuration')); + + // Log out and ensure there is no color and we have the original logo. + $this->drupalLogout(); + $this->drupalGet(''); + $this->assertNoRaw('files/color/bartik-', 'Make sure the color logo is not being used.'); + $this->assertRaw('bartik/logo.svg', 'Make sure the original bartik logo exists.'); + } + } diff --git a/core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php b/core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php index 22ae7b2b4051..ab1c8f2ca79e 100644 --- a/core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php +++ b/core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php @@ -105,6 +105,7 @@ function testPageCacheTags() { 'user:0', 'user:' . $author_1->id(), 'config:filter.format.basic_html', + 'config:color.theme.bartik', 'config:search.settings', 'config:system.menu.account', 'config:system.menu.tools', @@ -142,6 +143,7 @@ function testPageCacheTags() { 'node_view', 'node:' . $node_2->id(), 'user:' . $author_2->id(), + 'config:color.theme.bartik', 'config:filter.format.full_html', 'config:search.settings', 'config:system.menu.account', -- GitLab