Skip to content

Commit 039645d

Browse files
committed
Refresh related resources before adding to purge services
1 parent 9c8edd5 commit 039645d

File tree

6 files changed

+52
-22
lines changed

6 files changed

+52
-22
lines changed

features/bootstrap/ProfilerContext.php

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,19 +99,33 @@ public function theMercureMessageShouldContainTimestampedFields()
9999
Assert::assertArrayHasKey('modifiedAt', $messageArray);
100100
}
101101

102+
private function getMercureComponentGroupMessage()
103+
{
104+
$messageObjects = $this->thereShouldBeAPublishedMercureUpdatePublished(2);
105+
$update = $messageObjects[1];
106+
$messageData = $update->getData();
107+
return $this->jsonContext->getJsonAsArray($messageData);
108+
}
109+
102110
/**
103111
* @Then the Mercure message for component group should contain timestamped fields
104112
*/
105113
public function theMercureMessageForComponentGroupShouldContainTimestampedFields()
106114
{
107-
$messageObjects = $this->thereShouldBeAPublishedMercureUpdatePublished(2);
108-
$update = $messageObjects[1];
109-
$messageData = $update->getData();
110-
$messageArray = $this->jsonContext->getJsonAsArray($messageData);
115+
$messageArray = $this->getMercureComponentGroupMessage();
111116
Assert::assertArrayHasKey('createdAt', $messageArray);
112117
Assert::assertArrayHasKey('modifiedAt', $messageArray);
113118
}
114119

120+
/**
121+
* @Then the Mercure message for component group should contain :count component position
122+
*/
123+
public function theMercureMessageForTheComponentGroupShouldContainCompontnPosition(int $count)
124+
{
125+
$messageArray = $this->getMercureComponentGroupMessage();
126+
Assert::assertCount($count, $messageArray['componentPositions']);
127+
}
128+
115129
/**
116130
* @Then there should be :count mercure messages for draft resources
117131
*/

features/main/component_position.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Feature: Component positions
1717
Then the response status code should be 201
1818
And the JSON should be valid according to the schema file "component_position.schema.json"
1919
And the Mercure message for component group should contain timestamped fields
20+
And the Mercure message for component group should contain 1 component position
2021

2122
@loginUser
2223
Scenario Outline: I can restrict which components are permitted to be inside a component collection and a component that must be specifically defined as being allowed to pass validation

src/EventListener/Doctrine/DoctrineResourceFlushListenerInterface.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace Silverback\ApiComponentsBundle\EventListener\Doctrine;
1515

1616
use Doctrine\ORM\Event\OnFlushEventArgs;
17+
use Doctrine\ORM\Event\PostFlushEventArgs;
1718
use Doctrine\ORM\Event\PreUpdateEventArgs;
1819

1920
/**
@@ -30,5 +31,5 @@ public function preUpdate(PreUpdateEventArgs $eventArgs): void;
3031

3132
public function onFlush(OnFlushEventArgs $eventArgs): void;
3233

33-
public function postFlush(): void;
34+
public function postFlush(PostFlushEventArgs $eventArgs): void;
3435
}

src/EventListener/Doctrine/DoctrineResourceFlushTrait.php

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Doctrine\Common\Util\ClassUtils;
2222
use Doctrine\ORM\EntityRepository;
2323
use Doctrine\ORM\Event\OnFlushEventArgs;
24+
use Doctrine\ORM\Event\PostFlushEventArgs;
2425
use Doctrine\ORM\Event\PreUpdateEventArgs;
2526
use Doctrine\ORM\PersistentCollection;
2627
use Doctrine\Persistence\ManagerRegistry;
@@ -40,6 +41,7 @@ trait DoctrineResourceFlushTrait
4041
private ObjectRepository|EntityRepository $collectionRepository;
4142
private ObjectRepository|EntityRepository $positionRepository;
4243
private array $resourceIris = [];
44+
private array $gatherRelatedForEntities = [];
4345

4446
public function __construct(
4547
private readonly IriConverterInterface $iriConverter,
@@ -78,22 +80,29 @@ public function onFlush(OnFlushEventArgs $eventArgs): void
7880
{
7981
$em = $eventArgs->getObjectManager();
8082
$uow = $em->getUnitOfWork();
83+
$this->gatherRelatedForEntities = [];
8184

8285
foreach ($uow->getScheduledEntityInsertions() as $entity) {
83-
$this->collectUpdatedResource($entity, 'created', $em, true);
86+
$this->collectUpdatedResource($entity, 'created');
87+
$this->gatherRelatedForEntities[] = $entity;
8488
}
8589

8690
foreach ($uow->getScheduledEntityUpdates() as $entity) {
87-
$this->collectUpdatedResource($entity, 'updated', $em, true);
91+
$this->collectUpdatedResource($entity, 'updated');
92+
$this->gatherRelatedForEntities[] = $entity;
8893
}
8994

9095
foreach ($uow->getScheduledEntityDeletions() as $entity) {
91-
$this->collectUpdatedResource($entity, 'deleted', $em, true);
96+
$this->collectUpdatedResource($entity, 'deleted');
97+
$this->gatherRelatedForEntities[] = $entity;
9298
}
9399
}
94100

95-
public function postFlush(): void
101+
public function postFlush(PostFlushEventArgs $eventArgs): void
96102
{
103+
foreach ($this->gatherRelatedForEntities as $object) {
104+
$this->gatherRelationResourceClasses($eventArgs->getObjectManager(), $object);
105+
}
97106
$this->addResourcesToPurge($this->gatherResourcesForPositionsWithPageDataProperties(), 'updated');
98107
$this->addResourcesToPurge($this->gatherIrisForCollectionResources(), 'updated');
99108
$this->purgeResources();
@@ -105,13 +114,27 @@ private function gatherRelationResourceClasses(ObjectManager $em, $entity): void
105114
foreach (array_keys($associationMappings) as $property) {
106115
if ($this->propertyAccessor->isReadable($entity, $property)) {
107116
$value = $this->propertyAccessor->getValue($entity, $property);
117+
if (!$value) {
118+
return;
119+
}
120+
108121
if ($value instanceof PersistentCollection) {
109122
foreach ($value as $item) {
123+
if (!$item) {
124+
continue;
125+
}
126+
if ($em->contains($item)) {
127+
$em->refresh($item);
128+
}
110129
$this->collectUpdatedResource($item, 'updated');
111130
}
112-
} else {
113-
$this->collectUpdatedResource($value, 'updated');
131+
return;
114132
}
133+
134+
if ($em->contains($value)) {
135+
$em->refresh($value);
136+
}
137+
$this->collectUpdatedResource($value, 'updated');
115138
}
116139
}
117140
}
@@ -160,16 +183,13 @@ private function getAssociationMappings(ObjectManager $em, $entity): array
160183
return $em->getClassMetadata(ClassUtils::getClass($entity))->getAssociationMappings();
161184
}
162185

163-
private function collectUpdatedResource($resource, string $type, ?ObjectManager $em = null, bool $gatherRelated = false): void
186+
private function collectUpdatedResource($resource, string $type): void
164187
{
165188
if (!$resource) {
166189
return;
167190
}
168191
$this->addResourceIris([$resource], $type);
169192
$this->resourceChangedPropagator->collectItems([$resource], $type);
170-
if ($gatherRelated && $em) {
171-
$this->gatherRelationResourceClasses($em, $resource);
172-
}
173193
}
174194

175195
private function addResourcesToPurge(array $resources, string $type): void

src/Mercure/MercureAuthorization.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public function __construct(
4141
public function getAuthorizationCookie(): Cookie
4242
{
4343
$subscribeTopics = $this->getSubscribeTopics();
44-
// Todo: await merge of https://github.com/symfony/mercure/pull/93 to remove ability to publish any updates and set to null
44+
// TODO: await merge of https://github.com/symfony/mercure/pull/93 to remove ability to publish any updates and set to null
4545
// May also be able to await a mercure bundle update to set the cookie samesite in mercure configs
4646
$cookie = $this->mercureAuthorization->createCookie($this->requestStack->getCurrentRequest(), $subscribeTopics, [], [], $this->hubName);
4747

tests/Functional/app/config/services_test.yaml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,6 @@ services:
2828
class: Silverback\ApiComponentsBundle\Tests\Functional\TestBundle\Stub\HubStub
2929
arguments:
3030
$factory: '@mercure.hub.default.jwt.factory'
31-
32-
# TODO: REMOVE when API Platform is using Symfony http client and work out mocking that instead
33-
# TODO: In tests the debug client should automatically be used with API Platform v3 using symfony not guzzle
34-
# api_platform.http_cache.purger.varnish.xkey:
35-
# arguments:
36-
# $clients: [ '@http_client' ]
3731

3832
# Test service to provide responses to the mock http client
3933
Silverback\ApiComponentsBundle\Tests\Functional\MockClientCallback: ~

0 commit comments

Comments
 (0)