Skip to content

Commit

Permalink
bug #31438 [Serializer] Fix denormalization of object with variadic c…
Browse files Browse the repository at this point in the history
…onstructor typed argument (ajgarlag)

This PR was squashed before being merged into the 3.4 branch (closes #31438).

Discussion
----------

[Serializer] Fix denormalization of object with variadic constructor typed argument

| Q             | A
| ------------- | ---
| Branch?       | 3.4 up to 4.2
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #31436
| License       | MIT

This PR adds a test to demonstrate the bug, and a fix to squash it.

Commits
-------

c8c3c56 [Serializer] Fix denormalization of object with variadic constructor typed argument
  • Loading branch information
nicolas-grekas committed May 11, 2019
2 parents 11f8a1e + c8c3c56 commit 0055284
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 1 deletion.
Expand Up @@ -354,7 +354,13 @@ protected function instantiateObject(array &$data, $class, array &$context, \Ref
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, $data[$paramName]);
$variadicParameters = [];
foreach ($data[$paramName] as $parameterData) {
$variadicParameters[] = $this->denormalizeParameter($reflectionClass, $constructorParameter, $paramName, $parameterData, $context, $format);
}

$params = array_merge($params, $variadicParameters);
unset($data[$key]);
}
} elseif ($allowed && !$ignored && (isset($data[$key]) || \array_key_exists($key, $data))) {
$parameterData = $data[$key];
Expand Down
@@ -0,0 +1,27 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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 VariadicConstructorTypedArgsDummy
{
private $foo;

public function __construct(Dummy ...$foo)
{
$this->foo = $foo;
}

public function getFoo()
{
return $this->foo;
}
}
Expand Up @@ -8,11 +8,15 @@
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Tests\Fixtures\AbstractNormalizerDummy;
use Symfony\Component\Serializer\Tests\Fixtures\Dummy;
use Symfony\Component\Serializer\Tests\Fixtures\NullableConstructorArgumentDummy;
use Symfony\Component\Serializer\Tests\Fixtures\ProxyDummy;
use Symfony\Component\Serializer\Tests\Fixtures\StaticConstructorDummy;
use Symfony\Component\Serializer\Tests\Fixtures\StaticConstructorNormalizer;
use Symfony\Component\Serializer\Tests\Fixtures\VariadicConstructorTypedArgsDummy;

/**
* Provides a dummy Normalizer which extends the AbstractNormalizer.
Expand Down Expand Up @@ -128,4 +132,21 @@ public function testObjectWithNullableConstructorArgument()

$this->assertNull($dummy->getFoo());
}

/**
* @requires PHP 5.6
*/
public function testObjectWithVariadicConstructorTypedArguments()
{
$normalizer = new PropertyNormalizer();
$normalizer->setSerializer(new Serializer([$normalizer]));
$data = ['foo' => [['foo' => 'Foo', 'bar' => 'Bar', 'baz' => 'Baz', 'qux' => 'Qux'], ['foo' => 'FOO', 'bar' => 'BAR', 'baz' => 'BAZ', 'qux' => 'QUX']]];
$dummy = $normalizer->denormalize($data, VariadicConstructorTypedArgsDummy::class);

$this->assertInstanceOf(VariadicConstructorTypedArgsDummy::class, $dummy);
$this->assertCount(2, $dummy->getFoo());
foreach ($dummy->getFoo() as $foo) {
$this->assertInstanceOf(Dummy::class, $foo);
}
}
}

0 comments on commit 0055284

Please sign in to comment.