commit 08af0396e81f53cafc1931c468264f205ef8ad68 Author: Moshe Weitzman Date: Sun Oct 27 13:24:09 2013 -0400 Issue #2094241 by moshe weitzman, Wim Leers, amateescu | catch: Cache tag the page cache. diff --git a/core/includes/common.inc b/core/includes/common.inc index 5749ffe..07b5db6 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -3182,7 +3182,7 @@ function drupal_page_set_cache(Response $response, Request $request) { // because by the time it is read, the configuration might change. 'page_compressed' => $page_compressed, ), - 'tags' => array('content' => TRUE), + 'tags' => array('content' => TRUE) + drupal_cache_tags_page_get(), 'expire' => CacheBackendInterface::CACHE_PERMANENT, 'created' => REQUEST_TIME, ); @@ -4219,6 +4219,38 @@ function drupal_render_collect_cache_tags($element, $tags = array()) { } /** + * A #post_render callback at the top level of the $page array. Collects the + * tags for use in page cache. + * + * @param string $children + * An HTML string of rendered output. + * @param array $elements + * A render array. + * + * @return string + * The same $children that was passed in - no modifications. + */ +function drupal_post_render_cache_tags_page_set($children, array $elements) { + if (drupal_page_is_cacheable()) { + $tags = &drupal_static('system_cache_tags_page', array()); + $tags = drupal_render_collect_cache_tags($elements); + } + return $children; +} + +/** + * Return the cache tags that were stored during drupal_render_page(). + * + * @return array + * An array of cache tags. + * + * @see drupal_post_render_cache_tags_page_set() + */ +function drupal_cache_tags_page_get() { + return drupal_static('system_cache_tags_page', array()); +} + +/** * Prepares an element for caching based on a query. * * This smart caching strategy saves Drupal from querying and rendering to HTML diff --git a/core/modules/node/lib/Drupal/node/NodeViewBuilder.php b/core/modules/node/lib/Drupal/node/NodeViewBuilder.php index 020951f..30daf9b 100644 --- a/core/modules/node/lib/Drupal/node/NodeViewBuilder.php +++ b/core/modules/node/lib/Drupal/node/NodeViewBuilder.php @@ -88,7 +88,7 @@ protected function alterBuild(array &$build, EntityInterface $entity, EntityDisp // The node 'submitted' info is not rendered in a standard way (renderable // array) so we have to add a cache tag manually. - $build['#cache']['tags']['user'][] = $entity->uid; + $build['#cache']['tags']['user'][] = $entity->getAuthorId(); } } 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 89d8ff4..f80f92e 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php @@ -42,6 +42,29 @@ function setUp() { } /** + * Assure that cache tags are properly persisted. + * + * Since tag based invalidation works, we know that our tag properly + * persisted. + */ + function testPageCacheTags() { + $config = \Drupal::config('system.performance'); + $config->set('cache.page.use_internal', 1); + $config->set('cache.page.max_age', 300); + $config->save(); + + $path = 'system-test/cache_tags_page'; + $tags = array('system_test_cache_tags_page' => TRUE); + $this->drupalGet($path); + $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); + $this->drupalGet($path); + $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT'); + cache_invalidate_tags($tags); + $this->drupalGet($path); + $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); + } + + /** * Tests support for different cache items with different Accept headers. */ function testAcceptHeaderRequests() { diff --git a/core/modules/system/system.module b/core/modules/system/system.module index cf057b2..66e5a6f 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -261,6 +261,7 @@ function system_element_info() { '#theme_wrappers' => array('form'), ); $types['page'] = array( + '#post_render' => array('drupal_post_render_cache_tags_page_set'), '#show_messages' => TRUE, '#theme' => 'page', '#theme_wrappers' => array('html'), diff --git a/core/modules/system/tests/modules/system_test/lib/Drupal/system_test/Controller/SystemTestController.php b/core/modules/system/tests/modules/system_test/lib/Drupal/system_test/Controller/SystemTestController.php index db4302f..058aabe 100644 --- a/core/modules/system/tests/modules/system_test/lib/Drupal/system_test/Controller/SystemTestController.php +++ b/core/modules/system/tests/modules/system_test/lib/Drupal/system_test/Controller/SystemTestController.php @@ -39,6 +39,17 @@ public function lockExit() { } /** + * Set cache tag on on the returned render array. + */ + function system_test_cache_tags_page() { + $build['main'] = array( + '#markup' => 'Cache tags page example', + '#cache' => array('tags' => array('system_test_cache_tags_page' => TRUE)), + ); + return $build; + } + + /** * @todo Remove system_test_authorize_init_page(). */ public function authorizeInit($page_title) { diff --git a/core/modules/system/tests/modules/system_test/system_test.routing.yml b/core/modules/system/tests/modules/system_test/system_test.routing.yml index 4c6b565..660cfce 100644 --- a/core/modules/system/tests/modules/system_test/system_test.routing.yml +++ b/core/modules/system/tests/modules/system_test/system_test.routing.yml @@ -45,6 +45,13 @@ system_test.lock_exit: requirements: _access: 'TRUE' +system_test.cache_tags_page: + path: '/system-test/cache_tags_page' + defaults: + _controller: '\Drupal\system_test\Controller\SystemTestController::system_test_cache_tags_page' + requirements: + _access: 'TRUE' + system_test.authorize_init: path: '/system-test/authorize-init/{page_title}' defaults: diff --git a/core/modules/system/tests/modules/test_page_test/test_page_test.module b/core/modules/system/tests/modules/test_page_test/test_page_test.module index 5911afb..4fab773 100644 --- a/core/modules/system/tests/modules/test_page_test/test_page_test.module +++ b/core/modules/system/tests/modules/test_page_test/test_page_test.module @@ -22,5 +22,6 @@ function test_page_test_page() { return array( '#title' => t('Test page'), '#markup' => t('Test page text.'), + '#cache' => array('tags' => array('test-page' => TRUE)), ); }