From 5df64dca520473beff1e6417f2acd4c27669966e Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Wed, 26 Aug 2015 17:48:02 +0200 Subject: [PATCH] Fix the retrieval of the value with property path when using a loader --- .../Factory/PropertyAccessDecorator.php | 8 ++++- .../Factory/PropertyAccessDecoratorTest.php | 30 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php b/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php index ef41d497be..87a364a5f4 100644 --- a/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php +++ b/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php @@ -141,7 +141,13 @@ class PropertyAccessDecorator implements ChoiceListFactoryInterface if ($value instanceof PropertyPath) { $accessor = $this->propertyAccessor; $value = function ($choice) use ($accessor, $value) { - return $accessor->getValue($choice, $value); + // The callable may be invoked with a non-object/array value + // when such values are passed to + // ChoiceListInterface::getValuesForChoices(). Handle this case + // so that the call to getValue() doesn't break. + if (is_object($choice) || is_array($choice)) { + return $accessor->getValue($choice, $value); + } }; } diff --git a/src/Symfony/Component/Form/Tests/ChoiceList/Factory/PropertyAccessDecoratorTest.php b/src/Symfony/Component/Form/Tests/ChoiceList/Factory/PropertyAccessDecoratorTest.php index 8697a9cac5..311db477b1 100644 --- a/src/Symfony/Component/Form/Tests/ChoiceList/Factory/PropertyAccessDecoratorTest.php +++ b/src/Symfony/Component/Form/Tests/ChoiceList/Factory/PropertyAccessDecoratorTest.php @@ -93,6 +93,36 @@ class PropertyAccessDecoratorTest extends \PHPUnit_Framework_TestCase $this->assertSame('value', $this->factory->createListFromLoader($loader, 'property')); } + // https://github.com/symfony/symfony/issues/5494 + public function testCreateFromChoicesAssumeNullIfValuePropertyPathUnreadable() + { + $choices = array(null); + + $this->decoratedFactory->expects($this->once()) + ->method('createListFromChoices') + ->with($choices, $this->isInstanceOf('\Closure')) + ->will($this->returnCallback(function ($choices, $callback) { + return array_map($callback, $choices); + })); + + $this->assertSame(array(null), $this->factory->createListFromChoices($choices, 'property')); + } + + // https://github.com/symfony/symfony/issues/5494 + public function testCreateFromChoiceLoaderAssumeNullIfValuePropertyPathUnreadable() + { + $loader = $this->getMock('Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface'); + + $this->decoratedFactory->expects($this->once()) + ->method('createListFromLoader') + ->with($loader, $this->isInstanceOf('\Closure')) + ->will($this->returnCallback(function ($loader, $callback) { + return $callback(null); + })); + + $this->assertNull($this->factory->createListFromLoader($loader, 'property')); + } + public function testCreateFromLoaderPropertyPathInstance() { $loader = $this->getMock('Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface');