diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoicesToValuesTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoicesToValuesTransformer.php index 4492865e5a64b..0cd0409a6670b 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoicesToValuesTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoicesToValuesTransformer.php @@ -23,14 +23,18 @@ class ChoicesToValuesTransformer implements DataTransformerInterface { private $choiceList; + private $ignoreInvalidChoices; + /** * Constructor. * * @param ChoiceListInterface $choiceList + * @param bool $ignoreInvalidChoices */ - public function __construct(ChoiceListInterface $choiceList) + public function __construct(ChoiceListInterface $choiceList, $ignoreInvalidChoices) { $this->choiceList = $choiceList; + $this->ignoreInvalidChoices = $ignoreInvalidChoices; } /** @@ -74,7 +78,7 @@ public function reverseTransform($array) $choices = $this->choiceList->getChoicesForValues($array); - if (count($choices) !== count($array)) { + if (!$this->ignoreInvalidChoices && count($choices) !== count($array)) { throw new TransformationFailedException('Could not find all matching choices for the given values'); } diff --git a/src/Symfony/Component/Form/Extension/Core/EventListener/FixCheckboxInputListener.php b/src/Symfony/Component/Form/Extension/Core/EventListener/FixCheckboxInputListener.php index 8e72b04137b79..fedb6b8619e6b 100644 --- a/src/Symfony/Component/Form/Extension/Core/EventListener/FixCheckboxInputListener.php +++ b/src/Symfony/Component/Form/Extension/Core/EventListener/FixCheckboxInputListener.php @@ -27,14 +27,18 @@ class FixCheckboxInputListener implements EventSubscriberInterface { private $choiceList; + private $ignoreInvalidChoices; + /** * Constructor. * * @param ChoiceListInterface $choiceList + * @param bool $ignoreInvalidChoices */ - public function __construct(ChoiceListInterface $choiceList) + public function __construct(ChoiceListInterface $choiceList, $ignoreInvalidChoices) { $this->choiceList = $choiceList; + $this->ignoreInvalidChoices = $ignoreInvalidChoices; } public function preSubmit(FormEvent $event) @@ -62,7 +66,7 @@ public function preSubmit(FormEvent $event) } } - if (count($submittedValues) > 0) { + if (!$this->ignoreInvalidChoices && count($submittedValues) > 0) { throw new TransformationFailedException(sprintf( 'The following choices were not found: "%s"', implode('", "', array_keys($submittedValues)) diff --git a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php index cdaee86b25b03..e3b0b076cd47b 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php @@ -70,14 +70,14 @@ public function buildForm(FormBuilderInterface $builder, array $options) if ($options['multiple']) { $builder->addViewTransformer(new ChoicesToBooleanArrayTransformer($options['choice_list'])); - $builder->addEventSubscriber(new FixCheckboxInputListener($options['choice_list']), 10); + $builder->addEventSubscriber(new FixCheckboxInputListener($options['choice_list'], $options['ignore_invalid_choices']), 10); } else { $builder->addViewTransformer(new ChoiceToBooleanArrayTransformer($options['choice_list'], $builder->has('placeholder'))); $builder->addEventSubscriber(new FixRadioInputListener($options['choice_list'], $builder->has('placeholder')), 10); } } else { if ($options['multiple']) { - $builder->addViewTransformer(new ChoicesToValuesTransformer($options['choice_list'])); + $builder->addViewTransformer(new ChoicesToValuesTransformer($options['choice_list'], $options['ignore_invalid_choices'])); } else { $builder->addViewTransformer(new ChoiceToValueTransformer($options['choice_list'])); } @@ -208,19 +208,20 @@ public function setDefaultOptions(OptionsResolverInterface $resolver) }; $resolver->setDefaults(array( - 'multiple' => false, - 'expanded' => false, - 'choice_list' => $choiceList, - 'choices' => array(), - 'preferred_choices' => array(), - 'empty_data' => $emptyData, - 'empty_value' => $emptyValue, - 'error_bubbling' => false, - 'compound' => $compound, + 'multiple' => false, + 'expanded' => false, + 'choice_list' => $choiceList, + 'choices' => array(), + 'preferred_choices' => array(), + 'ignore_invalid_choices' => false, + 'empty_data' => $emptyData, + 'empty_value' => $emptyValue, + 'error_bubbling' => false, + 'compound' => $compound, // The view data is always a string, even if the "data" option // is manually set to an object. // See https://github.com/symfony/symfony/pull/5582 - 'data_class' => null, + 'data_class' => null, )); $resolver->setNormalizers(array( diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoicesToValuesTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoicesToValuesTransformerTest.php index 572971938d527..36166aa54c4b8 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoicesToValuesTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoicesToValuesTransformerTest.php @@ -19,15 +19,19 @@ class ChoicesToValuesTransformerTest extends \PHPUnit_Framework_TestCase { protected $transformer; + protected $transformer2; + protected function setUp() { $list = new SimpleChoiceList(array(0 => 'A', 1 => 'B', 2 => 'C')); - $this->transformer = new ChoicesToValuesTransformer($list); + $this->transformer = new ChoicesToValuesTransformer($list, false); + $this->transformer2 = new ChoicesToValuesTransformer($list, true); } protected function tearDown() { $this->transformer = null; + $this->transformer2 = null; } public function testTransform() @@ -73,4 +77,13 @@ public function testReverseTransformExpectsArray() { $this->transformer->reverseTransform('foobar'); } + + public function testIgnoreInvalidChoicesTransform() + { + // Value strategy in SimpleChoiceList is to copy and convert to string + $in = array(2, 3, 4, 5); + $out = array('2'); + + $this->assertSame($out, $this->transformer2->transform($in)); + } }
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: