8000 bug #57273 [FrameworkBundle] Fix setting default context for certain … · symfony/symfony@5c2633f · GitHub
[go: up one dir, main page]

Skip to content

Commit 5c2633f

Browse files
committed
bug #57273 [FrameworkBundle] Fix setting default context for certain normalizers (HypeMC)
This PR was merged into the 5.4 branch. Discussion ---------- [FrameworkBundle] Fix setting default context for certain normalizers | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | Fix #56875, fix #57316 | License | MIT Caused by #54791. The main problem is that `$context` defaults to `[]` instead of `$defaultContext`. There's a test to check this, but it didn't work when `circular_reference_handler` or `max_depth_handler` were not `null`. I also found an issue with `serializer.normalizer.property`. Since it’s not tagged with `serializer.normalizer`, which, to my understanding, is intentional, it would never have the default context bound to it. Commits ------- f903893 [FrameworkBundle] Fix setting default context for certain normalizers
2 parents 1b55cec + f903893 commit 5c2633f

File tree

7 files changed

+115
-75
lines changed

7 files changed

+115
-75
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,18 +1859,20 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder
18591859
}
18601860

18611861
$arguments = $container->getDefinition('serializer.normalizer.object')->getArguments();
1862-
$context = [];
1862+
$context = $arguments[6] ?? $defaultCont 8000 ext;
18631863

18641864
if (isset($config['circular_reference_handler']) && $config['circular_reference_handler']) {
1865-
$context += ($arguments[6] ?? $defaultContext) + ['circular_reference_handler' => new Reference($config['circular_reference_handler'])];
1865+
$context += ['circular_reference_handler' => new Reference($config['circular_reference_handler'])];
18661866
$container->getDefinition('serializer.normalizer.object')->setArgument(5, null);
18671867
}
18681868

18691869
if ($config['max_depth_handler'] ?? false) {
1870-
$context += ($arguments[6] ?? $defaultContext) + ['max_depth_handler' => new Reference($config['max_depth_handler'])];
1870+
$context += ['max_depth_handler' => new Reference($config['max_depth_handler'])];
18711871
}
18721872

18731873
$container->getDefinition('serializer.normalizer.object')->setArgument(6, $context);
1874+
1875+
$container->getDefinition('serializer.normalizer.property')->setArgument(5, $defaultContext);
18741876
}
18751877

18761878
private function registerPropertyInfoConfiguration(ContainerBuilder $container, PhpFileLoader $loader)

src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@
139139
service('property_info')->ignoreOnInvalid(),
140140
service('serializer.mapping.class_discriminator_resolver')->ignoreOnInvalid(),
141141
null,
142-
[],
143142
])
144143

145144
->alias(PropertyNormalizer::class, 'serializer.normalizer.property')

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/AbstractWebTestCase.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ protected static function getKernelClass(): string
5252

5353
protected static function createKernel(array $options = []): KernelInterface
5454
{
55-
$class = self::getKernelClass();
55+
$class = static::getKernelClass();
5656

5757
if (!isset($options['test_case'])) {
5858
throw new \InvalidArgumentException('The option "test_case" must be set.');

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SerializerTest.php

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional;
1313

14+
use Symfony\Bundle\FrameworkBundle\Tests\Functional\app\AppKernel;
15+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
16+
use Symfony\Component\DependencyInjection\ContainerBuilder;
17+
1418
/**
1519
* @author Kévin Dunglas <dunglas@gmail.com>
1620
*/
@@ -33,39 +37,55 @@ public function testDeserializeArrayOfObject()
3337
$this->assertEquals($expected, $result);
3438
}
3539

36-
/**
37-
* @dataProvider provideNormalizersAndEncodersWithDefaultContextOption
38-
*/
39-
public function testNormalizersAndEncodersUseDefaultContextConfigOption(string $normalizerId)
40+
public function testNormalizersAndEncodersUseDefaultContextConfigOption()
4041
{
41-
static::bootKernel(['test_case' => 'Serializer']);
42+
/** @var SerializerKernel $kernel */
43+
$kernel = static::bootKernel(['test_case' => 'Serializer', 'root_config' => 'default_context.yaml']);
44+
45+
foreach ($kernel->normalizersAndEncoders as $normalizerOrEncoderId) {
46+
$normalizerOrEncoder = static::getContainer()->get($normalizerOrEncoderId);
4247

43-
$normalizer = static::getContainer()->get($normalizerId);
48+
$reflectionObject = new \ReflectionObject($normalizerOrEncoder);
49+
$property = $reflectionObject->getProperty('defaultContext');
50+
$property->setAccessible(true);
4451

45-
$reflectionObject = new \ReflectionObject($normalizer);
46-
$property = $reflectionObject->getProperty('defaultContext');
47-
$property->setAccessible(true);
52+
$defaultContext = $property->getValue($normalizerOrEncoder);
4853

49-
$defaultContext = $property->getValue($normalizer);
54+
self::assertArrayHasKey('fake_context_option', $defaultContext);
55+
self::assertEquals('foo', $defaultContext['fake_context_option']);
56+
}
57+
}
5058

51-
self::assertArrayHasKey('fake_context_option', $defaultContext);
52-
self::assertEquals('foo', $defaultContext['fake_context_option']);
59+
protected static function getKernelClass(): string
60+
{
61+
return SerializerKernel::class;
5362
}
63+
}
64+
65+
class SerializerKernel extends AppKernel implements CompilerPassInterface
66+
{
67+
public $normalizersAndEncoders = [
68+
'serializer.normalizer.property.alias', // Special case as this normalizer isn't tagged
69+
];
5470

55-
public static function provideNormalizersAndEncodersWithDefaultContextOption(): array
71+
public function process(ContainerBuilder $container)
5672
{
57-
return [
58-
['serializer.normalizer.constraint_violation_list.alias'],
59-
['serializer.normalizer.dateinterval.alias'],
60-
['serializer.normalizer.datetime.alias'],
61-
['serializer.normalizer.json_serializable.alias'],
62-
['serializer.normalizer.problem.alias'],
63-
['serializer.normalizer.uid.alias'],
64-
['serializer.normalizer.object.alias'],
65-
['serializer.encoder.xml.alias'],
66-
['serializer.encoder.yaml.alias'],
67-
['serializer.encoder.csv.alias'],
68-
];
73+
$services = array_merge(
74+
$container->findTaggedServiceIds('serializer.normalizer'),
75+
$container->findTaggedServiceIds('serializer.encoder')
76+
);
77+
foreach ($services as $serviceId => $attributes) {
78+
$class = $container->getDefinition($serviceId)->getClass();
79+
if (null === $reflectionConstructor = (new \ReflectionClass($class))->getConstructor()) {
80+
continue;
81+
}
82+
foreach ($reflectionConstructor->getParameters() as $reflectionParam) {
83+
if ('array $defaultContext' === $reflectionParam->getType()->getName().' $'.$reflectionParam->getName()) {
84+
$this->normalizersAndEncoders[] = $serviceId.'.alias';
85+
break;
86+
}
87+
}
88+
}
6989
}
7090
}
7191

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AppKernel.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ public function __construct($varDir, $testCase, $rootConfig, $environment, $debu
4949
parent::__construct($environment, $debug);
5050
}
5151

52+
protected function getContainerClass(): string
53+
{
54+
return parent::getContainerClass().substr(md5($this->rootConfig), -16);
55+
}
56+
5257
public function registerBundles(): iterable
5358
{
5459
if (!file_exists($filename = $this->getProjectDir().'/'.$this->testCase.'/bundles.php')) {

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Serializer/config.yml

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -8,58 +8,13 @@ framework:
88
max_depth_handler: Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Serializer\MaxDepthHandler
99
default_context:
1010
enable_max_depth: true
11-
fake_context_option: foo
1211
property_info: { enabled: true }
1312

1413
services:
1514
serializer.alias:
1615
alias: serializer
1716
public: true
1817

19-
serializer.normalizer.constraint_violation_list.alias:
20-
alias: serializer.normalizer.constraint_violation_list
21-
public: true
22-
23-
serializer.normalizer.dateinterval.alias:
24-
alias: serializer.normalizer.dateinterval
25-
public: true
26-
27-
serializer.normalizer.datetime.alias:
28-
alias: serializer.normalizer.datetime
29-
public: true
30-
31-
serializer.normalizer.json_serializable.alias:
32-
alias: serializer.normalizer.json_serializable
33-
public: true
34-
35-
serializer.normalizer.problem.alias:
36-
alias: serializer.normalizer.problem
37-
public: true
38-
39-
serializer.normalizer.uid.alias:
40-
alias: serializer.normalizer.uid
41-
public: true
42-
43-
serializer.normalizer.property.alias:
44-
alias: serializer.normalizer.property
45-
public: true
46-
47-
serializer.normalizer.object.alias:
48-
alias: serializer.normalizer.object
49-
public: true
50-
51-
serializer.encoder.xml.alias:
52-
alias: serializer.encoder.xml
53-
public: true
54-
55-
serializer.encoder.yaml.alias:
56-
alias: serializer.encoder.yaml
57-
public: true
58-
59-
serializer.encoder.csv.alias:
60-
alias: serializer.encoder.csv
61-
public: true
62-
6318
Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Serializer\CircularReferenceHandler: ~
6419

6520
Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Serializer\MaxDepthHandler: ~
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
imports:
2+
- { resource: ../config/default.yml }
3+
4+
framework:
5+
serializer:
6+
enabled: true
7+
circular_reference_handler: ~ # This must be null
8+
max_depth_handler: ~ # This must be null
9+
default_context:
10+
fake_context_option: foo
11+
12+
services:
13+
serializer.normalizer.constraint_violation_list.alias:
14+
alias: serializer.normalizer.constraint_violation_list
15+
public: true
16+
17+
serializer.normalizer.dateinterval.alias:
18+
alias: serializer.normalizer.dateinterval
19+
public: true
20+
21+
serializer.normalizer.datetime.alias:
22+
alias: serializer.normalizer.datetime
23+
public: true
24+
25+
serializer.normalizer.json_serializable.alias:
26+
alias: serializer.normalizer.json_serializable
27+
public: true
28+
29+
serializer.normalizer.object.alias:
30+
alias: serializer.normalizer.object
31+
public: true
32+
33+
serializer.normalizer.problem.alias:
34+
alias: serializer.normalizer.problem
35+
public: true
36+
37+
serializer.normalizer.property.alias:
38+
alias: serializer.normalizer.property
39+
public: true
40+
41+
serializer.normalizer.uid.alias:
42+
alias: serializer.normalizer.uid
43+
public: true
44+
45+
serializer.encoder.csv.alias:
46+
alias: serializer.encoder.csv
47+
public: true
48+
49+
serializer.encoder.json.alias:
50+
alias: serializer.encoder.json
51+
public: true
52+
53+
serializer.encoder.xml.alias:
54+
alias: serializer.encoder.xml
55+
public: true
56+
57+
serializer.encoder.yaml.alias:
58+
alias: serializer.encoder.yaml
59+
public: true

0 commit comments

Comments
 (0)
0