Skip to content

Commit

Permalink
bug #30711 [Serializer] Use object class resolver when extracting att…
Browse files Browse the repository at this point in the history
…ributes (joelwurtz)

This PR was squashed before being merged into the 4.2 branch (closes #30711).

Discussion
----------

[Serializer] Use object class resolver when extracting attributes

| Q             | A
| ------------- | ---
| Branch?       | 4.2
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no (not sure)
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

Current ObjectNormalizer was not using the object class resolver when extracting attributes, i found this when trying to refactor api platform normalizers and dealing with doctrine proxy objet having __initialize__ property not wanted cf api-platform/core#2579

I don't think this is BC break, but maybe some people using this object class resolver can get different behavior ?

Commits
-------

1d8b5af [Serializer] Use object class resolver when extracting attributes
  • Loading branch information
fabpot committed Mar 27, 2019
2 parents 06e657a + 1d8b5af commit 84ce070
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
Expand Up @@ -32,6 +32,8 @@ class ObjectNormalizer extends AbstractObjectNormalizer

private $discriminatorCache = [];

private $objectClassResolver;

public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyAccessorInterface $propertyAccessor = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null, ClassDiscriminatorResolverInterface $classDiscriminatorResolver = null, callable $objectClassResolver = null, array $defaultContext = [])
{
if (!\class_exists(PropertyAccess::class)) {
Expand All @@ -41,6 +43,7 @@ public function __construct(ClassMetadataFactoryInterface $classMetadataFactory
parent::__construct($classMetadataFactory, $nameConverter, $propertyTypeExtractor, $classDiscriminatorResolver, $objectClassResolver, $defaultContext);

$this->propertyAccessor = $propertyAccessor ?: PropertyAccess::createPropertyAccessor();
$this->objectClassResolver = $objectClassResolver;
}

/**
Expand All @@ -60,7 +63,9 @@ protected function extractAttributes($object, $format = null, array $context = [
$attributes = [];

// methods
$reflClass = new \ReflectionClass($object);
$class = $this->objectClassResolver ? ($this->objectClassResolver)($object) : \get_class($object);
$reflClass = new \ReflectionClass($class);

foreach ($reflClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflMethod) {
if (
0 !== $reflMethod->getNumberOfRequiredParameters() ||
Expand Down
Expand Up @@ -1003,6 +1003,34 @@ public function denormalize($propertyName, string $class = null, string $format
$normalizer = new ObjectNormalizer(null, $nameConverter);
$this->assertArrayHasKey('foo-Symfony\Component\Serializer\Tests\Normalizer\ObjectDummy-json-bar', $normalizer->normalize(new ObjectDummy(), 'json', ['foo' => 'bar']));
}

public function testObjectClassResolver()
{
$classResolver = function ($object) {
return ObjectDummy::class;
};

$normalizer = new ObjectNormalizer(null, null, null, null, null, $classResolver);

$obj = new ProxyObjectDummy();
$obj->setFoo('foo');
$obj->bar = 'bar';
$obj->setBaz(true);
$obj->setCamelCase('camelcase');
$obj->unwantedProperty = 'notwanted';

$this->assertEquals(
[
'foo' => 'foo',
'bar' => 'bar',
'baz' => true,
'fooBar' => 'foobar',
'camelCase' => 'camelcase',
'object' => null,
],
$normalizer->normalize($obj, 'any')
);
}
}

class ObjectDummy
Expand Down Expand Up @@ -1064,6 +1092,11 @@ public function getObject()
}
}

class ProxyObjectDummy extends ObjectDummy
{
public $unwantedProperty;
}

class ObjectConstructorDummy
{
protected $foo;
Expand Down

0 comments on commit 84ce070

Please sign in to comment.