Skip to content

Commit 967058d

Browse files
committed
Fix ComponentGroup–Layout/Page ManyToMany join table not written
Creating ComponentGroups after the initial flush left the collection as ArrayCollection; Doctrine only tracks PersistentCollection changes for ManyToMany. Fix: create and link ComponentGroups in phaseOne and evaluateNested while both owner and group are still new entities, so Doctrine writes the join table on the same flush.
1 parent 87c4f4d commit 967058d

1 file changed

Lines changed: 35 additions & 39 deletions

File tree

src/Fixture/CwaFixtureBuilder.php

Lines changed: 35 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,9 @@ private function evaluateNested(): void
247247
}
248248
$this->timestampedPersister->persistTimestampedFields($page, true);
249249
$this->persistWithAssociations($page);
250+
foreach ($spec['builder']->getGroupBuilders() as $groupBuilder) {
251+
$this->createAndLinkComponentGroup($groupBuilder, $page);
252+
}
250253
$hasNew = true;
251254
}
252255

@@ -261,6 +264,9 @@ private function phaseOne(): void
261264
$layout = $layoutBuilder->getLayout();
262265
$this->timestampedPersister->persistTimestampedFields($layout, true);
263266
$this->persistWithAssociations($layout);
267+
foreach ($layoutBuilder->getGroupBuilders() as $groupBuilder) {
268+
$this->createAndLinkComponentGroup($groupBuilder, $layout);
269+
}
264270
}
265271

266272
foreach ($this->pageSpecs as $spec) {
@@ -271,6 +277,9 @@ private function phaseOne(): void
271277
}
272278
$this->timestampedPersister->persistTimestampedFields($page, true);
273279
$this->persistWithAssociations($page);
280+
foreach ($spec['builder']->getGroupBuilders() as $groupBuilder) {
281+
$this->createAndLinkComponentGroup($groupBuilder, $page);
282+
}
274283
}
275284

276285
foreach ($this->pageDataSpecs as $spec) {
@@ -285,52 +294,39 @@ private function phaseOne(): void
285294
$this->manager->flush();
286295
}
287296

288-
private function phaseTwo(): void
297+
private function createAndLinkComponentGroup(GroupBuilder $groupBuilder, Layout|Page $owner): void
289298
{
290-
$allGroupSpecs = [];
299+
$componentGroup = new ComponentGroup();
300+
$componentGroup->location = $groupBuilder->getName();
291301

292-
foreach ($this->layoutBuilders as $layoutBuilder) {
293-
foreach ($layoutBuilder->getGroupBuilders() as $groupBuilder) {
294-
$allGroupSpecs[] = ['group' => $groupBuilder, 'owner' => $layoutBuilder->getLayout()];
295-
}
302+
if ($owner instanceof Layout) {
303+
$componentGroup->reference = \sprintf('layout:%s/%s', $owner->reference, $groupBuilder->getName());
304+
} else {
305+
$componentGroup->reference = \sprintf('page:%s/%s', $owner->reference ?? $owner->getTitle(), $groupBuilder->getName());
296306
}
297307

298-
foreach ($this->pageSpecs as $spec) {
299-
foreach ($spec['builder']->getGroupBuilders() as $groupBuilder) {
300-
$allGroupSpecs[] = ['group' => $groupBuilder, 'owner' => $spec['builder']->getPage()];
301-
}
308+
foreach ($groupBuilder->getAllowedClasses() as $class) {
309+
$componentGroup->addAllowedComponent(
310+
$this->iriConverter->getIriFromResource(
311+
$class,
312+
UrlGeneratorInterface::ABS_PATH,
313+
(new GetCollection())->withClass($class)
314+
)
315+
);
302316
}
303317

304-
foreach ($allGroupSpecs as $item) {
305-
$groupBuilder = $item['group'];
306-
$owner = $item['owner'];
307-
308-
$componentGroup = new ComponentGroup();
309-
$componentGroup->location = $groupBuilder->getName();
310-
311-
if ($owner instanceof Layout) {
312-
$componentGroup->reference = \sprintf('layout:%s/%s', $owner->reference, $groupBuilder->getName());
313-
} else {
314-
$componentGroup->reference = \sprintf('page:%s/%s', $owner->reference ?? $owner->getTitle(), $groupBuilder->getName());
315-
}
316-
$owner->getComponentGroups()->add($componentGroup);
317-
318-
foreach ($groupBuilder->getAllowedClasses() as $class) {
319-
$componentGroup->addAllowedComponent(
320-
$this->iriConverter->getIriFromResource(
321-
$class,
322-
UrlGeneratorInterface::ABS_PATH,
323-
(new GetCollection())->withClass($class)
324-
)
325-
);
326-
}
327-
328-
$this->timestampedPersister->persistTimestampedFields($componentGroup, true);
329-
$this->componentGroupMap[spl_object_id($groupBuilder)] = $componentGroup;
330-
$this->manager->persist($componentGroup);
331-
}
318+
$this->timestampedPersister->persistTimestampedFields($componentGroup, true);
319+
// Add to the owning side BEFORE the first flush so Doctrine writes the join table.
320+
$owner->getComponentGroups()->add($componentGroup);
321+
$this->componentGroupMap[spl_object_id($groupBuilder)] = $componentGroup;
322+
$this->manager->persist($componentGroup);
323+
}
332324

333-
$this->manager->flush();
325+
private function phaseTwo(): void
326+
{
327+
// ComponentGroups are created and linked in phaseOne/evaluateNested
328+
// while both the owner and group are still new entities, so Doctrine
329+
// writes the ManyToMany join table correctly on the first flush.
334330
}
335331

336332
private function phaseThree(): void

0 commit comments

Comments
 (0)