Verified Commit a9885aa9 authored by godotislate's avatar godotislate
Browse files

fix: #3570209 ContentEntityStorageBase::setPersistentRevisionCache() merges...

fix: #3570209 ContentEntityStorageBase::setPersistentRevisionCache() merges cache tags from all revisions together

By: berdir
By: smustgrave
By: catch
(cherry picked from commit d1c9a4ee)
(cherry picked from commit fb510cbf)
parent 47fb5a6a
Loading
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -1308,17 +1308,18 @@ protected function setPersistentRevisionCache(array $entities): void {
      return;
    }
    $items = [];
    $cache_tags = ['entity_field_info'];
    foreach ($entities as $entity) {
      // When an entity is cleared from the entity cache via ::resetCache()
      // we must clear the related revisions from the revision cache, as well.
      // To make this possible, we add a tag with the entity's ID to the
      // revision's cache entry.
      // @see \Drupal\Core\Entity\ContentEntityStorageBase::resetCache()
      $cache_tags[] = "{$this->entityTypeId}:{$entity->id()}:revisions";
      $items[$this->buildRevisionCacheId($entity->getRevisionId())] = [
        'data' => $entity,
        'tags' => $cache_tags,
        'tags' => [
          'entity_field_info',
          "{$this->entityTypeId}:{$entity->id()}:revisions",
        ],
      ];
    }
    $this->cacheBackend->setMultiple($items);
+29 −4
Original line number Diff line number Diff line
@@ -316,11 +316,21 @@ public function testCacheInvalidationOnSave(): void {
    $persistent_cache = \Drupal::cache('entity');
    $memory_cache = \Drupal::service('entity.memory_cache');

    $assert_cache_exists = function ($cid) use ($persistent_cache, $memory_cache) {
      $this->assertNotFalse($persistent_cache->get($cid));
      $this->assertNotFalse($memory_cache->get($cid));
    $assert_cache_exists = function ($cid, $expected_cache_tag = NULL) use ($persistent_cache, $memory_cache): void {
      $cache_item = $persistent_cache->get($cid);
      $this->assertNotFalse($cache_item);
      if ($expected_cache_tag) {
        $expected_cache_tags = ['entity_field_info', $expected_cache_tag];
        $this->assertEquals($expected_cache_tags, $cache_item->tags);
      }
      $cache_item = $memory_cache->get($cid);
      $this->assertNotFalse($cache_item);
      if ($expected_cache_tag) {
        $expected_cache_tags = ['entity.memory_cache:' . $this->revEntityTypeId, $expected_cache_tag];
        $this->assertEquals($expected_cache_tags, $cache_item->tags);
      }
    };
    $assert_cache_not_exists = function ($cid) use ($persistent_cache, $memory_cache) {
    $assert_cache_not_exists = function ($cid) use ($persistent_cache, $memory_cache): void {
      $this->assertFalse($persistent_cache->get($cid));
      $this->assertFalse($memory_cache->get($cid));
    };
@@ -403,6 +413,21 @@ public function testCacheInvalidationOnSave(): void {
    $assert_cache_exists($other_revision_cache_id);
    $other_cache_id = "values:{$entity->getEntityTypeId()}:" . $other_entity->id();
    $assert_cache_exists($other_cache_id);

    // Load revisions of multiple entities, ensure they get the right cache
    // tags.
    $storage->resetCache();

    $storage->loadMultipleRevisions([$loaded_revision->getRevisionId(), $other_entity->getRevisionId()]);
    $assert_cache_exists($revision_cache_id, $this->revEntityTypeId . ":{$loaded_revision->id()}:revisions");
    $assert_cache_exists($other_revision_cache_id, $this->revEntityTypeId . ":{$other_entity->id()}:revisions");

    // Save the loaded revision, ensure that the other revision is still
    // cached.
    $loaded_revision->save();

    $assert_cache_not_exists($revision_cache_id);
    $assert_cache_exists($other_revision_cache_id);
  }

  /**