[Serializer] Allow to access extra infos in name converters

This commit is contained in:
Kévin Dunglas 2018-04-23 17:22:12 +02:00 committed by Fabien Potencier
parent 9ad492f312
commit 57fe0178c4
5 changed files with 56 additions and 6 deletions

View File

@ -8,6 +8,7 @@ CHANGELOG
* added support for XML comment encoding (encoding `['#comment' => ' foo ']` results `<!-- foo -->`)
* added optional `int[] $encoderIgnoredNodeTypes` argument to `XmlEncoder::__construct` to configure node types to be
ignored during encoding.
* added `AdvancedNameConverterInterface` to access the class, the format and the context in a name converter
4.1.0
-----

View File

@ -0,0 +1,30 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Serializer\NameConverter;
/**
* Gives access to the class, the format and the context in the property name converters.
*
* @author Kévin Dunglas <dunglas@gmail.com>
*/
interface AdvancedNameConverterInterface extends NameConverterInterface
{
/**
* {@inheritdoc}
*/
public function normalize($propertyName, string $class = null, string $format = null, array $context = array());
/**
* {@inheritdoc}
*/
public function denormalize($propertyName, string $class = null, string $format = null, array $context = array());
}

View File

@ -348,7 +348,7 @@ abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerIn
$params = array();
foreach ($constructorParameters as $constructorParameter) {
$paramName = $constructorParameter->name;
$key = $this->nameConverter ? $this->nameConverter->normalize($paramName) : $paramName;
$key = $this->nameConverter ? $this->nameConverter->normalize($paramName, $class, $format, $context) : $paramName;
$allowed = false === $allowedAttributes || \in_array($paramName, $allowedAttributes);
$ignored = !$this->isAllowedAttribute($class, $paramName, $format, $context);

View File

@ -108,7 +108,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
$stack[$attribute] = $attributeValue;
}
$data = $this->updateData($data, $attribute, $attributeValue);
$data = $this->updateData($data, $attribute, $attributeValue, $class, $format, $context);
}
foreach ($stack as $attribute => $attributeValue) {
@ -116,7 +116,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
throw new LogicException(sprintf('Cannot normalize attribute "%s" because the injected serializer is not a normalizer', $attribute));
}
$data = $this->updateData($data, $attribute, $this->serializer->normalize($attributeValue, $format, $this->createChildContext($context, $attribute)));
$data = $this->updateData($data, $attribute, $this->serializer->normalize($attributeValue, $format, $this->createChildContext($context, $attribute)), $class, $format, $context);
}
return $data;
@ -246,7 +246,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
foreach ($normalizedData as $attribute => $value) {
if ($this->nameConverter) {
$attribute = $this->nameConverter->denormalize($attribute);
$attribute = $this->nameConverter->denormalize($attribute, $class, $format, $context);
}
if ((false !== $allowedAttributes && !\in_array($attribute, $allowedAttributes)) || !$this->isAllowedAttribute($class, $attribute, $format, $context)) {
@ -400,10 +400,10 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
*
* @param mixed $attributeValue
*/
private function updateData(array $data, string $attribute, $attributeValue): array
private function updateData(array $data, string $attribute, $attributeValue, string $class, ?string $format, array $context): array
{
if ($this->nameConverter) {
$attribute = $this->nameConverter->normalize($attribute);
$attribute = $this->nameConverter->normalize($attribute, $class, $format, $context);
}
$data[$attribute] = $attributeValue;

View File

@ -18,6 +18,7 @@ use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
use Symfony\Component\PropertyInfo\PropertyInfoExtractor;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
use Symfony\Component\Serializer\NameConverter\AdvancedNameConverterInterface;
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
@ -861,6 +862,24 @@ class ObjectNormalizerTest extends TestCase
),
)));
}
public function testAdvancedNameConverter()
{
$nameConverter = new class() implements AdvancedNameConverterInterface {
public function normalize($propertyName, string $class = null, string $format = null, array $context = array())
{
return sprintf('%s-%s-%s-%s', $propertyName, $class, $format, $context['foo']);
}
public function denormalize($propertyName, string $class = null, string $format = null, array $context = array())
{
return sprintf('%s-%s-%s-%s', $propertyName, $class, $format, $context['foo']);
}
};
$normalizer = new ObjectNormalizer(null, $nameConverter);
$this->assertArrayHasKey('foo-Symfony\Component\Serializer\Tests\Normalizer\ObjectDummy-json-bar', $normalizer->normalize(new ObjectDummy(), 'json', array('foo' => 'bar')));
}
}
class ObjectDummy