core/lib/Drupal/Core/Entity/Entity.php | 12 ++++ .../node/lib/Drupal/node/Entity/NodeType.php | 3 - .../Tests/Entity/EntityCacheTagsTestBase.php | 67 +++++++++++++++++--- .../lib/Drupal/taxonomy/Entity/Vocabulary.php | 4 -- 4 files changed, 69 insertions(+), 17 deletions(-) diff --git a/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php index 5d70510..b7c23c4 100644 --- a/core/lib/Drupal/Core/Entity/Entity.php +++ b/core/lib/Drupal/Core/Entity/Entity.php @@ -320,6 +320,18 @@ public function preSave(EntityStorageControllerInterface $storage_controller) { */ public function postSave(EntityStorageControllerInterface $storage_controller, $update = TRUE) { $this->onSaveOrDelete(); + + // If this entity is a bundle entity type of another entity type, and we've + // updating an existing entity, and that other entity type has a view + // builder class, then invalidate the render cache of entities for which + // this entity is a bundle. + if ($update) { + $bundle_of = $this->getEntityType()->getBundleOf(); + $entity_manager = \Drupal::entityManager(); + if ($bundle_of !== FALSE && $entity_manager->hasController($bundle_of, 'view_builder')) { + $entity_manager->getViewBuilder($bundle_of)->resetCache(); + } + } } /** diff --git a/core/modules/node/lib/Drupal/node/Entity/NodeType.php b/core/modules/node/lib/Drupal/node/Entity/NodeType.php index d8e413b..97d9029 100644 --- a/core/modules/node/lib/Drupal/node/Entity/NodeType.php +++ b/core/modules/node/lib/Drupal/node/Entity/NodeType.php @@ -195,9 +195,6 @@ public function postSave(EntityStorageControllerInterface $storage_controller, $ else { // Invalidate the cache tag of the updated node type only. Cache::invalidateTags(array('node_type' => $this->id())); - - // Invalidate the render cache for all nodes. - \Drupal::entityManager()->getViewBuilder('node')->resetCache(); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCacheTagsTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCacheTagsTestBase.php index a83ec32..ed082d8 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCacheTagsTestBase.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCacheTagsTestBase.php @@ -64,25 +64,22 @@ public function setUp() { // this configurable field in later tests to ensure that modifications to // field (instance) configuration invalidate render cache entries. if ($this->entity->getEntityType()->isFieldable()) { - // add field, so we can modify the Field and FieldInstance entities to - // verify that changes to those indeed clear cache tags + // Add field, so we can modify the Field and FieldInstance entities to + // verify that changes to those indeed clear cache tags. $field_name = drupal_strtolower($this->randomName()); - $this->field = entity_create('field_config', array( + entity_create('field_config', array( 'name' => 'configurable_field', 'entity_type' => $this->entity->getEntityTypeId(), 'type' => 'test_field', 'settings' => array(), - )); - $this->field->save(); - - $this->instance = entity_create('field_instance_config', array( + ))->save(); + entity_create('field_instance_config', array( 'entity_type' => $this->entity->getEntityTypeId(), 'bundle' => $this->entity->bundle(), 'field_name' => 'configurable_field', 'label' => 'Configurable field', 'settings' => array(), - )); - $this->instance->save(); + ))->save(); // Reload the entity now that a new field has been added to it. $storage_controller = $this->container @@ -314,7 +311,7 @@ public function testReferencedEntity() { $this->verifyPageCache($non_referencing_entity_path, 'HIT'); - // Verify that after modifying the entity's full display, there is a cache + // Verify that after modifying the entity's "full" display, there is a cache // miss for both the referencing entity, and the listing of referencing // entities, but not for the non-referencing entity. $this->pass("Test modification of referenced entity's 'full' display.", 'Debug'); @@ -329,6 +326,56 @@ public function testReferencedEntity() { $this->verifyPageCache($listing_path, 'HIT'); + $bundle_entity_type = $this->entity->getEntityType()->getBundleEntityType(); + if ($bundle_entity_type !== 'bundle') { + // Verify that after modifying the corresponding bundle entity, there is a + // cache miss for both the referencing entity, and the listing of + // referencing entities, but not for the non-referencing entity. + $this->pass("Test modification of referenced entity's bundle entity.", 'Debug'); + $bundle_entity = entity_load($bundle_entity_type, $this->entity->bundle()); + $bundle_entity->save(); + $this->verifyPageCache($referencing_entity_path, 'MISS'); + $this->verifyPageCache($listing_path, 'MISS'); + $this->verifyPageCache($non_referencing_entity_path, 'HIT'); + + // Verify cache hits. + $this->verifyPageCache($referencing_entity_path, 'HIT'); + $this->verifyPageCache($listing_path, 'HIT'); + } + + + if ($this->entity->getEntityType()->isFieldable()) { + // Verify that after modifying a configurable field on the entity, there + // is a cache miss. + $this->pass("Test modification of referenced entity's configurable field.", 'Debug'); + $field_name = $this->entity->getEntityTypeId() . '.configurable_field'; + $field = entity_load('field_config', $field_name); + $field->save(); + $this->verifyPageCache($referencing_entity_path, 'MISS'); + $this->verifyPageCache($listing_path, 'MISS'); + $this->verifyPageCache($non_referencing_entity_path, 'HIT'); + + // Verify cache hits. + $this->verifyPageCache($referencing_entity_path, 'HIT'); + $this->verifyPageCache($listing_path, 'HIT'); + + + // Verify that after modifying a configurable field instance on the + // entity, there is a cache miss. + $this->pass("Test modification of referenced entity's configurable field instance.", 'Debug'); + $field_instance_name = $this->entity->getEntityTypeId() . '.' . $this->entity->bundle() . '.configurable_field'; + $field_instance = entity_load('field_instance_config', $field_instance_name); + $field_instance->save(); + $this->verifyPageCache($referencing_entity_path, 'MISS'); + $this->verifyPageCache($listing_path, 'MISS'); + $this->verifyPageCache($non_referencing_entity_path, 'HIT'); + + // Verify cache hits. + $this->verifyPageCache($referencing_entity_path, 'HIT'); + $this->verifyPageCache($listing_path, 'HIT'); + } + + // Verify that after invalidating the entity's cache tag directly, there is // a cache miss for both the referencing entity, and the listing of // referencing entities, but not for the non-referencing entity. diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php index c7f2f14..6a0132a 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php @@ -129,10 +129,6 @@ public function postSave(EntityStorageControllerInterface $storage_controller, $ // Update bundles. entity_invoke_bundle_hook('rename', 'taxonomy_term', $this->getOriginalId(), $this->id()); } - else { - // Invalidate the render cache for all terms. - \Drupal::entityManager()->getViewBuilder('taxonomy_term')->resetCache(); - } $storage_controller->resetCache($update ? array($this->getOriginalId()) : array()); }