diff --git a/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php index ac1c54def9..4adca3fe59 100644 --- a/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php @@ -136,11 +136,19 @@ class GetSetMethodNormalizer extends SerializerAwareNormalizer implements Normal foreach ($constructorParameters as $constructorParameter) { $paramName = lcfirst($this->formatAttribute($constructorParameter->name)); - if (isset($normalizedData[$paramName])) { + if (method_exists($constructorParameter, 'isVariadic') && $constructorParameter->isVariadic()) { + if (isset($normalizedData[$paramName])) { + if (!is_array($normalizedData[$paramName])) { + throw new RuntimeException(sprintf('Cannot create an instance of %s from serialized data because the variadic parameter %s can only accept an array.', $class, $constructorParameter->name)); + } + + $params = array_merge($params, $normalizedData[$paramName]); + } + } elseif (isset($normalizedData[$paramName])) { $params[] = $normalizedData[$paramName]; // don't run set for a parameter passed to the constructor unset($normalizedData[$paramName]); - } elseif ($constructorParameter->isOptional()) { + } elseif ($constructorParameter->isDefaultValueAvailable()) { $params[] = $constructorParameter->getDefaultValue(); } else { throw new RuntimeException( diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/VariadicConstructorArgsDummy.php b/src/Symfony/Component/Serializer/Tests/Fixtures/VariadicConstructorArgsDummy.php new file mode 100644 index 0000000000..c04aeba0c4 --- /dev/null +++ b/src/Symfony/Component/Serializer/Tests/Fixtures/VariadicConstructorArgsDummy.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Tests\Fixtures; + +class VariadicConstructorArgsDummy +{ + private $foo; + + public function __construct(...$foo) + { + $this->foo = $foo; + } + + public function getFoo() + { + return $this->foo; + } +} diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php index b22ccb5319..934b81b2e7 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php @@ -117,6 +117,28 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase $this->assertEquals(array(1, 2, 3), $obj->getBaz()); } + /** + * @requires PHP 5.6 + */ + public function testConstructorDenormalizeWithVariadicArgument() + { + $obj = $this->normalizer->denormalize( + array('foo' => array(1, 2, 3)), + 'Symfony\Component\Serializer\Tests\Fixtures\VariadicConstructorArgsDummy', 'any'); + $this->assertEquals(array(1, 2, 3), $obj->getFoo()); + } + + /** + * @requires PHP 5.6 + */ + public function testConstructorDenormalizeWithMissingVariadicArgument() + { + $obj = $this->normalizer->denormalize( + array(), + 'Symfony\Component\Serializer\Tests\Fixtures\VariadicConstructorArgsDummy', 'any'); + $this->assertEquals(array(), $obj->getFoo()); + } + public function testConstructorWithObjectDenormalize() { $data = new \stdClass();