55use Fp \JsFormValidatorBundle \Form \Constraint \UniqueEntity ;
66use Fp \JsFormValidatorBundle \Model \JsConfig ;
77use Fp \JsFormValidatorBundle \Model \JsFormElement ;
8+ use Symfony \Component \Form \ChoiceList \ChoiceListInterface ;
89use Symfony \Component \Form \DataTransformerInterface ;
9- use Symfony \Component \Form \Extension \Core \ChoiceList \ChoiceListInterface ;
10+ use Symfony \Component \Form \Extension \Core \Type \ChoiceType ;
11+ use Symfony \Component \Form \Extension \Core \Type \HiddenType ;
1012use Symfony \Component \Form \Form ;
1113use Symfony \Component \Form \FormInterface ;
1214use Symfony \Component \Translation \TranslatorInterface ;
1315use Symfony \Component \Validator \Constraint ;
1416use Symfony \Component \Validator \Mapping \ClassMetadata ;
1517use Symfony \Component \Validator \Mapping \GetterMetadata ;
1618use Symfony \Component \Validator \Mapping \PropertyMetadata ;
17- use Symfony \Component \Validator \ValidatorInterface ;
19+ use Symfony \Component \Validator \Validator \ ValidatorInterface ;
1820
1921/**
2022 * This factory uses to parse a form to a tree of JsFormElement's
@@ -91,7 +93,7 @@ public function __construct(
9193 */
9294 protected function getMetadataFor ($ className )
9395 {
94- return $ this ->validator ->getMetadataFactory ()-> getMetadataFor ($ className );
96+ return $ this ->validator ->getMetadataFor ($ className );
9597 }
9698
9799 /**
@@ -242,13 +244,15 @@ public function createJsModel(Form $form)
242244 $ model = new JsFormElement ;
243245 $ model ->id = $ this ->getElementId ($ form );
244246 $ model ->name = $ form ->getName ();
245- $ model ->type = $ conf ->getType ()->getInnerType ()-> getName ( );
247+ $ model ->type = get_class ( $ conf ->getType ()->getInnerType ());
246248 $ model ->invalidMessage = $ this ->translateMessage (
247249 $ conf ->getOption ('invalid_message ' ),
248250 $ conf ->getOption ('invalid_message_parameters ' )
249251 );
250- $ model ->transformers = $ this ->parseTransformers ($ form ->getConfig ()->getViewTransformers ());
251- $ model ->cascade = $ conf ->getOption ('cascade_validation ' );
252+ $ model ->transformers = $ this ->normalizeViewTransformers (
253+ $ form ,
254+ $ this ->parseTransformers ($ conf ->getViewTransformers ())
255+ );
252256 $ model ->bubbling = $ conf ->getOption ('error_bubbling ' );
253257 $ model ->data = $ this ->getValidationData ($ form );
254258 $ model ->children = $ this ->processChildren ($ form );
@@ -315,8 +319,8 @@ protected function getValidationData(Form $form)
315319 $ parent = $ form ->getParent ();
316320 if ($ parent && null !== $ parent ->getConfig ()->getDataClass ()) {
317321 $ classMetadata = $ metadata = $ this ->getMetadataFor ($ parent ->getConfig ()->getDataClass ());
318- if ($ classMetadata ->hasMemberMetadatas ($ form ->getName ())) {
319- $ metadata = $ classMetadata ->getMemberMetadatas ($ form ->getName ());
322+ if ($ classMetadata ->hasPropertyMetadata ($ form ->getName ())) {
323+ $ metadata = $ classMetadata ->getPropertyMetadata ($ form ->getName ());
320324 /** @var PropertyMetadata $item */
321325 foreach ($ metadata as $ item ) {
322326 $ this ->composeValidationData (
@@ -444,8 +448,33 @@ protected function getValidationGroups(Form $form)
444448 */
445449 protected function isProcessableElement ($ element )
446450 {
447- return ($ element instanceof Form)
448- && ('hidden ' !== $ element ->getConfig ()->getType ()->getName ());
451+ return ($ element instanceof Form) && (!is_a ($ element ->getConfig ()->getType (), HiddenType::class, true ));
452+ }
453+
454+ /**
455+ * Gets view transformers from the given form.
456+ * Merges in an extra Choice(s)ToBooleanArrayTransformer transformer in case of expanded choice.
457+ *
458+ * @param FormInterface $form
459+ * @param array $viewTransformers
460+ *
461+ * @return array
462+ */
463+ protected function normalizeViewTransformers (FormInterface $ form , array $ viewTransformers )
464+ {
465+ $ config = $ form ->getConfig ();
466+
467+ // Choice(s)ToBooleanArrayTransformer was deprecated in SF2.7 in favor of CheckboxListMapper and RadioListMapper
468+ if ($ config ->getType ()->getInnerType () instanceof ChoiceType && $ config ->getOption ('expanded ' )) {
469+ $ namespace = 'Symfony\Component\Form\Extension\Core\DataTransformer \\' ;
470+ $ transformer = $ config ->getOption ('multiple ' )
471+ ? array ('name ' => $ namespace . 'ChoicesToBooleanArrayTransformer ' )
472+ : array ('name ' => $ namespace . 'ChoiceToBooleanArrayTransformer ' );
473+ $ transformer ['choiceList ' ] = array_values ($ config ->getOption ('choices ' ));
474+ array_unshift ($ viewTransformers , $ transformer );
475+ }
476+
477+ return $ viewTransformers ;
449478 }
450479
451480 /**
@@ -471,7 +500,6 @@ protected function parseTransformers(array $transformers)
471500
472501 $ result [] = $ item ;
473502 }
474-
475503 return $ result ;
476504 }
477505
@@ -495,7 +523,7 @@ protected function getTransformerParam(DataTransformerInterface $transformer, $p
495523 } elseif (is_scalar ($ value ) || is_array ($ value )) {
496524 $ result = $ value ;
497525 } elseif ($ value instanceof ChoiceListInterface) {
498- $ result = $ value ->getChoices ();
526+ $ result = array_values ( $ value ->getChoices () );
499527 }
500528
501529 return $ result ;
0 commit comments