@@ -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