-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Serializer] Argument objects #19277
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
Changes from 1 commit
7bd4ac5
e99a90b
e64e999
4884a2e
f361e52
f46a176
93608dc
d4cdb00
5556fa5
3fe9802
e437e04
7b5d55d
98bcb91
988eba1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -268,6 +268,15 @@ protected function getConstructor(array &$data, $class, array &$context, \Reflec | |
return $reflectionClass->getConstructor(); | ||
} | ||
|
||
/** | ||
* @see instantiateComplexObject | ||
* @deprecated Since 3.1, will be removed in 4.0. Use instantiateComplexObject instead. | ||
*/ | ||
protected function instantiateObject(array &$data, $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes) | ||
{ | ||
return $this->instantiateComplexObject($data, $class, $context, $reflectionClass, $allowedAttributes); | ||
} | ||
|
||
/** | ||
* Instantiates an object using constructor parameters when needed. | ||
* | ||
|
@@ -287,7 +296,7 @@ protected function getConstructor(array &$data, $class, array &$context, \Reflec | |
* | ||
* @throws RuntimeException | ||
*/ | ||
protected function instantiateObject(array &$data, $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes, $format = null) | ||
protected function instantiateComplexObject(array &$data, $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes, $format = null) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It can now be: instantiateComplexObject(array &$data, $class, $format, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes) To mimic the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. my bad I kept the old signature, will change it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you think about using |
||
{ | ||
if ( | ||
isset($context[static::OBJECT_TO_POPULATE]) && | ||
|
@@ -319,33 +328,41 @@ protected function instantiateObject(array &$data, $class, array &$context, \Ref | |
|
||
$params = array_merge($params, $data[$paramName]); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why removing the unset? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. bad copy/paste, should be kept |
||
} elseif ($allowed && !$ignored && (isset($data[$key]) || array_key_exists($key, $data))) { | ||
|
||
continue; | ||
} | ||
|
||
if ($allowed && !$ignored && (isset($data[$key]) || array_key_exists($key, $data))) { | ||
$parameterData = $data[$key]; | ||
if (null !== $constructorParameter->getClass()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I personally find it easier to check check if the class is null or not in this case There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree but the type hint may be on a class not loadable. In this case, the exception thrown should be catched and the default value applied. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could you elaborate? On which scenario may it happen? Not that I'm not trusting you, but if that's the case I would like to add a test for it :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In case you use a type hint with a class from a third party library which is not loaded because you don't need it for example. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah I see, fair enough will change that then |
||
$parameterData = $this->serializer->denormalize($parameterData, $constructorParameter->getClass()->getName(), null, $context); | ||
$parameterData = $this->serializer->deserialize($parameterData, $constructorParameter->getClass()->getName(), null, $context); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
|
||
// Don't run set for a parameter passed to the constructor | ||
$params[] = $parameterData; | ||
unset($data[$key]); | ||
} elseif ($constructorParameter->isDefaultValueAvailable()) { | ||
|
||
continue; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should not be updated imo as this is less clear... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The more indent you have the harder it is to read. And if the choice is to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is only one line here and i agree that most of the time Edit: BTW, we could reverse the condition There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I like this one :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But not sure this would be accepted as this is a small detail and could create many merge conflicts. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah actually I think I'll revert everything for that part, it's just CS and although I think it makes a big difference it terms of readability, I fear that it will cause lots of conflicts later on. One solution would be do go back in earlier versions and fix that version after version, but it's rather tedious and slow. |
||
|
||
if ($constructorParameter->isDefaultValueAvailable()) { | ||
$params[] = $constructorParameter->getDefaultValue(); | ||
} else { | ||
throw new RuntimeException( | ||
sprintf( | ||
'Cannot create an instance of %s from serialized data because its constructor requires parameter "%s" to be present.', | ||
$class, | ||
$constructorParameter->name | ||
) | ||
); | ||
} | ||
|
||
throw new RuntimeException( | ||
sprintf( | ||
'Cannot create an instance of %s from serialized data because its constructor requires parameter "%s" to be present.', | ||
$class, | ||
$constructorParameter->name | ||
) | ||
); | ||
} | ||
|
||
if ($constructor->isConstructor()) { | ||
return $reflectionClass->newInstanceArgs($params); | ||
} else { | ||
return $constructor->invokeArgs(null, $params); | ||
} | ||
|
||
return $constructor->invokeArgs(null, $params); | ||
} | ||
|
||
return new $class(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,7 +47,7 @@ public function denormalize($data, $class, $format = null, array $context = arra | |
$normalizedData = $this->prepareForDenormalization($data); | ||
|
||
$reflectionClass = new \ReflectionClass($class); | ||
$object = $this->instantiateObject($normalizedData, $class, $context, $reflectionClass, $allowedAttributes); | ||
$object = $this->instantiateComplexObject($normalizedData, $class, $context, $reflectionClass, $allowedAttributes, $format); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunatelly this looks like a bc break as people may depend on the call to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure to see what you mean, before it was simply failing so people could not used it. The method has been changed because there's a BC break in the method signature (we are adding There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In case someone extends There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could do something like: protected function instantiateObject(..., $allowedAttributes/**, $format*/)
{
$format = null;
if (func_num_args() >= 6) {
$format = func_get_arg(5);
}
// ...
}
protected function instantiateComplexObject(...)
{
static $deprecationTriggered = false;
if (false === $deprecationTriggered) {
$deprecationTriggered = true;
$class = get_class($this);
if (0 !== strpos($class, 'Symfony\\')
&& self::class !== (new \ReflectionMethod($this, 'instantiateObject'))->getDeclaringClass()->getName()) {
@trigger_error(..., E_USER_DEPRECATED);
}
}
return $this->instantiateObject(...);
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. taking There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is forbidden by the PHP interpreter itself: https://3v4l.org/S48gf There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If you override it this way there is not BC as the added param is optional. In all honesty I would be happy to say yes to this solution it's the easiest way to deal with it really. The only thing I'm worried about is that it may introduce a BC break (but that's up to you to decide if it is or not) and the fact that the user may not see the change (i.e. see that he has to inject the format now). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Anyway, it's not a BC break because the parent function is still called with the good number of arguments. See https://3v4l.org/XpYGK. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nvm, even with my example it wouldn't be a problem as you would call the parent function with the right number of parameters. Not doing so is looking for trouble and would be the developer fault. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This solution is often used in symfony so i'd say it's not part of the symfony bc promises. |
||
|
||
$classMethods = get_class_methods($object); | ||
foreach ($normalizedData as $attribute => $value) { | ||
|
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.
missing
@trigger_error()
call for thisThere 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.
@xabbuh done