diff --git a/public/modules/custom/helfi_annif/src/KeywordManager.php b/public/modules/custom/helfi_annif/src/KeywordManager.php index 08d91e3f7..35bfd8129 100644 --- a/public/modules/custom/helfi_annif/src/KeywordManager.php +++ b/public/modules/custom/helfi_annif/src/KeywordManager.php @@ -4,6 +4,7 @@ namespace Drupal\helfi_annif; +use Drupal\Core\Cache\CacheTagsInvalidatorInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; @@ -44,6 +45,8 @@ final class KeywordManager { * The keyword generator. * @param \Drupal\Core\Queue\QueueFactory $queueFactory * The queue factory. + * @param \Drupal\Core\Cache\CacheTagsInvalidatorInterface $cacheTagsInvalidator + * The cache validator. * * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException @@ -52,6 +55,7 @@ public function __construct( private readonly EntityTypeManagerInterface $entityTypeManager, private readonly KeywordClient $keywordGenerator, private readonly QueueFactory $queueFactory, + private readonly CacheTagsInvalidatorInterface $cacheTagsInvalidator, ) { $this->termStorage = $this->entityTypeManager->getStorage('taxonomy_term'); } @@ -268,6 +272,7 @@ private function saveKeywords(EntityInterface $entity, array $keywords) : void { // processedItems is set for update hooks. $this->processedItems[$this->getEntityKey($entity)] = TRUE; + $this->invalidateCacheTags($terms); $entity->save(); } @@ -315,4 +320,19 @@ private function getTerm(Keyword $keyword, string $langcode) { return $term; } + /** + * Invalidate Annif-keyword terms' cache tags. + * + * @param array $terms + * Array of terms to process. + */ + private function invalidateCacheTags(array $terms): void { + $cacheTags = array_map( + fn ($term) => $term->getCacheTags(), + $terms + ); + + $this->cacheTagsInvalidator->invalidateTags(array_merge(...$cacheTags)); + } + } diff --git a/public/modules/custom/helfi_annif/src/Plugin/Block/RecommendationsBlock.php b/public/modules/custom/helfi_annif/src/Plugin/Block/RecommendationsBlock.php index 1ba6a66ac..ee1ec8660 100644 --- a/public/modules/custom/helfi_annif/src/Plugin/Block/RecommendationsBlock.php +++ b/public/modules/custom/helfi_annif/src/Plugin/Block/RecommendationsBlock.php @@ -94,7 +94,11 @@ public function getCacheContexts(): array { * {@inheritdoc} */ public function getCacheTags(): array { - return Cache::mergeTags(parent::getCacheTags(), $this->getContextValue('node')->getCacheTags()); + return Cache::mergeTags( + parent::getCacheTags(), + $this->getContextValue('node')->getCacheTags(), + $this->getAnnifKeywordCacheTags() + ); } /** @@ -115,4 +119,25 @@ private function handleNoRecommendations(array $response): array { return $response; } + /** + * Get list of cache tags for the block. + * + * @return array + * Array of cache tags for Annif-keywords related to this node. + */ + private function getAnnifKeywordCacheTags(): array { + $entity = $this->getContextValue('node'); + if (!$entity->hasField('field_annif_keywords') || $entity->get('field_annif_keywords')->isEmpty()) { + return []; + } + + $cacheTags = array_map( + fn ($term) => $term->getCacheTags(), + $entity->get('field_annif_keywords')->referencedEntities() + ); + + // Flatten array by merging the destructed arrays. + return array_merge(...$cacheTags); + } + } diff --git a/public/modules/custom/helfi_annif/tests/src/Kernel/KeywordManagerTest.php b/public/modules/custom/helfi_annif/tests/src/Kernel/KeywordManagerTest.php index 17204fc88..4dc41198b 100644 --- a/public/modules/custom/helfi_annif/tests/src/Kernel/KeywordManagerTest.php +++ b/public/modules/custom/helfi_annif/tests/src/Kernel/KeywordManagerTest.php @@ -25,6 +25,7 @@ class KeywordManagerTest extends KernelTestBase { use AnnifApiTestTrait; + /** * {@inheritdoc} */ @@ -133,10 +134,13 @@ private function getSut( ->get(Argument::any()) ->willReturn($queue); + $cacheInvalidator = $this->container->get('cache_tags.invalidator'); + return new KeywordManager( $entityTypeManager, $client, - $queueFactory->reveal() + $queueFactory->reveal(), + $cacheInvalidator ); } diff --git a/public/modules/custom/helfi_annif/tests/src/Unit/KeywordManagerTest.php b/public/modules/custom/helfi_annif/tests/src/Unit/KeywordManagerTest.php index 12c1b56b8..89973ac22 100644 --- a/public/modules/custom/helfi_annif/tests/src/Unit/KeywordManagerTest.php +++ b/public/modules/custom/helfi_annif/tests/src/Unit/KeywordManagerTest.php @@ -4,6 +4,7 @@ namespace Drupal\Tests\helfi_annif\Unit\TextConverter; +use Drupal\Core\Cache\CacheTagsInvalidatorInterface; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Queue\QueueFactory; @@ -128,10 +129,15 @@ private function getSut( ->get(Argument::any()) ->willReturn($queue); + $cacheInvalidator = $this->prophesize(CacheTagsInvalidatorInterface::class); + $cacheInvalidator + ->invalidateTags(['taxonomy_term:1234']); + return new KeywordManager( $entityTypeManager->reveal(), $client, - $queueFactory->reveal() + $queueFactory->reveal(), + $cacheInvalidator->reveal(), ); }