diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php index 78102cb6a9616..35fc1fc3b69b3 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php @@ -361,32 +361,9 @@ protected function instantiateObject(array &$data, $class, array &$context, \Ref $params = array_merge($params, $data[$paramName]); } } elseif ($allowed && !$ignored && (isset($data[$key]) || array_key_exists($key, $data))) { - $parameterData = $data[$key]; - if (null === $parameterData && $constructorParameter->allowsNull()) { - $params[] = null; - // Don't run set for a parameter passed to the constructor - unset($data[$key]); - continue; - } - try { - if (null !== $constructorParameter->getClass()) { - if (!$this->serializer instanceof DenormalizerInterface) { - throw new LogicException(sprintf('Cannot create an instance of %s from serialized data because the serializer inject in "%s" is not a denormalizer', $constructorParameter->getClass(), static::class)); - } - $parameterClass = $constructorParameter->getClass()->getName(); - $parameterData = $this->serializer->denormalize($parameterData, $parameterClass, $format, $this->createChildContext($context, $paramName)); - } - } catch (\ReflectionException $e) { - throw new RuntimeException(sprintf('Could not determine the class of the parameter "%s".', $key), 0, $e); - } catch (MissingConstructorArgumentsException $e) { - if (!$constructorParameter->getType()->allowsNull()) { - throw $e; - } - $parameterData = null; - } + $params[] = $this->createConstructorArgument($data[$key], $key, $constructorParameter, $context, $format); // Don't run set for a parameter passed to the constructor - $params[] = $parameterData; unset($data[$key]); } elseif (isset($context[static::DEFAULT_CONSTRUCTOR_ARGUMENTS][$class][$key])) { $params[] = $context[static::DEFAULT_CONSTRUCTOR_ARGUMENTS][$class][$key]; @@ -407,6 +384,46 @@ protected function instantiateObject(array &$data, $class, array &$context, \Ref return new $class(); } + /** + * @param mixed $parameterData + * @param string $key + * @param \ReflectionParameter $constructorParameter + * @param array $context + * @param string|null $format + * + * @return mixed value of constructor parameter - an argument + * + * @throws LogicException + * @throws RuntimeException + * @throws MissingConstructorArgumentsException + */ + protected function createConstructorArgument($parameterData, string $key, \ReflectionParameter $constructorParameter, array &$context, string $format = null) + { + if (null === $parameterData && $constructorParameter->allowsNull()) { + return null; + } + try { + if (null !== $constructorParameter->getClass()) { + if (!$this->serializer instanceof DenormalizerInterface) { + throw new LogicException(sprintf('Cannot create an instance of %s from serialized data because the serializer inject in "%s" is not a denormalizer', $constructorParameter->getClass(), static::class)); + } + $parameterClass = $constructorParameter->getClass()->getName(); + + return $this->serializer->denormalize($parameterData, $parameterClass, $format, $this->createChildContext($context, $constructorParameter->name)); + } + } catch (\ReflectionException $e) { + throw new RuntimeException(sprintf('Could not determine the class of the parameter "%s".', $key), 0, $e); + } catch (MissingConstructorArgumentsException $e) { + if (!$constructorParameter->getType()->allowsNull()) { + throw $e; + } + + return null; + } + + return $parameterData; + } + /** * @param array $parentContext * @param string $attribute