core/includes/theme.inc | 16 ++++++++++++++++ .../Drupal/Core/Page/DefaultHtmlFragmentRenderer.php | 5 +++-- core/modules/block/lib/Drupal/block/Entity/Block.php | 3 +-- .../modules/block/lib/Drupal/block/Tests/BlockTest.php | 6 ++++-- .../menu/lib/Drupal/menu/Tests/MenuCacheTagsTest.php | 5 +++-- .../lib/Drupal/system/Form/ThemeSettingsForm.php | 10 ++++++++++ .../Drupal/system/Tests/Bootstrap/PageCacheTest.php | 9 ++++++++- .../Tests/Cache/PageCacheTagsIntegrationTest.php | 2 ++ .../system/Tests/Entity/EntityCacheTagsTestBase.php | 15 ++++++++------- core/modules/system/system.module | 1 + 10 files changed, 56 insertions(+), 16 deletions(-) diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 178702b..ac6d77f 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -1925,6 +1925,22 @@ function drupal_pre_render_html(array $element) { return $element; } + +/** + * #pre_render callback for the page element type. + * + * @param array $element + * A structured array containing the page element type build properties. + * + * @see system_element_info() + */ +function drupal_pre_render_page(array $element) { + global $theme; + $element['#cache']['tags']['theme'] = $theme; + $element['#cache']['tags']['theme_global_settings'] = TRUE; + return $element; +} + /** * Prepares variables for HTML document templates. * diff --git a/core/lib/Drupal/Core/Page/DefaultHtmlFragmentRenderer.php b/core/lib/Drupal/Core/Page/DefaultHtmlFragmentRenderer.php index 18f21f9..8de2067 100644 --- a/core/lib/Drupal/Core/Page/DefaultHtmlFragmentRenderer.php +++ b/core/lib/Drupal/Core/Page/DefaultHtmlFragmentRenderer.php @@ -36,7 +36,6 @@ public function __construct(LanguageManager $language_manager) { * {@inheritdoc} */ public function render(HtmlFragment $fragment, $status_code = 200) { - global $theme; // Converts the given HTML fragment which represents the main content region // of the page into a render array. $page_content['main'] = array( @@ -57,7 +56,9 @@ public function render(HtmlFragment $fragment, $status_code = 200) { $page->setContent(drupal_render($page_array)); // Collect cache tags for all the content in all the regions on the page. $tags = $page_array['#cache']['tags']; - $tags['theme'] = $theme; + // Enforce the generic "content" cache tag on all pages. + // @todo Remove the "content" cache tag. @see https://drupal.org/node/2124957 + $tags['content'] = TRUE; $page->setCacheTags($tags); $page->setStatusCode($status_code); diff --git a/core/modules/block/lib/Drupal/block/Entity/Block.php b/core/modules/block/lib/Drupal/block/Entity/Block.php index 6baeebd..aa9141c 100644 --- a/core/modules/block/lib/Drupal/block/Entity/Block.php +++ b/core/modules/block/lib/Drupal/block/Entity/Block.php @@ -152,7 +152,6 @@ public function toArray() { * {@inheritdoc} */ public function postSave(EntityStorageInterface $storage, $update = TRUE) { - global $theme; parent::postSave($storage, $update); if ($update) { @@ -161,7 +160,7 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) { // When placing a new block, invalidate all cache entries for this theme, // since any page that uses this theme might be affected. else { - Cache::invalidateTags(array('theme' => $theme)); + Cache::invalidateTags(array('theme' => $this->theme)); } } diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockTest.php index bee1a48..734c2be 100644 --- a/core/modules/block/lib/Drupal/block/Tests/BlockTest.php +++ b/core/modules/block/lib/Drupal/block/Tests/BlockTest.php @@ -281,11 +281,12 @@ public function testBlockCacheTags() { $cid = sha1(implode(':', $cid_parts)); $cache_entry = \Drupal::cache('render')->get($cid); $expected_cache_tags = array( + 'theme:stark', + 'theme_global_settings:1', 'content:1', 'block_view:1', 'block:powered', 'block_plugin:system_powered_by_block', - 'theme:stark', ); $this->assertIdentical($cache_entry->tags, $expected_cache_tags); $cache_entry = \Drupal::cache('render')->get('entity_view:block:powered:en:stark'); @@ -319,12 +320,13 @@ public function testBlockCacheTags() { $cid = sha1(implode(':', $cid_parts)); $cache_entry = \Drupal::cache('render')->get($cid); $expected_cache_tags = array( + 'theme:stark', + 'theme_global_settings:1', 'content:1', 'block_view:1', 'block:powered-2', 'block:powered', 'block_plugin:system_powered_by_block', - 'theme:stark', ); $this->assertEqual($cache_entry->tags, $expected_cache_tags); $expected_cache_tags = array( diff --git a/core/modules/menu/lib/Drupal/menu/Tests/MenuCacheTagsTest.php b/core/modules/menu/lib/Drupal/menu/Tests/MenuCacheTagsTest.php index 2b0dfcb..029bd00 100644 --- a/core/modules/menu/lib/Drupal/menu/Tests/MenuCacheTagsTest.php +++ b/core/modules/menu/lib/Drupal/menu/Tests/MenuCacheTagsTest.php @@ -59,12 +59,13 @@ public function testMenuBlock() { // Verify a cache hit, but also the presence of the correct cache tags. $expected_tags = array( + 'theme:stark', + 'theme_global_settings:1', 'content:1', 'block_view:1', 'block:' . $block->id(), 'block_plugin:system_menu_block__llama', 'menu:llama', - 'theme:stark', ); $this->verifyPageCache($path, 'HIT', $expected_tags); @@ -118,7 +119,7 @@ public function testMenuBlock() { $this->verifyPageCache($path, 'MISS'); // Verify a cache hit. - $this->verifyPageCache($path, 'HIT', array('theme:stark')); + $this->verifyPageCache($path, 'HIT', array('content:1', 'theme:stark', 'theme_global_settings:1')); } } diff --git a/core/modules/system/lib/Drupal/system/Form/ThemeSettingsForm.php b/core/modules/system/lib/Drupal/system/Form/ThemeSettingsForm.php index 9459aad..8367a03 100644 --- a/core/modules/system/lib/Drupal/system/Form/ThemeSettingsForm.php +++ b/core/modules/system/lib/Drupal/system/Form/ThemeSettingsForm.php @@ -418,6 +418,16 @@ public function submitForm(array &$form, array &$form_state) { theme_settings_convert_to_config($values, $config)->save(); + // 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' => $values['bartik'])); + } + else { + Cache::invalidateTags(array('theme_global_settings' => TRUE)); + } + + // @todo Remove this in https://drupal.org/node/2124957. Cache::invalidateTags(array('content' => TRUE)); } diff --git a/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php b/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php index 2d36baa..7f6b6a0 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php @@ -66,7 +66,14 @@ function testPageCacheTags() { $cid = sha1(implode(':', $cid_parts)); $cache_entry = \Drupal::cache('render')->get($cid); sort($cache_entry->tags); - $this->assertIdentical($cache_entry->tags, array('pre_render:1', 'system_test_cache_tags_page:1', 'theme:stark')); + $expected_tags = array( + 'content:1', + 'pre_render:1', + 'system_test_cache_tags_page:1', + 'theme:stark', + 'theme_global_settings:1', + ); + $this->assertIdentical($cache_entry->tags, $expected_tags); Cache::invalidateTags($tags); $this->drupalGet($path); diff --git a/core/modules/system/lib/Drupal/system/Tests/Cache/PageCacheTagsIntegrationTest.php b/core/modules/system/lib/Drupal/system/Tests/Cache/PageCacheTagsIntegrationTest.php index 4b39bcb..f9f76ac 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Cache/PageCacheTagsIntegrationTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Cache/PageCacheTagsIntegrationTest.php @@ -78,6 +78,7 @@ function testPageCacheTags() { $this->verifyPageCacheTags('node/' . $node_1->id(), array( 'content:1', 'theme:bartik', + 'theme_global_settings:1', 'block_view:1', 'block:bartik_content', 'block:bartik_tools', @@ -102,6 +103,7 @@ function testPageCacheTags() { $this->verifyPageCacheTags('node/' . $node_2->id(), array( 'content:1', 'theme:bartik', + 'theme_global_settings:1', 'block_view:1', 'block:bartik_content', 'block:bartik_tools', diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCacheTagsTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCacheTagsTestBase.php index b6c25b1..5112cc2 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCacheTagsTestBase.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCacheTagsTestBase.php @@ -210,6 +210,8 @@ public function testReferencedEntity() { $non_referencing_entity_path = $this->non_referencing_entity->getSystemPath(); $listing_path = 'entity_test/list/' . $entity_type . '_reference/' . $entity_type . '/' . $this->entity->id(); + $theme_cache_tags = array('content:1', 'theme:stark', 'theme_global_settings:1'); + // Generate the standardized entity cache tags. $cache_tag = $entity_type . ':' . $this->entity->id(); $view_cache_tag = $entity_type . '_view:1'; @@ -232,7 +234,7 @@ public function testReferencedEntity() { $this->verifyPageCache($referencing_entity_path, 'MISS'); // Verify a cache hit, but also the presence of the correct cache tags. - $tags = array_merge(array('theme:stark'), $referencing_entity_cache_tags); + $tags = array_merge($theme_cache_tags, $referencing_entity_cache_tags); $this->verifyPageCache($referencing_entity_path, 'HIT', $tags); // Also verify the existence of an entity render cache entry. @@ -245,7 +247,7 @@ public function testReferencedEntity() { $this->verifyPageCache($non_referencing_entity_path, 'MISS'); // Verify a cache hit, but also the presence of the correct cache tags. - $tags = array_merge(array('theme:stark'), $non_referencing_entity_cache_tags); + $tags = array_merge($theme_cache_tags, $non_referencing_entity_cache_tags); $this->verifyPageCache($non_referencing_entity_path, 'HIT', $tags); // Also verify the existence of an entity render cache entry. @@ -259,7 +261,7 @@ public function testReferencedEntity() { $this->verifyPageCache($listing_path, 'MISS'); // Verify a cache hit, but also the presence of the correct cache tags. - $tags = array_merge(array('theme:stark'), $referencing_entity_cache_tags); + $tags = array_merge($theme_cache_tags, $referencing_entity_cache_tags); $this->verifyPageCache($listing_path, 'HIT', $tags); @@ -407,13 +409,12 @@ public function testReferencedEntity() { $this->verifyPageCache($non_referencing_entity_path, 'HIT'); // Verify cache hits. - $tags = array( + $tags = array_merge($theme_cache_tags, array( 'entity_test_view:1', 'entity_test:' . $this->referencing_entity->id(), - 'theme:stark', - ); + )); $this->verifyPageCache($referencing_entity_path, 'HIT', $tags); - $this->verifyPageCache($listing_path, 'HIT', array('theme:stark')); + $this->verifyPageCache($listing_path, 'HIT', $theme_cache_tags); } } diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 7b35fca..e782dc7 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -294,6 +294,7 @@ function system_element_info() { ); $types['page'] = array( '#show_messages' => TRUE, + '#pre_render' => array('drupal_pre_render_page'), '#theme' => 'page', '#title' => '', );