-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Serializer] SerializedPath option not working on non-scalar types, which are serialized into scalar (eg. DateTime) #49494
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Faced the same problem. Hey @boenner. What is the logical fallacy if properties are set to values? symfony/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php Lines 654 to 656 in 1dcb0f9
Because of this construction, we get an exception when serializing an object, for example, to json. A similar problem is described here #49225 |
The normalizer is trying to set the value multiple times because non-scalar values are pushed twice into I took your tests, @HonzaMatosik, into a branch and changed the behavior: https://github.com/boenner/symfony/tree/serializer-serializedpath-with-non-scalar-types. Can you check if that fix works for you? |
Hi this works great |
…enner) This PR was merged into the 6.2 branch. Discussion ---------- [Serializer] Fix serialized path for non-scalar values | Q | A | ------------- | --- | Branch? | 6.2 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #49494 | License | MIT | Doc PR | no This relates to #49494 and #49225. When non-scalar values are normalized, they are normalized twice in the `normalize()` function: ```php if (null !== $attributeValue && !\is_scalar($attributeValue)) { $stack[$attribute] = $attributeValue; } $data = $this->updateData($data, $attribute, $attributeValue, $class, $format, $attributeContext, $attributesMetadata, $classMetadata); ``` and a bit later: ```php foreach ($stack as $attribute => $attributeValue) { ... $data = $this->updateData($data, $attribute, $this->serializer->normalize($attributeValue, $format, $childContext), $class, $format, $attributeContext, $attributesMetadata, $classMetadata); } ``` For non-scalar values with a `SerializedPath` annotation this leads to an exception because the serializer is trying to re-populate the path. Running `updateData()` only once fixes this, but breaks a couple of tests across the components as it changes the order of elements in the serialized string (non-scalar values will be pushed to the end). Other than the string comparisons, nothing seems to break. This was also an issue while reviewing the PR for the `SerializedPath` annotation (#43534 (comment)) and got reverted because of the potential BC break. I'm not sure what benefit normalizing twice brings, so I added the test from `@HonzaMatosik`, changed the behavior in the normalizer and fixed the broken tests. If that's not the preferred solution here, I'd be ok with just eleminating the "The element you are trying to set is already populated" exception in the `SerializedPath` and allow overwriting values. Commits ------- d82ec41 [Serializer] Fix serializedpath for non scalar types
…enner) This PR was merged into the 6.2 branch. Discussion ---------- [Serializer] Fix serialized path for non-scalar values | Q | A | ------------- | --- | Branch? | 6.2 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #49494 | License | MIT | Doc PR | no This relates to symfony/symfony#49494 and symfony/symfony#49225. When non-scalar values are normalized, they are normalized twice in the `normalize()` function: ```php if (null !== $attributeValue && !\is_scalar($attributeValue)) { $stack[$attribute] = $attributeValue; } $data = $this->updateData($data, $attribute, $attributeValue, $class, $format, $attributeContext, $attributesMetadata, $classMetadata); ``` and a bit later: ```php foreach ($stack as $attribute => $attributeValue) { ... $data = $this->updateData($data, $attribute, $this->serializer->normalize($attributeValue, $format, $childContext), $class, $format, $attributeContext, $attributesMetadata, $classMetadata); } ``` For non-scalar values with a `SerializedPath` annotation this leads to an exception because the serializer is trying to re-populate the path. Running `updateData()` only once fixes this, but breaks a couple of tests across the components as it changes the order of elements in the serialized string (non-scalar values will be pushed to the end). Other than the string comparisons, nothing seems to break. This was also an issue while reviewing the PR for the `SerializedPath` annotation (symfony/symfony#43534 (comment)) and got reverted because of the potential BC break. I'm not sure what benefit normalizing twice brings, so I added the test from `@HonzaMatosik`, changed the behavior in the normalizer and fixed the broken tests. If that's not the preferred solution here, I'd be ok with just eleminating the "The element you are trying to set is already populated" exception in the `SerializedPath` and allow overwriting values. Commits ------- d82ec41d18 [Serializer] Fix serializedpath for non scalar types
Symfony version(s) affected
6.2.0
Description
If SerializedPath is set on non-scalar types, eg.
DateTimeImmutable
:Normalization fails with error:
But
DateTimeImmutable
is serialized into string, so expected result is:How to reproduce
I created unit test for this case, which should be sufficient for reproducing: HonzaMatosik@51f1969
Possible Solution
No response
Additional Context
No response
The text was updated successfully, but these errors were encountered: