1313
1414use A2lix \AutoFormBundle \Form \Attribute \AutoTypeCustom ;
1515use A2lix \AutoFormBundle \Form \Type \AutoType ;
16+ use Doctrine \Common \Collections \ArrayCollection ;
1617use Symfony \Component \Form \Extension \Core \Type \CollectionType ;
1718use Symfony \Component \Form \FormBuilderInterface ;
1819use Symfony \Component \Form \FormInterface ;
2627 * child_name?: string,
2728 * child_excluded?: bool,
2829 * child_embedded?: bool,
30+ * child_translated?: bool,
2931 * child_groups?: list<string>,
3032 * ...
3133 * }
3537 * children: array<string, ChildOptions|ChildBuilderCallable>,
3638 * children_excluded: list<string>|"*",
3739 * children_embedded: list<string>|"*",
40+ * children_translated: bool,
3841 * children_groups: list<string>|null,
3942 * builder: FormBuilderCallable|null,
4043 * }
@@ -52,6 +55,7 @@ public function __construct(
5255 public function buildChildren (FormBuilderInterface $ builder , array $ formOptions ): void
5356 {
5457 $ dataClass = $ this ->getDataClass ($ form = $ builder ->getForm ());
58+ dump ($ dataClass );
5559
5660 if (null === $ classProperties = $ this ->propertyInfoExtractor ->getProperties ($ dataClass )) {
5761 throw new \RuntimeException (\sprintf ('Unable to extract properties of "%s". ' , $ dataClass ));
@@ -61,7 +65,7 @@ public function buildChildren(FormBuilderInterface $builder, array $formOptions)
6165 $ allChildrenExcluded = '* ' === $ formOptions ['children_excluded ' ];
6266 $ allChildrenEmbedded = '* ' === $ formOptions ['children_embedded ' ];
6367 $ childrenGroups = $ formOptions ['children_groups ' ] ?? ['Default ' ];
64- $ formLevel = $ this ->getFormLevel ($ form );
68+ $ formDepth = $ this ->getFormDepth ($ form );
6569
6670 /** @var list<string> $classProperties */
6771 foreach ($ classProperties as $ classProperty ) {
@@ -116,12 +120,17 @@ public function buildChildren(FormBuilderInterface $builder, array $formOptions)
116120 // PropertyInfo? Enrich childOptions
117121 if (null !== $ propTypeInfo = $ this ->propertyInfoExtractor ->getType ($ dataClass , $ classProperty )) {
118122 // @phpstan-ignore argument.type
123+ $ formChildTranslated = ($ formOptions ['children_translated ' ] || ($ childOptions ['child_translated ' ] ?? false ))
124+ && ('translations ' === $ classProperty );
125+ // @phpstan-ignore argument.type
119126 $ formChildEmbedded = $ allChildrenEmbedded || \in_array ($ classProperty , $ formOptions ['children_embedded ' ], true )
120127 || ($ childOptions ['child_embedded ' ] ?? false );
121128
122- if ($ formChildEmbedded ) {
123- $ childOptions = $ this ->updateChildOptions ($ childOptions , $ propTypeInfo , $ formLevel );
124- }
129+ $ childOptions = match (true ) {
130+ $ formChildTranslated => $ this ->updateTranslatedChildOptions ($ childOptions , $ propTypeInfo , $ refProperty ),
131+ $ formChildEmbedded => $ this ->updateEmbeddedChildOptions ($ childOptions , $ propTypeInfo , $ refProperty , $ formDepth ),
132+ default => $ childOptions ,
133+ };
125134 }
126135
127136 $ this ->addChild ($ builder , $ classProperty , $ childOptions );
@@ -171,6 +180,7 @@ private function addChild(FormBuilderInterface $builder, string|FormBuilderInter
171180 $ options ['child_type ' ],
172181 $ options ['child_excluded ' ],
173182 $ options ['child_embedded ' ],
183+ $ options ['child_translated ' ],
174184 $ options ['child_groups ' ],
175185 );
176186
@@ -193,14 +203,41 @@ private function getDataClass(FormInterface $form): string
193203
194204 throw new \RuntimeException ('Unable to get dataClass ' );
195205 }
206+ /**
207+ * @param ChildOptions $baseChildOptions
208+ *
209+ * @return ChildOptions
210+ */
211+ private function updateTranslatedChildOptions (
212+ array $ baseChildOptions ,
213+ TypeInfo $ propTypeInfo ,
214+ \ReflectionProperty $ refProperty ,
215+ ): array {
216+ if (!$ propTypeInfo instanceof TypeInfo \CollectionType) {
217+ return [];
218+ }
219+
220+ dump ($ refProperty );
221+
222+ return [
223+ 'child_type ' => 'A2lix\TranslationFormBundle\Form\Type\TranslationsType ' ,
224+ 'translation_class ' => $ propTypeInfo ->getCollectionValueType ()->getClassName (),
225+ 'required ' => $ propTypeInfo ->isNullable (),
226+ ...$ baseChildOptions ,
227+ ];
228+ }
196229
197230 /**
198231 * @param ChildOptions $baseChildOptions
199232 *
200233 * @return ChildOptions
201234 */
202- private function updateChildOptions (array $ baseChildOptions , TypeInfo $ propTypeInfo , int $ formLevel ): array
203- {
235+ private function updateEmbeddedChildOptions (
236+ array $ baseChildOptions ,
237+ TypeInfo $ propTypeInfo ,
238+ \ReflectionProperty $ refProperty ,
239+ int $ formDepth
240+ ): array {
204241 // TypeInfo matching native FormType? Abort, guessers are enough
205242 if (self ::isTypeInfoWithMatchingNativeFormType ($ propTypeInfo )) {
206243 return $ baseChildOptions ;
@@ -214,7 +251,7 @@ private function updateChildOptions(array $baseChildOptions, TypeInfo $propTypeI
214251 'allow_delete ' => true ,
215252 'delete_empty ' => true ,
216253 'by_reference ' => false ,
217- 'prototype_name ' => '__name ' .$ formLevel .'__ ' ,
254+ 'prototype_name ' => '__name ' .$ formDepth .'__ ' ,
218255 ...$ baseChildOptions ,
219256 ];
220257
@@ -279,18 +316,18 @@ private static function isTypeInfoWithMatchingNativeFormType(TypeInfo $propTypeI
279316 /**
280317 * @param FormInterface<mixed> $form
281318 */
282- private function getFormLevel (FormInterface $ form ): int
319+ private function getFormDepth (FormInterface $ form ): int
283320 {
284321 if ($ form ->isRoot ()) {
285322 return 0 ;
286323 }
287324
288- $ level = 0 ;
325+ $ depth = 0 ;
289326 while (null !== $ formParent = $ form ->getParent ()) {
290327 $ form = $ formParent ;
291- ++$ level ;
328+ ++$ depth ;
292329 }
293330
294- return $ level ;
331+ return $ depth ;
295332 }
296333}
0 commit comments