-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Serializer] Add name_converter
flag and use an array of name converters
#35374
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 all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -111,6 +111,15 @@ abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerIn | |
*/ | ||
public const IGNORED_ATTRIBUTES = 'ignored_attributes'; | ||
|
||
/** | ||
* The name converter to use when (de)normalizing a property. | ||
* | ||
* It has to correspond of a class of the given name converters. | ||
* | ||
* If not specified or if it does not exist, the first name converter will be used if available. | ||
*/ | ||
public const NAME_CONVERTER = 'name_converter'; | ||
|
||
/** | ||
* @internal | ||
*/ | ||
|
@@ -130,16 +139,30 @@ abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerIn | |
|
||
/** | ||
* @var NameConverterInterface|null | ||
* | ||
* @deprecated since Symfony 5.1, use $nameConverters instead. | ||
*/ | ||
protected $nameConverter; | ||
|
||
/** | ||
* @var array<string, NameConverterInterface> | ||
*/ | ||
protected $nameConverters = []; | ||
|
||
/** | ||
* Sets the {@link ClassMetadataFactoryInterface} to use. | ||
*/ | ||
public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, array $defaultContext = []) | ||
public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, /* array */ $nameConverter/*s*/ = [], array $defaultContext = []) | ||
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'm not sure if it's possible to change or deprecate the name of a constructor argument since it could be used by DI with a named argument. |
||
{ | ||
$this->classMetadataFactory = $classMetadataFactory; | ||
$this->nameConverter = $nameConverter; | ||
if (!\is_array($nameConverter)) { | ||
@trigger_error(sprintf('The 2nd constructor argument of the class "%s" should be an array of name converters, using a name converter directly or null is deprecated since Symfony 5.1.', __CLASS__), E_USER_DEPRECATED); | ||
$this->nameConverter = $nameConverter; | ||
} else { | ||
foreach ($nameConverter as $nameConverterInstance) { | ||
$this->nameConverters[\get_class($nameConverterInstance)] = $nameConverterInstance; | ||
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. Is it a good idea to use the FQCN for referencing a name converter? 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. nope, it's not: it prevents passing two differently configured instances of the same class 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. We could use a service locator too. |
||
} | ||
} | ||
$this->defaultContext = array_merge($this->defaultContext, $defaultContext); | ||
|
||
if (isset($this->defaultContext[self::CALLBACKS])) { | ||
|
@@ -347,7 +370,14 @@ protected function instantiateObject(array &$data, string $class, array &$contex | |
$params = []; | ||
foreach ($constructorParameters as $constructorParameter) { | ||
$paramName = $constructorParameter->name; | ||
$key = $this->nameConverter ? $this->nameConverter->normalize($paramName, $class, $format, $context) : $paramName; | ||
$key = $paramName; | ||
if (\count($this->nameConverters) > 0) { | ||
$nameConverter = $this->nameConverters[$context[static::NAME_CONVERTER] ?? null] ?? reset($this->nameConverters); | ||
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 the given name converter in context doesn't correspond to one of the name converters, the first name converter is used instead. 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. an exception should be thrown instead to me |
||
$key = $nameConverter->normalize($paramName, $class, $format, $context); | ||
} elseif ($this->nameConverter) { | ||
@trigger_error(sprintf('Using the "nameConverter" property of the class "%s" is deprecated since Symfony 5.1, use the "nameConverters" property instead.', __CLASS__), E_USER_DEPRECATED); | ||
$key = $this->nameConverter->normalize($paramName, $class, $format, $context); | ||
} | ||
|
||
$allowed = false === $allowedAttributes || \in_array($paramName, $allowedAttributes); | ||
$ignored = !$this->isAllowedAttribute($class, $paramName, $format, $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.
why? it looks fine to me