[Form] fix Catchable Fatal Error if choices is not an array

This commit is contained in:
Gladhon 2015-12-29 09:29:43 +01:00 committed by Nicolas Grekas
parent a63dd194ed
commit f3c2a9beda
2 changed files with 33 additions and 12 deletions

View File

@ -263,9 +263,11 @@ class ChoiceType extends AbstractType
return $choices; 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 // 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 * are lost. Store them in a utility array that is used from the
* "choice_label" closure by default. * "choice_label" closure by default.
* *
* @param array $choices The choice labels indexed by choices. * @param array|\Traversable $choices The choice labels indexed by choices.
* Labels are replaced by generated keys. * @param object $choiceLabels The object that receives the choice labels
* @param object $choiceLabels The object that receives the choice labels * indexed by generated keys.
* indexed by generated keys. * @param int $nextKey The next generated key.
* @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 * @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. * 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) { foreach ($choices as $choice => $choiceLabel) {
if (is_array($choiceLabel)) { if (is_array($choiceLabel) || $choiceLabel instanceof \Traversable) {
$choiceLabel = ''; // Dereference $choices[$choice] $normalizedChoices[$choice] = self::normalizeLegacyChoices($choiceLabel, $choiceLabels, $nextKey);
self::normalizeLegacyChoices($choices[$choice], $choiceLabels, $nextKey);
continue; continue;
} }
$choiceLabels->labels[$nextKey] = $choiceLabel; $choiceLabels->labels[$nextKey] = $choiceLabel;
$choices[$choice] = $nextKey++; $normalizedChoices[$choice] = $nextKey++;
} }
return $normalizedChoices;
} }
} }

View File

@ -487,6 +487,21 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase
$this->assertTrue($form->isSynchronized()); $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 * @group legacy
*/ */