feature #24321 added ability to handle parent classes for PropertyNormalizer (ivoba)
This PR was squashed before being merged into the 3.4 branch (closes #24321).
Discussion
----------
added ability to handle parent classes for PropertyNormalizer
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | no
| New feature? | yes <!-- don't forget updating src/**/CHANGELOG.md files -->
| BC breaks? | no
| Deprecations? | no <!-- don't forget updating UPGRADE-*.md files -->
| Tests pass? | yes
| Fixed tickets | #24152 <!-- #-prefixed issue number(s), if any -->
| License | MIT
| Doc PR | symfony/symfony-docs#... <!--highly recommended for new features-->
<!--
- Bug fixes must be submitted against the lowest branch where they apply
(lowest branches are regularly merged to upper ones so they get the fixes too).
- Features and deprecations must be submitted against the 3.4,
legacy code removals go to the master branch.
- Please fill in this template according to the PR you're about to submit.
- Replace this comment by a description of what your PR is solving.
-->
This adds the ability for PropertyNormalizer to normalize/denormalize properties from parent classes.
Commits
-------
5ecafc5e25
added ability to handle parent classes for PropertyNormalizer
This commit is contained in:
commit
0f5e38c732
@ -79,7 +79,7 @@ class PropertyNormalizer extends AbstractObjectNormalizer
|
||||
}
|
||||
|
||||
try {
|
||||
$reflectionProperty = new \ReflectionProperty(is_string($classOrObject) ? $classOrObject : get_class($classOrObject), $attribute);
|
||||
$reflectionProperty = $this->getReflectionProperty($classOrObject, $attribute);
|
||||
if ($reflectionProperty->isStatic()) {
|
||||
return false;
|
||||
}
|
||||
@ -98,13 +98,15 @@ class PropertyNormalizer extends AbstractObjectNormalizer
|
||||
$reflectionObject = new \ReflectionObject($object);
|
||||
$attributes = array();
|
||||
|
||||
foreach ($reflectionObject->getProperties() as $property) {
|
||||
if (!$this->isAllowedAttribute($object, $property->name)) {
|
||||
continue;
|
||||
}
|
||||
do {
|
||||
foreach ($reflectionObject->getProperties() as $property) {
|
||||
if (!$this->isAllowedAttribute($reflectionObject->getName(), $property->name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$attributes[] = $property->name;
|
||||
}
|
||||
$attributes[] = $property->name;
|
||||
}
|
||||
} while ($reflectionObject = $reflectionObject->getParentClass());
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
@ -115,7 +117,7 @@ class PropertyNormalizer extends AbstractObjectNormalizer
|
||||
protected function getAttributeValue($object, $attribute, $format = null, array $context = array())
|
||||
{
|
||||
try {
|
||||
$reflectionProperty = new \ReflectionProperty(get_class($object), $attribute);
|
||||
$reflectionProperty = $this->getReflectionProperty($object, $attribute);
|
||||
} catch (\ReflectionException $reflectionException) {
|
||||
return;
|
||||
}
|
||||
@ -134,7 +136,7 @@ class PropertyNormalizer extends AbstractObjectNormalizer
|
||||
protected function setAttributeValue($object, $attribute, $value, $format = null, array $context = array())
|
||||
{
|
||||
try {
|
||||
$reflectionProperty = new \ReflectionProperty(get_class($object), $attribute);
|
||||
$reflectionProperty = $this->getReflectionProperty($object, $attribute);
|
||||
} catch (\ReflectionException $reflectionException) {
|
||||
return;
|
||||
}
|
||||
@ -150,4 +152,26 @@ class PropertyNormalizer extends AbstractObjectNormalizer
|
||||
|
||||
$reflectionProperty->setValue($object, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|object $classOrObject
|
||||
* @param string $attribute
|
||||
*
|
||||
* @return \ReflectionProperty
|
||||
*
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
private function getReflectionProperty($classOrObject, $attribute)
|
||||
{
|
||||
$reflectionClass = new \ReflectionClass($classOrObject);
|
||||
while (true) {
|
||||
try {
|
||||
return $reflectionClass->getProperty($attribute);
|
||||
} catch (\ReflectionException $e) {
|
||||
if (!$reflectionClass = $reflectionClass->getParentClass()) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,33 @@
|
||||
<?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 GroupDummyChild extends GroupDummy
|
||||
{
|
||||
private $baz;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBaz()
|
||||
{
|
||||
return $this->baz;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $baz
|
||||
*/
|
||||
public function setBaz($baz)
|
||||
{
|
||||
$this->baz = $baz;
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
|
||||
use Symfony\Component\Serializer\Serializer;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
use Symfony\Component\Serializer\Tests\Fixtures\GroupDummy;
|
||||
use Symfony\Component\Serializer\Tests\Fixtures\GroupDummyChild;
|
||||
use Symfony\Component\Serializer\Tests\Fixtures\MaxDepthDummy;
|
||||
use Symfony\Component\Serializer\Tests\Fixtures\PropertyCircularReferenceDummy;
|
||||
use Symfony\Component\Serializer\Tests\Fixtures\PropertySiblingHolder;
|
||||
@ -65,6 +66,35 @@ class PropertyNormalizerTest extends TestCase
|
||||
$this->assertEquals('bar', $obj->getBar());
|
||||
}
|
||||
|
||||
public function testNormalizeWithParentClass()
|
||||
{
|
||||
$group = new GroupDummyChild();
|
||||
$group->setBaz('baz');
|
||||
$group->setFoo('foo');
|
||||
$group->setBar('bar');
|
||||
$group->setKevin('Kevin');
|
||||
$group->setCoopTilleuls('coop');
|
||||
$this->assertEquals(
|
||||
array('foo' => 'foo', 'bar' => 'bar', 'kevin' => 'Kevin',
|
||||
'coopTilleuls' => 'coop', 'fooBar' => null, 'symfony' => null, 'baz' => 'baz', ),
|
||||
$this->normalizer->normalize($group, 'any')
|
||||
);
|
||||
}
|
||||
|
||||
public function testDenormalizeWithParentClass()
|
||||
{
|
||||
$obj = $this->normalizer->denormalize(
|
||||
array('foo' => 'foo', 'bar' => 'bar', 'kevin' => 'Kevin', 'baz' => 'baz'),
|
||||
GroupDummyChild::class,
|
||||
'any'
|
||||
);
|
||||
$this->assertEquals('foo', $obj->getFoo());
|
||||
$this->assertEquals('bar', $obj->getBar());
|
||||
$this->assertEquals('Kevin', $obj->getKevin());
|
||||
$this->assertEquals('baz', $obj->getBaz());
|
||||
$this->assertNull($obj->getSymfony());
|
||||
}
|
||||
|
||||
public function testConstructorDenormalize()
|
||||
{
|
||||
$obj = $this->normalizer->denormalize(
|
||||
@ -147,12 +177,14 @@ class PropertyNormalizerTest extends TestCase
|
||||
'bar' => 'bar',
|
||||
), $this->normalizer->normalize($obj, null, array(PropertyNormalizer::GROUPS => array('c'))));
|
||||
|
||||
// The PropertyNormalizer is not able to hydrate properties from parent classes
|
||||
// The PropertyNormalizer is also able to hydrate properties from parent classes
|
||||
$this->assertEquals(array(
|
||||
'symfony' => 'symfony',
|
||||
'foo' => 'foo',
|
||||
'fooBar' => 'fooBar',
|
||||
'bar' => 'bar',
|
||||
'kevin' => 'kevin',
|
||||
'coopTilleuls' => 'coopTilleuls',
|
||||
), $this->normalizer->normalize($obj, null, array(PropertyNormalizer::GROUPS => array('a', 'c'))));
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user