Skip to content

Commit 25afa54

Browse files
committed
Double check for xdraft before creating new draft
1 parent 6cee8fa commit 25afa54

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

features/publishable/publishable.feature

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,8 @@ Feature: Access to unpublished/draft resources should be configurable
219219
@loginAdmin
220220
Scenario: As a user with draft access, when I update a published resource with a draft resource available, it should update and return the draft resource.
221221
Given there is a published resource with a draft set to publish at "2999-12-31T23:59:59+00:00"
222-
When I send a "PUT" request to the resource "publishable_draft" with body:
222+
And I add "Content-Type" header equal to "application/merge-patch+json"
223+
When I send a "PATCH" request to the resource "publishable_published" with body:
223224
"""
224225
{
225226
"reference": "updated"
@@ -229,6 +230,20 @@ Feature: Access to unpublished/draft resources should be configurable
229230
And the JSON node "publishedAt" should be equal to "2999-12-31T23:59:59+00:00"
230231
And the JSON node "reference" should be equal to "updated"
231232

233+
@loginAdmin
234+
Scenario: As a user with draft access, when I update a published with no draft, it should update and return a draft resource.
235+
Given there is a publishable resource set to publish at "1970-12-31T23:59:59+00:00"
236+
And I add "Content-Type" header equal to "application/merge-patch+json"
237+
When I send a "PATCH" request to the resource "publishable_published" with body:
238+
"""
239+
{
240+
"reference": "updated_again"
241+
}
242+
"""
243+
Then the response status code should be 200
244+
And the JSON node "publishedAt" should be null
245+
And the JSON node "reference" should be equal to "updated_again"
246+
232247
@loginAdmin
233248
Scenario Outline: As a user with draft access, when I update a published resource with a publication date in the past (or now), it should be ignored.
234249
Given there is a publishable resource set to publish at "1970-12-31T23:59:59+00:00"

src/Serializer/Normalizer/PublishableNormalizer.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ public function normalize($object, $format = null, array $context = []): float|a
8282
$resourceMetadata->setPublishable($isPublished);
8383

8484
$type = $object::class;
85+
8586
$configuration = $this->publishableStatusChecker->getAttributeReader()->getConfiguration($type);
8687
$em = $this->getManagerFromType($type);
8788
$classMetadata = $this->getClassMetadataInfo($em, $type);
@@ -171,7 +172,16 @@ public function denormalize($data, $type, $format = null, array $context = []):
171172
}
172173

173174
// Any field has been modified: create a draft
174-
$draft = $this->createDraft($object, $configuration, $type);
175+
// if we sent 2 simultaneous requests then the initial sql query will have got the live version even if there is a draft now, so let's re-check before creating
176+
$em = $this->getManagerFromType($type);
177+
$em->refresh($object);
178+
$configuration = $this->publishableStatusChecker->getAttributeReader()->getConfiguration($type);
179+
$em = $this->getManagerFromType($type);
180+
$classMetadata = $this->getClassMetadataInfo($em, $type);
181+
$draft = $classMetadata->getFieldValue($object, $configuration->reverseAssociationName);
182+
if (!$draft) {
183+
$draft = $this->createDraft($object, $configuration, $type);
184+
}
175185
$context[AbstractNormalizer::OBJECT_TO_POPULATE] = $draft;
176186

177187
return $this->denormalizer->denormalize($data, $type, $format, $context);
@@ -244,6 +254,9 @@ public function createDraft(object $object, Publishable $configuration, string $
244254
// Add draft object to UnitOfWork
245255
$em->persist($draft);
246256

257+
// todo: perhaps we need to flush here so if we get another request before flushed, we do not get a duplicate key sql error trying to create a draft when one already exists
258+
$em->flush($draft);
259+
247260
// Clear the cache of the published resource because it should now also return an associated draft
248261
$event = new ResourceChangedEvent($object, 'updated');
249262
$this->eventDispatcher->dispatch($event);

0 commit comments

Comments
 (0)