properly handle null data when denormalizing
If null is passed to denormalize(), no property values can be set on the denormalized object. Additionally, this fixes passing values to the denormalized object's constructor if the incoming data is an object.
This commit is contained in:
parent
9572918064
commit
123fc62652
@ -114,6 +114,18 @@ class GetSetMethodNormalizer extends SerializerAwareNormalizer implements Normal
|
|||||||
*/
|
*/
|
||||||
public function denormalize($data, $class, $format = null, array $context = array())
|
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);
|
$reflectionClass = new \ReflectionClass($class);
|
||||||
$constructor = $reflectionClass->getConstructor();
|
$constructor = $reflectionClass->getConstructor();
|
||||||
|
|
||||||
@ -124,10 +136,10 @@ class GetSetMethodNormalizer extends SerializerAwareNormalizer implements Normal
|
|||||||
foreach ($constructorParameters as $constructorParameter) {
|
foreach ($constructorParameters as $constructorParameter) {
|
||||||
$paramName = lcfirst($this->formatAttribute($constructorParameter->name));
|
$paramName = lcfirst($this->formatAttribute($constructorParameter->name));
|
||||||
|
|
||||||
if (isset($data[$paramName])) {
|
if (isset($normalizedData[$paramName])) {
|
||||||
$params[] = $data[$paramName];
|
$params[] = $normalizedData[$paramName];
|
||||||
// don't run set for a parameter passed to the constructor
|
// don't run set for a parameter passed to the constructor
|
||||||
unset($data[$paramName]);
|
unset($normalizedData[$paramName]);
|
||||||
} elseif ($constructorParameter->isOptional()) {
|
} elseif ($constructorParameter->isOptional()) {
|
||||||
$params[] = $constructorParameter->getDefaultValue();
|
$params[] = $constructorParameter->getDefaultValue();
|
||||||
} else {
|
} else {
|
||||||
@ -144,7 +156,7 @@ class GetSetMethodNormalizer extends SerializerAwareNormalizer implements Normal
|
|||||||
$object = new $class;
|
$object = new $class;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($data as $attribute => $value) {
|
foreach ($normalizedData as $attribute => $value) {
|
||||||
$setter = 'set'.$this->formatAttribute($attribute);
|
$setter = 'set'.$this->formatAttribute($attribute);
|
||||||
|
|
||||||
if (method_exists($object, $setter)) {
|
if (method_exists($object, $setter)) {
|
||||||
|
@ -15,6 +15,11 @@ use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
|
|||||||
|
|
||||||
class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase
|
class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var GetSetMethodNormalizer
|
||||||
|
*/
|
||||||
|
private $normalizer;
|
||||||
|
|
||||||
protected function setUp()
|
protected function setUp()
|
||||||
{
|
{
|
||||||
$this->normalizer = new GetSetMethodNormalizer();
|
$this->normalizer = new GetSetMethodNormalizer();
|
||||||
@ -44,6 +49,17 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals('bar', $obj->getBar());
|
$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()
|
public function testDenormalizeOnCamelCaseFormat()
|
||||||
{
|
{
|
||||||
$this->normalizer->setCamelizedAttributes(array('camel_case'));
|
$this->normalizer->setCamelizedAttributes(array('camel_case'));
|
||||||
@ -54,6 +70,11 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals('camelCase', $obj->getCamelCase());
|
$this->assertEquals('camelCase', $obj->getCamelCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDenormalizeNull()
|
||||||
|
{
|
||||||
|
$this->assertEquals(new GetSetDummy(), $this->normalizer->denormalize(null, __NAMESPACE__.'\GetSetDummy'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider attributeProvider
|
* @dataProvider attributeProvider
|
||||||
*/
|
*/
|
||||||
@ -96,6 +117,17 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals(array(1, 2, 3), $obj->getBaz());
|
$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
|
* @dataProvider provideCallbacks
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user