Skip to content

Commit

Permalink
purge tags for many-to-many relations
Browse files Browse the repository at this point in the history
  • Loading branch information
usu committed May 28, 2024
1 parent ce8df60 commit d2dd926
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 4 deletions.
24 changes: 24 additions & 0 deletions api/src/HttpCache/PurgeHttpCacheListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ public function preUpdate(PreUpdateEventArgs $eventArgs): void {
* Collects tags from inserted, updated and deleted entities, including relations.
*/
public function onFlush(OnFlushEventArgs $eventArgs): void {
/** @var EntityManagerInterface */
$em = method_exists($eventArgs, 'getObjectManager') ? $eventArgs->getObjectManager() : $eventArgs->getEntityManager();
$uow = $em->getUnitOfWork();

Expand All @@ -92,6 +93,16 @@ public function onFlush(OnFlushEventArgs $eventArgs): void {
$this->gatherResourceTags($em, $originalEntity);
$this->gatherRelationTags($em, $originalEntity);
}

// trigger cache purges for changes on many-to-many relations
// for some reason, changes to Many-To-Many relations are not included in the preUpdate changeSet
foreach ($uow->getScheduledCollectionUpdates() as $collection) {
$this->addTagsForManyToManyRelations($collection, $collection->getInsertDiff());
$this->addTagsForManyToManyRelations($collection, $collection->getDeleteDiff());
}
foreach ($uow->getScheduledCollectionDeletions() as $collection) {
$this->addTagsForManyToManyRelations($collection, $collection->getDeleteDiff());
}
}

/**
Expand All @@ -101,6 +112,19 @@ public function postFlush(): void {
$this->cacheManager->flush();
}

private function addTagsForManyToManyRelations($collection, $entities) {
$associationMapping = $collection->getMapping();

foreach ($entities as $entity) {
$relatedProperty = $associationMapping['isOwningSide'] ? $associationMapping['inversedBy'] : $associationMapping['mappedBy'];
if (!$relatedProperty) {
continue;
}

$this->addTagForItem($entity, $relatedProperty);
}
}

/**
* Computes the original state of the entity based on the current entity and on the changeset.
*/
Expand Down
9 changes: 5 additions & 4 deletions api/tests/Api/Categories/UpdateCategoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -521,19 +521,20 @@ public function testPatchCategoryPurgesCacheTags() {
'short' => 'LP',
'preferredContentTypes' => [
$this->getIriFor('contentTypeColumnLayout'),
$this->getIriFor('contentTypeSafetyConcept'),
$this->getIriFor('contentTypeNotes'),
],
], 'headers' => ['Content-Type' => 'application/merge-patch+json']]);

$this->assertResponseStatusCodeSame(200);

$contentTypeColumnLayout = static::getFixture('contentTypeColumnLayout');
$contentTypeNotes = static::getFixture('contentTypeNotes');
$contentTypeSafetyConcept = static::getFixture('contentTypeSafetyConcept');
self::assertEqualsCanonicalizing([
$category->getId(),
// TODO: fix PurgeHttpCacheListener to include the following tags:
// $contentTypeColumnLayout->getId().'#categories',
// $contentTypeSafetyConcept->getId().'#categories',
$contentTypeColumnLayout->getId().'#categories',
$contentTypeNotes->getId().'#categories',
$contentTypeSafetyConcept->getId().'#categories', // SafetyConcept was previously in the list, so this is purged because it was removed
], $purgedCacheTags);
}
}

0 comments on commit d2dd926

Please sign in to comment.