Skip to content

Commit

Permalink
feature #24321 added ability to handle parent classes for PropertyNor…
Browse files Browse the repository at this point in the history
…malizer (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
-------

5ecafc5 added ability to handle parent classes for PropertyNormalizer
  • Loading branch information
fabpot committed Oct 11, 2017
2 parents 78e5858 + 5ecafc5 commit 0f5e38c
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 10 deletions.
42 changes: 33 additions & 9 deletions src/Symfony/Component/Serializer/Normalizer/PropertyNormalizer.php
Expand Up @@ -79,7 +79,7 @@ protected function isAllowedAttribute($classOrObject, $attribute, $format = null
}

try {
$reflectionProperty = new \ReflectionProperty(is_string($classOrObject) ? $classOrObject : get_class($classOrObject), $attribute);
$reflectionProperty = $this->getReflectionProperty($classOrObject, $attribute);
if ($reflectionProperty->isStatic()) {
return false;
}
Expand All @@ -98,13 +98,15 @@ protected function extractAttributes($object, $format = null, array $context = a
$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;
}
Expand All @@ -115,7 +117,7 @@ protected function extractAttributes($object, $format = null, array $context = a
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;
}
Expand All @@ -134,7 +136,7 @@ protected function getAttributeValue($object, $attribute, $format = null, array
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;
}
Expand All @@ -150,4 +152,26 @@ protected function setAttributeValue($object, $attribute, $value, $format = null

$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;
}
}
Expand Up @@ -20,6 +20,7 @@
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;
Expand Down Expand Up @@ -65,6 +66,35 @@ public function testDenormalize()
$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(
Expand Down Expand Up @@ -147,12 +177,14 @@ public function testGroupsNormalize()
'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'))));
}

Expand Down

0 comments on commit 0f5e38c

Please sign in to comment.