Skip to content

Commit

Permalink
Merge branch '6.4' into 7.0
Browse files Browse the repository at this point in the history
* 6.4: (21 commits)
  [ErrorHandler] Add missing self-closing tags on link elements
  Fix merge (bis)
  Fix merge
  Add missing return type
  [FrameworkBundle] ConfigBuilderCacheWarmer should be non-optional
  [HttpClient] Fix pausing responses before they start when using curl
  [Notifier] Updated the NTFY notifier to run without a user parameter
  [Translation] Fix constant domain resolution in PhpAstExtractor
  separate child and parent context in NotificationEmail on writes
  [Mailer] [Mailgun] Fix sender header encoding
  do not overwrite the cache key when it is false
  [Mailer] [Scaleway] Fix attachment handling
  [Mailer] Throw TransportException when unable to read from socket
  [Serializer] Rewrite `AbstractObjectNormalizer::createChildContext()` to use the provided `cache_key` from original context when creating child contexts
  Revert #47715
  [HttpClient] Fix error chunk creation in passthru
  Adjusting and removing the 'review' attribute from the pt_br translation XML.
  [DependencyInjection] Fix loading all env vars from secrets when only a subset is needed
  Fix option filenameMaxLength to the File constraint (Image)
  [Serializer] Take unnamed variadic parameters into account when denormalizing
  ...
  • Loading branch information
nicolas-grekas committed Jan 29, 2024
2 parents fffaead + 3f730a6 commit f1c9d0f
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Normalizer/AbstractNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ protected function instantiateObject(array &$data, string $class, array &$contex
$variadicParameters[$parameterKey] = $this->denormalizeParameter($reflectionClass, $constructorParameter, $paramName, $parameterData, $attributeContext, $format);
}

$params = array_merge($params, $variadicParameters);
$params = array_merge(array_values($params), $variadicParameters);
$unsetKeys[] = $key;
}
} elseif ($allowed && !$ignored && (isset($data[$key]) || \array_key_exists($key, $data))) {
Expand Down
6 changes: 5 additions & 1 deletion Normalizer/AbstractObjectNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,11 @@ private function isMaxDepthReached(array $attributesMetadata, string $class, str
protected function createChildContext(array $parentContext, string $attribute, ?string $format): array
{
$context = parent::createChildContext($parentContext, $attribute, $format);
$context['cache_key'] = $this->getCacheKey($format, $context);
if ($context['cache_key'] ?? false) {
$context['cache_key'] .= '-'.$attribute;
} elseif (false !== ($context['cache_key'] ?? null)) {
$context['cache_key'] = $this->getCacheKey($format, $context);
}

return $context;
}
Expand Down
44 changes: 44 additions & 0 deletions Tests/Fixtures/DummyWithWithVariadicParameterConstructor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Serializer\Tests\Fixtures;

class DummyWithWithVariadicParameterConstructor
{
private $foo;

private $bar;

private $baz;

public function __construct(string $foo, int $bar = 1, Dummy ...$baz)
{
$this->foo = $foo;
$this->bar = $bar;
$this->baz = $baz;
}

public function getFoo(): string
{
return $this->foo;
}

public function getBar(): int
{
return $this->bar;
}

/** @return Dummy[] */
public function getBaz(): array
{
return $this->baz;
}
}
20 changes: 20 additions & 0 deletions Tests/Normalizer/AbstractNormalizerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use Symfony\Component\Serializer\Tests\Fixtures\AbstractNormalizerDummy;
use Symfony\Component\Serializer\Tests\Fixtures\Attributes\IgnoreDummy;
use Symfony\Component\Serializer\Tests\Fixtures\Dummy;
use Symfony\Component\Serializer\Tests\Fixtures\DummyWithWithVariadicParameterConstructor;
use Symfony\Component\Serializer\Tests\Fixtures\NullableConstructorArgumentDummy;
use Symfony\Component\Serializer\Tests\Fixtures\NullableOptionalConstructorArgumentDummy;
use Symfony\Component\Serializer\Tests\Fixtures\StaticConstructorDummy;
Expand Down Expand Up @@ -248,6 +249,25 @@ public static function getNormalizer()
yield [new ObjectNormalizer(null, null, null, $extractor)];
}

public function testVariadicConstructorDenormalization()
{
$data = [
'foo' => 'woo',
'baz' => [
['foo' => null, 'bar' => null, 'baz' => null, 'qux' => null],
['foo' => null, 'bar' => null, 'baz' => null, 'qux' => null],
],
];

$normalizer = new ObjectNormalizer();
$normalizer->setSerializer(new Serializer([$normalizer]));

$expected = new DummyWithWithVariadicParameterConstructor('woo', 1, new Dummy(), new Dummy());
$actual = $normalizer->denormalize($data, DummyWithWithVariadicParameterConstructor::class);

$this->assertEquals($expected, $actual);
}

public static function getNormalizerWithCustomNameConverter()
{
$extractor = new PhpDocExtractor();
Expand Down
110 changes: 110 additions & 0 deletions Tests/Normalizer/AbstractObjectNormalizerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,116 @@ public function testDenormalizeUntypedStringObject()
$this->assertEquals(new DummyWithStringObject(new DummyString()), $actual);
$this->assertEquals('', $actual->value->value);
}

public function testProvidingContextCacheKeyGeneratesSameChildContextCacheKey()
{
$foobar = new Dummy();
$foobar->foo = new EmptyDummy();
$foobar->bar = 'bar';
$foobar->baz = 'baz';

$normalizer = new class() extends AbstractObjectNormalizerDummy {
public $childContextCacheKey;

protected function extractAttributes(object $object, string $format = null, array $context = []): array
{
return array_keys((array) $object);
}

protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []): mixed
{
return $object->{$attribute};
}

protected function createChildContext(array $parentContext, string $attribute, ?string $format): array
{
$childContext = parent::createChildContext($parentContext, $attribute, $format);
$this->childContextCacheKey = $childContext['cache_key'];

return $childContext;
}
};

$serializer = new Serializer([$normalizer]);

$serializer->normalize($foobar, null, ['cache_key' => 'hardcoded', 'iri' => '/dummy/1']);
$firstChildContextCacheKey = $normalizer->childContextCacheKey;

$serializer->normalize($foobar, null, ['cache_key' => 'hardcoded', 'iri' => '/dummy/2']);
$secondChildContextCacheKey = $normalizer->childContextCacheKey;

$this->assertSame($firstChildContextCacheKey, $secondChildContextCacheKey);
}

public function testChildContextKeepsOriginalContextCacheKey()
{
$foobar = new Dummy();
$foobar->foo = new EmptyDummy();
$foobar->bar = 'bar';
$foobar->baz = 'baz';

$normalizer = new class() extends AbstractObjectNormalizerDummy {
public $childContextCacheKey;

protected function extractAttributes(object $object, string $format = null, array $context = []): array
{
return array_keys((array) $object);
}

protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []): mixed
{
return $object->{$attribute};
}

protected function createChildContext(array $parentContext, string $attribute, ?string $format): array
{
$childContext = parent::createChildContext($parentContext, $attribute, $format);
$this->childContextCacheKey = $childContext['cache_key'];

return $childContext;
}
};

$serializer = new Serializer([$normalizer]);
$serializer->normalize($foobar, null, ['cache_key' => 'hardcoded', 'iri' => '/dummy/1']);

$this->assertSame('hardcoded-foo', $normalizer->childContextCacheKey);
}

public function testChildContextCacheKeyStaysFalseWhenOriginalCacheKeyIsFalse()
{
$foobar = new Dummy();
$foobar->foo = new EmptyDummy();
$foobar->bar = 'bar';
$foobar->baz = 'baz';

$normalizer = new class() extends AbstractObjectNormalizerDummy {
public $childContextCacheKey;

protected function extractAttributes(object $object, string $format = null, array $context = []): array
{
return array_keys((array) $object);
}

protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []): mixed
{
return $object->{$attribute};
}

protected function createChildContext(array $parentContext, string $attribute, ?string $format): array
{
$childContext = parent::createChildContext($parentContext, $attribute, $format);
$this->childContextCacheKey = $childContext['cache_key'];

return $childContext;
}
};

$serializer = new Serializer([$normalizer]);
$serializer->normalize($foobar, null, ['cache_key' => false]);

$this->assertFalse($normalizer->childContextCacheKey);
}
}

class AbstractObjectNormalizerDummy extends AbstractObjectNormalizer
Expand Down

0 comments on commit f1c9d0f

Please sign in to comment.