diff --git a/Normalizer/AbstractObjectNormalizer.php b/Normalizer/AbstractObjectNormalizer.php index 732586bd..79ede1a9 100644 --- a/Normalizer/AbstractObjectNormalizer.php +++ b/Normalizer/AbstractObjectNormalizer.php @@ -584,7 +584,7 @@ private function validateAndDenormalize(array $types, string $currentClass, stri $expectedTypes[Type::BUILTIN_TYPE_OBJECT === $builtinType && $class ? $class : $builtinType] = true; - if (Type::BUILTIN_TYPE_OBJECT === $builtinType) { + if (Type::BUILTIN_TYPE_OBJECT === $builtinType && null !== $class) { if (!$this->serializer instanceof DenormalizerInterface) { throw new LogicException(sprintf('Cannot denormalize attribute "%s" for class "%s" because injected serializer is not a denormalizer.', $attribute, $class)); } diff --git a/Tests/Normalizer/AbstractObjectNormalizerTest.php b/Tests/Normalizer/AbstractObjectNormalizerTest.php index 35616b65..4e781c5d 100644 --- a/Tests/Normalizer/AbstractObjectNormalizerTest.php +++ b/Tests/Normalizer/AbstractObjectNormalizerTest.php @@ -113,6 +113,17 @@ public function testDenormalizeWithExtraAttributesAndNoGroupsWithMetadataFactory ); } + public function testDenormalizePlainObject() + { + $extractor = new PhpDocExtractor(); + $normalizer = new ObjectNormalizer(null, null, null, $extractor); + $dummy = $normalizer->denormalize(['plainObject' => (object) ['foo' => 'bar']], DummyWithPlainObject::class); + + $this->assertInstanceOf(DummyWithPlainObject::class, $dummy); + $this->assertInstanceOf(\stdClass::class, $dummy->plainObject); + $this->assertSame('bar', $dummy->plainObject->foo); + } + public function testDenormalizeCollectionDecodedFromXmlWithOneChild() { $denormalizer = $this->getDenormalizerForDummyCollection(); @@ -598,6 +609,12 @@ protected function setAttributeValue(object $object, string $attribute, $value, } } +class DummyWithPlainObject +{ + /** @var object */ + public $plainObject; +} + class ObjectWithBasicProperties { /** @var bool */