-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Serializer] Integrate the PropertyInfo Component (recursive denormalization and hardening) #17660
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
Conversation
* @throws UnexpectedValueException | ||
* @throws LogicException | ||
*/ | ||
protected function validateAndDenormalize($currentClass, $attribute, $data, $format, array $context) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{
should be on next line.
* @throws UnexpectedValueException | ||
* @throws LogicException | ||
*/ | ||
protected function validateAndDenormalize($currentClass, $attribute, $data, $format, array $context) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this method intended to be overridden by subclasses?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes (by ApiBundle especially).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it would be better to design an extension point based on composition instead of designing for inheritance. Inheritance-based extension points are always a huge pain to maintain BC when refactoring the logic (see the extraction of name converter from this class for instance)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After double checking, this extension point isn't needed anymore for API Platform. As I've no use case anymore, I changed the visibility of this method to private.
…n the type do not match (dunglas) This PR was squashed before being merged into the 3.1-dev branch (closes #17738). Discussion ---------- [PropertyAccess] Throw an InvalidArgumentException when the type do not match | Q | A | ------------- | --- | Bug fix? | no (?) | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | n/a | License | MIT | Doc PR | n/a Currently, when the Property Access Component call a setter with a value not matching its typehint, a `\TypeError` is thrown with PHP 7 and a `PHP Catchable fatal error` with PHP 5. This PR make the component returning an `InvalidArgumentException` with both version. It's a (better) alternative to #17660 (the hardening part) to make the Symfony Serializer (and probably many other pieces of code) more robust when types do not match. /cc @csarrazi @mRoca @blazarecki Commits ------- e70fdbc [PropertyAccess] Throw an InvalidArgumentException when the type do not match
#17738 has been merged now. |
I've looked at this more deeply and #17959 and this one complement. They don't cover same cases. Both should be merged. (Will need a rebase). |
ping @symfony/deciders |
@@ -24,8 +29,20 @@ | |||
const ENABLE_MAX_DEPTH = 'enable_max_depth'; | |||
const DEPTH_KEY_PATTERN = 'depth_%s::%s'; | |||
|
|||
/** | |||
* @var PropertyTypeExtractorInterface|null | |||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docblock is not needed (as the property is private, IDEs should be able to infer the type from the constructor).
All comments of @xabbuh fixed now. |
Tests should be green now. |
AppVeyor errors not related. |
} | ||
} | ||
|
||
throw new UnexpectedValueException(sprintf('The type of the attribute "%s" for the class "%s" must be one of "%s" ("%s" given).', $attribute, $currentClass, implode('", "', array_keys($expectedTypes)), gettype($data))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type of the "%s" attribute for class "%s" must be one of "%s" ("%s" given).
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
ping @symfony/deciders |
@@ -498,6 +501,29 @@ public function testMaxDepth() | |||
|
|||
$this->assertEquals($expected, $result); | |||
} | |||
|
|||
public function testDernomalizeRecursive() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo in name (misplaced r
)
This PR was squashed before being merged into the 3.1-dev branch (closes #17959). Discussion ---------- [Serializer] Harden the ObjectNormalizer | Q | A | ------------- | --- | Branch | master | Bug fix? | no | New feature? | yes | BC breaks? | yes | Deprecations? | no | Tests pass? | yes | Fixed tickets | n/a | License | MIT | Doc PR | n/a Transform `\TypeError`s to catchable serializer exceptions. Follows #17738 and completes #17660. Commits ------- 26a07fb [Serializer] Harden the ObjectNormalizer
- Refactored PR 14844 "Denormalize with typehinting" - Now using PropertyInfo to extract type information - Updated tests - Updated composer.json
8924b23
to
0c10b4e
Compare
Failure not related. |
👍 |
Recursive denormalization handling and hardening.
b107296
to
5194482
Compare
…ursive denormalization and hardening) (mihai-stancu, dunglas) This PR was merged into the 3.1-dev branch. Discussion ---------- [Serializer] Integrate the PropertyInfo Component (recursive denormalization and hardening) | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #16143, #17193, #14844 | License | MIT | Doc PR | todo Integrates the PropertyInfo Component in order to: * denormalize a graph of objects recursively (see tests) * harden the hydratation logic The hardening part is interesting. Considering the following example: ```php class Foo { public function setDate(\DateTimeInterface $date) { } } // initialize $normalizer $normalizer->denormalize(['date' => 1234], Foo::class); ``` Previously, a PHP error was thrown because the type passed to the setter (an int) doesn't match the one checked with the typehint. With the PropertyInfo integration, an `UnexpectedValueExcption` is throw instead. It's especially interesting for web APIs dealing with JSON documents. For instance in API Platform, previously a 500 error was thrown, but thanks to this fix a 400 HTTP code with a descriptive error message will be returned. (/cc @csarrazi @mRoca @blazarecki, it's an alternative to https://github.com/dunglas/php-to-json-schema for protecting an API). /cc @mihai-stancu Commits ------- 5194482 [Serializer] Integrate the PropertyInfo Component 6b464b0 Recursive denormalize using PropertyInfo
Thanks for working on this @mihai-stancu! |
@dunglas thank you for seeing it through! |
…glas) This PR was submitted for the 3.1 branch but it was merged into the 3.2 branch instead (closes #7042). Discussion ---------- [Serializer] Docs for the PropertyInfo integration Docs for symfony/symfony#17660. Commits ------- 8e2deb0 [Serializer] Docs for the PropertyInfo integration
Integrates the PropertyInfo Component in order to:
The hardening part is interesting. Considering the following example:
Previously, a PHP error was thrown because the type passed to the setter (an int) doesn't match the one checked with the typehint. With the PropertyInfo integration, an
UnexpectedValueExcption
is throw instead.It's especially interesting for web APIs dealing with JSON documents. For instance in API Platform, previously a 500 error was thrown, but thanks to this fix a 400 HTTP code with a descriptive error message will be returned. (/cc @csarrazi @mRoca @blazarecki, it's an alternative to https://github.com/dunglas/php-to-json-schema for protecting an API).
/cc @mihai-stancu