diff --git a/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_field_name.yml b/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_field_name.yml index a4ad1c1..53e1a99 100644 --- a/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_field_name.yml +++ b/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_field_name.yml @@ -200,4 +200,4 @@ display: contexts: - languages - user - cacheable: false + max_age: 0 diff --git a/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_entity_test_mul_view.yml b/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_entity_test_mul_view.yml index 8f81302..cbd869e 100644 --- a/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_entity_test_mul_view.yml +++ b/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_entity_test_mul_view.yml @@ -117,4 +117,4 @@ display: contexts: - languages - 'languages:language_interface' - cacheable: false + max_age: 0 diff --git a/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_entity_test_view.yml b/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_entity_test_view.yml index bb381c2..3f9d8ba 100644 --- a/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_entity_test_view.yml +++ b/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_entity_test_view.yml @@ -118,4 +118,4 @@ display: - entity_test_view_grants - languages - 'languages:language_interface' - cacheable: false + max_age: 0 diff --git a/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_reverse_entity_test_mul_view.yml b/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_reverse_entity_test_mul_view.yml index 8ee78f1..10c87b1 100644 --- a/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_reverse_entity_test_mul_view.yml +++ b/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_reverse_entity_test_mul_view.yml @@ -119,4 +119,4 @@ display: - entity_test_view_grants - languages - 'languages:language_interface' - cacheable: false + max_age: 0 diff --git a/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_reverse_entity_test_view.yml b/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_reverse_entity_test_view.yml index e0c2ee2..f559df0 100644 --- a/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_reverse_entity_test_view.yml +++ b/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_reverse_entity_test_view.yml @@ -118,4 +118,4 @@ display: contexts: - languages - 'languages:language_interface' - cacheable: false + max_age: 0 diff --git a/core/modules/file/config/optional/views.view.files.yml b/core/modules/file/config/optional/views.view.files.yml index 23bfd82..0cd4986 100644 --- a/core/modules/file/config/optional/views.view.files.yml +++ b/core/modules/file/config/optional/views.view.files.yml @@ -716,7 +716,7 @@ display: contexts: - languages - url - cacheable: false + max_age: 0 page_1: display_plugin: page id: page_1 @@ -749,7 +749,7 @@ display: contexts: - languages - url - cacheable: false + max_age: 0 page_2: display_plugin: page id: page_2 @@ -1103,4 +1103,4 @@ display: contexts: - languages - url - cacheable: false + max_age: 0 diff --git a/core/modules/node/config/optional/views.view.content.yml b/core/modules/node/config/optional/views.view.content.yml index 7849a0c..7fa28ad 100644 --- a/core/modules/node/config/optional/views.view.content.yml +++ b/core/modules/node/config/optional/views.view.content.yml @@ -563,7 +563,7 @@ display: - url - user - 'user.node_grants:view' - cacheable: false + max_age: 0 page_1: display_options: path: admin/content/node @@ -591,4 +591,4 @@ display: - url - user - 'user.node_grants:view' - cacheable: false + max_age: 0 diff --git a/core/modules/node/src/Plugin/views/argument_default/Node.php b/core/modules/node/src/Plugin/views/argument_default/Node.php index e6d8343..e28b026 100644 --- a/core/modules/node/src/Plugin/views/argument_default/Node.php +++ b/core/modules/node/src/Plugin/views/argument_default/Node.php @@ -7,8 +7,9 @@ namespace Drupal\node\Plugin\views\argument_default; +use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Routing\RouteMatchInterface; -use Drupal\views\Plugin\CacheablePluginInterface; use Drupal\views\Plugin\views\argument_default\ArgumentDefaultPluginBase; use Drupal\node\NodeInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -23,7 +24,7 @@ * title = @Translation("Content ID from URL") * ) */ -class Node extends ArgumentDefaultPluginBase implements CacheablePluginInterface { +class Node extends ArgumentDefaultPluginBase implements CacheableDependencyInterface { /** * The route match. @@ -75,8 +76,8 @@ public function getArgument() { /** * {@inheritdoc} */ - public function isCacheable() { - return TRUE; + public function getCacheMaxAge() { + return Cache::PERMANENT; } /** @@ -86,4 +87,11 @@ public function getCacheContexts() { return ['url']; } + /** + * {@inheritdoc} + */ + public function getCacheTags() { + return []; + } + } diff --git a/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php b/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php index b439c06..c5c6231 100644 --- a/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php +++ b/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php @@ -7,10 +7,11 @@ namespace Drupal\taxonomy\Plugin\views\argument_default; +use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\taxonomy\TermInterface; -use Drupal\views\Plugin\CacheablePluginInterface; use Drupal\views\ViewExecutable; use Drupal\views\Plugin\views\display\DisplayPluginBase; use Drupal\views\Plugin\views\argument_default\ArgumentDefaultPluginBase; @@ -28,7 +29,7 @@ * title = @Translation("Taxonomy term ID from URL") * ) */ -class Tid extends ArgumentDefaultPluginBase implements CacheablePluginInterface { +class Tid extends ArgumentDefaultPluginBase implements CacheableDependencyInterface { /** * The route match. @@ -223,8 +224,8 @@ public function getArgument() { /** * {@inheritdoc} */ - public function isCacheable() { - return TRUE; + public function getCacheMaxAge() { + return Cache::PERMANENT; } /** @@ -237,6 +238,13 @@ public function getCacheContexts() { /** * {@inheritdoc} */ + public function getCacheTags() { + return []; + } + + /** + * {@inheritdoc} + */ public function calculateDependencies() { $dependencies = parent::calculateDependencies(); diff --git a/core/modules/user/src/Plugin/views/argument_default/CurrentUser.php b/core/modules/user/src/Plugin/views/argument_default/CurrentUser.php index 3b2f2a8..3c8118c 100644 --- a/core/modules/user/src/Plugin/views/argument_default/CurrentUser.php +++ b/core/modules/user/src/Plugin/views/argument_default/CurrentUser.php @@ -7,7 +7,8 @@ namespace Drupal\user\Plugin\views\argument_default; -use Drupal\views\Plugin\CacheablePluginInterface; +use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\views\Plugin\views\argument_default\ArgumentDefaultPluginBase; /** @@ -20,7 +21,7 @@ * title = @Translation("User ID from logged in user") * ) */ -class CurrentUser extends ArgumentDefaultPluginBase implements CacheablePluginInterface { +class CurrentUser extends ArgumentDefaultPluginBase implements CacheableDependencyInterface { public function getArgument() { return \Drupal::currentUser()->id(); @@ -29,8 +30,8 @@ public function getArgument() { /** * {@inheritdoc} */ - public function isCacheable() { - return TRUE; + public function getCacheMaxAge() { + return Cache::PERMANENT; } /** @@ -40,4 +41,11 @@ public function getCacheContexts() { return ['user']; } + /** + * {@inheritdoc} + */ + public function getCacheTags() { + return []; + } + } diff --git a/core/modules/user/src/Plugin/views/argument_default/User.php b/core/modules/user/src/Plugin/views/argument_default/User.php index 269be4e..16a9e69 100644 --- a/core/modules/user/src/Plugin/views/argument_default/User.php +++ b/core/modules/user/src/Plugin/views/argument_default/User.php @@ -7,9 +7,10 @@ namespace Drupal\user\Plugin\views\argument_default; +use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Routing\RouteMatchInterface; -use Drupal\views\Plugin\CacheablePluginInterface; use Drupal\views\Plugin\views\argument_default\ArgumentDefaultPluginBase; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; @@ -24,7 +25,7 @@ * title = @Translation("User ID from route context") * ) */ -class User extends ArgumentDefaultPluginBase implements CacheablePluginInterface { +class User extends ArgumentDefaultPluginBase implements CacheableDependencyInterface { /** * The route match. @@ -115,8 +116,8 @@ public function getArgument() { /** * {@inheritdoc} */ - public function isCacheable() { - return TRUE; + public function getCacheMaxAge() { + return Cache::PERMANENT; } /** @@ -126,4 +127,11 @@ public function getCacheContexts() { return ['url']; } + /** + * {@inheritdoc} + */ + public function getCacheTags() { + return []; + } + } diff --git a/core/modules/views/config/schema/views.schema.yml b/core/modules/views/config/schema/views.schema.yml index 7ea599d..2a19267 100644 --- a/core/modules/views/config/schema/views.schema.yml +++ b/core/modules/views/config/schema/views.schema.yml @@ -118,15 +118,19 @@ views.view.*: type: mapping label: 'Cache metadata' mapping: - cacheable: + max_age: type: boolean - label: 'Cacheable' + label: 'Cache maximum age' contexts: type: sequence label: 'Cache contexts' sequence: type: string - + tags: + type: sequence + label: 'Cache tags' + sequence: + type: string views_block: type: block_settings label: 'View block' diff --git a/core/modules/views/src/Entity/Render/RendererBase.php b/core/modules/views/src/Entity/Render/RendererBase.php index a0baec6..1d52228 100644 --- a/core/modules/views/src/Entity/Render/RendererBase.php +++ b/core/modules/views/src/Entity/Render/RendererBase.php @@ -7,10 +7,11 @@ namespace Drupal\views\Entity\Render; +use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Language\LanguageManagerInterface; -use Drupal\views\Plugin\CacheablePluginInterface; use Drupal\views\Plugin\views\query\QueryPluginBase; use Drupal\views\ResultRow; use Drupal\views\ViewExecutable; @@ -18,7 +19,7 @@ /** * Defines a base class for entity row renderers. */ -abstract class RendererBase implements CacheablePluginInterface { +abstract class RendererBase implements CacheableDependencyInterface { /** * The view executable wrapping the view storage entity. @@ -67,8 +68,8 @@ public function __construct(ViewExecutable $view, LanguageManagerInterface $lang /** * {@inheritdoc} */ - public function isCacheable() { - return TRUE; + public function getCacheMaxAge() { + return Cache::PERMANENT; } /** @@ -79,6 +80,13 @@ public function getCacheContexts() { } /** + * {@inheritdoc} + */ + public function getCacheTags() { + return []; + } + + /** * Returns the language code associated to the given row. * * @param \Drupal\views\ResultRow $row diff --git a/core/modules/views/src/Entity/View.php b/core/modules/views/src/Entity/View.php index 34b4ab0..d65f457 100644 --- a/core/modules/views/src/Entity/View.php +++ b/core/modules/views/src/Entity/View.php @@ -316,7 +316,7 @@ protected function addCacheMetadata() { $display =& $this->getDisplay($display_id); $executable->setDisplay($display_id); - list($display['cache_metadata']['cacheable'], $display['cache_metadata']['contexts']) = $executable->getDisplay()->calculateCacheMetadata(); + list($display['cache_metadata']['max_age'], $display['cache_metadata']['contexts']) = $executable->getDisplay()->calculateCacheMetadata(); // Always include at least the 'languages:' context as there will most // probably be translatable strings in the view output. $display['cache_metadata']['contexts'] = Cache::mergeContexts($display['cache_metadata']['contexts'], ['languages:' . LanguageInterface::TYPE_INTERFACE]); diff --git a/core/modules/views/src/Plugin/CacheablePluginInterface.php b/core/modules/views/src/Plugin/CacheablePluginInterface.php deleted file mode 100644 index b700ce7..0000000 --- a/core/modules/views/src/Plugin/CacheablePluginInterface.php +++ /dev/null @@ -1,35 +0,0 @@ -getPlugin('argument_default')) && $plugin instanceof CacheablePluginInterface) { - $result &= $plugin->isCacheable(); + if (($plugin = $this->getPlugin('argument_default')) && $plugin instanceof CacheableDependencyInterface) { + $max_age = Cache::mergeMaxAges($max_age, $plugin->getCacheMaxAge()); } - if (($plugin = $this->getPlugin('argument_validator')) && $plugin instanceof CacheablePluginInterface) { - $result &= $plugin->isCacheable(); + if (($plugin = $this->getPlugin('argument_validator')) && $plugin instanceof CacheableDependencyInterface) { + $max_age = Cache::mergeMaxAges($max_age, $plugin->getCacheMaxAge()); } // Summaries use style plugins. - if (($plugin = $this->getPlugin('style')) && $plugin instanceof CacheablePluginInterface) { - $result &= $plugin->isCacheable(); + if (($plugin = $this->getPlugin('style')) && $plugin instanceof CacheableDependencyInterface) { + $max_age = Cache::mergeMaxAges($max_age, $plugin->getCacheMaxAge()); } - return $result; + return $max_age; } /** @@ -1211,16 +1212,16 @@ public function getCacheContexts() { $contexts[] = 'url'; // Asks all subplugins (argument defaults, argument validator and styles). - if (($plugin = $this->getPlugin('argument_default')) && $plugin instanceof CacheablePluginInterface) { - $contexts = array_merge($plugin->getCacheContexts(), $contexts); + if (($plugin = $this->getPlugin('argument_default')) && $plugin instanceof CacheableDependencyInterface) { + $contexts = Cache::mergeContexts($contexts, $plugin->getCacheContexts()); } - if (($plugin = $this->getPlugin('argument_validator')) && $plugin instanceof CacheablePluginInterface) { - $contexts = array_merge($plugin->getCacheContexts(), $contexts); + if (($plugin = $this->getPlugin('argument_validator')) && $plugin instanceof CacheableDependencyInterface) { + $contexts = Cache::mergeContexts($contexts, $plugin->getCacheContexts()); } - if (($plugin = $this->getPlugin('style')) && $plugin instanceof CacheablePluginInterface) { - $contexts = array_merge($plugin->getCacheContexts(), $contexts); + if (($plugin = $this->getPlugin('style')) && $plugin instanceof CacheableDependencyInterface) { + $contexts = Cache::mergeContexts($contexts, $plugin->getCacheContexts()); } return $contexts; @@ -1229,6 +1230,28 @@ public function getCacheContexts() { /** * {@inheritdoc} */ + public function getCacheTags() { + $tags = []; + + // Asks all subplugins (argument defaults, argument validator and styles). + if (($plugin = $this->getPlugin('argument_default')) && $plugin instanceof CacheableDependencyInterface) { + $tags = Cache::mergeTags($tags, $plugin->getCacheTags()); + } + + if (($plugin = $this->getPlugin('argument_validator')) && $plugin instanceof CacheableDependencyInterface) { + $tags = Cache::mergeTags($tags, $plugin->getCacheTags()); + } + + if (($plugin = $this->getPlugin('style')) && $plugin instanceof CacheableDependencyInterface) { + $tags = Cache::mergeTags($tags, $plugin->getCacheTags()); + } + + return $tags; + } + + /** + * {@inheritdoc} + */ public function calculateDependencies() { $dependencies = []; if (($argument_default = $this->getPlugin('argument_default')) && $argument_default instanceof DependentPluginInterface) { diff --git a/core/modules/views/src/Plugin/views/argument_default/Fixed.php b/core/modules/views/src/Plugin/views/argument_default/Fixed.php index 03b9330..f012242 100644 --- a/core/modules/views/src/Plugin/views/argument_default/Fixed.php +++ b/core/modules/views/src/Plugin/views/argument_default/Fixed.php @@ -7,8 +7,9 @@ namespace Drupal\views\Plugin\views\argument_default; +use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Form\FormStateInterface; -use Drupal\views\Plugin\CacheablePluginInterface; /** * The fixed argument default handler. @@ -20,7 +21,7 @@ * title = @Translation("Fixed") * ) */ -class Fixed extends ArgumentDefaultPluginBase implements CacheablePluginInterface { +class Fixed extends ArgumentDefaultPluginBase implements CacheableDependencyInterface { protected function defineOptions() { $options = parent::defineOptions(); @@ -48,8 +49,8 @@ public function getArgument() { /** * {@inheritdoc} */ - public function isCacheable() { - return TRUE; + public function getCacheMaxAge() { + return Cache::PERMANENT; } /** @@ -59,4 +60,11 @@ public function getCacheContexts() { return []; } + /** + * {@inheritdoc} + */ + public function getCacheTags() { + return []; + } + } diff --git a/core/modules/views/src/Plugin/views/argument_default/QueryParameter.php b/core/modules/views/src/Plugin/views/argument_default/QueryParameter.php index feccd21..f4bf3f4 100644 --- a/core/modules/views/src/Plugin/views/argument_default/QueryParameter.php +++ b/core/modules/views/src/Plugin/views/argument_default/QueryParameter.php @@ -7,8 +7,9 @@ namespace Drupal\views\Plugin\views\argument_default; +use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Form\FormStateInterface; -use Drupal\views\Plugin\CacheablePluginInterface; /** * A query parameter argument default handler. @@ -20,7 +21,7 @@ * title = @Translation("Query parameter") * ) */ -class QueryParameter extends ArgumentDefaultPluginBase implements CacheablePluginInterface { +class QueryParameter extends ArgumentDefaultPluginBase implements CacheableDependencyInterface { /** * {@inheritdoc} @@ -87,8 +88,8 @@ public function getArgument() { /** * {@inheritdoc} */ - public function isCacheable() { - return TRUE; + public function getCacheMaxAge() { + return Cache::PERMANENT; } /** @@ -98,4 +99,11 @@ public function getCacheContexts() { return ['url']; } + /** + * {@inheritdoc} + */ + public function getCacheTags() { + return []; + } + } diff --git a/core/modules/views/src/Plugin/views/argument_default/Raw.php b/core/modules/views/src/Plugin/views/argument_default/Raw.php index 40bddf3..38e02b2 100644 --- a/core/modules/views/src/Plugin/views/argument_default/Raw.php +++ b/core/modules/views/src/Plugin/views/argument_default/Raw.php @@ -7,10 +7,11 @@ namespace Drupal\views\Plugin\views\argument_default; +use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Path\AliasManagerInterface; use Drupal\Core\Path\CurrentPathStack; -use Drupal\views\Plugin\CacheablePluginInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; @@ -24,7 +25,7 @@ * title = @Translation("Raw value from URL") * ) */ -class Raw extends ArgumentDefaultPluginBase implements CacheablePluginInterface { +class Raw extends ArgumentDefaultPluginBase implements CacheableDependencyInterface { /** * The alias manager. @@ -116,8 +117,8 @@ public function getArgument() { /** * {@inheritdoc} */ - public function isCacheable() { - return TRUE; + public function getCacheMaxAge() { + return Cache::PERMANENT; } /** @@ -127,4 +128,11 @@ public function getCacheContexts() { return ['url']; } + /** + * {@inheritdoc} + */ + public function getCacheTags() { + return []; + } + } diff --git a/core/modules/views/src/Plugin/views/cache/CachePluginBase.php b/core/modules/views/src/Plugin/views/cache/CachePluginBase.php index 21e666f..0cf468b 100644 --- a/core/modules/views/src/Plugin/views/cache/CachePluginBase.php +++ b/core/modules/views/src/Plugin/views/cache/CachePluginBase.php @@ -386,12 +386,14 @@ protected function prepareViewResult(array $result) { /** * Alters the cache metadata of a display upon saving a view. * - * @param bool $is_cacheable - * Whether the display is cacheable. + * @param int $max_age + * The maximum age for which this display may be cached. * @param string[] $cache_contexts * The cache contexts the display varies by. + * @param string[] $cache_tags + * The cache tags the display is invalidated by. */ - public function alterCacheMetadata(&$is_cacheable, array &$cache_contexts) { + public function alterCacheMetadata(&$max_age, array &$cache_contexts, array &$cache_tags) { } } diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php index 290d1a7..75f371e 100644 --- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php +++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php @@ -12,6 +12,7 @@ use Drupal\Component\Utility\Unicode; use Drupal\Component\Utility\SafeMarkup; use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Plugin\PluginDependencyTrait; @@ -19,7 +20,6 @@ use Drupal\Core\Theme\Registry; use Drupal\Core\Url; use Drupal\views\Form\ViewsForm; -use Drupal\views\Plugin\CacheablePluginInterface; use Drupal\views\Plugin\views\area\AreaPluginBase; use Drupal\views\ViewExecutable; use Drupal\views\Plugin\views\PluginBase; @@ -2262,18 +2262,20 @@ public function preExecute() { * {@inheritdoc} */ public function calculateCacheMetadata () { - $is_cacheable = TRUE; + $max_age = Cache::PERMANENT; $cache_contexts = []; + $cache_tags = []; // Iterate over ordinary views plugins. foreach (Views::getPluginTypes('plugin') as $plugin_type) { $plugin = $this->getPlugin($plugin_type); - if ($plugin instanceof CacheablePluginInterface) { - $cache_contexts = array_merge($cache_contexts, $plugin->getCacheContexts()); - $is_cacheable &= $plugin->isCacheable(); + if ($plugin instanceof CacheableDependencyInterface) { + $max_age = Cache::mergeMaxAges($max_age, $plugin->getCacheMaxAge()); + $cache_contexts = Cache::mergeContexts($cache_contexts, $plugin->getCacheContexts()); + $cache_tags = Cache::mergeTags($cache_tags, $plugin->getCacheTags()); } else { - $is_cacheable = FALSE; + $max_age = 0; } } @@ -2282,16 +2284,17 @@ public function calculateCacheMetadata () { foreach (array_keys(Views::getHandlerTypes()) as $handler_type) { $handlers = $this->getHandlers($handler_type); foreach ($handlers as $handler) { - if ($handler instanceof CacheablePluginInterface) { - $cache_contexts = array_merge($cache_contexts, $handler->getCacheContexts()); - $is_cacheable &= $handler->isCacheable(); + if ($handler instanceof CacheableDependencyInterface) { + $max_age = Cache::mergeMaxAges($max_age, $handler->getCacheMaxAge()); + $cache_contexts = Cache::mergeContexts($cache_contexts, $handler->getCacheContexts()); + $cache_tags = Cache::mergeTags($cache_tags, $handler->getCacheTags()); } } } /** @var \Drupal\views\Plugin\views\cache\CachePluginBase $cache_plugin */ if ($cache_plugin = $this->getPlugin('cache')) { - $cache_plugin->alterCacheMetadata($is_cacheable, $cache_contexts); + $cache_plugin->alterCacheMetadata($is_cacheable, $cache_contexts, $cache_tags); } return [$is_cacheable, $cache_contexts]; diff --git a/core/modules/views/src/Plugin/views/field/Field.php b/core/modules/views/src/Plugin/views/field/Field.php index 66dbdeb..4b359a3 100644 --- a/core/modules/views/src/Plugin/views/field/Field.php +++ b/core/modules/views/src/Plugin/views/field/Field.php @@ -9,6 +9,8 @@ use Drupal\Component\Utility\SafeMarkup; use Drupal\Component\Utility\Xss as CoreXss; +use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Field\FieldStorageDefinitionInterface; @@ -23,7 +25,6 @@ use Drupal\Core\Session\AccountInterface; use Drupal\views\FieldAPIHandlerTrait; use Drupal\views\Entity\Render\EntityTranslationRenderTrait; -use Drupal\views\Plugin\CacheablePluginInterface; use Drupal\views\Plugin\views\display\DisplayPluginBase; use Drupal\views\ResultRow; use Drupal\views\ViewExecutable; @@ -38,7 +39,7 @@ * * @ViewsField("field") */ -class Field extends FieldPluginBase implements CacheablePluginInterface, MultiItemsFieldHandlerInterface { +class Field extends FieldPluginBase implements CacheableDependencyInterface, MultiItemsFieldHandlerInterface { use EntityTranslationRenderTrait; use FieldAPIHandlerTrait; @@ -953,8 +954,8 @@ public function calculateDependencies() { /** * {@inheritdoc} */ - public function isCacheable() { - return FALSE; + public function getCacheMaxAge() { + return Cache::PERMANENT; } /** @@ -967,6 +968,18 @@ public function getCacheContexts() { } /** + * {@inheritdoc} + */ + public function getCacheTags() { + $field_definition = $this->getFieldDefinition(); + $field_storage_definition = $this->getFieldStorageDefinition(); + return Cache::mergeTags( + $field_definition instanceof CacheableDependencyInterface ? $field_definition->getCacheTags() : [], + $field_storage_definition instanceof CacheableDependencyInterface ? $field_storage_definition->getCacheTags() : [] + ); + } + + /** * Gets the table mapping for the entity type of the field. * * @return \Drupal\Core\Entity\Sql\DefaultTableMapping diff --git a/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php index d2e9fe8..ee383b1 100644 --- a/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php +++ b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php @@ -7,11 +7,12 @@ namespace Drupal\views\Plugin\views\filter; +use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Form\FormHelper; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; use Drupal\user\RoleInterface; -use Drupal\views\Plugin\CacheablePluginInterface; use Drupal\views\Plugin\views\HandlerBase; use Drupal\Component\Utility\Html; use Drupal\Component\Utility\SafeMarkup; @@ -47,7 +48,7 @@ /** * Base class for Views filters handler plugins. */ -abstract class FilterPluginBase extends HandlerBase implements CacheablePluginInterface { +abstract class FilterPluginBase extends HandlerBase implements CacheableDependencyInterface { /** * Contains the actual value of the field,either configured in the views ui @@ -1465,8 +1466,8 @@ protected static function arrayFilterZero($var) { /** * {@inheritdoc} */ - public function isCacheable() { - return TRUE; + public function getCacheMaxAge() { + return Cache::PERMANENT; } /** @@ -1483,6 +1484,13 @@ public function getCacheContexts() { return $cache_contexts; } + /** + * {@inheritdoc} + */ + public function getCacheTags() { + return []; + } + } /** diff --git a/core/modules/views/src/Plugin/views/query/QueryPluginBase.php b/core/modules/views/src/Plugin/views/query/QueryPluginBase.php index 2b2b4a2..29f4d6d 100644 --- a/core/modules/views/src/Plugin/views/query/QueryPluginBase.php +++ b/core/modules/views/src/Plugin/views/query/QueryPluginBase.php @@ -7,8 +7,9 @@ namespace Drupal\views\Plugin\views\query; +use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Form\FormStateInterface; -use Drupal\views\Plugin\CacheablePluginInterface; use Drupal\views\Plugin\views\PluginBase; use Drupal\views\Plugin\views\display\DisplayPluginBase; use Drupal\views\ViewExecutable; @@ -36,7 +37,7 @@ /** * Base plugin class for Views queries. */ -abstract class QueryPluginBase extends PluginBase implements CacheablePluginInterface { +abstract class QueryPluginBase extends PluginBase implements CacheableDependencyInterface { /** * A pager plugin that should be provided by the display. @@ -316,9 +317,9 @@ public function getEntityTableInfo() { /** * {@inheritdoc} */ - public function isCacheable() { + public function getCacheMaxAge() { // This plugin can't really determine that. - return TRUE; + return Cache::PERMANENT; } /** diff --git a/core/modules/views/src/Plugin/views/sort/Random.php b/core/modules/views/src/Plugin/views/sort/Random.php index 1cdfc03..54436c6 100644 --- a/core/modules/views/src/Plugin/views/sort/Random.php +++ b/core/modules/views/src/Plugin/views/sort/Random.php @@ -7,15 +7,15 @@ namespace Drupal\views\Plugin\views\sort; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Form\FormStateInterface; -use Drupal\views\Plugin\CacheablePluginInterface; /** * Handle a random sort. * * @ViewsSort("random") */ -class Random extends SortPluginBase implements CacheablePluginInterface { +class Random extends SortPluginBase implements CacheableDependencyInterface { /** * {@inheritdoc} @@ -36,8 +36,8 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { /** * {@inheritdoc} */ - public function isCacheable() { - return FALSE; + public function getCacheMaxAge() { + return 0; } /** @@ -47,4 +47,11 @@ public function getCacheContexts() { return []; } + /** + * {@inheritdoc} + */ + public function getCacheTags() { + return []; + } + } diff --git a/core/modules/views/src/Plugin/views/sort/SortPluginBase.php b/core/modules/views/src/Plugin/views/sort/SortPluginBase.php index 8fe2b43..4777119 100644 --- a/core/modules/views/src/Plugin/views/sort/SortPluginBase.php +++ b/core/modules/views/src/Plugin/views/sort/SortPluginBase.php @@ -7,8 +7,9 @@ namespace Drupal\views\Plugin\views\sort; +use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Form\FormStateInterface; -use Drupal\views\Plugin\CacheablePluginInterface; use Drupal\views\Plugin\views\HandlerBase; /** @@ -27,7 +28,7 @@ /** * Base sort handler that has no options and performs a simple sort. */ -abstract class SortPluginBase extends HandlerBase implements CacheablePluginInterface { +abstract class SortPluginBase extends HandlerBase implements CacheableDependencyInterface { /** * Determine if a sort can be exposed. @@ -228,10 +229,10 @@ public function defaultExposeOptions() { /** * {@inheritdoc} */ - public function isCacheable() { + public function getCacheMaxAge() { // The result of a sort does not depend on outside information, so by // default it is cacheable. - return TRUE; + return Cache::PERMANENT; } /** @@ -246,6 +247,13 @@ public function getCacheContexts() { return $cache_contexts; } + /** + * {@inheritdoc} + */ + public function getCacheTags() { + return []; + } + } /** diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.numeric_test.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.numeric_test.yml index e8e99ad..3701655 100644 --- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.numeric_test.yml +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.numeric_test.yml @@ -174,7 +174,7 @@ display: cache_metadata: contexts: - language - cacheable: false + max_age: 0 page_1: display_plugin: page id: page_1 @@ -186,4 +186,4 @@ display: cache_metadata: contexts: - language - cacheable: false + max_age: 0