From d7cda62ebf29f3dac1f38a156b5e82ece627869a Mon Sep 17 00:00:00 2001 From: michaljusiega Date: Fri, 11 Aug 2023 12:06:00 +0200 Subject: [PATCH] fix(serializer): use name converter #5495 --- features/hydra/error.feature | 12 ++++++++++++ features/jsonld/context.feature | 2 +- src/Serializer/AbstractItemNormalizer.php | 10 +++++++++- src/Symfony/Bundle/Resources/config/jsonld.xml | 2 +- tests/Serializer/ItemNormalizerTest.php | 2 +- 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/features/hydra/error.feature b/features/hydra/error.feature index 2dafb3ae705..97415f5f76c 100644 --- a/features/hydra/error.feature +++ b/features/hydra/error.feature @@ -139,3 +139,15 @@ Feature: Error handling And the JSON node "@id" should be equal to "/relation_embedders/1" And the JSON node "anotherRelated.@id" should be equal to "/related_dummies/1" And the JSON node "anotherRelated.symfony" should be equal to "phalcon" + + Scenario: Get an error because of sending bad type property + When I add "Content-Type" header equal to "application/json" + And I send a "POST" request to "/greetings" with body: + """ + { + "0": 1 + } + """ + Then the response status code should be 201 + And the response should be in JSON + And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8" diff --git a/features/jsonld/context.feature b/features/jsonld/context.feature index 45f324a742f..07ebacf38e2 100644 --- a/features/jsonld/context.feature +++ b/features/jsonld/context.feature @@ -40,7 +40,7 @@ Feature: JSON-LD contexts generation }, "jsonData": "Dummy/jsonData", "arrayData": "Dummy/arrayData", - "nameConverted": "Dummy/nameConverted", + "name_converted": "Dummy/name_converted", "name": "http://schema.org/name", "alias": "https://schema.org/alternateName", "foo": "Dummy/foo" diff --git a/src/Serializer/AbstractItemNormalizer.php b/src/Serializer/AbstractItemNormalizer.php index e9aa4986b7c..bae6c83be53 100644 --- a/src/Serializer/AbstractItemNormalizer.php +++ b/src/Serializer/AbstractItemNormalizer.php @@ -375,13 +375,21 @@ public function denormalize($data, $class, $format = null, array $context = []) return $object; } + $options = $this->getFactoryOptions($context); + $propertyNames = iterator_to_array($this->propertyNameCollectionFactory->create($resourceClass, $options)); + // Revert attributes that aren't allowed to be changed after a post-denormalize check foreach (array_keys($data) as $attribute) { + $attribute = $this->nameConverter ? $this->nameConverter->denormalize((string) $attribute) : $attribute; + if (!\in_array($attribute, $propertyNames, true)) { + continue; + } + if (!$this->canAccessAttributePostDenormalize($object, $previousObject, $attribute, $context)) { if (null !== $previousObject) { $this->setValue($object, $attribute, $this->propertyAccessor->getValue($previousObject, $attribute)); } else { - $propertyMetadata = $this->propertyMetadataFactory->create($resourceClass, $attribute, $this->getFactoryOptions($context)); + $propertyMetadata = $this->propertyMetadataFactory->create($resourceClass, $attribute, $options); $this->setValue($object, $attribute, $propertyMetadata->getDefault()); } } diff --git a/src/Symfony/Bundle/Resources/config/jsonld.xml b/src/Symfony/Bundle/Resources/config/jsonld.xml index 38042c0b34e..b534ffc2faa 100644 --- a/src/Symfony/Bundle/Resources/config/jsonld.xml +++ b/src/Symfony/Bundle/Resources/config/jsonld.xml @@ -11,7 +11,7 @@ - null + diff --git a/tests/Serializer/ItemNormalizerTest.php b/tests/Serializer/ItemNormalizerTest.php index 5cdef4e96da..75b06d75509 100644 --- a/tests/Serializer/ItemNormalizerTest.php +++ b/tests/Serializer/ItemNormalizerTest.php @@ -168,7 +168,7 @@ public function testDenormalizeWithIri() { $context = ['resource_class' => Dummy::class, 'api_allow_update' => true]; - $propertyNameCollection = new PropertyNameCollection(['name']); + $propertyNameCollection = new PropertyNameCollection(['id', 'name']); $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class); $propertyNameCollectionFactoryProphecy->create(Dummy::class, [])->willReturn($propertyNameCollection)->shouldBeCalled();