Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2760a17

Browse files
[Serializer] Fix deserializing of nested snake_case attributes using CamelCaseToSnakeCaseNameConverter
1 parent 08018d8 commit 2760a17

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -326,13 +326,15 @@ public function denormalize(mixed $data, string $type, string $format = null, ar
326326
$mappedClass = $this->getMappedClass($normalizedData, $type, $context);
327327

328328
$nestedAttributes = $this->getNestedAttributes($mappedClass);
329-
$nestedData = [];
329+
$nestedData = $originalNestedData = [];
330330
$propertyAccessor = PropertyAccess::createPropertyAccessor();
331331
foreach ($nestedAttributes as $property => $serializedPath) {
332332
if (null === $value = $propertyAccessor->getValue($normalizedData, $serializedPath)) {
333333
continue;
334334
}
335-
$nestedData[$property] = $value;
335+
$convertedProperty = $this->nameConverter ? $this->nameConverter->normalize($property, $mappedClass, $format, $context) : $property;
336+
$nestedData[$convertedProperty] = $value;
337+
$originalNestedData[$property] = $value;
336338
$normalizedData = $this->removeNestedValue($serializedPath->getElements(), $normalizedData);
337339
}
338340

@@ -345,7 +347,7 @@ public function denormalize(mixed $data, string $type, string $format = null, ar
345347
if ($this->nameConverter) {
346348
$notConverted = $attribute;
347349
$attribute = $this->nameConverter->denormalize($attribute, $resolvedClass, $format, $context);
348-
if (isset($nestedData[$notConverted]) && !isset($nestedData[$attribute])) {
350+
if (isset($nestedData[$notConverted]) && !isset($originalNestedData[$attribute])) {
349351
throw new LogicException(sprintf('Duplicate values for key "%s" found. One value is set via the SerializedPath annotation: "%s", the other one is set via the SerializedName annotation: "%s".', $notConverted, implode('->', $nestedAttributes[$notConverted]->getElements()), $attribute));
350352
}
351353
}

src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
3434
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
3535
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
36+
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
3637
use Symfony\Component\Serializer\NameConverter\MetadataAwareNameConverter;
3738
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
3839
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
@@ -140,6 +141,20 @@ public function testDenormalizeWithNestedAttributesWithoutMetadata()
140141
$this->assertNull($test->notfoo);
141142
}
142143

144+
public function testDenormalizeWithSnakeCaseNestedAttributes()
145+
{
146+
$factory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
147+
$normalizer = new AbstractObjectNormalizerDummy($factory, new CamelCaseToSnakeCaseNameConverter());
148+
$serializer = new Serializer([$normalizer]);
149+
$data = [
150+
'one' => [
151+
'two_three' => 'fooBar',
152+
],
153+
];
154+
$test = $serializer->denormalize($data, SnakeCaseNestedDummy::class, 'any');
155+
$this->assertSame('fooBar', $test->fooBar);
156+
}
157+
143158
public function testDenormalizeWithNestedAttributes()
144159
{
145160
$normalizer = new AbstractObjectNormalizerWithMetadata();
@@ -770,7 +785,7 @@ protected function setAttributeValue(object $object, string $attribute, $value,
770785

771786
protected function isAllowedAttribute($classOrObject, string $attribute, string $format = null, array $context = []): bool
772787
{
773-
return \in_array($attribute, ['foo', 'baz', 'quux', 'value']);
788+
return \in_array($attribute, ['foo', 'baz', 'quux', 'value', 'fooBar']);
774789
}
775790

776791
public function instantiateObject(array &$data, string $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes, string $format = null): object
@@ -861,6 +876,14 @@ public function __construct(
861876
}
862877
}
863878

879+
class SnakeCaseNestedDummy
880+
{
881+
/**
882+
* @SerializedPath("[one][two_three]")
883+
*/
884+
public $fooBar;
885+
}
886+
864887
/**
865888
* @DiscriminatorMap(typeProperty="type", mapping={
866889
* "first" = FirstNestedDummyWithConstructorAndDiscriminator::class,

0 commit comments

Comments
 (0)