8000 feature #59536 [JsonEncoder] Allow to warm up object and list (mtarld) · symfony/symfony@1f83bf1 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1f83bf1

Browse files
committed
feature #59536 [JsonEncoder] Allow to warm up object and list (mtarld)
This PR was merged into the 7.3 branch. Discussion ---------- [JsonEncoder] Allow to warm up object and list | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | no | New feature? | yes | Deprecations? | no | Issues | | License | MIT As discussed with `@chalasr`, configuration in FrameworkBundle must be avoided as much as possible. That's why #59396 might not be the way to go. Instead, this PR addresses the most common use cases, which are warming up cache files for `GivenClass` and `list<GivenClass>`. This can be configured by setting the `object` and `list` attributes of `json_encoder.encodable`, or `asObject` and `asList` of the `JsonEncodable` attribute accordingly. Commits ------- cb36ec0 [JsonEncoder] Allow to warm up item and list
2 parents b8f1db9 + cb36ec0 commit 1f83bf1

File tree

8 files changed

+56
-24
lines changed

8 files changed

+56
-24
lines changed

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

+5-2
Original file line numberDiff line numberDiff line change
@@ -750,8 +750,11 @@ static function (ChildDefinition $definition, AsPeriodicTask|AsCronTask $attribu
750750
}
751751
);
752752
}
753-
$container->registerAttributeForAutoconfiguration(JsonEncodable::class, static function (ChildDefinition $definition): void {
754-
$definition->addTag('json_encoder.encodable');
753+
$container->registerAttributeForAutoconfiguration(JsonEncodable::class, static function (ChildDefinition $definition, JsonEncodable $attribute): void {
754+
$definition->addTag('json_encoder.encodable', [
755+
'object' => $attribute->asObject,
756+
'list' => $attribute->asList,
757+
]);
755758
$definition->addTag('container.excluded');
756759
});
757760

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,6 @@ public function testWarmupEncodableClasses()
6262
static::getContainer()->get('json_encoder.cache_warmer.encoder_decoder.alias')->warmUp(static::getContainer()->getParameter('kernel.cache_dir'));
6363

6464
$this->assertFileExists($encodersDir);
65-
$this->assertCount(1, glob($encodersDir.'/*'));
65+
$this->assertCount(2, glob($encodersDir.'/*'));
6666
}
6767
}

src/Symfony/Component/JsonEncoder/Attribute/JsonEncodable.php

+5
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,9 @@
1919
#[\Attribute(\Attribute::TARGET_CLASS)]
2020
final class JsonEncodable
2121
{
22+
public function __construct(
23+
public bool $asObject = true,
24+
public bool $asList = true,
25+
) {
26+
}
2227
}

src/Symfony/Component/JsonEncoder/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ CHANGELOG
66

77
* Introduce the component as experimental
88
* Add native PHP lazy ghost support
9+
* Allow to select the warmup of object and list in `JsonEncodable` and `json_encoder.encodable`

src/Symfony/Component/JsonEncoder/CacheWarmer/EncoderDecoderCacheWarmer.php

+15-6
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ final class EncoderDecoderCacheWarmer implements CacheWarmerInterface
3333
private DecoderGenerator $decoderGenerator;
3434

3535
/**
36-
* @param iterable<class-string> $encodableClassNames
36+
* @param iterable<class-string, array{object: bool, list: bool}> $encodable
3737
*/
3838
public function __construct(
39-
private iterable $encodableClassNames,
39+
private iterable $encodable,
4040
PropertyMetadataLoaderInterface $encodePropertyMetadataLoader,
4141
PropertyMetadataLoaderInterface $decodePropertyMetadataLoader,
4242
string $encodersDir,
@@ -49,11 +49,20 @@ public function __construct(
4949

5050
public function warmUp(string $cacheDir, ?string $buildDir = null): array
5151
{
52-
foreach ($this->encodableClassNames as $className) {
53-
$type = Type::object($className);
52+
foreach ($this->encodable as $className => $encodable) {
53+
if ($encodable['object']) {
54+
$type = Type::object($className);
5455

55-
$this->warmUpEncoder($type);
56-
$this->warmUpDecoders($type);
56+
$this->warmUpEncoder($type);
57+
$this->warmUpDecoders($type);
58+
}
59+
60+
if ($encodable['list']) {
61+
$type = Type::list(Type::object($className));
62+
63+
$this->warmUpEncoder($type);
64+
$this->warmUpDecoders($type);
65+
}
5766
}
5867

5968
return [];

src/Symfony/Component/JsonEncoder/DependencyInjection/EncodablePass.php

+9-6
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
use Symfony\Component\DependencyInjection\ContainerBuilder;
1616

1717
/**
18-
* Sets the encodable classes to the services that need them.
18+
* Sets the encodable metadata to the services that need them.
1919
*
2020
* @author Mathias Arlaud <mathias.arlaud@gmail.com>
2121
*/
@@ -27,27 +27,30 @@ public function process(ContainerBuilder $container): void
2727
return;
2828
}
2929

30-
$encodableClassNames = [];
30+
$encodable = [];
3131

3232
// retrieve concrete services tagged with "json_encoder.encodable" tag
3333
foreach ($container->getDefinitions() as $id => $definition) {
34-
if (!$definition->hasTag('json_encoder.encodable')) {
34+
if (!$tag = ($definition->getTag('json_encoder.encodable')[0] ?? null)) {
3535
continue;
3636
}
3737

3838
if (($className = $container->getDefinition($id)->getClass()) && !$container->getDefinition($id)->isAbstract()) {
39-
$encodableClassNames[] = $className;
39+
$encodable[$className] = [
40+
'object' => $tag['object'],
41+
'list' => $tag['list'],
42+
];
4043
}
4144

4245
$container->removeDefinition($id);
4346
}
4447

4548
$container->getDefinition('.json_encoder.cache_warmer.encoder_decoder')
46-
->replaceArgument(0, $encodableClassNames);
49+
->replaceArgument(0, $encodable);
4750

4851
if ($container->hasDefinition('.json_encoder.cache_warmer.lazy_ghost')) {
4952
$container->getDefinition('.json_encoder.cache_warmer.lazy_ghost')
50-
->replaceArgument(0, $encodableClassNames);
53+
->replaceArgument(0, array_keys($encodable));
5154
}
5255
}
5356
}

src/Symfony/Component/JsonEncoder/Tests/CacheWarmer/EncoderDecoderCacheWarmerTest.php

+16-3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\JsonEncoder\CacheWarmer\EncoderDecoderCacheWarmer;
1616
use Symfony\Component\JsonEncoder\Mapping\PropertyMetadataLoader;
1717
use Symfony\Component\JsonEncoder\Tests\Fixtures\Model\ClassicDummy;
18+
use Symfony\Component\JsonEncoder\Tests\Fixtures\Model\DummyWithNameAttributes;
1819
use Symfony\Component\TypeInfo\TypeResolver\TypeResolver;
1920

2021
class EncoderDecoderCacheWarmerTest extends TestCase
@@ -42,24 +43,36 @@ protected function setUp(): void
4243

4344
public function testWarmUp()
4445
{
45-
$this->cacheWarmer()->warmUp('useless');
46+
$this->cacheWarmer([
47+
ClassicDummy::class => ['object' => true, 'list' => true],
48+
DummyWithNameAttributes::class => ['object' => true, 'list' => false],
49+
])->warmUp('useless');
4650

4751
$this->assertSame([
52+
\sprintf('%s/5acb3571777e02a2712fb9a9126a338f.json.php', $this->encodersDir),
4853
\sprintf('%s/d147026bb5d25e5012afcdc1543cf097.json.php', $this->encodersDir),
54+
\sprintf('%s/de878efdd0bf652bdd72d1dc95f6d80d.json.php', $this->encodersDir),
4955
], glob($this->encodersDir.'/*'));
5056

5157
$this->assertSame([
58+
\sprintf('%s/5acb3571777e02a2712fb9a9126a338f.json.php', $this->decodersDir),
59+
\sprintf('%s/5acb3571777e02a2712fb9a9126a338f.json.stream.php', $this->decodersDir),
5260
\sprintf('%s/d147026bb5d25e5012afcdc1543cf097.json.php', $this->decodersDir),
5361
\sprintf('%s/d147026bb5d25e5012afcdc1543cf097.json.stream.php', $this->decodersDir),
62+
\sprintf('%s/de878efdd0bf652bdd72d1dc95f6d80d.json.php', $this->decodersDir),
63+
\sprintf('%s/de878efdd0bf652bdd72d1dc95f6d80d.json.stream.php', $this->decodersDir),
5464
], glob($this->decodersDir.'/*'));
5565
}
5666

57-
private function cacheWarmer(): EncoderDecoderCacheWarmer
67+
/**
68+
* @param array<class-string, array{object: bool, list: bool}> $encodableClasses
69+
*/
70+
private function cacheWarmer(array $encodableClasses = []): EncoderDecoderCacheWarmer
5871
{
5972
$typeResolver = TypeResolver::create();
6073

6174
return new EncoderDecoderCacheWarmer(
62-
[ClassicDummy::class],
75+
$encodableClasses,
6376
new PropertyMetadataLoader($typeResolver),
6477
new PropertyMetadataLoader($typeResolver),
6578
$this->encodersDir,

src/Symfony/Component/JsonEncoder/Tests/DependencyInjection/EncodablePassTest.php

+4-6
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ public function testSetEncodableClassNames()
2525
$container->register('.json_encoder.cache_warmer.encoder_decoder')->setArguments([null]);
2626
$container->register('.json_encoder.cache_warmer.lazy_ghost')->setArguments([null]);
2727

28-
$container->register('encodable')->setClass('Foo')->addTag('json_encoder.encodable');
29-
$container->register('abstractEncodable')->setClass('Bar')->addTag('json_encoder.encodable')->setAbstract(true);
28+
$container->register('encodable')->setClass('Foo')->addTag('json_encoder.encodable', ['object' => true, 'list' => true]);
29+
$container->register('abstractEncodable')->setClass('Bar')->addTag('json_encoder.encodable', ['object' => true, 'list' => true])->setAbstract(true);
3030
$container->register('notEncodable')->setClass('Baz');
3131

3232
$pass = new EncodablePass();
@@ -35,9 +35,7 @@ public function testSetEncodableClassNames()
3535
$encoderDecoderCacheWarmer = $container->getDefinition('.json_encoder.cache_warmer.encoder_decoder');
3636
$lazyGhostCacheWarmer = $container->getDefinition('.json_encoder.cache_warmer.lazy_ghost');
3737

38-
$expectedEncodableClassNames = ['Foo'];
39-
40-
$this->assertSame($expectedEncodableClassNames, $encoderDecoderCacheWarmer->getArgument(0));
41-
$this->assertSame($expectedEncodableClassNames, $lazyGhostCacheWarmer->getArgument(0));
38+
$this->assertSame(['Foo' => ['object' => true, 'list' => true]], $encoderDecoderCacheWarmer->getArgument(0));
39+
$this->assertSame(['Foo'], $lazyGhostCacheWarmer->getArgument(0));
4240
}
4341
}

0 commit comments

Comments
 (0)
0