diff --git a/core/lib/Drupal/Core/Cache/MutableCacheableDependencyInterface.php b/core/lib/Drupal/Core/Cache/MutableCacheableDependencyInterface.php
new file mode 100644
index 0000000..6434dc1
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/MutableCacheableDependencyInterface.php
@@ -0,0 +1,52 @@
+cacheContexts = Cache::mergeContexts($this->cacheContexts, $cache_contexts);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addCacheTags(array $cache_tags) {
+ $this->cacheTags = Cache::mergeTags($this->cacheTags, $cache_tags);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addCacheMaxAge($max_age) {
+ $this->cacheMaxAge = Cache::mergeMaxAges($this->cacheMaxAge, $max_age);
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Cache/RuntimeCacheContextsDependencyInterface.php b/core/lib/Drupal/Core/Cache/RuntimeCacheContextsDependencyInterface.php
deleted file mode 100644
index aff94fd..0000000
--- a/core/lib/Drupal/Core/Cache/RuntimeCacheContextsDependencyInterface.php
+++ /dev/null
@@ -1,27 +0,0 @@
-getCacheTags());
+ Cache::invalidateTags($this->getOriginalCacheTags());
return $this->setStatus(FALSE);
}
diff --git a/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php
index e2172c6..7f1034c 100644
--- a/core/lib/Drupal/Core/Entity/Entity.php
+++ b/core/lib/Drupal/Core/Entity/Entity.php
@@ -8,6 +8,7 @@
namespace Drupal\Core\Entity;
use Drupal\Core\Cache\Cache;
+use Drupal\Core\Cache\MutableCacheableDependencyTrait;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\Unicode;
@@ -24,6 +25,8 @@
*/
abstract class Entity implements EntityInterface {
+ use MutableCacheableDependencyTrait;
+
use DependencySerializationTrait {
__sleep as traitSleep;
}
@@ -50,13 +53,6 @@
protected $typedData;
/**
- * Runtime cache contexts.
- *
- * @var array
- */
- protected $runtimeCacheContexts = [];
-
- /**
* Constructs an Entity object.
*
* @param array $values
@@ -447,13 +443,13 @@ public function referencedEntities() {
* {@inheritdoc}
*/
public function getCacheContexts() {
- return $this->runtimeCacheContexts;
+ return $this->cacheContexts;
}
/**
* {@inheritdoc}
*/
- public function getCacheTags() {
+ public function getOriginalCacheTags() {
// @todo Add bundle-specific listing cache tag?
// https://www.drupal.org/node/2145751
if ($this->isNew()) {
@@ -465,8 +461,18 @@ public function getCacheTags() {
/**
* {@inheritdoc}
*/
+ public function getCacheTags() {
+ if ($this->cacheTags) {
+ return Cache::mergeTags($this->getOriginalCacheTags(), $this->cacheTags);
+ }
+ return $this->getOriginalCacheTags();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
public function getCacheMaxAge() {
- return Cache::PERMANENT;
+ return $this->cacheMaxAge;
}
/**
@@ -521,7 +527,7 @@ protected function invalidateTagsOnSave($update) {
}
if ($update) {
// An existing entity was updated, also invalidate its unique cache tag.
- $tags = Cache::mergeTags($tags, $this->getCacheTags());
+ $tags = Cache::mergeTags($tags, $this->getOriginalCacheTags());
}
Cache::invalidateTags($tags);
}
@@ -542,7 +548,7 @@ protected static function invalidateTagsOnDelete(EntityTypeInterface $entity_typ
// other pages than the one it's on. The one it's on is handled by its own
// cache tag, but subsequent list pages would not be invalidated, hence we
// must invalidate its list cache tags as well.)
- $tags = Cache::mergeTags($tags, $entity->getCacheTags());
+ $tags = Cache::mergeTags($tags, $entity->getOriginalCacheTags());
}
Cache::invalidateTags($tags);
}
@@ -618,11 +624,4 @@ public function getConfigTarget() {
return $this->uuid();
}
- /**
- * {@inheritdoc}
- */
- public function addRuntimeCacheContexts(array $cache_contexts) {
- $this->runtimeCacheContexts = Cache::mergeContexts($this->runtimeCacheContexts, $cache_contexts);
- }
-
}
diff --git a/core/lib/Drupal/Core/Entity/EntityInterface.php b/core/lib/Drupal/Core/Entity/EntityInterface.php
index 495ffaa..b4cf66f 100644
--- a/core/lib/Drupal/Core/Entity/EntityInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityInterface.php
@@ -9,14 +9,14 @@
use Drupal\Core\Access\AccessibleInterface;
use Drupal\Core\Cache\CacheableDependencyInterface;
-use Drupal\Core\Cache\RuntimeCacheContextsDependencyInterface;
+use Drupal\Core\Cache\MutableCacheableDependencyInterface;
/**
* Defines a common interface for all entity objects.
*
* @ingroup entity_api
*/
-interface EntityInterface extends AccessibleInterface, CacheableDependencyInterface, RuntimeCacheContextsDependencyInterface {
+interface EntityInterface extends AccessibleInterface, CacheableDependencyInterface, MutableCacheableDependencyInterface {
/**
* Gets the entity UUID (Universally Unique Identifier).
@@ -350,6 +350,14 @@ public function referencedEntities();
public function getOriginalId();
/**
+ * Returns the original cache tags of this entity, without mutations.
+ *
+ * @return string[]
+ * List of cache tags.
+ */
+ public function getOriginalCacheTags();
+
+ /**
* Sets the original ID.
*
* @param int|string|null $id
diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
index 8281eb9..3a71f44 100644
--- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
+++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
@@ -370,7 +370,7 @@ public function resetCache(array $entities = NULL) {
Cache::invalidateTags($tags);
}
else {
- Cache::invalidateTags($this->getCacheTags());
+ Cache::invalidateTags($this->getOriginalCacheTags());
}
}
diff --git a/core/modules/aggregator/src/Entity/Item.php b/core/modules/aggregator/src/Entity/Item.php
index 6986aaa..0badf9a 100644
--- a/core/modules/aggregator/src/Entity/Item.php
+++ b/core/modules/aggregator/src/Entity/Item.php
@@ -225,7 +225,7 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) {
// handles the regular cases. The Item entity has one special case: a newly
// created Item is *also* associated with a Feed, so we must invalidate the
// associated Feed's cache tag.
- Cache::invalidateTags($this->getCacheTags());
+ Cache::invalidateTags($this->getOriginalCacheTags());
}
/**
diff --git a/core/modules/block/src/Entity/Block.php b/core/modules/block/src/Entity/Block.php
index 948d293..5637785 100644
--- a/core/modules/block/src/Entity/Block.php
+++ b/core/modules/block/src/Entity/Block.php
@@ -246,7 +246,7 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) {
// so we must invalidate the associated block's cache tag (which includes
// the theme cache tag).
if (!$update) {
- Cache::invalidateTags($this->getCacheTags());
+ Cache::invalidateTags($this->getOriginalCacheTags());
}
}
diff --git a/core/modules/block/src/Tests/BlockViewBuilderTest.php b/core/modules/block/src/Tests/BlockViewBuilderTest.php
index ccb53e4..dc8ce5a 100644
--- a/core/modules/block/src/Tests/BlockViewBuilderTest.php
+++ b/core/modules/block/src/Tests/BlockViewBuilderTest.php
@@ -194,7 +194,7 @@ public function testBlockViewBuilderAlter() {
// Enable the block view alter hook that adds a suffix, for basic testing.
\Drupal::state()->set('block_test_view_alter_suffix', TRUE);
- Cache::invalidateTags($this->block->getCacheTags());
+ Cache::invalidateTags($this->block->getOriginalCacheTags());
$build = $this->getBlockRenderArray();
$this->assertTrue(isset($build['#suffix']) && $build['#suffix'] === '
Goodbye!', 'A block with content is altered.');
$this->assertIdentical($this->renderer->renderRoot($build), 'Llamas > unicorns!
Goodbye!');
@@ -206,7 +206,7 @@ public function testBlockViewBuilderAlter() {
$request->setMethod('GET');
\Drupal::state()->set('block_test.content', NULL);
- Cache::invalidateTags($this->block->getCacheTags());
+ Cache::invalidateTags($this->block->getOriginalCacheTags());
$default_keys = array('entity_view', 'block', 'test_block');
$default_tags = array('block_view', 'config:block.block.test_block');
diff --git a/core/modules/contact/src/Tests/Views/ContactLinkTest.php b/core/modules/contact/src/Tests/Views/ContactLinkTest.php
index 4c82d18..35a725f 100644
--- a/core/modules/contact/src/Tests/Views/ContactLinkTest.php
+++ b/core/modules/contact/src/Tests/Views/ContactLinkTest.php
@@ -86,7 +86,7 @@ public function testContactLink() {
// Disable contact link for no_contact.
$this->userData->set('contact', $no_contact_account->id(), 'enabled', FALSE);
// @todo Remove cache invalidation in https://www.drupal.org/node/2477903.
- Cache::invalidateTags($no_contact_account->getCacheTags());
+ Cache::invalidateTags($no_contact_account->getOriginalCacheTags());
$this->drupalGet('test-contact-link');
$this->assertContactLinks($accounts, array('root', 'admin'));
}
diff --git a/core/modules/image/src/Entity/ImageStyle.php b/core/modules/image/src/Entity/ImageStyle.php
index a05d3a8..927ede1 100644
--- a/core/modules/image/src/Entity/ImageStyle.php
+++ b/core/modules/image/src/Entity/ImageStyle.php
@@ -267,7 +267,7 @@ public function flush($path = NULL) {
// Clear caches so that formatters may be added for this style.
drupal_theme_rebuild();
- Cache::invalidateTags($this->getCacheTags());
+ Cache::invalidateTags($this->getOriginalCacheTags());
return $this;
}
diff --git a/core/modules/shortcut/src/Entity/Shortcut.php b/core/modules/shortcut/src/Entity/Shortcut.php
index a2179f9..dd553e8 100644
--- a/core/modules/shortcut/src/Entity/Shortcut.php
+++ b/core/modules/shortcut/src/Entity/Shortcut.php
@@ -102,7 +102,7 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) {
// newly created shortcut is *also* added to a shortcut set, so we must
// invalidate the associated shortcut set's cache tag.
if (!$update) {
- Cache::invalidateTags($this->getCacheTags());
+ Cache::invalidateTags($this->getOriginalCacheTags());
}
}
diff --git a/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php b/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php
index 0b365cb..48a19e2 100644
--- a/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php
+++ b/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php
@@ -571,7 +571,7 @@ public function testReferencedEntity() {
// a cache miss for every route except the ones for the non-referencing
// entity and the empty entity listing.
$this->pass("Test invalidation of referenced entity's cache tag.", 'Debug');
- Cache::invalidateTags($this->entity->getCacheTags());
+ Cache::invalidateTags($this->entity->getOriginalCacheTags());
$this->verifyPageCache($referencing_entity_url, 'MISS');
$this->verifyPageCache($listing_url, 'MISS');
$this->verifyPageCache($nonempty_entity_listing_url, 'MISS');
diff --git a/core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php b/core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php
index 0b6f430..bafdef3 100644
--- a/core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php
+++ b/core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php
@@ -121,7 +121,7 @@ public function testEntityUri() {
// Verify that after invalidating the entity's cache tag directly, there is
// a cache miss.
$this->pass("Test invalidation of entity's cache tag.", 'Debug');
- Cache::invalidateTags($this->entity->getCacheTags());
+ Cache::invalidateTags($this->entity->getOriginalCacheTags());
$this->verifyPageCache($entity_url, 'MISS');
// Verify a cache hit.
diff --git a/core/modules/views/src/Plugin/views/cache/CachePluginBase.php b/core/modules/views/src/Plugin/views/cache/CachePluginBase.php
index 06a18e3..9e22e61 100644
--- a/core/modules/views/src/Plugin/views/cache/CachePluginBase.php
+++ b/core/modules/views/src/Plugin/views/cache/CachePluginBase.php
@@ -153,7 +153,7 @@ public function cacheGet($type) {
* Clear out cached data for a view.
*/
public function cacheFlush() {
- Cache::invalidateTags($this->view->storage->getCacheTags());
+ Cache::invalidateTags($this->view->storage->getOriginalCacheTags());
}
/**
diff --git a/core/modules/views/src/Tests/Plugin/CacheTagTest.php b/core/modules/views/src/Tests/Plugin/CacheTagTest.php
index 3d497d5..e4c1684 100644
--- a/core/modules/views/src/Tests/Plugin/CacheTagTest.php
+++ b/core/modules/views/src/Tests/Plugin/CacheTagTest.php
@@ -197,7 +197,7 @@ public function testTagCaching() {
$view->destroy();
// Invalidate the views cache tags in order to invalidate the render
// caching.
- \Drupal::service('cache_tags.invalidator')->invalidateTags($view->storage->getCacheTags());
+ \Drupal::service('cache_tags.invalidator')->invalidateTags($view->storage->getOriginalCacheTags());
$build = $view->buildRenderable();
$renderer->renderPlain($build);
diff --git a/core/modules/views_ui/src/ViewUI.php b/core/modules/views_ui/src/ViewUI.php
index b738d94..ef7ea73 100644
--- a/core/modules/views_ui/src/ViewUI.php
+++ b/core/modules/views_ui/src/ViewUI.php
@@ -1339,8 +1339,29 @@ public function hasTrustedData() {
/**
* {@inheritdoc}
*/
- public function addRuntimeCacheContexts(array $cache_contexts) {
- $this->storage->addRuntimeCacheContexts($cache_contexts);
+ public function addCacheContexts(array $cache_contexts) {
+ $this->storage->addCacheContexts($cache_contexts);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addCacheMaxAge($max_age) {
+ $this->storage->addCacheMaxAge($max_age);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOriginalCacheTags() {
+ return $this->storage->getOriginalCacheTags();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addCacheTags(array $cache_tags) {
+ $this->storage->addCacheTags($cache_tags);
}
}