Issue #2464427 by jibran, Wim Leers, Berdir, borisson_: Replace CacheablePluginInterface with CacheableDependencyInterface

8.0.x
Nathaniel Catchpole 2015-10-02 09:26:50 +01:00
parent 07662ec63d
commit 400baf1609
61 changed files with 485 additions and 237 deletions

View File

@ -143,7 +143,7 @@ display:
- 'languages:language_interface'
- url.query_args
- user.permissions
cacheable: false
max-age: 0
feed_1:
display_plugin: feed
id: feed_1
@ -401,7 +401,7 @@ display:
- 'languages:language_content'
- 'languages:language_interface'
- user.permissions
cacheable: false
max-age: 0
page_1:
display_plugin: page
id: page_1
@ -423,4 +423,4 @@ display:
- 'languages:language_interface'
- url.query_args
- user.permissions
cacheable: false
max-age: 0

View File

@ -468,7 +468,8 @@ display:
- url
- url.query_args
- user.permissions
cacheable: false
max-age: 0
tags: { }
page_1:
display_plugin: page
id: page_1
@ -492,4 +493,5 @@ display:
- url
- url.query_args
- user.permissions
cacheable: false
max-age: 0
tags: { }

View File

@ -3,6 +3,7 @@ status: true
dependencies:
module:
- comment
- node
- user
id: comments_recent
label: 'Recent comments'
@ -241,7 +242,8 @@ display:
- 'languages:language_content'
- 'languages:language_interface'
- user.permissions
cacheable: false
max-age: -1
tags: { }
block_1:
display_plugin: block
id: block_1
@ -258,4 +260,5 @@ display:
- 'languages:language_content'
- 'languages:language_interface'
- user.permissions
cacheable: false
max-age: -1
tags: { }

View File

@ -200,4 +200,4 @@ display:
contexts:
- languages
- user
cacheable: false
max-age: 0

View File

@ -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

View File

@ -117,4 +117,4 @@ display:
contexts:
- languages
- 'languages:language_interface'
cacheable: false
max-age: 0

View File

@ -118,4 +118,4 @@ display:
- entity_test_view_grants
- languages
- 'languages:language_interface'
cacheable: false
max-age: 0

View File

@ -127,4 +127,4 @@ display:
- entity_test_view_grants
- languages
- 'languages:language_interface'
cacheable: false
max-age: 0

View File

@ -126,4 +126,4 @@ display:
contexts:
- languages
- 'languages:language_interface'
cacheable: false
max-age: 0

View File

@ -723,7 +723,8 @@ display:
- url
- url.query_args
- user.permissions
cacheable: false
max-age: 0
tags: { }
page_1:
display_plugin: page
id: page_1
@ -759,7 +760,8 @@ display:
- url
- url.query_args
- user.permissions
cacheable: false
max-age: 0
tags: { }
page_2:
display_plugin: page
id: page_2
@ -1115,4 +1117,5 @@ display:
- url
- url.query_args
- user.permissions
cacheable: false
max-age: 0
tags: { }

View File

@ -102,9 +102,9 @@ class HistoryUserTimestamp extends FilterPluginBase {
/**
* {@inheritdoc}
*/
public function isCacheable() {
public function getCacheMaxAge() {
// This filter depends on the current time and therefore is never cacheable.
return FALSE;
return 0;
}
}

View File

@ -1,8 +1,11 @@
langcode: en
status: false
dependencies:
config:
- core.entity_view_mode.node.teaser
module:
- node
- user
id: archive
label: Archive
module: node
@ -174,7 +177,8 @@ display:
- url.query_args
- 'user.node_grants:view'
- user.permissions
cacheable: false
max-age: -1
tags: { }
block_1:
id: block_1
display_title: Block
@ -212,7 +216,8 @@ display:
- url.query_args
- 'user.node_grants:view'
- user.permissions
cacheable: false
max-age: -1
tags: { }
page_1:
id: page_1
display_title: Page
@ -231,4 +236,5 @@ display:
- url.query_args
- 'user.node_grants:view'
- user.permissions
cacheable: false
max-age: -1
tags: { }

View File

@ -568,7 +568,8 @@ display:
- user
- 'user.node_grants:view'
- user.permissions
cacheable: false
max-age: 0
tags: { }
page_1:
display_options:
path: admin/content/node
@ -599,4 +600,5 @@ display:
- user
- 'user.node_grants:view'
- user.permissions
cacheable: false
max-age: 0
tags: { }

View File

@ -296,7 +296,8 @@ display:
- user
- 'user.node_grants:view'
- user.permissions
cacheable: false
max-age: 0
tags: { }
block_1:
display_plugin: block
id: block_1
@ -311,4 +312,5 @@ display:
- user
- 'user.node_grants:view'
- user.permissions
cacheable: false
max-age: 0
tags: { }

View File

@ -1,6 +1,9 @@
langcode: en
status: true
dependencies:
config:
- core.entity_view_mode.node.rss
- core.entity_view_mode.node.teaser
module:
- node
- user
@ -244,7 +247,8 @@ display:
- url.query_args
- 'user.node_grants:view'
- user.permissions
cacheable: false
max-age: -1
tags: { }
feed_1:
display_plugin: feed
id: feed_1
@ -278,7 +282,8 @@ display:
- 'languages:language_interface'
- 'user.node_grants:view'
- user.permissions
cacheable: false
max-age: -1
tags: { }
page_1:
display_options:
path: node
@ -293,4 +298,5 @@ display:
- url.query_args
- 'user.node_grants:view'
- user.permissions
cacheable: false
max-age: -1
tags: { }

View File

@ -355,7 +355,8 @@ display:
- url.query_args
- 'user.node_grants:view'
- user.permissions
cacheable: false
max-age: 0
tags: { }
attachment_1:
id: attachment_1
display_title: Attachment
@ -422,7 +423,8 @@ display:
- url.query_args
- 'user.node_grants:view'
- user.permissions
cacheable: false
max-age: 0
tags: { }
page_1:
id: page_1
display_title: Page
@ -448,4 +450,5 @@ display:
- url.query_args
- 'user.node_grants:view'
- user.permissions
cacheable: false
max-age: 0
tags: { }

View File

@ -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 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
* 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 @@ class Node extends ArgumentDefaultPluginBase implements CacheablePluginInterface
/**
* {@inheritdoc}
*/
public function isCacheable() {
return TRUE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**

View File

@ -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 @@ use Symfony\Component\Serializer\SerializerInterface;
* display_types = {"data"}
* )
*/
class Serializer extends StylePluginBase implements CacheablePluginInterface {
class Serializer extends StylePluginBase implements CacheableDependencyInterface {
/**
* Overrides \Drupal\views\Plugin\views\style\StylePluginBase::$usesRowPlugin.
@ -155,8 +156,8 @@ class Serializer extends StylePluginBase implements CacheablePluginInterface {
/**
* {@inheritdoc}
*/
public function isCacheable() {
return TRUE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**
@ -166,4 +167,11 @@ class Serializer extends StylePluginBase implements CacheablePluginInterface {
return ['request_format'];
}
/**
* {@inheritdoc}
*/
public function getCacheTags() {
return [];
}
}

View File

@ -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\Language\LanguageManagerInterface;
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 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
*
* @ViewsField("bulk_form")
*/
class BulkForm extends FieldPluginBase implements CacheablePluginInterface {
class BulkForm extends FieldPluginBase implements CacheableDependencyInterface {
use RedirectDestinationTrait;
use UncacheableFieldHandlerTrait;
@ -114,10 +114,10 @@ class BulkForm extends FieldPluginBase implements CacheablePluginInterface {
/**
* {@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;
}
/**
@ -127,6 +127,13 @@ class BulkForm extends FieldPluginBase implements CacheablePluginInterface {
return $this->languageManager->isMultilingual() ? $this->getEntityTranslationRenderer()->getCacheContexts() : [];
}
/**
* {@inheritdoc}
*/
public function getCacheTags() {
return [];
}
/**
* {@inheritdoc}
*/

View File

@ -59,6 +59,7 @@ class UpdatePostUpdateTest extends UpdatePathTestBase {
$this->assertIdentical($updates, \Drupal::state()->get('post_update_test_execution', []));
$key_value = \Drupal::keyValue('post_update');
array_unshift($updates, 'views_post_update_update_cacheability_metadata');
array_unshift($updates, 'block_post_update_disable_blocks_with_missing_contexts');
$this->assertEqual($updates, $key_value->get('existing_updates'));

View File

@ -249,7 +249,8 @@ display:
- url.query_args
- 'user.node_grants:view'
- user.permissions
cacheable: false
max-age: -1
tags: { }
feed_1:
id: feed_1
display_title: Feed
@ -286,7 +287,8 @@ display:
- url
- 'user.node_grants:view'
- user.permissions
cacheable: false
max-age: -1
tags: { }
page_1:
id: page_1
display_title: Page
@ -305,4 +307,5 @@ display:
- url.query_args
- 'user.node_grants:view'
- user.permissions
cacheable: false
max-age: -1
tags: { }

View File

@ -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 @@ use Drupal\taxonomy\VocabularyStorageInterface;
* 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 @@ class Tid extends ArgumentDefaultPluginBase implements CacheablePluginInterface
/**
* {@inheritdoc}
*/
public function isCacheable() {
return TRUE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**

View File

@ -165,7 +165,7 @@ display:
- url.query_args
- 'user.node_grants:view'
- user.permissions
cacheable: false
max-age: 0
page_1:
display_plugin: page
id: page_1
@ -255,4 +255,4 @@ display:
- url.query_args
- 'user.node_grants:view'
- user.permissions
cacheable: false
max-age: 0

View File

@ -199,4 +199,4 @@ display:
contexts:
- 'languages:language_content'
- 'languages:language_interface'
cacheable: false
max-age: 0

View File

@ -875,7 +875,8 @@ display:
- url
- url.query_args
- user.permissions
cacheable: false
max-age: 0
tags: { }
page_1:
display_plugin: page
id: page_1
@ -907,4 +908,5 @@ display:
- url
- url.query_args
- user.permissions
cacheable: false
max-age: 0
tags: { }

View File

@ -169,7 +169,8 @@ display:
- 'languages:language_content'
- 'languages:language_interface'
- user.permissions
cacheable: false
max-age: -1
tags: { }
block_1:
display_plugin: block
id: block_1
@ -185,4 +186,5 @@ display:
- 'languages:language_content'
- 'languages:language_interface'
- user.permissions
cacheable: false
max-age: -1
tags: { }

View File

@ -199,7 +199,8 @@ display:
- 'languages:language_content'
- 'languages:language_interface'
- user.permissions
cacheable: false
max-age: -1
tags: { }
who_s_online_block:
display_plugin: block
id: who_s_online_block
@ -214,4 +215,5 @@ display:
- 'languages:language_content'
- 'languages:language_interface'
- user.permissions
cacheable: false
max-age: -1
tags: { }

View File

@ -7,11 +7,12 @@
namespace Drupal\user\Plugin\views\access;
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;
@ -27,7 +28,7 @@ use Symfony\Component\Routing\Route;
* 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.
@ -135,8 +136,8 @@ class Permission extends AccessPluginBase implements CacheablePluginInterface {
/**
* {@inheritdoc}
*/
public function isCacheable() {
return TRUE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**
@ -146,4 +147,11 @@ class Permission extends AccessPluginBase implements CacheablePluginInterface {
return ['user.permissions'];
}
/**
* {@inheritdoc}
*/
public function getCacheTags() {
return [];
}
}

View File

@ -8,9 +8,10 @@
namespace Drupal\user\Plugin\views\access;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Cache\Cache;
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 +28,7 @@ use Drupal\Core\Session\AccountInterface;
* 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 +150,8 @@ class Role extends AccessPluginBase implements CacheablePluginInterface {
/**
* {@inheritdoc}
*/
public function isCacheable() {
return TRUE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**
@ -160,5 +161,12 @@ class Role extends AccessPluginBase implements CacheablePluginInterface {
return ['user.roles'];
}
/**
* {@inheritdoc}
*/
public function getCacheTags() {
return [];
}
}

View File

@ -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 @@ use Drupal\views\Plugin\views\argument_default\ArgumentDefaultPluginBase;
* 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 @@ class CurrentUser extends ArgumentDefaultPluginBase implements CacheablePluginIn
/**
* {@inheritdoc}
*/
public function isCacheable() {
return TRUE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**

View File

@ -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 @@ use Drupal\node\NodeInterface;
* 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 @@ class User extends ArgumentDefaultPluginBase implements CacheablePluginInterface
/**
* {@inheritdoc}
*/
public function isCacheable() {
return TRUE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**

View File

@ -7,6 +7,7 @@
namespace Drupal\user\Tests\Views;
use Drupal\Core\Cache\Cache;
use Drupal\user\Plugin\views\access\Role;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\Views;
@ -58,10 +59,12 @@ class AccessRoleTest extends AccessTestBase {
$this->drupalLogin($this->webUser);
$this->drupalGet('test-role');
$this->assertResponse(403);
$this->assertCacheContext('user.roles');
$this->drupalLogin($this->normalUser);
$this->drupalGet('test-role');
$this->assertResponse(200);
$this->assertCacheContext('user.roles');
// Test allowing multiple roles.
$view = Views::getView('test_access_role')->storage;
@ -85,12 +88,15 @@ class AccessRoleTest extends AccessTestBase {
$this->drupalLogin($this->webUser);
$this->drupalGet('test-role');
$this->assertResponse(403);
$this->assertCacheContext('user.roles');
$this->drupalLogout();
$this->drupalGet('test-role');
$this->assertResponse(200);
$this->assertCacheContext('user.roles');
$this->drupalLogin($this->normalUser);
$this->drupalGet('test-role');
$this->assertResponse(200);
$this->assertCacheContext('user.roles');
}
/**
@ -112,17 +118,25 @@ class AccessRoleTest extends AccessTestBase {
/** @var \Drupal\Core\Session\AccountSwitcherInterface $account_switcher */
$account_switcher = \Drupal::service('account_switcher');
// First access as user without access.
// First access as user with access.
$build = DisplayPluginBase::buildBasicRenderable('test_access_role', 'default');
$account_switcher->switchTo($this->normalUser);
$result = $renderer->renderPlain($build);
$this->assertTrue(in_array('user.roles', $build['#cache']['contexts']));
$this->assertEqual(['config:views.view.test_access_role'], $build['#cache']['tags']);
$this->assertEqual(Cache::PERMANENT, $build['#cache']['max-age']);
$this->assertNotEqual($result, '');
// Then with access.
// Then without access.
$build = DisplayPluginBase::buildBasicRenderable('test_access_role', 'default');
$account_switcher->switchTo($this->webUser);
$result = $renderer->renderPlain($build);
// @todo Fix this in https://www.drupal.org/node/2551037,
// DisplayPluginBase::applyDisplayCachablityMetadata() is not invoked when
// using buildBasicRenderable() and a Views access plugin returns FALSE.
//$this->assertTrue(in_array('user.roles', $build['#cache']['contexts']));
//$this->assertEqual([], $build['#cache']['tags']);
$this->assertEqual(Cache::PERMANENT, $build['#cache']['max-age']);
$this->assertEqual($result, '');
}

View File

@ -118,15 +118,23 @@ 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
# Deprecated.
cacheable:
type: boolean
label: 'Cacheable'
views_block:
type: block_settings
label: 'View block'

View File

@ -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 @@ use Drupal\views\ViewExecutable;
/**
* 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 @@ abstract class RendererBase implements CacheablePluginInterface {
/**
* {@inheritdoc}
*/
public function isCacheable() {
return TRUE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**
@ -77,6 +78,13 @@ abstract class RendererBase implements CacheablePluginInterface {
return [];
}
/**
* {@inheritdoc}
*/
public function getCacheTags() {
return [];
}
/**
* Alters the query if needed.
*

View File

@ -311,8 +311,9 @@ class View extends ConfigEntityBase implements ViewEntityInterface {
*
* 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 @@ class View extends ConfigEntityBase implements ViewEntityInterface {
$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]);

View File

@ -188,7 +188,11 @@ class ViewsEntitySchemaSubscriber implements EntityTypeListenerInterface, EventS
}
foreach ($all_views as $view) {
$view->save();
// All changes done to the views here can be trusted and this might be
// called during updates, when it is not safe to rely on configuration
// containing valid schema. Trust the data and disable schema validation
// and casting.
$view->trustData()->save();
}
}

View File

@ -1,35 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\views\Plugin\CacheablePluginInterface.
*/
namespace Drupal\views\Plugin;
/**
* Provides caching information about the result cacheability of views plugins.
*
* For caching on the render level, we rely on bubbling of the cache contexts.
*/
interface CacheablePluginInterface {
/**
* Returns TRUE if this plugin is cacheable at all.
*
* @return bool
*/
public function isCacheable();
/**
* Returns an array of cache contexts, this plugin varies by.
*
* Note: This method is called on views safe time, so you do have the
* configuration available. For example an exposed filter changes its
* cacheability depending on the URL.
*
* @return string[]
*/
public function getCacheContexts();
}

View File

@ -10,9 +10,10 @@ namespace Drupal\views\Plugin\views\argument;
use Drupal\Component\Plugin\DependentPluginInterface;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheableDependencyInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\views\Plugin\CacheablePluginInterface;
use Drupal\views\Plugin\views\PluginBase;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\ViewExecutable;
@ -58,7 +59,7 @@ use Drupal\views\Views;
* - numeric: If set to TRUE this field is numeric and will use %d instead of
* %s in queries.
*/
abstract class ArgumentPluginBase extends HandlerBase implements CacheablePluginInterface {
abstract class ArgumentPluginBase extends HandlerBase implements CacheableDependencyInterface {
var $validator = NULL;
var $argument = NULL;
@ -1235,24 +1236,24 @@ abstract class ArgumentPluginBase extends HandlerBase implements CacheablePlugin
/**
* {@inheritdoc}
*/
public function isCacheable() {
$result = TRUE;
public function getCacheMaxAge() {
$max_age = Cache::PERMANENT;
// Asks all subplugins (argument defaults, argument validator and styles).
if (($plugin = $this->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;
}
/**
@ -1266,21 +1267,43 @@ abstract class ArgumentPluginBase extends HandlerBase implements CacheablePlugin
$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;
}
/**
* {@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}
*/

View File

@ -102,6 +102,13 @@ abstract class ArgumentDefaultPluginBase extends PluginBase {
}
}
/**
* {@inheritdoc}
*/
public function getCacheTags() {
return [];
}
}
/**

View File

@ -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 @@ use Drupal\views\Plugin\CacheablePluginInterface;
* 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 @@ class Fixed extends ArgumentDefaultPluginBase implements CacheablePluginInterfac
/**
* {@inheritdoc}
*/
public function isCacheable() {
return TRUE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**

View File

@ -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 @@ use Drupal\views\Plugin\CacheablePluginInterface;
* title = @Translation("Query parameter")
* )
*/
class QueryParameter extends ArgumentDefaultPluginBase implements CacheablePluginInterface {
class QueryParameter extends ArgumentDefaultPluginBase implements CacheableDependencyInterface {
/**
* {@inheritdoc}
@ -87,8 +88,8 @@ class QueryParameter extends ArgumentDefaultPluginBase implements CacheablePlugi
/**
* {@inheritdoc}
*/
public function isCacheable() {
return TRUE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**

View File

@ -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 @@ use Symfony\Component\HttpFoundation\Request;
* 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 @@ class Raw extends ArgumentDefaultPluginBase implements CacheablePluginInterface
/**
* {@inheritdoc}
*/
public function isCacheable() {
return TRUE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**

View File

@ -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 @@ abstract class CachePluginBase extends PluginBase {
'items_per_page' => $this->view->getItemsPerPage(),
'offset' => $this->view->getOffset(),
];
$key_data += \Drupal::service('cache_contexts_manager')->convertTokensToKeys($this->displayHandler->getCacheMetadata()['contexts'])->getKeys();
$key_data += \Drupal::service('cache_contexts_manager')->convertTokensToKeys($this->displayHandler->getCacheMetadata()->getCacheContexts())->getKeys();
$this->resultsKey = $this->view->storage->id() . ':' . $this->displayHandler->display['id'] . ':results:' . hash('sha256', serialize($key_data));
}
@ -288,12 +289,10 @@ abstract class CachePluginBase extends PluginBase {
/**
* 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) {
}
/**

View File

@ -12,6 +12,7 @@ use Drupal\Component\Utility\Html;
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;
@ -19,7 +20,6 @@ use Drupal\Core\Session\AccountInterface;
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;
@ -2149,9 +2149,9 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
$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 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
* {@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 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
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 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
*/
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();
}
return $this->display['cache_metadata'];
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 $cache_metadata;
}
/**

View File

@ -429,20 +429,16 @@ interface DisplayPluginInterface {
/**
* 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();

View File

@ -8,10 +8,11 @@
namespace Drupal\views\Plugin\views\exposed_form;
use Drupal\Component\Utility\Html;
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 @@ use Drupal\views\Plugin\views\PluginBase;
/**
* 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 @@ abstract class ExposedFormPluginBase extends PluginBase implements CacheablePlug
/**
* {@inheritdoc}
*/
public function isCacheable() {
return TRUE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**
@ -364,6 +365,13 @@ abstract class ExposedFormPluginBase extends PluginBase implements CacheablePlug
return $contexts;
}
/**
* {@inheritdoc}
*/
public function getCacheTags() {
return [];
}
}
/**

View File

@ -8,6 +8,8 @@
namespace Drupal\views\Plugin\views\field;
use Drupal\Component\Utility\Xss;
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;
@ -22,7 +24,6 @@ use Drupal\Core\Render\RendererInterface;
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;
@ -37,7 +38,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
*
* @ViewsField("field")
*/
class Field extends FieldPluginBase implements CacheablePluginInterface, MultiItemsFieldHandlerInterface {
class Field extends FieldPluginBase implements CacheableDependencyInterface, MultiItemsFieldHandlerInterface {
use FieldAPIHandlerTrait;
/**
@ -961,8 +962,8 @@ class Field extends FieldPluginBase implements CacheablePluginInterface, MultiIt
/**
* {@inheritdoc}
*/
public function isCacheable() {
return FALSE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**
@ -972,6 +973,18 @@ class Field extends FieldPluginBase implements CacheablePluginInterface, MultiIt
return $this->getEntityFieldRenderer()->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.
*

View File

@ -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\views\Plugin\views\display\DisplayPluginBase;
@ -46,7 +47,7 @@ use Drupal\views\ViewExecutable;
/**
* 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
@ -1464,8 +1465,8 @@ abstract class FilterPluginBase extends HandlerBase implements CacheablePluginIn
/**
* {@inheritdoc}
*/
public function isCacheable() {
return TRUE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**
@ -1482,6 +1483,13 @@ abstract class FilterPluginBase extends HandlerBase implements CacheablePluginIn
return $cache_contexts;
}
/**
* {@inheritdoc}
*/
public function getCacheTags() {
return [];
}
}
/**

View File

@ -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 @@ abstract class SqlBase extends PagerPluginBase implements CacheablePluginInterfa
/**
* {@inheritdoc}
*/
public function isCacheable() {
return TRUE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**
@ -387,4 +388,11 @@ abstract class SqlBase extends PagerPluginBase implements CacheablePluginInterfa
return ['url.query_args'];
}
/**
* {@inheritdoc}
*/
public function getCacheTags() {
return [];
}
}

View File

@ -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 @@ use Drupal\views\Views;
/**
* 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.
@ -320,9 +320,8 @@ abstract class QueryPluginBase extends PluginBase implements CacheablePluginInte
/**
* {@inheritdoc}
*/
public function isCacheable() {
// This plugin can't really determine that.
return TRUE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**
@ -345,13 +344,6 @@ abstract class QueryPluginBase extends PluginBase implements CacheablePluginInte
return [];
}
/**
* {@inheritdoc}
*/
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
}
/**

View File

@ -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 @@ class Random extends SortPluginBase implements CacheablePluginInterface {
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 @@ class Random extends SortPluginBase implements CacheablePluginInterface {
/**
* {@inheritdoc}
*/
public function isCacheable() {
return FALSE;
public function getCacheMaxAge() {
return 0;
}
/**
@ -49,4 +47,11 @@ class Random extends SortPluginBase implements CacheablePluginInterface {
return [];
}
/**
* {@inheritdoc}
*/
public function getCacheTags() {
return [];
}
}

View File

@ -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 @@ use Drupal\views\Plugin\views\HandlerBase;
/**
* 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.
@ -227,10 +228,10 @@ abstract class SortPluginBase extends HandlerBase implements CacheablePluginInte
/**
* {@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;
}
/**
@ -245,6 +246,13 @@ abstract class SortPluginBase extends HandlerBase implements CacheablePluginInte
return $cache_contexts;
}
/**
* {@inheritdoc}
*/
public function getCacheTags() {
return [];
}
}
/**

View File

@ -9,8 +9,8 @@ namespace Drupal\views\Plugin\views\style;
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 @@ use Symfony\Component\HttpFoundation\Request;
* 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 @@ class Table extends StylePluginBase implements CacheablePluginInterface {
/**
* {@inheritdoc}
*/
public function isCacheable() {
return TRUE;
public function getCacheMaxAge() {
return 0;
}
/**
@ -454,4 +454,11 @@ class Table extends StylePluginBase implements CacheablePluginInterface {
return $contexts;
}
/**
* {@inheritdoc}
*/
public function getCacheTags() {
return [];
}
}

View File

@ -85,7 +85,18 @@ class GlossaryTest extends ViewTestBase {
],
[
'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',

View File

@ -0,0 +1,46 @@
<?php
/**
* @file
* Contains \Drupal\views\Tests\Update\CacheabilityMetadataUpdateTest.
*/
namespace Drupal\views\Tests\Update;
use Drupal\system\Tests\Update\UpdatePathTestBase;
use Drupal\views\Views;
/**
* Tests that views cacheability metadata post update hook runs properly.
*
* @see views_post_update_update_cacheability_metadata().
*
* @group Update
*/
class CacheabilityMetadataUpdateTest extends UpdatePathTestBase {
/**
* {@inheritdoc}
*/
protected function setDatabaseDumpFiles() {
$this->databaseDumpFiles = [__DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz'];
}
/**
* Tests that views cacheability metadata updated properly.
*/
public function testUpdateHookN() {
$this->runUpdates();
foreach (Views::getAllViews() as $view) {
$displays = $view->get('display');
foreach (array_keys($displays) as $display_id) {
$display = $view->getDisplay($display_id);
$this->assertFalse(isset($display['cache_metadata']['cacheable']));
$this->assertTrue(isset($display['cache_metadata']['contexts']));
$this->assertTrue(isset($display['cache_metadata']['max-age']));
$this->assertTrue(isset($display['cache_metadata']['tags']));
}
}
}
}

View File

@ -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

View File

@ -323,4 +323,4 @@ display:
- entity_test_view_grants
- 'languages:language_content'
- 'languages:language_interface'
cacheable: false
max-age: 0

View File

@ -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

View File

@ -137,4 +137,4 @@ display:
contexts:
- 'languages:language_content'
- 'languages:language_interface'
cacheable: false
max-age: 0

View File

@ -500,4 +500,4 @@ display:
- 'languages:language_content'
- 'languages:language_interface'
- 'user.node_grants:view'
cacheable: false
max-age: 0

View File

@ -0,0 +1,36 @@
<?php
/**
* @file
* Post update functions for Views.
*/
/**
* @addtogroup updates-8.0.0-beta
* @{
*/
/**
* Update the cacheability metadata for all views.
*/
function views_post_update_update_cacheability_metadata() {
// Load all views.
$views = \Drupal::entityManager()->getStorage('view')->loadMultiple();
/* @var \Drupal\views\Entity\View[] $views */
foreach ($views as $view) {
$displays = $view->get('display');
foreach (array_keys($displays) as $display_id) {
$display =& $view->getDisplay($display_id);
// Unset the cache_metadata key, so all cacheability metadata for the
// display is recalculated.
unset($display['cache_metadata']);
}
$view->save();
}
}
/**
* @} End of "addtogroup updates-8.0.0-beta".
*/