diff --git a/core/modules/aggregator/config/optional/views.view.aggregator_sources.yml b/core/modules/aggregator/config/optional/views.view.aggregator_sources.yml index cccd45b..c4d6a15 100644 --- a/core/modules/aggregator/config/optional/views.view.aggregator_sources.yml +++ b/core/modules/aggregator/config/optional/views.view.aggregator_sources.yml @@ -141,7 +141,7 @@ display: contexts: - 'languages:language_content' - 'languages:language_interface' - cacheable: false + max_age: 0 feed_1: display_plugin: feed id: feed_1 @@ -398,7 +398,7 @@ display: contexts: - 'languages:language_content' - 'languages:language_interface' - cacheable: false + max_age: 0 page_1: display_plugin: page id: page_1 @@ -418,4 +418,4 @@ display: contexts: - 'languages:language_content' - 'languages:language_interface' - cacheable: false + max_age: 0 diff --git a/core/modules/block_content/config/optional/views.view.block_content.yml b/core/modules/block_content/config/optional/views.view.block_content.yml index ad5e1f9..5409102 100644 --- a/core/modules/block_content/config/optional/views.view.block_content.yml +++ b/core/modules/block_content/config/optional/views.view.block_content.yml @@ -464,7 +464,7 @@ display: - 'languages:language_content' - 'languages:language_interface' - url - cacheable: false + max_age: 0 page_1: display_plugin: page id: page_1 @@ -486,4 +486,4 @@ display: - 'languages:language_content' - 'languages:language_interface' - url - cacheable: false + max_age: 0 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 9938a65..57ba803 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/contact/tests/modules/contact_test_views/test_views/views.view.test_contact_link.yml b/core/modules/contact/tests/modules/contact_test_views/test_views/views.view.test_contact_link.yml index 84b2a2b..9ba9e55 100644 --- a/core/modules/contact/tests/modules/contact_test_views/test_views/views.view.test_contact_link.yml +++ b/core/modules/contact/tests/modules/contact_test_views/test_views/views.view.test_contact_link.yml @@ -133,7 +133,7 @@ display: contexts: - 'languages:language_content' - 'languages:language_interface' - cacheable: false + max_age: 0 page_1: display_plugin: page id: page_1 @@ -146,4 +146,4 @@ display: contexts: - 'languages:language_content' - '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_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 489ea04..e95103a 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 291b474..d190788 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 33911a6..ff48483 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 @@ -127,4 +127,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 c281ef5c..6cb60b6 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 @@ -126,4 +126,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 5e727fb..f9a521c 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/history/src/Plugin/views/filter/HistoryUserTimestamp.php b/core/modules/history/src/Plugin/views/filter/HistoryUserTimestamp.php index 4117ec0..2216927 100644 --- a/core/modules/history/src/Plugin/views/filter/HistoryUserTimestamp.php +++ b/core/modules/history/src/Plugin/views/filter/HistoryUserTimestamp.php @@ -102,9 +102,9 @@ public function adminSummary() { /** * {@inheritdoc} */ - public function isCacheable() { + public function getCacheMaxAge() { // This filter depends on the current time and therefore is never cacheable. - return FALSE; + return 0; } } diff --git a/core/modules/node/config/optional/views.view.content.yml b/core/modules/node/config/optional/views.view.content.yml index c8201f2..4214f79 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 556b9aa..afd66da 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/rest/src/Plugin/views/style/Serializer.php b/core/modules/rest/src/Plugin/views/style/Serializer.php index 67a8364..ceccd61 100644 --- a/core/modules/rest/src/Plugin/views/style/Serializer.php +++ b/core/modules/rest/src/Plugin/views/style/Serializer.php @@ -7,8 +7,9 @@ namespace Drupal\rest\Plugin\views\style; +use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Form\FormStateInterface; -use Drupal\views\Plugin\CacheablePluginInterface; use Drupal\views\ViewExecutable; use Drupal\views\Plugin\views\display\DisplayPluginBase; use Drupal\views\Plugin\views\style\StylePluginBase; @@ -27,7 +28,7 @@ * display_types = {"data"} * ) */ -class Serializer extends StylePluginBase implements CacheablePluginInterface { +class Serializer extends StylePluginBase implements CacheableDependencyInterface { /** * Overrides \Drupal\views\Plugin\views\style\StylePluginBase::$usesRowPlugin. @@ -153,8 +154,8 @@ public function getFormats() { /** * {@inheritdoc} */ - public function isCacheable() { - return TRUE; + public function getCacheMaxAge() { + return Cache::PERMANENT; } /** @@ -164,4 +165,11 @@ public function getCacheContexts() { return ['request_format']; } + /** + * {@inheritdoc} + */ + public function getCacheTags() { + return []; + } + } diff --git a/core/modules/system/src/Plugin/views/field/BulkForm.php b/core/modules/system/src/Plugin/views/field/BulkForm.php index 609d4c0..3a3b65c 100644 --- a/core/modules/system/src/Plugin/views/field/BulkForm.php +++ b/core/modules/system/src/Plugin/views/field/BulkForm.php @@ -7,6 +7,7 @@ namespace Drupal\system\Plugin\views\field; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\RevisionableInterface; @@ -15,7 +16,6 @@ use Drupal\Core\Routing\RedirectDestinationTrait; use Drupal\Core\TypedData\TranslatableInterface; use Drupal\views\Entity\Render\EntityTranslationRenderTrait; -use Drupal\views\Plugin\CacheablePluginInterface; use Drupal\views\Plugin\views\display\DisplayPluginBase; use Drupal\views\Plugin\views\field\FieldPluginBase; use Drupal\views\Plugin\views\field\UncacheableFieldHandlerTrait; @@ -29,7 +29,7 @@ * * @ViewsField("bulk_form") */ -class BulkForm extends FieldPluginBase implements CacheablePluginInterface { +class BulkForm extends FieldPluginBase implements CacheableDependencyInterface { use RedirectDestinationTrait; use UncacheableFieldHandlerTrait; @@ -114,10 +114,10 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o /** * {@inheritdoc} */ - public function isCacheable() { + public function getCacheMaxAge() { // @todo Consider making the bulk operation form cacheable. See // https://www.drupal.org/node/2503009. - return FALSE; + return 0; } /** @@ -130,6 +130,13 @@ public function getCacheContexts() { /** * {@inheritdoc} */ + public function getCacheTags() { + return []; + } + + /** + * {@inheritdoc} + */ public function getEntityTypeId() { return $this->getEntityType(); } diff --git a/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml b/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml index e1086d1..f3784d6 100644 --- a/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml +++ b/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml @@ -247,7 +247,7 @@ display: - 'languages:language_interface' - url - 'user.node_grants:view' - cacheable: false + max_age: 0 feed_1: id: feed_1 display_title: Feed @@ -283,7 +283,7 @@ display: - 'languages:language_interface' - url - 'user.node_grants:view' - cacheable: false + max_age: 0 page_1: id: page_1 display_title: Page @@ -300,4 +300,4 @@ display: - 'languages:language_interface' - url - 'user.node_grants:view' - cacheable: false + max_age: 0 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 f162195..55cc6ef 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. @@ -216,8 +217,8 @@ public function getArgument() { /** * {@inheritdoc} */ - public function isCacheable() { - return TRUE; + public function getCacheMaxAge() { + return Cache::PERMANENT; } /** @@ -230,6 +231,13 @@ public function getCacheContexts() { /** * {@inheritdoc} */ + public function getCacheTags() { + return []; + } + + /** + * {@inheritdoc} + */ public function calculateDependencies() { $dependencies = parent::calculateDependencies(); diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_term_relationship.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_term_relationship.yml index 22521bc..5e13b59 100644 --- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_term_relationship.yml +++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_term_relationship.yml @@ -199,4 +199,4 @@ display: contexts: - 'languages:language_content' - 'languages:language_interface' - cacheable: false + max_age: 0 diff --git a/core/modules/user/src/Plugin/views/access/Permission.php b/core/modules/user/src/Plugin/views/access/Permission.php index 0dc5165..7b9f7a7 100644 --- a/core/modules/user/src/Plugin/views/access/Permission.php +++ b/core/modules/user/src/Plugin/views/access/Permission.php @@ -8,11 +8,12 @@ namespace Drupal\user\Plugin\views\access; use Drupal\Component\Utility\SafeMarkup; +use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Session\AccountInterface; use Drupal\user\PermissionHandlerInterface; -use Drupal\views\Plugin\CacheablePluginInterface; use Drupal\views\Plugin\views\access\AccessPluginBase; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Routing\Route; @@ -28,7 +29,7 @@ * help = @Translation("Access will be granted to users with the specified permission string.") * ) */ -class Permission extends AccessPluginBase implements CacheablePluginInterface { +class Permission extends AccessPluginBase implements CacheableDependencyInterface { /** * Overrides Drupal\views\Plugin\Plugin::$usesOptions. @@ -136,8 +137,8 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { /** * {@inheritdoc} */ - public function isCacheable() { - return TRUE; + public function getCacheMaxAge() { + return Cache::PERMANENT; } /** @@ -147,4 +148,11 @@ public function getCacheContexts() { return ['user.permissions']; } + /** + * {@inheritdoc} + */ + public function getCacheTags() { + return []; + } + } diff --git a/core/modules/user/src/Plugin/views/access/Role.php b/core/modules/user/src/Plugin/views/access/Role.php index 4c2b732..b21af04 100644 --- a/core/modules/user/src/Plugin/views/access/Role.php +++ b/core/modules/user/src/Plugin/views/access/Role.php @@ -8,9 +8,9 @@ namespace Drupal\user\Plugin\views\access; use Drupal\Component\Utility\SafeMarkup; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\user\RoleStorageInterface; -use Drupal\views\Plugin\CacheablePluginInterface; use Drupal\views\Plugin\views\access\AccessPluginBase; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Routing\Route; @@ -27,7 +27,7 @@ * help = @Translation("Access will be granted to users with any of the specified roles.") * ) */ -class Role extends AccessPluginBase implements CacheablePluginInterface { +class Role extends AccessPluginBase implements CacheableDependencyInterface { /** * Overrides Drupal\views\Plugin\Plugin::$usesOptions. @@ -149,8 +149,8 @@ public function calculateDependencies() { /** * {@inheritdoc} */ - public function isCacheable() { - return TRUE; + public function getCacheMaxAge() { + return 0; } /** @@ -160,5 +160,12 @@ public function getCacheContexts() { return ['user.roles']; } + /** + * {@inheritdoc} + */ + public function getCacheTags() { + return []; + } + } 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 b3c86ec..0d435df 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 edfb709..d50d2c0 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. @@ -108,8 +109,8 @@ public function getArgument() { /** * {@inheritdoc} */ - public function isCacheable() { - return TRUE; + public function getCacheMaxAge() { + return Cache::PERMANENT; } /** @@ -119,4 +120,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..ea1bc38 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: - type: boolean - label: 'Cacheable' + max_age: + type: integer + 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 deb1806..19f98c3 100644 --- a/core/modules/views/src/Entity/Render/RendererBase.php +++ b/core/modules/views/src/Entity/Render/RendererBase.php @@ -7,9 +7,10 @@ namespace Drupal\views\Entity\Render; +use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Entity\EntityTypeInterface; 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; @@ -17,7 +18,7 @@ /** * Defines a base class for entity renderers. */ -abstract class RendererBase implements CacheablePluginInterface { +abstract class RendererBase implements CacheableDependencyInterface { /** * The view executable wrapping the view storage entity. @@ -66,8 +67,8 @@ public function __construct(ViewExecutable $view, LanguageManagerInterface $lang /** * {@inheritdoc} */ - public function isCacheable() { - return TRUE; + public function getCacheMaxAge() { + return Cache::PERMANENT; } /** @@ -78,6 +79,13 @@ public function getCacheContexts() { } /** + * {@inheritdoc} + */ + public function getCacheTags() { + return []; + } + + /** * Alters the query if needed. * * @param \Drupal\views\Plugin\views\query\QueryPluginBase $query diff --git a/core/modules/views/src/Entity/View.php b/core/modules/views/src/Entity/View.php index de736ec..4978ae0 100644 --- a/core/modules/views/src/Entity/View.php +++ b/core/modules/views/src/Entity/View.php @@ -311,8 +311,9 @@ public function preSave(EntityStorageInterface $storage) { * * Cache metadata is set per view and per display, and ends up being stored in * the view's configuration. This allows Views to determine very efficiently: - * - whether a view is cacheable at all - * - what the cache key for a given view should be + * - the max-age + * - the cache contexts + * - the cache tags * * In other words: this allows us to do the (expensive) work of initializing * Views plugins and handlers to determine their effect on the cacheability of @@ -327,7 +328,10 @@ protected function addCacheMetadata() { $display =& $this->getDisplay($display_id); $executable->setDisplay($display_id); - list($display['cache_metadata']['cacheable'], $display['cache_metadata']['contexts']) = $executable->getDisplay()->calculateCacheMetadata(); + $cache_metadata = $executable->getDisplay()->calculateCacheMetadata(); + $display['cache_metadata']['max_age'] = $cache_metadata->getCacheMaxAge(); + $display['cache_metadata']['contexts'] = $cache_metadata->getCacheContexts(); + $display['cache_metadata']['tags'] = $cache_metadata->getCacheTags(); // 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 99f55ae..43eb1f9 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 20715f3..bb88532 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 06a18e3..3b28ffa 100644 --- a/core/modules/views/src/Plugin/views/cache/CachePluginBase.php +++ b/core/modules/views/src/Plugin/views/cache/CachePluginBase.php @@ -8,6 +8,7 @@ namespace Drupal\views\Plugin\views\cache; use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableMetadata; use Drupal\views\Plugin\views\PluginBase; use Drupal\Core\Database\Query\Select; use Drupal\views\ResultRow; @@ -211,7 +212,7 @@ public function generateResultsKey() { 'items_per_page' => $this->view->getItemsPerPage(), 'offset' => $this->view->getOffset(), ]; - $key_data += \Drupal::service('cache_contexts_manager')->convertTokensToKeys($this->displayHandler->getCacheMetadata()['contexts']); + $key_data += \Drupal::service('cache_contexts_manager')->convertTokensToKeys($this->displayHandler->getCacheMetadata()->getCacheContexts()); $this->resultsKey = $this->view->storage->id() . ':' . $this->displayHandler->display['id'] . ':results:' . hash('sha256', serialize($key_data)); } @@ -288,12 +289,10 @@ 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 string[] $cache_contexts - * The cache contexts the display varies by. + * @param \Drupal\Core\Cache\CacheableMetadata $cache_metadata + * The cache metadata. */ - public function alterCacheMetadata(&$is_cacheable, array &$cache_contexts) { + public function alterCacheMetadata(CacheableMetadata $cache_metadata) { } /** diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php index 3245bd2..92c393f 100644 --- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php +++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php @@ -13,6 +13,7 @@ use Drupal\Component\Utility\SafeMarkup; use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\CacheableMetadata; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Plugin\PluginDependencyTrait; @@ -20,7 +21,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; @@ -2151,9 +2151,9 @@ protected function applyDisplayCachablityMetadata(array &$element) { $cache = $this->getPlugin('cache'); (new CacheableMetadata()) - ->setCacheTags($this->view->getCacheTags()) + ->setCacheTags(Cache::mergeTags($this->view->getCacheTags(), isset($this->display['cache_metadata']['tags']) ? $this->display['cache_metadata']['tags'] : [])) ->setCacheContexts(isset($this->display['cache_metadata']['contexts']) ? $this->display['cache_metadata']['contexts'] : []) - ->setCacheMaxAge($cache->getCacheMaxAge()) + ->setCacheMaxAge(Cache::mergeMaxAges($cache->getCacheMaxAge(), isset($this->display['cache_metadata']['max_age']) ? $this->display['cache_metadata']['max_age'] : Cache::PERMANENT)) ->merge(CacheableMetadata::createFromRenderArray($element)) ->applyTo($element); } @@ -2271,18 +2271,13 @@ public function preExecute() { * {@inheritdoc} */ public function calculateCacheMetadata () { - $is_cacheable = TRUE; - $cache_contexts = []; + $cache_metadata = new CacheableMetadata(); // 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(); - } - else { - $is_cacheable = FALSE; + if ($plugin instanceof CacheableDependencyInterface) { + $cache_metadata = $cache_metadata->merge(CacheableMetadata::createFromObject($plugin)); } } @@ -2291,19 +2286,18 @@ 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) { + $cache_metadata = $cache_metadata->merge(CacheableMetadata::createFromObject($handler)); } } } /** @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($cache_metadata); } - return [(bool) $is_cacheable, $cache_contexts]; + return $cache_metadata; } /** @@ -2311,9 +2305,18 @@ public function calculateCacheMetadata () { */ public function getCacheMetadata() { if (!isset($this->display['cache_metadata'])) { - list($this->display['cache_metadata']['cacheable'], $this->display['cache_metadata']['contexts']) = $this->calculateCacheMetadata(); + $cache_metadata = $this->calculateCacheMetadata(); + $this->display['cache_metadata']['max_age'] = $cache_metadata->getCacheMaxAge(); + $this->display['cache_metadata']['contexts'] = $cache_metadata->getCacheContexts(); + $this->display['cache_metadata']['tags'] = $cache_metadata->getCacheTags(); + } + else { + $cache_metadata = (new CacheableMetadata()) + ->setCacheMaxAge($this->display['cache_metadata']['max_age']) + ->setCacheContexts($this->display['cache_metadata']['contexts']) + ->setCacheTags($this->display['cache_metadata']['tags']); } - return $this->display['cache_metadata']; + return $cache_metadata; } /** diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginInterface.php b/core/modules/views/src/Plugin/views/display/DisplayPluginInterface.php index c1aba0c..6690c21 100644 --- a/core/modules/views/src/Plugin/views/display/DisplayPluginInterface.php +++ b/core/modules/views/src/Plugin/views/display/DisplayPluginInterface.php @@ -439,20 +439,16 @@ public function preExecute(); /** * Calculates the display's cache metadata by inspecting each handler/plugin. * - * @return array - * Returns an array: - * - first value: (boolean) Whether the display is cacheable. - * - second value: (string[]) The cache contexts the display varies by. + * @return \Drupal\Core\Cache\CacheableMetadata + * The cache metadata. */ public function calculateCacheMetadata(); /** * Gets the cache metadata. * - * @return array - * Returns an array: - * - first value: (boolean) Whether the display is cacheable. - * - second value: (string[]) The cache contexts the display varies by. + * @return \Drupal\Core\Cache\CacheableMetadata + * The cache metadata. */ public function getCacheMetadata(); diff --git a/core/modules/views/src/Plugin/views/exposed_form/ExposedFormPluginBase.php b/core/modules/views/src/Plugin/views/exposed_form/ExposedFormPluginBase.php index 11a3e2d..7e19634 100644 --- a/core/modules/views/src/Plugin/views/exposed_form/ExposedFormPluginBase.php +++ b/core/modules/views/src/Plugin/views/exposed_form/ExposedFormPluginBase.php @@ -8,10 +8,11 @@ namespace Drupal\views\Plugin\views\exposed_form; use Drupal\Component\Utility\SafeMarkup; +use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Form\FormState; use Drupal\Core\Form\FormStateInterface; use Drupal\views\Form\ViewsExposedForm; -use Drupal\views\Plugin\CacheablePluginInterface; use Drupal\views\ViewExecutable; use Drupal\views\Plugin\views\display\DisplayPluginBase; use Drupal\views\Plugin\views\PluginBase; @@ -35,7 +36,7 @@ /** * Base class for Views exposed filter form plugins. */ -abstract class ExposedFormPluginBase extends PluginBase implements CacheablePluginInterface { +abstract class ExposedFormPluginBase extends PluginBase implements CacheableDependencyInterface { /** * Overrides Drupal\views\Plugin\Plugin::$usesOptions. @@ -336,8 +337,8 @@ public function resetForm(&$form, FormStateInterface $form_state) { /** * {@inheritdoc} */ - public function isCacheable() { - return TRUE; + public function getCacheMaxAge() { + return Cache::PERMANENT; } /** @@ -364,6 +365,13 @@ public function getCacheContexts() { return $contexts; } + /** + * {@inheritdoc} + */ + public function getCacheTags() { + return []; + } + } /** diff --git a/core/modules/views/src/Plugin/views/field/Field.php b/core/modules/views/src/Plugin/views/field/Field.php index 386456c..28122df 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\EntityFieldRenderer; -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 FieldAPIHandlerTrait; /** @@ -952,8 +953,8 @@ public function calculateDependencies() { /** * {@inheritdoc} */ - public function isCacheable() { - return FALSE; + public function getCacheMaxAge() { + return Cache::PERMANENT; } /** @@ -964,6 +965,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/pager/SqlBase.php b/core/modules/views/src/Plugin/views/pager/SqlBase.php index b2d7389..597bb26 100644 --- a/core/modules/views/src/Plugin/views/pager/SqlBase.php +++ b/core/modules/views/src/Plugin/views/pager/SqlBase.php @@ -7,13 +7,14 @@ namespace Drupal\views\Plugin\views\pager; +use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Form\FormStateInterface; -use Drupal\views\Plugin\CacheablePluginInterface; /** * A common base class for sql based pager. */ -abstract class SqlBase extends PagerPluginBase implements CacheablePluginInterface { +abstract class SqlBase extends PagerPluginBase implements CacheableDependencyInterface { protected function defineOptions() { $options = parent::defineOptions(); @@ -374,8 +375,8 @@ public function exposedFormValidate(&$form, FormStateInterface $form_state) { /** * {@inheritdoc} */ - public function isCacheable() { - return TRUE; + public function getCacheMaxAge() { + return Cache::PERMANENT; } /** @@ -392,4 +393,11 @@ public function getCacheContexts() { return $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 0d6d9f8..540a110 100644 --- a/core/modules/views/src/Plugin/views/query/QueryPluginBase.php +++ b/core/modules/views/src/Plugin/views/query/QueryPluginBase.php @@ -8,8 +8,8 @@ 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; @@ -37,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. @@ -317,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; } /** @@ -342,13 +342,6 @@ public function getCacheTags() { return []; } - /** - * {@inheritdoc} - */ - public function getCacheMaxAge() { - 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 9d8fdbb..944ac7f 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} @@ -26,8 +26,6 @@ public function usesGroupBy() { public function query() { $this->query->addOrderBy('rand'); - // @todo Replace this once https://www.drupal.org/node/2464427 is in. - $this->view->element['#cache']['max-age'] = 0; } public function buildOptionsForm(&$form, FormStateInterface $form_state) { @@ -38,8 +36,8 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { /** * {@inheritdoc} */ - public function isCacheable() { - return FALSE; + public function getCacheMaxAge() { + return 0; } /** @@ -49,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 98f3797..f2742be 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/src/Plugin/views/style/Table.php b/core/modules/views/src/Plugin/views/style/Table.php index 4efeda2..3960bf9 100644 --- a/core/modules/views/src/Plugin/views/style/Table.php +++ b/core/modules/views/src/Plugin/views/style/Table.php @@ -9,8 +9,8 @@ use Drupal\Component\Plugin\Discovery\DiscoveryInterface; use Drupal\Component\Utility\Html; +use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Form\FormStateInterface; -use Drupal\views\Plugin\CacheablePluginInterface; use Drupal\views\Plugin\views\wizard\WizardInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; @@ -28,7 +28,7 @@ * display_types = {"normal"} * ) */ -class Table extends StylePluginBase implements CacheablePluginInterface { +class Table extends StylePluginBase implements CacheableDependencyInterface { /** * Does the style plugin for itself support to add fields to it's output. @@ -432,8 +432,8 @@ public function wizardSubmit(&$form, FormStateInterface $form_state, WizardInter /** * {@inheritdoc} */ - public function isCacheable() { - return TRUE; + public function getCacheMaxAge() { + return 0; } /** @@ -453,4 +453,11 @@ public function getCacheContexts() { return $contexts; } + /** + * {@inheritdoc} + */ + public function getCacheTags() { + return []; + } + } diff --git a/core/modules/views/src/Tests/GlossaryTest.php b/core/modules/views/src/Tests/GlossaryTest.php index 7d55f85..8919854 100644 --- a/core/modules/views/src/Tests/GlossaryTest.php +++ b/core/modules/views/src/Tests/GlossaryTest.php @@ -73,7 +73,18 @@ public function testGlossaryView() { // Verify cache tags. $this->assertPageCacheContextsAndTags($url, ['languages:' . LanguageInterface::TYPE_CONTENT, 'languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'url', 'user.node_grants:view', 'user.permissions'], [ 'config:views.view.glossary', + // Listed for letter 'a'. 'node:' . $nodes_by_char['a'][0]->id(), 'node:' . $nodes_by_char['a'][1]->id(), 'node:' . $nodes_by_char['a'][2]->id(), + // Link for letter 'd'. + 'node:1', + // Link for letter 'p'. + 'node:16', + // Link for letter 'r'. + 'node:2', + // Link for letter 'l'. + 'node:21', + // Link for letter 'u'. + 'node:6', 'node_list', 'user:0', 'user_list', diff --git a/core/modules/views/src/Tests/Update/UpdateTest.php b/core/modules/views/src/Tests/Update/UpdateTest.php new file mode 100644 index 0000000..2abf260 --- /dev/null +++ b/core/modules/views/src/Tests/Update/UpdateTest.php @@ -0,0 +1,105 @@ +user = $this->drupalCreateUser(['administer software updates', 'access site in maintenance mode']); + $this->updateUrl = Url::fromRoute('system.db_update'); + } + + /** + * Tests that update hooks are properly run. + */ + public function testUpdateHooks() { + // Verify that the 8000 schema is in place. + $this->assertEqual(drupal_get_installed_schema_version('views'), 8000); + /* @var \Drupal\views\Entity\View $view */ + $view = Views::getView('test_view_update'); + $displays = $view->get('display'); + foreach (array_keys($displays) as $display_id) { + $display = $view->getDisplay($display_id); + $this->assertTrue(isset($display['cache_metadata']['cacheable'])); + } + + // Increment the schema version. + \Drupal::state()->set('views', 8001); + + $this->drupalLogin($this->user); + $this->drupalGet($this->updateUrl, ['external' => TRUE]); + $this->clickLink(t('Continue')); + $this->assertRaw('Update all views to re-generate the cacheability metadata.'); + // Run the update hooks. + $this->clickLink(t('Apply pending updates')); + + // Ensure schema has changed. + $this->assertEqual(drupal_get_installed_schema_version('views', TRUE), 8001); + /* @var \Drupal\views\Entity\View $view */ + $view = Views::getView('test_view_update'); + $displays = $view->get('display'); + foreach (array_keys($displays) as $display_id) { + $display = $view->getDisplay($display_id); + $this->assertFalse(isset($display['cache_metadata']['cacheable'])); + } + } + +} 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 8593665..7bcc16b 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 diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_test_link.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_test_link.yml index 509826c..e2a148c 100644 --- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_test_link.yml +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_test_link.yml @@ -323,4 +323,4 @@ display: - entity_test_view_grants - 'languages:language_content' - 'languages:language_interface' - cacheable: false + max_age: 0 diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_feed_icon.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_feed_icon.yml index a5bb9f5..b0087c7 100644 --- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_feed_icon.yml +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_feed_icon.yml @@ -174,7 +174,7 @@ display: - 'languages:language_interface' - url - 'user.node_grants:view' - cacheable: false + max_age: 0 feed_1: display_plugin: feed id: feed_1 @@ -198,7 +198,7 @@ display: - 'languages:language_interface' - url - 'user.node_grants:view' - cacheable: false + max_age: 0 page_1: display_plugin: page id: page_1 @@ -213,4 +213,4 @@ display: - 'languages:language_interface' - url - 'user.node_grants:view' - cacheable: false + max_age: 0 diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_field_attachment_test.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_field_attachment_test.yml index eae936f..eeb345e 100644 --- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_field_attachment_test.yml +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_field_attachment_test.yml @@ -137,4 +137,4 @@ display: contexts: - 'languages:language_content' - 'languages:language_interface' - cacheable: false + max_age: 0 diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_row_render_cache.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_row_render_cache.yml index 28a1812..aed7b54 100644 --- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_row_render_cache.yml +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_row_render_cache.yml @@ -500,4 +500,4 @@ display: - 'languages:language_content' - 'languages:language_interface' - 'user.node_grants:view' - cacheable: false + max_age: 0 diff --git a/core/modules/views/tests/modules/views_test_updates/config/schema/views_test_updates.views.schema.yml b/core/modules/views/tests/modules/views_test_updates/config/schema/views_test_updates.views.schema.yml new file mode 100644 index 0000000..a689aad --- /dev/null +++ b/core/modules/views/tests/modules/views_test_updates/config/schema/views_test_updates.views.schema.yml @@ -0,0 +1,9 @@ +# Schema for the views plugins of the Views test updates module. + +views.view.display.cache_metadata.*: + type: views.view.display.cache_metadata + label: 'Cache metadata' + mapping: + cacheable: + type: boolean + label: 'Cacheable' diff --git a/core/modules/views/tests/modules/views_test_updates/test_views/views.view.test_view_update_8001.yml b/core/modules/views/tests/modules/views_test_updates/test_views/views.view.test_view_update_8001.yml new file mode 100644 index 0000000..fcb1486 --- /dev/null +++ b/core/modules/views/tests/modules/views_test_updates/test_views/views.view.test_view_update_8001.yml @@ -0,0 +1,75 @@ +langcode: en +status: true +dependencies: { } +id: test_view_update_8001 +label: 'Test view update 8001' +module: views +description: '' +tag: '' +base_table: views_test_data +base_field: id +core: '8' +display: + default: + display_options: + defaults: + fields: false + pager: false + sorts: false + row: + type: fields + fields: + age: + field: age + id: age + relationship: none + table: views_test_data + plugin_id: numeric + id: + field: id + id: id + relationship: none + table: views_test_data + plugin_id: numeric + name: + field: name + id: name + relationship: none + table: views_test_data + plugin_id: string + pager: + options: + offset: 0 + type: none + sorts: + id: + field: id + id: id + order: ASC + relationship: none + table: views_test_data + plugin_id: numeric + display_extenders: { } + display_plugin: default + display_title: Master + id: default + position: 0 + cache_metadata: + max_age: -1 + contexts: + - 'languages:language_interface' + tags: { } + cacheable: false + embed_1: + display_options: + display_extenders: { } + display_plugin: embed + display_title: Embedded + id: embed_1 + position: 1 + cache_metadata: + max_age: -1 + contexts: + - 'languages:language_interface' + tags: { } + cacheable: false diff --git a/core/modules/views/tests/modules/views_test_updates/views_test_updates.info.yml b/core/modules/views/tests/modules/views_test_updates/views_test_updates.info.yml new file mode 100644 index 0000000..4a3540d --- /dev/null +++ b/core/modules/views/tests/modules/views_test_updates/views_test_updates.info.yml @@ -0,0 +1,8 @@ +name: 'Views Test Update' +type: module +description: 'Test Views module updates.' +package: Testing +version: VERSION +core: 8.x +dependencies: + - views diff --git a/core/modules/views/views.install b/core/modules/views/views.install index e8e3e5e..f5cc48e 100644 --- a/core/modules/views/views.install +++ b/core/modules/views/views.install @@ -5,9 +5,36 @@ * Contains install and update functions for Views. */ +use Drupal\views\Entity\View; + /** * Implements hook_install(). */ function views_install() { module_set_weight('views', 10); } + +/** + * @addtogroup updates-8.0.x-beta + * @{ + */ + +/** + * Update all views to re-generate the cacheability metadata. + */ +function views_update_8001(&$sandbox) { + // Remove cacheable key form cache_metadata. + // @see https://www.drupal.org/node/2464427 + foreach (View::loadMultiple() as $view) { + $displays = $view->get('display'); + foreach (array_keys($displays) as $display_id) { + $display =& $view->getDisplay($display_id); + unset($display['cache_metadata']['cacheable']); + } + $view->save(); + } +} + +/** + * @} End of "addtogroup updates-8.0.x-beta". + */