Skip to content

Commit 1ec3ff9

Browse files
committed
fix(symfony): cache invalidation should handle multiple GetCollection operations
1 parent 14d5e82 commit 1ec3ff9

3 files changed

Lines changed: 173 additions & 14 deletions

File tree

src/Symfony/Bundle/Resources/config/doctrine_orm_http_cache_purger.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
service('api_platform.http_cache.purger'),
2424
service('api_platform.iri_converter'),
2525
service('api_platform.resource_class_resolver'),
26+
service('api_platform.metadata.resource.metadata_collection_factory'),
2627
service('api_platform.property_accessor'),
2728
service('api_platform.object_mapper')->nullOnInvalid(),
2829
service('api_platform.object_mapper.metadata_factory')->nullOnInvalid(),

src/Symfony/Doctrine/EventListener/PurgeHttpCacheListener.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use ApiPlatform\Metadata\Exception\OperationNotFoundException;
1919
use ApiPlatform\Metadata\GetCollection;
2020
use ApiPlatform\Metadata\IriConverterInterface;
21+
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
2122
use ApiPlatform\Metadata\ResourceClassResolverInterface;
2223
use ApiPlatform\Metadata\UrlGeneratorInterface;
2324
use ApiPlatform\Metadata\Util\ClassInfoTrait;
@@ -48,9 +49,10 @@ final class PurgeHttpCacheListener
4849
public function __construct(private readonly PurgerInterface $purger,
4950
private readonly IriConverterInterface $iriConverter,
5051
private readonly ResourceClassResolverInterface $resourceClassResolver,
52+
private readonly ResourceMetadataCollectionFactoryInterface $resourceMetadataCollectionFactory,
5153
?PropertyAccessorInterface $propertyAccessor = null,
5254
private readonly ?ObjectMapperInterface $objectMapper = null,
53-
private readonly ?ObjectMapperMetadataFactoryInterface $objectMapperMetadata = null)
55+
private readonly ?ObjectMapperMetadataFactoryInterface $objectMapperMetadata = null, )
5456
{
5557
$this->propertyAccessor = $propertyAccessor ?? PropertyAccess::createPropertyAccessor();
5658
}
@@ -128,8 +130,17 @@ private function gatherResourceAndItemTags(object $entity, bool $purgeItem): voi
128130

129131
foreach ($resources as $resource) {
130132
try {
131-
$iri = $this->iriConverter->getIriFromResource($resource, UrlGeneratorInterface::ABS_PATH, new GetCollection());
132-
$this->tags[$iri] = $iri;
133+
// Here we need to loop on all GetCollection Operations, there can be multiple for a single resource class
134+
$resourceClass = $this->resourceClassResolver->getResourceClass($resource);
135+
$resourceMetadataCollection = $this->resourceMetadataCollectionFactory->create($resourceClass);
136+
foreach ($resourceMetadataCollection as $resourceMetadata) {
137+
foreach ($resourceMetadata->getOperations() as $operation) {
138+
if ($operation instanceof GetCollection) {
139+
$iri = $this->iriConverter->getIriFromResource($resource, UrlGeneratorInterface::ABS_PATH, $operation);
140+
$this->tags[$iri] = $iri;
141+
}
142+
}
143+
}
133144

134145
if ($purgeItem) {
135146
$this->addTagForItem($entity);

0 commit comments

Comments
 (0)