From f3c2a9bedaad10633874b6bf89a95d0eb4a0c7fc Mon Sep 17 00:00:00 2001 From: Gladhon Date: Tue, 29 Dec 2015 09:29:43 +0100 Subject: [PATCH] [Form] fix Catchable Fatal Error if choices is not an array --- .../Form/Extension/Core/Type/ChoiceType.php | 30 +++++++++++-------- .../Extension/Core/Type/ChoiceTypeTest.php | 15 ++++++++++ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php index 1465551b90..59c6303d0b 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php @@ -263,9 +263,11 @@ class ChoiceType extends AbstractType return $choices; } - ChoiceType::normalizeLegacyChoices($choices, $choiceLabels); + if (null === $choices) { + return; + } - return $choices; + return ChoiceType::normalizeLegacyChoices($choices, $choiceLabels); }; // BC closure, to be removed in 3.0 @@ -503,26 +505,30 @@ class ChoiceType extends AbstractType * are lost. Store them in a utility array that is used from the * "choice_label" closure by default. * - * @param array $choices The choice labels indexed by choices. - * Labels are replaced by generated keys. - * @param object $choiceLabels The object that receives the choice labels - * indexed by generated keys. - * @param int $nextKey The next generated key. + * @param array|\Traversable $choices The choice labels indexed by choices. + * @param object $choiceLabels The object that receives the choice labels + * indexed by generated keys. + * @param int $nextKey The next generated key. + * + * @return array The choices in a normalized array with labels replaced by generated keys. * * @internal Public only to be accessible from closures on PHP 5.3. Don't * use this method as it may be removed without notice and will be in 3.0. */ - public static function normalizeLegacyChoices(array &$choices, $choiceLabels, &$nextKey = 0) + public static function normalizeLegacyChoices($choices, $choiceLabels, &$nextKey = 0) { + $normalizedChoices = array(); + foreach ($choices as $choice => $choiceLabel) { - if (is_array($choiceLabel)) { - $choiceLabel = ''; // Dereference $choices[$choice] - self::normalizeLegacyChoices($choices[$choice], $choiceLabels, $nextKey); + if (is_array($choiceLabel) || $choiceLabel instanceof \Traversable) { + $normalizedChoices[$choice] = self::normalizeLegacyChoices($choiceLabel, $choiceLabels, $nextKey); continue; } $choiceLabels->labels[$nextKey] = $choiceLabel; - $choices[$choice] = $nextKey++; + $normalizedChoices[$choice] = $nextKey++; } + + return $normalizedChoices; } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php index b404405d19..d7536f7640 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php @@ -487,6 +487,21 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $this->assertTrue($form->isSynchronized()); } + /** + * @group legacy + */ + public function testLegacyNullChoices() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => false, + 'choices' => null, + )); + $this->assertNull($form->getConfig()->getOption('choices')); + $this->assertFalse($form->getConfig()->getOption('multiple')); + $this->assertFalse($form->getConfig()->getOption('expanded')); + } + /** * @group legacy */