diff --git a/core/includes/common.inc b/core/includes/common.inc index 3841d90..2969eae 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -9,6 +9,7 @@ use Drupal\Component\Utility\Url; use Drupal\Component\Utility\Xss; use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableHelper; use Drupal\Core\Language\Language; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request; @@ -4581,9 +4582,15 @@ function drupal_render_cid_create($elements) { return $elements['#cache']['cid']; } elseif (isset($elements['#cache']['keys'])) { + // Add cache context keys when constants are used in the 'keys' parameter. + $cacheable_helper = new CacheableHelper; + $keys = $cacheable_helper->addCacheContextsToKeys($elements['#cache']['keys']); + $granularity = isset($elements['#cache']['granularity']) ? $elements['#cache']['granularity'] : NULL; // Merge in additional cache ID parts based provided by drupal_render_cid_parts(). - $cid_parts = array_merge($elements['#cache']['keys'], drupal_render_cid_parts($granularity)); + + $cid_parts = array_merge($keys, drupal_render_cid_parts($granularity)); + return implode(':', $cid_parts); } return FALSE; diff --git a/core/lib/Drupal/Core/Cache/CacheableHelper.php b/core/lib/Drupal/Core/Cache/CacheableHelper.php new file mode 100644 index 0000000..0ff3fd4 --- /dev/null +++ b/core/lib/Drupal/Core/Cache/CacheableHelper.php @@ -0,0 +1,89 @@ +preExecute(); + $keys = array((string) $query, $query->getArguments()); + return hash('sha256', serialize($keys)); + } + + /** + * Converts cache contexts to string representations of the context. + * + * @param $keys + * An array of cache keys that may or may not contain cache contexts. + * @return array + * A copy of the input, with cache contexts converted. + */ + function addCacheContextsToKeys($keys) { + $keys_with_contexts = array(); + foreach ($keys as $key) { + $keys_with_contexts[] = $this->getContext($key) ?: $key; + } + return $keys_with_contexts; + } + + /** + * Provides the string representaton of a cache context. + * + * @todo Document this properly once the input arguments are decided on, + * assuming the reuse of existing cache constants is temporary. + * + * @return string + * The string representaton of a cache context. + */ + protected function getContext($context) { + switch ($context) { + case DRUPAL_CACHE_PER_PAGE: + // @todo: Make this use the request properly. + return $this->currentPath(); + case DRUPAL_CACHE_PER_USER: + return "u." . $this->currentUser()->id(); + case DRUPAL_CACHE_PER_ROLE: + return 'r.' . implode(',', $this->currentUser()->getRoles()); + default: + return FALSE; + } + } + + /** + * @return \Drupal\Core\Session\AccountInterface + * The current user. + */ + protected function currentUser() { + return \Drupal::currentUser(); + } + + /** + * @return string + * The current path. + */ + protected function currentPath() { + global $base_root; + return $base_root . request_uri(); + } + +} diff --git a/core/lib/Drupal/Core/CacheableInterface.php b/core/lib/Drupal/Core/CacheableInterface.php new file mode 100644 index 0000000..958470a --- /dev/null +++ b/core/lib/Drupal/Core/CacheableInterface.php @@ -0,0 +1,45 @@ +id() == 1 || - count(\Drupal::moduleHandler()->getImplementations('node_grants')) || - !\Drupal::request()->isMethodSafe(); foreach ($list as $key => $block) { - $settings = $block->get('settings'); - if ($not_cacheable || in_array($settings['cache'], array(DRUPAL_NO_CACHE, DRUPAL_CACHE_CUSTOM))) { - // Non-cached blocks get built immediately. - if ($block->access()) { - $build[$key] = entity_view($block, 'block'); - } - } - else { - $build[$key] = array( - '#block' => $block, - '#weight' => $block->get('weight'), - '#pre_render' => array('_block_get_renderable_block'), - '#cache' => array( - 'keys' => array($key, $settings['module']), - 'granularity' => $settings['cache'], - 'bin' => 'block', - 'tags' => array('content' => TRUE), - ), - ); + if ($block->access()) { + $build[$key] = entity_view($block, 'block'); } // Add contextual links for this block; skip the main content block, since diff --git a/core/modules/block/lib/Drupal/block/BlockBase.php b/core/modules/block/lib/Drupal/block/BlockBase.php index 48e469b..86f33fc 100644 --- a/core/modules/block/lib/Drupal/block/BlockBase.php +++ b/core/modules/block/lib/Drupal/block/BlockBase.php @@ -11,6 +11,7 @@ use Drupal\block\BlockInterface; use Drupal\Component\Utility\Unicode; use Drupal\Core\Language\Language; +use Drupal\Core\CacheableInterface; use Drupal\Core\Session\AccountInterface; /** @@ -20,7 +21,8 @@ * block settings, and handling for general user-defined block visibility * settings. */ -abstract class BlockBase extends PluginBase implements BlockPluginInterface { +abstract class BlockBase extends PluginBase implements BlockPluginInterface, + CacheableInterface { /** * {@inheritdoc} @@ -32,7 +34,9 @@ public function __construct(array $configuration, $plugin_id, array $plugin_defi 'label' => '', 'module' => $plugin_definition['module'], 'label_display' => BlockInterface::BLOCK_LABEL_VISIBLE, - 'cache' => DRUPAL_NO_CACHE, + 'cache' => array( + 'max_age' => 0, + ), ); } @@ -109,6 +113,12 @@ public function buildConfigurationForm(array $form, array &$form_state) { '#return_value' => BlockInterface::BLOCK_LABEL_VISIBLE, ); + $form['cache']['max_age'] = array( + '#type' => 'select', + '#title' => t('Cache: Max age'), + '#default_value' => $this->configuration['cache']['max_age'], + '#options' => drupal_map_assoc(array(0, 60, 300, 1800, 3600, 21600, 518400), 'format_interval'), + ); // Add plugin-specific settings for this block type. $form += $this->blockForm($form, $form_state); return $form; @@ -152,6 +162,7 @@ public function submitConfigurationForm(array &$form, array &$form_state) { $this->configuration['label'] = $form_state['values']['label']; $this->configuration['label_display'] = $form_state['values']['label_display']; $this->configuration['module'] = $form_state['values']['module']; + $this->configuration['cache'] = $form_state['values']['cache']; $this->blockSubmit($form, $form_state); } } @@ -185,4 +196,51 @@ public function getMachineNameSuggestion() { return $transliterated; } + /** + * Returns an underscore'd version of the class name. Override this method to + * customize. + * + * {@inheritdoc} + */ + public function cacheKeys() { + return array(str_replace('\\', '_', get_called_class())); + } + + + /** + * Uses the "content" tag by default. Implementations are encouraged to + * overide this method to provide more granular tags. + * + * {@inheritdoc} + */ + public function cacheTags() { + return array('content' => TRUE); + } + + /** + * {@inheritdoc} + */ + public function cacheBin() { + return 'block'; + } + + /** + * {@inheritdoc} + */ + public function cacheMaxAge() { + return (int)$this->configuration['cache']['max_age']; + } + + /** + * Similar to the page cache, a block is cacheable if it has a max age. Blocks + * that should never be cached can override this method to simply return + * false. + * + * {@inheritdoc} + */ + public function isCacheable() { + return (int)$this->configuration['cache']['max_age'] > 0; + } + + } diff --git a/core/modules/block/lib/Drupal/block/BlockViewBuilder.php b/core/modules/block/lib/Drupal/block/BlockViewBuilder.php index 5aed185..6b59bdd 100644 --- a/core/modules/block/lib/Drupal/block/BlockViewBuilder.php +++ b/core/modules/block/lib/Drupal/block/BlockViewBuilder.php @@ -40,21 +40,32 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la $plugin_id = $plugin->getPluginId(); $base_id = $plugin->getBasePluginId(); $derivative_id = $plugin->getDerivativeId(); + $configuration = $plugin->getConfiguration(); - if ($content = $plugin->build()) { - $configuration = $plugin->getConfiguration(); - $build[$entity_id] = array( - '#theme' => 'block', - 'content' => $content, - '#configuration' => $configuration, - '#plugin_id' => $plugin_id, - '#base_plugin_id' => $base_id, - '#derivative_plugin_id' => $derivative_id, + $build[$entity_id] = array( + '#theme' => 'block', + '#weight' => $entity->get('weight'), + '#configuration' => $configuration + array('label' => check_plain($configuration['label'])), + '#plugin_id' => $plugin_id, + '#base_plugin_id' => $base_id, + '#derivative_plugin_id' => $derivative_id, + ); + + if ($plugin->isCacheable()) { + $build[$entity_id] += array( + 'content' => array( + '#pre_render' => array(array($plugin, 'build')), + ), + '#cache' => array( + 'keys' => $plugin->cacheKeys(), + 'bin' => $plugin->cacheBin(), + 'tags' => $plugin->cacheTags(), + 'expire' => REQUEST_TIME + $plugin->cacheMaxAge(), + ), ); - $build[$entity_id]['#configuration']['label'] = check_plain($configuration['label']); } else { - $build[$entity_id] = array(); + $build[$entity_id]['content'] = $plugin->build(); } drupal_alter(array('block_view', "block_view_$base_id"), $build[$entity_id], $plugin); diff --git a/core/modules/block/lib/Drupal/block/Plugin/views/display/Block.php b/core/modules/block/lib/Drupal/block/Plugin/views/display/Block.php index 657b635..94bea95 100644 --- a/core/modules/block/lib/Drupal/block/Plugin/views/display/Block.php +++ b/core/modules/block/lib/Drupal/block/Plugin/views/display/Block.php @@ -46,7 +46,6 @@ protected function defineOptions() { $options['block_description'] = array('default' => '', 'translatable' => TRUE); $options['block_category'] = array('default' => 'Lists (Views)', 'translatable' => TRUE); - $options['block_caching'] = array('default' => DRUPAL_NO_CACHE); $options['block_hide_empty'] = array('default' => FALSE); $options['allow'] = array( @@ -131,13 +130,6 @@ public function optionsSummary(&$categories, &$options) { 'value' => empty($filtered_allow) ? t('None') : t('Items per page'), ); - $types = $this->blockCachingModes(); - $options['block_caching'] = array( - 'category' => 'other', - 'title' => t('Block caching'), - 'value' => $types[$this->getCacheType()], - ); - $options['block_hide_empty'] = array( 'category' => 'other', 'title' => t('Hide block if the view output is empty'), @@ -146,33 +138,6 @@ public function optionsSummary(&$categories, &$options) { } /** - * Provide a list of core's block caching modes. - */ - protected function blockCachingModes() { - return array( - DRUPAL_NO_CACHE => t('Do not cache'), - DRUPAL_CACHE_GLOBAL => t('Cache once for everything (global)'), - DRUPAL_CACHE_PER_PAGE => t('Per page'), - DRUPAL_CACHE_PER_ROLE => t('Per role'), - DRUPAL_CACHE_PER_ROLE | DRUPAL_CACHE_PER_PAGE => t('Per role per page'), - DRUPAL_CACHE_PER_USER => t('Per user'), - DRUPAL_CACHE_PER_USER | DRUPAL_CACHE_PER_PAGE => t('Per user per page'), - ); - } - - /** - * Provide a single method to figure caching type, keeping a sensible default - * for when it's unset. - */ - public function getCacheType() { - $cache_type = $this->getOption('block_caching'); - if (empty($cache_type)) { - $cache_type = DRUPAL_NO_CACHE; - } - return $cache_type; - } - - /** * Provide the default form for setting options. */ public function buildOptionsForm(&$form, &$form_state) { @@ -196,16 +161,6 @@ public function buildOptionsForm(&$form, &$form_state) { '#default_value' => $this->getOption('block_category'), ); break; - case 'block_caching': - $form['#title'] .= t('Block caching type'); - - $form['block_caching'] = array( - '#type' => 'radios', - '#description' => t("This sets the default status for Drupal's built-in block caching method; this requires that caching be turned on in block administration, and be careful because you have little control over when this cache is flushed."), - '#options' => $this->blockCachingModes(), - '#default_value' => $this->getCacheType(), - ); - break; case 'block_hide_empty': $form['#title'] .= t('Block empty settings'); @@ -251,7 +206,6 @@ public function submitOptionsForm(&$form, &$form_state) { switch ($form_state['section']) { case 'block_description': case 'block_category': - case 'block_caching': case 'allow': case 'block_hide_empty': $this->setOption($form_state['section'], $form_state['values'][$form_state['section']]); diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockCacheTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockCacheTest.php index 6206dbb..bdc706c 100644 --- a/core/modules/block/lib/Drupal/block/Tests/BlockCacheTest.php +++ b/core/modules/block/lib/Drupal/block/Tests/BlockCacheTest.php @@ -127,14 +127,16 @@ function testCacheGlobal() { } /** - * Test DRUPAL_NO_CACHE. + * Test non-cacheable block. */ function testNoCache() { - $this->setCacheMode(DRUPAL_NO_CACHE); + $this->block->getPlugin()->setConfigurationValue('cache', array('max_age' => 0)); + $this->block->save(); + $current_content = $this->randomName(); \Drupal::state()->set('block_test.content', $current_content); - // If DRUPAL_NO_CACHE has no effect, the next request would be cached. + // If max_age = 0 has no effect, the next request would be cached. $this->drupalGet(''); $this->assertText($current_content, 'Block content displays.'); @@ -198,7 +200,9 @@ function testCachePerPage() { * Private helper method to set the test block's cache mode. */ private function setCacheMode($cache_mode) { - $this->block->getPlugin()->setConfigurationValue('cache', $cache_mode); + $block = $this->block->getPlugin(); + $block->setConfigurationValue('cache', array('max_age' => 600)); + $block->setConfigurationValue('test_cache_contexts', array($cache_mode)); $this->block->save(); } diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockInterfaceTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockInterfaceTest.php index 3f22caa..cc1abd6 100644 --- a/core/modules/block/lib/Drupal/block/Tests/BlockInterfaceTest.php +++ b/core/modules/block/lib/Drupal/block/Tests/BlockInterfaceTest.php @@ -48,7 +48,6 @@ public function testBlockInterface() { 'display_message' => 'no message set', 'module' => 'block_test', 'label_display' => BlockInterface::BLOCK_LABEL_VISIBLE, - 'cache' => DRUPAL_NO_CACHE, ); // Initial configuration of the block at construction time. $display_block = $manager->createInstance('test_block_instantiation', $configuration); diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockStorageUnitTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockStorageUnitTest.php index 99977cb..f70a7c1 100644 --- a/core/modules/block/lib/Drupal/block/Tests/BlockStorageUnitTest.php +++ b/core/modules/block/lib/Drupal/block/Tests/BlockStorageUnitTest.php @@ -99,7 +99,6 @@ protected function createTests() { 'region' => '-1', 'plugin' => 'test_html_id', 'settings' => array( - 'cache' => 1, 'label' => '', 'module' => 'block_test', 'label_display' => BlockInterface::BLOCK_LABEL_VISIBLE, diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockTest.php index af49957..cb09834 100644 --- a/core/modules/block/lib/Drupal/block/Tests/BlockTest.php +++ b/core/modules/block/lib/Drupal/block/Tests/BlockTest.php @@ -245,37 +245,4 @@ function moveBlockToRegion(array $block, $region) { )); $this->assertFieldByXPath($xpath, NULL, t('Block found in %region_name region.', array('%region_name' => drupal_html_class($region)))); } - - /** - * Test _block_rehash(). - */ - function testBlockRehash() { - \Drupal::moduleHandler()->install(array('block_test')); - $this->assertTrue(module_exists('block_test'), 'Test block module enabled.'); - - // Clear the block cache to load the block_test module's block definitions. - $this->container->get('plugin.manager.block')->clearCachedDefinitions(); - - // Add a test block. - $block = array(); - $block['id'] = 'test_cache'; - $block['theme'] = \Drupal::config('system.theme')->get('default'); - $block['region'] = 'header'; - $block = $this->drupalPlaceBlock('test_cache', array('region' => 'header')); - - // Our test block's caching should default to DRUPAL_CACHE_PER_ROLE. - $settings = $block->get('settings'); - $this->assertEqual($settings['cache'], DRUPAL_CACHE_PER_ROLE, 'Test block cache mode defaults to DRUPAL_CACHE_PER_ROLE.'); - - // Disable caching for this block. - $block->getPlugin()->setConfigurationValue('cache', DRUPAL_NO_CACHE); - $block->save(); - // Flushing all caches should call _block_rehash(). - $this->resetAll(); - // Verify that block is updated with the new caching mode. - $block = entity_load('block', $block->id()); - $settings = $block->get('settings'); - $this->assertEqual($settings['cache'], DRUPAL_NO_CACHE, "Test block's database entry updated to DRUPAL_NO_CACHE."); - } - } diff --git a/core/modules/block/tests/Drupal/block/Tests/BlockBaseTest.php b/core/modules/block/tests/Drupal/block/Tests/BlockBaseTest.php index f0d04ec..8d96c33 100644 --- a/core/modules/block/tests/Drupal/block/Tests/BlockBaseTest.php +++ b/core/modules/block/tests/Drupal/block/Tests/BlockBaseTest.php @@ -12,11 +12,6 @@ use Drupal\Core\Transliteration\PHPTransliteration; use Drupal\Tests\UnitTestCase; -// @todo Remove once the constants are replaced with constants on classes. -if (!defined('DRUPAL_NO_CACHE')) { - define('DRUPAL_NO_CACHE', -1); -} - /** * Tests the base block plugin. * diff --git a/core/modules/block/tests/modules/block_test/config/block.block.test_block.yml b/core/modules/block/tests/modules/block_test/config/block.block.test_block.yml index 49ef788..68cf942 100644 --- a/core/modules/block/tests/modules/block_test/config/block.block.test_block.yml +++ b/core/modules/block/tests/modules/block_test/config/block.block.test_block.yml @@ -9,7 +9,6 @@ settings: label: 'Test block html id' module: block_test label_display: false - cache: true visibility: path: visibility: 0 diff --git a/core/modules/block/tests/modules/block_test/lib/Drupal/block_test/Plugin/Block/TestCacheBlock.php b/core/modules/block/tests/modules/block_test/lib/Drupal/block_test/Plugin/Block/TestCacheBlock.php index 2fa6122..fc9a28f 100644 --- a/core/modules/block/tests/modules/block_test/lib/Drupal/block_test/Plugin/Block/TestCacheBlock.php +++ b/core/modules/block/tests/modules/block_test/lib/Drupal/block_test/Plugin/Block/TestCacheBlock.php @@ -21,22 +21,15 @@ class TestCacheBlock extends BlockBase { /** * {@inheritdoc} - * - * Sets a different caching strategy for testing purposes. */ - public function defaultConfiguration() { + public function build() { return array( - 'cache' => DRUPAL_CACHE_PER_ROLE, + '#markup' => \Drupal::state()->get('block_test.content'), ); } - /** - * {@inheritdoc} - */ - public function build() { - return array( - '#children' => \Drupal::state()->get('block_test.content'), - ); + public function cacheKeys() { + return array_merge(parent::cacheKeys(), $this->configuration['test_cache_contexts']); } } diff --git a/core/modules/block/tests/modules/block_test/lib/Drupal/block_test/Plugin/Block/TestXSSTitleBlock.php b/core/modules/block/tests/modules/block_test/lib/Drupal/block_test/Plugin/Block/TestXSSTitleBlock.php index 156abf9..3146b59 100644 --- a/core/modules/block/tests/modules/block_test/lib/Drupal/block_test/Plugin/Block/TestXSSTitleBlock.php +++ b/core/modules/block/tests/modules/block_test/lib/Drupal/block_test/Plugin/Block/TestXSSTitleBlock.php @@ -16,16 +16,4 @@ * ) */ class TestXSSTitleBlock extends TestCacheBlock { - - /** - * {@inheritdoc} - * - * Sets a different caching strategy for testing purposes. - */ - public function defaultConfiguration() { - return array( - 'cache' => DRUPAL_NO_CACHE, - ); - } - } 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 3fd3f64..64f713e 100644 --- a/core/modules/book/lib/Drupal/book/Plugin/Block/BookNavigationBlock.php +++ b/core/modules/book/lib/Drupal/book/Plugin/Block/BookNavigationBlock.php @@ -25,7 +25,6 @@ class BookNavigationBlock extends BlockBase { */ public function defaultConfiguration() { return array( - 'cache' => DRUPAL_CACHE_PER_PAGE | DRUPAL_CACHE_PER_ROLE, 'block_mode' => "all pages", ); } @@ -61,6 +60,7 @@ public function blockSubmit($form, &$form_state) { */ public function build() { $current_bid = 0; + if ($node = menu_get_object()) { $current_bid = empty($node->book['bid']) ? 0 : $node->book['bid']; } @@ -116,4 +116,12 @@ public function build() { return array(); } + public function cacheKeys() { + return array('book_navigation', 'book', DRUPAL_CACHE_PER_PAGE, DRUPAL_CACHE_PER_ROLE); + } + + public function cacheTags() { + // @todo Save tags for each entity in the book. + return array('content' => TRUE); + } } diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module index 2271f56..b71264f2 100644 --- a/core/modules/forum/forum.module +++ b/core/modules/forum/forum.module @@ -552,23 +552,6 @@ function forum_form_node_form_alter(&$form, &$form_state, $form_id) { } /** - * Render API callback: Lists nodes based on the element's #query property. - * - * This function can be used as a #pre_render callback. - * - * @see \Drupal\forum\Plugin\block\block\NewTopicsBlock::build() - * @see \Drupal\forum\Plugin\block\block\ActiveTopicsBlock::build() - */ -function forum_block_view_pre_render($elements) { - $result = $elements['#query']->execute(); - if ($node_title_list = node_title_list($result)) { - $elements['forum_list'] = $node_title_list; - $elements['forum_more'] = array('#theme' => 'more_link', '#url' => 'forum', '#title' => t('Read the latest forum topics.')); - } - return $elements; -} - -/** * Implements hook_preprocess_HOOK() for block templates. */ function forum_preprocess_block(&$variables) { diff --git a/core/modules/forum/lib/Drupal/forum/Plugin/Block/ActiveTopicsBlock.php b/core/modules/forum/lib/Drupal/forum/Plugin/Block/ActiveTopicsBlock.php index d83f736..0ed096a 100644 --- a/core/modules/forum/lib/Drupal/forum/Plugin/Block/ActiveTopicsBlock.php +++ b/core/modules/forum/lib/Drupal/forum/Plugin/Block/ActiveTopicsBlock.php @@ -21,17 +21,13 @@ class ActiveTopicsBlock extends ForumBlockBase { /** * {@inheritdoc} */ - public function build() { - $query = db_select('forum_index', 'f') + protected function forumQuery() { + return db_select('forum_index', 'f') ->fields('f') ->addTag('node_access') ->addMetaData('base_table', 'forum_index') ->orderBy('f.last_comment_timestamp', 'DESC') ->range(0, $this->configuration['block_count']); - - return array( - drupal_render_cache_by_query($query, 'forum_block_view'), - ); } } diff --git a/core/modules/forum/lib/Drupal/forum/Plugin/Block/ForumBlockBase.php b/core/modules/forum/lib/Drupal/forum/Plugin/Block/ForumBlockBase.php index c2ad994..9b63a76 100644 --- a/core/modules/forum/lib/Drupal/forum/Plugin/Block/ForumBlockBase.php +++ b/core/modules/forum/lib/Drupal/forum/Plugin/Block/ForumBlockBase.php @@ -9,6 +9,7 @@ use Drupal\block\BlockBase; use Drupal\Core\Session\AccountInterface; +use Drupal\Core\Cache\CacheableHelper; /** * Provides a base class for Forum blocks. @@ -18,9 +19,26 @@ /** * {@inheritdoc} */ + public function build() { + $result = $this->forumQuery()->execute(); + if ($node_title_list = node_title_list($result)) { + $elements['forum_list'] = $node_title_list; + $elements['forum_more'] = array( + '#theme' => 'more_link', + '#url' => 'forum', + '#title' => t('Read the latest forum topics.') + ); + } + return $elements; + } + + abstract protected function forumQuery(); + + /** + * {@inheritdoc} + */ public function defaultConfiguration() { return array( - 'cache' => DRUPAL_CACHE_CUSTOM, 'properties' => array( 'administrative' => TRUE, ), @@ -55,4 +73,14 @@ public function blockSubmit($form, &$form_state) { $this->configuration['block_count'] = $form_state['values']['block_count']; } + + public function cacheKeys() { + return array('forum_block_view', $this->cacheKeyFromQuery($this->forumQuery())); + } + + protected function cacheKeyFromQuery($query) { + $cacheable_helper = new CacheableHelper; + return $cacheable_helper->keyFromQuery($query); + } + } diff --git a/core/modules/forum/lib/Drupal/forum/Plugin/Block/NewTopicsBlock.php b/core/modules/forum/lib/Drupal/forum/Plugin/Block/NewTopicsBlock.php index 8b75a83..a61970f 100644 --- a/core/modules/forum/lib/Drupal/forum/Plugin/Block/NewTopicsBlock.php +++ b/core/modules/forum/lib/Drupal/forum/Plugin/Block/NewTopicsBlock.php @@ -21,17 +21,12 @@ class NewTopicsBlock extends ForumBlockBase { /** * {@inheritdoc} */ - public function build() { - $query = db_select('forum_index', 'f') + protected function forumQuery() { + return db_select('forum_index', 'f') ->fields('f') ->addTag('node_access') ->addMetaData('base_table', 'forum_index') ->orderBy('f.created', 'DESC') ->range(0, $this->configuration['block_count']); - - return array( - drupal_render_cache_by_query($query, 'forum_block_view'), - ); } - } diff --git a/core/modules/language/lib/Drupal/language/Plugin/Derivative/LanguageBlock.php b/core/modules/language/lib/Drupal/language/Plugin/Derivative/LanguageBlock.php index acf276f..0de6dcf 100644 --- a/core/modules/language/lib/Drupal/language/Plugin/Derivative/LanguageBlock.php +++ b/core/modules/language/lib/Drupal/language/Plugin/Derivative/LanguageBlock.php @@ -27,7 +27,6 @@ public function getDerivativeDefinitions(array $base_plugin_definition) { foreach ($configurable_types as $type) { $this->derivatives[$type] = $base_plugin_definition; $this->derivatives[$type]['admin_label'] = t('Language switcher (!type)', array('!type' => $info[$type]['name'])); - $this->derivatives[$type]['cache'] = DRUPAL_NO_CACHE; } // If there is just one configurable type then change the title of the // block. diff --git a/core/modules/system/lib/Drupal/system/Plugin/Derivative/SystemMenuBlock.php b/core/modules/system/lib/Drupal/system/Plugin/Derivative/SystemMenuBlock.php index 5542808..0c1d37f 100644 --- a/core/modules/system/lib/Drupal/system/Plugin/Derivative/SystemMenuBlock.php +++ b/core/modules/system/lib/Drupal/system/Plugin/Derivative/SystemMenuBlock.php @@ -52,7 +52,6 @@ public function getDerivativeDefinitions(array $base_plugin_definition) { foreach ($this->menuStorage->loadMultiple() as $menu => $entity) { $this->derivatives[$menu] = $base_plugin_definition; $this->derivatives[$menu]['admin_label'] = $entity->label(); - $this->derivatives[$menu]['cache'] = DRUPAL_NO_CACHE; } return $this->derivatives; } diff --git a/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlock.php b/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlock.php index 482c25f..73612e1 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlock.php +++ b/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlock.php @@ -101,4 +101,8 @@ public function getMachineNameSuggestion() { return 'views_block__' . $this->view->storage->id() . '_' . $this->view->current_display; } + public function cacheKeys() { + return array($this->getMachineNameSuggestion()); + } + } diff --git a/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsBlock.php b/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsBlock.php index 30d242a..c8ba106 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsBlock.php +++ b/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsBlock.php @@ -102,7 +102,6 @@ public function getDerivativeDefinitions(array $base_plugin_definition) { $this->derivatives[$delta] = array( 'category' => $display->getOption('block_category'), 'admin_label' => $desc, - 'cache' => $display->getCacheType() ); $this->derivatives[$delta] += $base_plugin_definition; } diff --git a/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsExposedFilterBlock.php b/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsExposedFilterBlock.php index 96bdd4c..a85efa3 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsExposedFilterBlock.php +++ b/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsExposedFilterBlock.php @@ -93,7 +93,6 @@ public function getDerivativeDefinitions(array $base_plugin_definition) { $desc = t('Exposed form: @view-@display_id', array('@view' => $view->id(), '@display_id' => $display->display['id'])); $this->derivatives[$delta] = array( 'admin_label' => $desc, - 'cache' => DRUPAL_NO_CACHE, ); $this->derivatives[$delta] += $base_plugin_definition; } diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php index 83e226f..177f2bb 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php @@ -2638,7 +2638,6 @@ public function getSpecialBlocks() { $blocks[$delta] = array( 'info' => $desc, - 'cache' => DRUPAL_NO_CACHE, ); } diff --git a/core/modules/views/tests/Drupal/views/Tests/Plugin/Block/ViewsBlockTest.php b/core/modules/views/tests/Drupal/views/Tests/Plugin/Block/ViewsBlockTest.php index 15d4d6e..d0a4d37 100644 --- a/core/modules/views/tests/Drupal/views/Tests/Plugin/Block/ViewsBlockTest.php +++ b/core/modules/views/tests/Drupal/views/Tests/Plugin/Block/ViewsBlockTest.php @@ -15,9 +15,6 @@ if (!defined('BLOCK_LABEL_VISIBLE')) { define('BLOCK_LABEL_VISIBLE', 'visible'); } -if (!defined('DRUPAL_NO_CACHE')) { - define('DRUPAL_NO_CACHE', -1); -} /** * Tests the views block plugin. diff --git a/core/profiles/minimal/config/block.block.stark_admin.yml b/core/profiles/minimal/config/block.block.stark_admin.yml index 1c11ab5..4a97153 100644 --- a/core/profiles/minimal/config/block.block.stark_admin.yml +++ b/core/profiles/minimal/config/block.block.stark_admin.yml @@ -9,7 +9,6 @@ settings: label: Administration module: system label_display: visible - cache: '-1' visibility: path: visibility: '0' diff --git a/core/profiles/minimal/config/block.block.stark_login.yml b/core/profiles/minimal/config/block.block.stark_login.yml index a727ff5..5fe2ed7 100644 --- a/core/profiles/minimal/config/block.block.stark_login.yml +++ b/core/profiles/minimal/config/block.block.stark_login.yml @@ -9,7 +9,6 @@ settings: label: 'User login' module: user label_display: visible - cache: '-1' visibility: path: visibility: '0' diff --git a/core/profiles/minimal/config/block.block.stark_tools.yml b/core/profiles/minimal/config/block.block.stark_tools.yml index 6073ede..bb78801 100644 --- a/core/profiles/minimal/config/block.block.stark_tools.yml +++ b/core/profiles/minimal/config/block.block.stark_tools.yml @@ -9,7 +9,6 @@ settings: label: Tools module: system label_display: visible - cache: '-1' visibility: path: visibility: '0' diff --git a/core/profiles/standard/config/block.block.bartik_breadcrumbs.yml b/core/profiles/standard/config/block.block.bartik_breadcrumbs.yml index c915c46..5bf1d6e 100644 --- a/core/profiles/standard/config/block.block.bartik_breadcrumbs.yml +++ b/core/profiles/standard/config/block.block.bartik_breadcrumbs.yml @@ -10,7 +10,6 @@ settings: label: Breadcrumbs module: system label_display: '0' - cache: '-1' visibility: path: visibility: '0' diff --git a/core/profiles/standard/config/block.block.bartik_content.yml b/core/profiles/standard/config/block.block.bartik_content.yml index 5b7187b..11b355f 100644 --- a/core/profiles/standard/config/block.block.bartik_content.yml +++ b/core/profiles/standard/config/block.block.bartik_content.yml @@ -10,7 +10,6 @@ settings: label: 'Main page content' module: system label_display: '0' - cache: '-1' visibility: path: visibility: '0' diff --git a/core/profiles/standard/config/block.block.bartik_footer.yml b/core/profiles/standard/config/block.block.bartik_footer.yml index 2ad2766..e7aa271 100644 --- a/core/profiles/standard/config/block.block.bartik_footer.yml +++ b/core/profiles/standard/config/block.block.bartik_footer.yml @@ -10,7 +10,6 @@ settings: label: 'Footer menu' module: system label_display: visible - cache: '-1' visibility: path: visibility: '0' diff --git a/core/profiles/standard/config/block.block.bartik_help.yml b/core/profiles/standard/config/block.block.bartik_help.yml index c697560..3d44a22 100644 --- a/core/profiles/standard/config/block.block.bartik_help.yml +++ b/core/profiles/standard/config/block.block.bartik_help.yml @@ -10,7 +10,6 @@ settings: label: 'System Help' module: system label_display: '0' - cache: '-1' visibility: path: visibility: '0' diff --git a/core/profiles/standard/config/block.block.bartik_login.yml b/core/profiles/standard/config/block.block.bartik_login.yml index e94f562..408608c 100644 --- a/core/profiles/standard/config/block.block.bartik_login.yml +++ b/core/profiles/standard/config/block.block.bartik_login.yml @@ -10,7 +10,6 @@ settings: label: 'User login' module: user label_display: visible - cache: '-1' visibility: path: visibility: '0' diff --git a/core/profiles/standard/config/block.block.bartik_powered.yml b/core/profiles/standard/config/block.block.bartik_powered.yml index 265f271..b8aab83 100644 --- a/core/profiles/standard/config/block.block.bartik_powered.yml +++ b/core/profiles/standard/config/block.block.bartik_powered.yml @@ -10,7 +10,6 @@ settings: label: 'Powered by Drupal' module: system label_display: '0' - cache: '-1' visibility: path: visibility: '0' diff --git a/core/profiles/standard/config/block.block.bartik_search.yml b/core/profiles/standard/config/block.block.bartik_search.yml index d37e197..f2ad36a 100644 --- a/core/profiles/standard/config/block.block.bartik_search.yml +++ b/core/profiles/standard/config/block.block.bartik_search.yml @@ -10,7 +10,6 @@ settings: label: Search module: search label_display: visible - cache: '-1' visibility: path: visibility: '0' diff --git a/core/profiles/standard/config/block.block.bartik_tools.yml b/core/profiles/standard/config/block.block.bartik_tools.yml index b940651..ca68f47 100644 --- a/core/profiles/standard/config/block.block.bartik_tools.yml +++ b/core/profiles/standard/config/block.block.bartik_tools.yml @@ -10,7 +10,6 @@ settings: label: Tools module: system label_display: visible - cache: '-1' visibility: path: visibility: '0' diff --git a/core/profiles/standard/config/block.block.seven_breadcrumbs.yml b/core/profiles/standard/config/block.block.seven_breadcrumbs.yml index d314031..0305fa4 100644 --- a/core/profiles/standard/config/block.block.seven_breadcrumbs.yml +++ b/core/profiles/standard/config/block.block.seven_breadcrumbs.yml @@ -10,7 +10,6 @@ settings: label: Breadcrumbs module: system label_display: '0' - cache: '-1' visibility: path: visibility: '0' diff --git a/core/profiles/standard/config/block.block.seven_content.yml b/core/profiles/standard/config/block.block.seven_content.yml index 39f26ff..0cd8d02 100644 --- a/core/profiles/standard/config/block.block.seven_content.yml +++ b/core/profiles/standard/config/block.block.seven_content.yml @@ -10,7 +10,6 @@ settings: label: 'Main page content' module: system label_display: '0' - cache: '-1' visibility: path: visibility: '0' diff --git a/core/profiles/standard/config/block.block.seven_help.yml b/core/profiles/standard/config/block.block.seven_help.yml index 8536232..087bba9 100644 --- a/core/profiles/standard/config/block.block.seven_help.yml +++ b/core/profiles/standard/config/block.block.seven_help.yml @@ -10,7 +10,6 @@ settings: label: 'System Help' module: system label_display: '0' - cache: '-1' visibility: path: visibility: '0' diff --git a/core/profiles/standard/config/block.block.seven_login.yml b/core/profiles/standard/config/block.block.seven_login.yml index d3e62fa..a34238d 100644 --- a/core/profiles/standard/config/block.block.seven_login.yml +++ b/core/profiles/standard/config/block.block.seven_login.yml @@ -10,7 +10,6 @@ settings: label: 'User login' module: user label_display: visible - cache: '-1' visibility: path: visibility: '0'