Skip to content

Commit 6391fe5

Browse files
committed
fix(cache): call iriConverter only for resources
1 parent d960a8b commit 6391fe5

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

src/Doctrine/EventListener/PurgeHttpCacheListener.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use ApiPlatform\Exception\RuntimeException;
2323
use ApiPlatform\HttpCache\PurgerInterface;
2424
use ApiPlatform\Metadata\GetCollection;
25+
use ApiPlatform\Util\ClassInfoTrait;
2526
use Doctrine\Common\Util\ClassUtils;
2627
use Doctrine\ORM\EntityManagerInterface;
2728
use Doctrine\ORM\Event\OnFlushEventArgs;
@@ -39,6 +40,8 @@
3940
*/
4041
final class PurgeHttpCacheListener
4142
{
43+
use ClassInfoTrait;
44+
4245
private $purger;
4346
private $iriConverter;
4447
private $resourceClassResolver;
@@ -163,8 +166,11 @@ private function addTagsFor($value): void
163166

164167
private function addTagForItem($value): void
165168
{
169+
if (!$this->resourceClassResolver->isResourceClass($this->getObjectClass($value))) {
170+
return;
171+
}
172+
166173
try {
167-
// TODO: test if this is a resource class
168174
$iri = $this->iriConverter instanceof LegacyIriConverterInterface ? $this->iriConverter->getIriFromItem($value) : $this->iriConverter->getIriFromResource($value);
169175
$this->tags[$iri] = $iri;
170176
} catch (RuntimeException|InvalidArgumentException $e) {

tests/Doctrine/EventListener/PurgeHttpCacheListenerTest.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
use ApiPlatform\Exception\ItemNotFoundException;
2323
use ApiPlatform\HttpCache\PurgerInterface;
2424
use ApiPlatform\Metadata\GetCollection;
25+
use ApiPlatform\Tests\Fixtures\NotAResource;
26+
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\ContainNonResource;
2527
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Dummy;
2628
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\DummyNoGetOperation;
2729
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\RelatedDummy;
@@ -74,6 +76,7 @@ public function testOnFlush()
7476
$iriConverterProphecy->getIriFromResource(Argument::any())->willThrow(new ItemNotFoundException());
7577

7678
$resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
79+
$resourceClassResolverProphecy->isResourceClass(Argument::type('string'))->willReturn(true)->shouldBeCalled();
7780
$resourceClassResolverProphecy->getResourceClass(Argument::type(Dummy::class))->willReturn(Dummy::class)->shouldBeCalled();
7881
$resourceClassResolverProphecy->getResourceClass(Argument::type(DummyNoGetOperation::class))->willReturn(DummyNoGetOperation::class)->shouldBeCalled();
7982

@@ -125,6 +128,7 @@ public function testPreUpdate()
125128
$iriConverterProphecy->getIriFromResource($newRelatedDummy)->willReturn('/related_dummies/new')->shouldBeCalled();
126129

127130
$resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
131+
$resourceClassResolverProphecy->isResourceClass(Argument::type('string'))->willReturn(true)->shouldBeCalled();
128132
$resourceClassResolverProphecy->getResourceClass(Argument::type(Dummy::class))->willReturn(Dummy::class)->shouldBeCalled();
129133

130134
$emProphecy = $this->prophesize(EntityManagerInterface::class);
@@ -168,4 +172,45 @@ public function testNothingToPurge()
168172
$listener->preUpdate($eventArgs);
169173
$listener->postFlush();
170174
}
175+
176+
public function testNotAResourceClass()
177+
{
178+
$containNonResource = new ContainNonResource();
179+
$nonResource = new NotAResource('foo', 'bar');
180+
181+
$purgerProphecy = $this->prophesize(PurgerInterface::class);
182+
$purgerProphecy->purge([])->shouldNotBeCalled();
183+
184+
$iriConverterProphecy = $this->prophesize(IriConverterInterface::class);
185+
$iriConverterProphecy->getIriFromResource(ContainNonResource::class, UrlGeneratorInterface::ABS_PATH, Argument::any())->willReturn('/dummies/1');
186+
$iriConverterProphecy->getIriFromResource($nonResource)->shouldNotBeCalled();
187+
188+
$resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
189+
$resourceClassResolverProphecy->getResourceClass(Argument::type(ContainNonResource::class))->willReturn(ContainNonResource::class)->shouldBeCalled();
190+
$resourceClassResolverProphecy->isResourceClass(NotAResource::class)->willReturn(false)->shouldBeCalled();
191+
192+
$emProphecy = $this->prophesize(EntityManagerInterface::class);
193+
194+
$uowProphecy = $this->prophesize(UnitOfWork::class);
195+
$uowProphecy->getScheduledEntityInsertions()->willReturn([$containNonResource])->shouldBeCalled();
196+
$uowProphecy->getScheduledEntityUpdates()->willReturn([])->shouldBeCalled();
197+
$uowProphecy->getScheduledEntityDeletions()->willReturn([])->shouldBeCalled();
198+
199+
$emProphecy = $this->prophesize(EntityManagerInterface::class);
200+
$emProphecy->getUnitOfWork()->willReturn($uowProphecy->reveal())->shouldBeCalled();
201+
202+
$dummyClassMetadata = new ClassMetadata(ContainNonResource::class);
203+
$dummyClassMetadata->associationMappings = [
204+
'notAResource' => [],
205+
];
206+
$emProphecy->getClassMetadata(ContainNonResource::class)->willReturn($dummyClassMetadata);
207+
$eventArgs = new OnFlushEventArgs($emProphecy->reveal());
208+
209+
$propertyAccessorProphecy = $this->prophesize(PropertyAccessorInterface::class);
210+
$propertyAccessorProphecy->isReadable(Argument::type(ContainNonResource::class), 'notAResource')->willReturn(true);
211+
$propertyAccessorProphecy->getValue(Argument::type(ContainNonResource::class), 'notAResource')->shouldBeCalled()->willReturn($nonResource);
212+
213+
$listener = new PurgeHttpCacheListener($purgerProphecy->reveal(), $iriConverterProphecy->reveal(), $resourceClassResolverProphecy->reveal(), $propertyAccessorProphecy->reveal());
214+
$listener->onFlush($eventArgs);
215+
}
171216
}

0 commit comments

Comments
 (0)