core/includes/common.inc | 12 ++- .../Core/Page/DefaultHtmlFragmentRenderer.php | 10 +-- .../Tests/CommentDefaultFormatterCacheTagsTest.php | 2 +- core/modules/system/src/Form/ThemeSettingsForm.php | 2 +- .../src/Tests/Cache/PageCacheTagsTestBase.php | 2 +- core/tests/Drupal/Tests/Core/Cache/CacheTest.php | 85 ++++++++++++++++++++++ 6 files changed, 97 insertions(+), 16 deletions(-) diff --git a/core/includes/common.inc b/core/includes/common.inc index 877f623..24ac99a 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -3115,16 +3115,14 @@ function drupal_render_cache_set(&$markup, array $elements) { $data['#post_render_cache'] = $elements['#post_render_cache']; } - // Tag every render cache item with the "rendered" cache tag. This allows us - // to invalidate the entire render cache, regardless of the cache bin. - $cache_tags = Cache::mergeTags($elements['#cache']['tags'] ?: [], ['rendered']); - - // Persist cache tags associated with this element. - $data['#cache']['tags'] = $cache_tags; + // Persist cache tags associated with this element. Also associate the + // "rendered" cache tag. This allows us to invalidate the entire render cache, + // regardless of the cache bin. + $data['#cache']['tags'] = Cache::mergeTags($elements['#cache']['tags'], ['rendered']); $bin = isset($elements['#cache']['bin']) ? $elements['#cache']['bin'] : 'render'; $expire = isset($elements['#cache']['expire']) ? $elements['#cache']['expire'] : Cache::PERMANENT; - \Drupal::cache($bin)->set($cid, $data, $expire, $cache_tags); + \Drupal::cache($bin)->set($cid, $data, $expire, $data['#cache']['tags']); } /** diff --git a/core/lib/Drupal/Core/Page/DefaultHtmlFragmentRenderer.php b/core/lib/Drupal/Core/Page/DefaultHtmlFragmentRenderer.php index d7b5531..77bfc3c 100644 --- a/core/lib/Drupal/Core/Page/DefaultHtmlFragmentRenderer.php +++ b/core/lib/Drupal/Core/Page/DefaultHtmlFragmentRenderer.php @@ -69,12 +69,10 @@ public function render(HtmlFragmentInterface $fragment, $status_code = 200) { } if ($fragment instanceof CacheableInterface) { - // Collect cache tags for all the content in all the regions on the page. - $tags = $page_array['#cache']['tags']; - // Tag every render cache item with the "rendered" cache tag. This allows us - // to invalidate the entire render cache, regardless of the cache bin. - $tags = Cache::mergeTags($tags, ['rendered']); - $page->setCacheTags($tags); + // Persist cache tags associated with this page. Also associate the + // "rendered" cache tag. This allows us to invalidate the entire render + // cache, regardless of the cache bin. + $page->setCacheTags(Cache::mergeTags($page_array['#cache']['tags'], ['rendered'])); } return $page; diff --git a/core/modules/comment/src/Tests/CommentDefaultFormatterCacheTagsTest.php b/core/modules/comment/src/Tests/CommentDefaultFormatterCacheTagsTest.php index bc4466d..9c14685 100644 --- a/core/modules/comment/src/Tests/CommentDefaultFormatterCacheTagsTest.php +++ b/core/modules/comment/src/Tests/CommentDefaultFormatterCacheTagsTest.php @@ -111,7 +111,7 @@ public function testCacheTags() { 'user:2', ); sort($expected_cache_tags); - $this->assertEqual($build['#cache']['tags'], $expected_cache_tags); //, 'The test entity has the expected cache tags when it has comments.'); + $this->assertEqual($build['#cache']['tags'], $expected_cache_tags, 'The test entity has the expected cache tags when it has comments.'); } } diff --git a/core/modules/system/src/Form/ThemeSettingsForm.php b/core/modules/system/src/Form/ThemeSettingsForm.php index 7859138..fb4df2a 100644 --- a/core/modules/system/src/Form/ThemeSettingsForm.php +++ b/core/modules/system/src/Form/ThemeSettingsForm.php @@ -426,7 +426,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { // Invalidate either the theme-specific cache tag or the global theme // settings cache tag, depending on whose settings were actually changed. if (isset($values['theme'])) { - Cache::invalidateTags(array('theme:')); + Cache::invalidateTags(array('theme:' . $values['theme'])); } else { Cache::invalidateTags(array('theme_global_settings')); diff --git a/core/modules/system/src/Tests/Cache/PageCacheTagsTestBase.php b/core/modules/system/src/Tests/Cache/PageCacheTagsTestBase.php index de97aab..f3a0d76 100644 --- a/core/modules/system/src/Tests/Cache/PageCacheTagsTestBase.php +++ b/core/modules/system/src/Tests/Cache/PageCacheTagsTestBase.php @@ -14,7 +14,7 @@ * Provides helper methods for page cache tags tests. */ abstract class PageCacheTagsTestBase extends WebTestBase { -protected $dumpHeaders = TRUE; + /** * {@inheritdoc} */ diff --git a/core/tests/Drupal/Tests/Core/Cache/CacheTest.php b/core/tests/Drupal/Tests/Core/Cache/CacheTest.php new file mode 100644 index 0000000..612899d --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Cache/CacheTest.php @@ -0,0 +1,85 @@ +setExpectedException('LogicException', $expected_exception_message); + } + Cache::validateTags($tags); + } + + /** + * Provides a list of pairs of cache tags arrays to be merged. + * + * @return array + */ + public function mergeTagsProvider() { + return [ + [[], [], []], + [['bar'], ['foo'], ['bar', 'foo']], + [['foo'], ['bar'], ['bar', 'foo']], + [['foo'], ['bar', 'foo'], ['bar', 'foo']], + [['foo'], ['foo', 'bar'], ['bar', 'foo']], + [['bar', 'foo'], ['foo', 'bar'], ['bar', 'foo']], + [['foo', 'bar'], ['foo', 'bar'], ['bar', 'foo']], + ]; + } + + /** + * @covers mergeTags + * + * @dataProvider mergeTagsProvider + */ + public function testMergeTags(array $a, array $b, array $expected) { + $this->assertEquals($expected, Cache::mergeTags($a, $b)); + } + +}