-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Allow arrays being denormalized in AbstractObjectNormalizer #19545
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
Has been solved in #19277 but sadly will only be available in |
@theofidry in your opinion, should this be considered a bug or a new feature? Thanks. |
Well it never really worked and has never been documented either so I'm not sure we can consider it being a bug. That said it's a change with a limited impact and not having it can be a serious limitation, so it could be passed as a bug and backported to be released in a patch version rather than waiting months for the 3.2. But I think @dunglas is more qualified than me to make a decision on this :P |
Actually I'm not able to test it, because the profiler of 3.2-dev let's Chrome and Firefox eat up all my memory... But it would be nice to have this feature in 3.1 branch aswell... |
Ok, just got it working, but I think the fix in #19277 does not fit my case. |
What does it give you instead of an array of two nested resources? |
Something like this: -premises: array:4 [▼
0 => array:35 [▶]
1 => array:35 [▶]
2 => array:35 [▶]
3 => array:35 [▶]
] But what I expected was this: -premises: array:4 [▼
0 => Premise {▶}
1 => Premise {▶}
2 => Premise {▶}
3 => Premise {▶}
] When I do a dump of Type {#877 ▼
-builtinType: "array"
-nullable: false
-class: null
-collection: true
-collectionKeyType: Type {#875 ▼
-builtinType: "int"
-nullable: false
-class: null
-collection: false
-collectionKeyType: null
-collectionValueType: null
}
-collectionValueType: Type {#876 ▼
-builtinType: "object"
-nullable: false
-class: "AppBundle\Resource\Premise"
-collection: false
-collectionKeyType: null
-collectionValueType: null
}
} So I think the class-type is correctly figured-out by the property type extractor but data being an array of classes is not handled properlt. |
I'll take a look at this when I'll have a bit of time. In the meantime I'm afraid a custom normalizer will be the solution. |
Ok, thanks alot :) |
I created a custom ObjectNormalizer that now checks explicitly for an array. I realized that if (is_array($data)
&& $builtinType === Type::BUILTIN_TYPE_ARRAY
&& $type->isCollection()
&& $type->getCollectionValueType()
&& $type->getCollectionValueType()->getBuiltinType() === TYPE::BUILTIN_TYPE_OBJECT
)
{
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));
}
$out = array();
foreach($data as $key => $value) {
if ($this->serializer->supportsDenormalization($key, $type->getCollectionValueType()->getClassName(), $format)) {
$out[$key] = $this->serializer->denormalize($value, $type->getCollectionValueType()->getClassName(), $format, $context);
}
}
if (!empty($out)) {
return $out;
}
} vs. if (is_array($data)
&& $builtinType === Type::BUILTIN_TYPE_ARRAY
&& $type->isCollection()
&& $type->getCollectionValueType()
&& $type->getCollectionValueType()->getBuiltinType() === TYPE::BUILTIN_TYPE_OBJECT
)
{
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));
}
if ($this->serializer->supportsDenormalization($key, $type->getCollectionValueType()->getClassName(), $format)) {
return $this->serializer->denormalize($value, $type->getCollectionValueType()->getClassName() . '[]', $format, $context);
}
} |
I'll open a PR soon to fix this (it is very similar to your last example). |
This PR was squashed before being merged into the 3.1 branch (closes #19649). Discussion ---------- [Serializer] Fix denormalization of arrays | Q | A | ------------- | --- | Branch? | 3.1 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #19545 | License | MIT | Doc PR | n/a ping @hensoko @theofidry Commits ------- 99c582b [Serializer] Fix denormalization of arrays
Heyho,
I currently work on a problem when using the ObjectNormalizer with an multidimensional array as input. My array looks like this:
I defined the following classes the data of this array should be passed to:
When using the Serializer-Component of Symfony to denormalize the input-array I expected to get the following result:
but instead I get the following:
I defined the following services to get a serializer-service using the ReflectionExtrator:
I tested it with latest Symfony 3.1.3. I think the issue occures because of a missing check for a collection in class
AbstractObjectNormalizer
in line 255 to 263. It is only checked for an object, but if$type
is an collection this is not honored. I get a correct result if I add the following check just before line 255, but I think this is not a nice solution because of the need to add brackets after the class-name:I get the same result with PhpDocExtractor.
The text was updated successfully, but these errors were encountered: