Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
ObjectNormalizer: allow null and scalar
  • Loading branch information
Hanmac committed Nov 3, 2025
commit 80f1df4f270f729e5a61d21c41233d1c7ca2ff94
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,11 @@ public function normalize(mixed $object, ?string $format = null, array $context
foreach ($stack as $attribute => $attributeValue) {
$attributeContext = $this->getAttributeNormalizationContext($object, $attribute, $context);

if (null === $attributeValue || \is_scalar($attributeValue)) {
$data = $this->updateData($data, $attribute, $attributeValue, $class, $format, $attributeContext, $attributesMetadata, $classMetadata);
continue;
}

if (!$this->serializer instanceof NormalizerInterface) {
if (null === $attributeValue || \is_scalar($attributeValue)) {
$data = $this->updateData($data, $attribute, $attributeValue, $class, $format, $attributeContext, $attributesMetadata, $classMetadata);
continue;
}
throw new LogicException(\sprintf('Cannot normalize attribute "%s" because the injected serializer is not a normalizer.', $attribute));
}

Expand Down Expand Up @@ -465,7 +464,7 @@ private function validateAndDenormalize(array $types, string $currentClass, stri

// This try-catch should cover all NotNormalizableValueException (and all return branches after the first
// exception) so we could try denormalizing all types of an union type. If the target type is not an union
// type, we will just re-throw the catched exception.
// type, we will just re-throw the caught exception.
// In the case of no denormalization succeeds with an union type, it will fall back to the default exception
// with the acceptable types list.
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -960,7 +960,7 @@ protected function createChildContext(array $parentContext, string $attribute, ?
$this->assertSame($firstChildContextCacheKey, $secondChildContextCacheKey);
}

public function testChildContextKeepsOriginalContextCacheKey()
public function testChildContextChangesContextCacheKey()
{
$foobar = new Dummy();
$foobar->foo = new EmptyDummy();
Expand Down Expand Up @@ -992,7 +992,7 @@ protected function createChildContext(array $parentContext, string $attribute, ?
$serializer = new Serializer([$normalizer]);
$serializer->normalize($foobar, null, ['cache_key' => 'hardcoded', 'iri' => '/dummy/1']);

$this->assertSame('hardcoded-foo', $normalizer->childContextCacheKey);
$this->assertSame('hardcoded-baz', $normalizer->childContextCacheKey);
}

public function testChildContextCacheKeyStaysFalseWhenOriginalCacheKeyIsFalse()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,8 @@ public function testNormalize()
$obj->setObject($object);

$this->serializer
->expects($this->once())
->method('normalize')
->with($object, 'any')
->willReturn('string_object')
->willReturnCallback(fn ($data) => $data === $object ? 'string_object' : $data)
;

$this->assertEquals(
Expand All @@ -111,6 +109,29 @@ public function testNormalize()
);
}

public function testNormalizeWithoutSerializer()
{
$obj = new GetSetDummy();
$obj->setFoo('foo');
$obj->setBar('bar');
$obj->setBaz(true);
$obj->setCamelCase('camelcase');

$this->normalizer = new GetSetMethodNormalizer();

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

public function testDenormalize()
{
$obj = $this->normalizer->denormalize(
Expand All @@ -125,6 +146,7 @@ public function testDenormalize()

public function testIgnoredAttributesInContext()
{
$this->serializer->method('normalize')->willReturnArgument(0);
$ignoredAttributes = ['foo', 'bar', 'baz', 'object'];
$obj = new GetSetDummy();
$obj->setFoo('foo');
Expand Down Expand Up @@ -281,6 +303,7 @@ protected function getDenormalizerForGroups(): GetSetMethodNormalizer

public function testGroupsNormalizeWithNameConverter()
{
$this->serializer->method('normalize')->willReturnArgument(0);
$classMetadataFactory = new ClassMetadataFactory(new AttributeLoader());
$this->normalizer = new GetSetMethodNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter());
$this->normalizer->setSerializer($this->serializer);
Expand Down Expand Up @@ -460,6 +483,7 @@ public function testHasGetterDenormalize()

public function testHasGetterNormalize()
{
$this->serializer->method('normalize')->willReturnArgument(0);
$obj = new ObjectWithHasGetterDummy();
$obj->setFoo(true);

Expand All @@ -477,6 +501,7 @@ public function testCallMagicMethodDenormalize()

public function testCallMagicMethodNormalize()
{
$this->serializer->method('normalize')->willReturnArgument(0);
$obj = new ObjectWithMagicMethod();

$this->assertSame(
Expand Down Expand Up @@ -537,6 +562,7 @@ public function testDenormalizeWithDiscriminator()

public function testSupportsAndNormalizeWithOnlyParentGetter()
{
$this->serializer->method('normalize')->willReturnArgument(0);
$obj = new GetSetDummyChild();
$obj->setFoo('foo');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,8 @@ public function testNormalize()
$obj->setGo(true);

$this->serializer
->expects($this->once())
->method('normalize')
->with($object, 'any')
->willReturn('string_object')
->willReturnCallback(static fn ($data) => $data === $object ? 'string_object' : $data)
;

$this->assertEquals(
Expand All @@ -132,8 +130,35 @@ public function testNormalize()
);
}

public function testNormalizeWithoutSerializer()
{
$obj = new ObjectDummy();
$obj->setFoo('foo');
$obj->bar = 'bar';
$obj->setBaz(true);
$obj->setCamelCase('camelcase');
$obj->setObject(null);
$obj->setGo(true);

$this->normalizer = new ObjectNormalizer();

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

public function testNormalizeObjectWithUninitializedProperties()
{
$this->serializer->method('normalize')->willReturnArgument(0);
$obj = new Php74Dummy();
$this->assertEquals(
['initializedProperty' => 'defaultValue'],
Expand All @@ -153,6 +178,7 @@ public function testNormalizeObjectWithUnsetProperties()

public function testNormalizeObjectWithLazyProperties()
{
$this->serializer->method('normalize')->willReturnArgument(0);
$obj = new LazyObjectInner();
unset($obj->foo);
$this->assertEquals(
Expand All @@ -163,6 +189,7 @@ public function testNormalizeObjectWithLazyProperties()

public function testNormalizeObjectWithUninitializedPrivateProperties()
{
$this->serializer->method('normalize')->willReturnArgument(0);
$obj = new Php74DummyPrivate();
$this->assertEquals(
['initializedProperty' => 'defaultValue'],
Expand All @@ -172,6 +199,7 @@ public function testNormalizeObjectWithUninitializedPrivateProperties()

public function testNormalizeObjectWithPrivatePropertyWithoutGetter()
{
$this->serializer->method('normalize')->willReturnArgument(0);
$obj = new DummyPrivatePropertyWithoutGetter();
$this->assertEquals(
['bar' => 'bar'],
Expand Down Expand Up @@ -504,6 +532,7 @@ protected function getDenormalizerForGroups(): ObjectNormalizer

public function testGroupsNormalizeWithNameConverter()
{
$this->serializer->method('normalize')->willReturnArgument(0);
$classMetadataFactory = new ClassMetadataFactory(new AttributeLoader());
$this->normalizer = new ObjectNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter());
$this->normalizer->setSerializer($this->serializer);
Expand Down Expand Up @@ -687,11 +716,13 @@ public function testNoTraversableSupport()

public function testNormalizeStatic()
{
$this->serializer->method('normalize')->willReturnArgument(0);
$this->assertEquals(['foo' => 'K'], $this->normalizer->normalize(new ObjectWithStaticPropertiesAndMethods()));
}

public function testNormalizeUpperCaseAttributes()
{
$this->serializer->method('normalize')->willReturnArgument(0);
$this->assertEquals(['Foo' => 'Foo', 'Bar' => 'BarBar'], $this->normalizer->normalize(new ObjectWithUpperCaseAttributeNames()));
}

Expand Down Expand Up @@ -877,6 +908,7 @@ public function testObjectClassResolver()

public function testNormalizeStdClass()
{
$this->serializer->method('normalize')->willReturnArgument(0);
$o1 = new \stdClass();
$o1->foo = 'f';
$o1->bar = 'b';
Expand Down Expand Up @@ -962,7 +994,7 @@ public function testObjectNormalizerWithAttributeLoaderAndObjectHasStaticPropert

protected function getNormalizerForAccessors($accessorPrefixes = null): ObjectNormalizer
{
$accessorPrefixes = $accessorPrefixes ?? ReflectionExtractor::$defaultAccessorPrefixes;
$accessorPrefixes ??= ReflectionExtractor::$defaultAccessorPrefixes;
$classMetadataFactory = new ClassMetadataFactory(new AttributeLoader());
$propertyAccessorBuilder = (new PropertyAccessorBuilder())
->setReadInfoExtractor(
Expand Down
Loading