diff --git a/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php index 94ed6d8b63..88732bbd3e 100644 --- a/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php @@ -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)) { @@ -41,6 +43,7 @@ class ObjectNormalizer extends AbstractObjectNormalizer parent::__construct($classMetadataFactory, $nameConverter, $propertyTypeExtractor, $classDiscriminatorResolver, $objectClassResolver, $defaultContext); $this->propertyAccessor = $propertyAccessor ?: PropertyAccess::createPropertyAccessor(); + $this->objectClassResolver = $objectClassResolver; } /** @@ -60,7 +63,9 @@ class ObjectNormalizer extends AbstractObjectNormalizer $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() || diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php index b2bc76a86a..b4e0805281 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php @@ -1003,6 +1003,34 @@ class ObjectNormalizerTest extends TestCase $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 @@ -1064,6 +1092,11 @@ class ObjectDummy } } +class ProxyObjectDummy extends ObjectDummy +{ + public $unwantedProperty; +} + class ObjectConstructorDummy { protected $foo;