diff --git a/Normalizer/AbstractObjectNormalizer.php b/Normalizer/AbstractObjectNormalizer.php index 4edbe9c3..487cd4bd 100644 --- a/Normalizer/AbstractObjectNormalizer.php +++ b/Normalizer/AbstractObjectNormalizer.php @@ -520,7 +520,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 16e869ef..0b91fc0d 100644 --- a/Tests/Normalizer/AbstractObjectNormalizerTest.php +++ b/Tests/Normalizer/AbstractObjectNormalizerTest.php @@ -121,6 +121,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 testDenormalizeWithDuplicateNestedAttributes() { $this->expectException(LogicException::class); @@ -1109,6 +1120,12 @@ protected function setAttributeValue(object $object, string $attribute, $value, } } +class DummyWithPlainObject +{ + /** @var object */ + public $plainObject; +} + class ObjectWithBasicProperties { /** @var bool */