bug #11428 [Serializer] properly handle null data when denormalizing (xabbuh)

This PR was merged into the 2.3 branch.

Discussion
----------

[Serializer] properly handle null data when denormalizing

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #10794
| License       | MIT
| Doc PR        |

Commits
-------

123fc62 properly handle null data when denormalizing
This commit is contained in:
Fabien Potencier 2014-08-01 08:14:57 +02:00
commit 73ddf39ffc
2 changed files with 48 additions and 4 deletions

View File

@ -114,6 +114,18 @@ class GetSetMethodNormalizer extends SerializerAwareNormalizer implements Normal
*/
public function denormalize($data, $class, $format = null, array $context = array())
{
if (is_array($data) || is_object($data) && $data instanceof \ArrayAccess) {
$normalizedData = $data;
} elseif (is_object($data)) {
$normalizedData = array();
foreach ($data as $attribute => $value) {
$normalizedData[$attribute] = $value;
}
} else {
$normalizedData = array();
}
$reflectionClass = new \ReflectionClass($class);
$constructor = $reflectionClass->getConstructor();
@ -124,10 +136,10 @@ class GetSetMethodNormalizer extends SerializerAwareNormalizer implements Normal
foreach ($constructorParameters as $constructorParameter) {
$paramName = lcfirst($this->formatAttribute($constructorParameter->name));
if (isset($data[$paramName])) {
$params[] = $data[$paramName];
if (isset($normalizedData[$paramName])) {
$params[] = $normalizedData[$paramName];
// don't run set for a parameter passed to the constructor
unset($data[$paramName]);
unset($normalizedData[$paramName]);
} elseif ($constructorParameter->isOptional()) {
$params[] = $constructorParameter->getDefaultValue();
} else {
@ -144,7 +156,7 @@ class GetSetMethodNormalizer extends SerializerAwareNormalizer implements Normal
$object = new $class();
}
foreach ($data as $attribute => $value) {
foreach ($normalizedData as $attribute => $value) {
$setter = 'set'.$this->formatAttribute($attribute);
if (method_exists($object, $setter)) {

View File

@ -15,6 +15,11 @@ use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase
{
/**
* @var GetSetMethodNormalizer
*/
private $normalizer;
protected function setUp()
{
$this->normalizer = new GetSetMethodNormalizer();
@ -44,6 +49,17 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('bar', $obj->getBar());
}
public function testDenormalizeWithObject()
{
$data = new \stdClass();
$data->foo = 'foo';
$data->bar = 'bar';
$data->fooBar = 'foobar';
$obj = $this->normalizer->denormalize($data, __NAMESPACE__.'\GetSetDummy', 'any');
$this->assertEquals('foo', $obj->getFoo());
$this->assertEquals('bar', $obj->getBar());
}
public function testDenormalizeOnCamelCaseFormat()
{
$this->normalizer->setCamelizedAttributes(array('camel_case'));
@ -54,6 +70,11 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('camelCase', $obj->getCamelCase());
}
public function testDenormalizeNull()
{
$this->assertEquals(new GetSetDummy(), $this->normalizer->denormalize(null, __NAMESPACE__.'\GetSetDummy'));
}
/**
* @dataProvider attributeProvider
*/
@ -96,6 +117,17 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array(1, 2, 3), $obj->getBaz());
}
public function testConstructorWithObjectDenormalize()
{
$data = new \stdClass();
$data->foo = 'foo';
$data->bar = 'bar';
$data->fooBar = 'foobar';
$obj = $this->normalizer->denormalize($data, __NAMESPACE__.'\GetConstructorDummy', 'any');
$this->assertEquals('foo', $obj->getFoo());
$this->assertEquals('bar', $obj->getBar());
}
/**
* @dataProvider provideCallbacks
*/