Skip to content

Commit

Permalink
Merge branch '7.1' into 7.2
Browse files Browse the repository at this point in the history
* 7.1:
  [Serializer] fix default context in Serializer
  • Loading branch information
fabpot committed Jan 29, 2025
2 parents 461524d + cb88edf commit 320f30b
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 5 deletions.
1 change: 1 addition & 0 deletions DependencyInjection/SerializerPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public function process(ContainerBuilder $container): void
$defaultContext = $container->getParameter('serializer.default_context');
$this->bindDefaultContext($container, array_merge($normalizers, $encoders), $defaultContext);
$container->getParameterBag()->remove('serializer.default_context');
$container->getDefinition('serializer')->setArgument('$defaultContext', $defaultContext);
}

$this->configureSerializer($container, 'serializer', $normalizers, $encoders, 'default');
Expand Down
8 changes: 5 additions & 3 deletions Serializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,12 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
/**
* @param array<NormalizerInterface|DenormalizerInterface> $normalizers
* @param array<EncoderInterface|DecoderInterface> $encoders
* @param array<string, mixed> $defaultContext
*/
public function __construct(
private array $normalizers = [],
array $encoders = [],
private array $defaultContext = [],
) {
foreach ($normalizers as $normalizer) {
if ($normalizer instanceof SerializerAwareInterface) {
Expand Down Expand Up @@ -154,12 +156,12 @@ public function normalize(mixed $data, ?string $format = null, array $context =
return $data;
}

if (\is_array($data) && !$data && ($context[self::EMPTY_ARRAY_AS_OBJECT] ?? false)) {
if (\is_array($data) && !$data && ($context[self::EMPTY_ARRAY_AS_OBJECT] ?? $this->defaultContext[self::EMPTY_ARRAY_AS_OBJECT] ?? false)) {
return new \ArrayObject();
}

if (is_iterable($data)) {
if ($data instanceof \Countable && ($context[AbstractObjectNormalizer::PRESERVE_EMPTY_OBJECTS] ?? false) && !\count($data)) {
if ($data instanceof \Countable && ($context[AbstractObjectNormalizer::PRESERVE_EMPTY_OBJECTS] ?? $this->defaultContext[AbstractObjectNormalizer::PRESERVE_EMPTY_OBJECTS] ?? false) && !\count($data)) {
return new \ArrayObject();
}

Expand Down Expand Up @@ -211,7 +213,7 @@ public function denormalize(mixed $data, string $type, ?string $format = null, a
throw new NotNormalizableValueException(\sprintf('Could not denormalize object of type "%s", no supporting normalizer found.', $type));
}

if (isset($context[DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS])) {
if (isset($context[DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS]) || isset($this->defaultContext[DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS])) {
unset($context[DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS]);
$context['not_normalizable_value_exceptions'] = [];
$errors = &$context['not_normalizable_value_exceptions'];
Expand Down
7 changes: 5 additions & 2 deletions Tests/DependencyInjection/SerializerPassTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,20 @@ public function testServicesAreOrderedAccordingToPriority()

public function testBindSerializerDefaultContext()
{
$context = ['enable_max_depth' => true];

$container = new ContainerBuilder();
$container->setParameter('kernel.debug', false);
$container->register('serializer')->setArguments([null, null]);
$container->register('serializer')->setArguments([null, null, []]);
$container->setParameter('serializer.default_context', ['enable_max_depth' => true]);
$definition = $container->register('n1')->addTag('serializer.normalizer')->addTag('serializer.encoder');

$serializerPass = new SerializerPass();
$serializerPass->process($container);

$bindings = $definition->getBindings();
$this->assertEquals($bindings['array $defaultContext'], new BoundArgument(['enable_max_depth' => true], false));
$this->assertEquals($bindings['array $defaultContext'], new BoundArgument($context, false));
$this->assertEquals($context, $container->getDefinition('serializer')->getArgument('$defaultContext'));
}

public function testNormalizersAndEncodersAreDecoratedAndOrderedWhenCollectingData()
Expand Down
26 changes: 26 additions & 0 deletions Tests/SerializerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1675,6 +1675,32 @@ public function testPartialDenormalizationWithInvalidVariadicParameter()
DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS => true,
]);
}

public function testEmptyArrayAsObjectDefaultContext()
{
$serializer = new Serializer(
defaultContext: [Serializer::EMPTY_ARRAY_AS_OBJECT => true],
);
$this->assertEquals(new \ArrayObject(), $serializer->normalize([]));
}

public function testPreserveEmptyObjectsAsDefaultContext()
{
$serializer = new Serializer(
defaultContext: [AbstractObjectNormalizer::PRESERVE_EMPTY_OBJECTS => true],
);
$this->assertEquals(new \ArrayObject(), $serializer->normalize(new \ArrayIterator()));
}

public function testCollectDenormalizationErrorsDefaultContext()
{
$data = ['variadic' => ['a random string']];
$serializer = new Serializer([new UidNormalizer(), new ObjectNormalizer()], [], [DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS => true]);

$this->expectException(PartialDenormalizationException::class);

$serializer->denormalize($data, DummyWithVariadicParameter::class);
}
}

class Model
Expand Down

0 comments on commit 320f30b

Please sign in to comment.