diff --git a/core/lib/Drupal/Core/Entity/EntityBase.php b/core/lib/Drupal/Core/Entity/EntityBase.php index aa25d63c00679134301bc90fb7099032b3c0849c..6b25963c5162147f8309ba3f3ef7e9ae04eaa1ee 100644 --- a/core/lib/Drupal/Core/Entity/EntityBase.php +++ b/core/lib/Drupal/Core/Entity/EntityBase.php @@ -483,7 +483,10 @@ public function getCacheContexts() { protected function getListCacheTagsToInvalidate() { $tags = $this->getEntityType()->getListCacheTags(); if ($this->getEntityType()->hasKey('bundle')) { - $tags[] = $this->getEntityTypeId() . '_list:' . $this->bundle(); + $tags = Cache::mergeTags( + $tags, + $this->getEntityType()->getBundleListCacheTags($this->bundle()) + ); } return $tags; } diff --git a/core/lib/Drupal/Core/Entity/EntityType.php b/core/lib/Drupal/Core/Entity/EntityType.php index d9e8ffd806aa3537df71ba71b9478a0bfaac51a5..9eab50b9a2224c03cf78d0052e08a78e3c01c07c 100644 --- a/core/lib/Drupal/Core/Entity/EntityType.php +++ b/core/lib/Drupal/Core/Entity/EntityType.php @@ -865,6 +865,13 @@ public function getListCacheTags() { return $this->list_cache_tags; } + /** + * {@inheritdoc} + */ + public function getBundleListCacheTags(string $bundle): array { + return [$this->id() . '_list:' . $bundle]; + } + /** * {@inheritdoc} */ diff --git a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php index c7275d31fef827c30fe2f08017bffe71761416d4..4522902f76bbc8cda1bc1bf6535081f7443a95e7 100644 --- a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php +++ b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php @@ -733,6 +733,17 @@ public function getListCacheContexts(); */ public function getListCacheTags(); + /** + * The list cache tags associated with a specific bundle. + * + * Enables code listing entities of this type and bundle to ensure that newly created + * entities show up immediately. + * + * @return string[] + * An array of the cache tags for this bundle. + */ + public function getBundleListCacheTags(string $bundle): array; + /** * Gets the key that is used to store configuration dependencies. * diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php index d810500b1a0eee019e5f63c5aa01fdbf7c9590ce..5db0f96c1e8b0c463c6af3a36d84a1b4de37b770 100644 --- a/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php @@ -487,4 +487,15 @@ public function testEntityClassImplements(): void { $this->assertFalse($entity_type->entityClassImplements(\DateTimeInterface::class)); } + /** + * Tests the ::getBundleListCacheTags() method. + * + * @covers ::getBundleListCacheTags + */ + public function testGetBundleListCacheTags(): void { + $entity_type = $this->setUpEntityType(['entity_keys' => ['id' => 'id']]); + $bundle = $this->randomMachineName(); + $this->assertEquals([$entity_type->id() . '_list:' . $bundle], $entity_type->getBundleListCacheTags($bundle)); + } + } diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityUnitTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityUnitTest.php index c1c1f58894e0264b8a09bc63d7034da79da447d9..3357139aaa5358e68b516b849eb35c2c2c28e7fb 100644 --- a/core/tests/Drupal/Tests/Core/Entity/EntityUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/EntityUnitTest.php @@ -102,6 +102,10 @@ protected function setUp(): void { $this->entityType->expects($this->any()) ->method('getListCacheTags') ->willReturn([$this->entityTypeId . '_list']); + $this->entityType->expects($this->any()) + ->method('getBundleListCacheTags') + ->with($this->entityTypeId) + ->willReturn([$this->entityTypeId . '_list:' . $this->entityTypeId]); $this->entityTypeManager = $this->createMock(EntityTypeManagerInterface::class); $this->entityTypeManager->expects($this->any())