diff --git a/Normalizer/AbstractObjectNormalizer.php b/Normalizer/AbstractObjectNormalizer.php index 34068030..6567c886 100644 --- a/Normalizer/AbstractObjectNormalizer.php +++ b/Normalizer/AbstractObjectNormalizer.php @@ -547,7 +547,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 16ed0c2d..fa34dcf2 100644 --- a/Tests/Normalizer/AbstractObjectNormalizerTest.php +++ b/Tests/Normalizer/AbstractObjectNormalizerTest.php @@ -122,6 +122,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); @@ -1145,6 +1156,12 @@ protected function setAttributeValue(object $object, string $attribute, $value, } } +class DummyWithPlainObject +{ + /** @var object */ + public $plainObject; +} + class ObjectWithBasicProperties { /** @var bool */