From cb36ec0d09b5cd3cc3ae390e6ae5ea51c556c8af Mon Sep 17 00:00:00 2001 From: Mathias Arlaud Date: Fri, 17 Jan 2025 09:45:41 +0100 Subject: [PATCH] [JsonEncoder] Allow to warm up item and list --- .../FrameworkExtension.php | 7 +++++-- .../Tests/Functional/JsonEncoderTest.php | 2 +- .../JsonEncoder/Attribute/JsonEncodable.php | 5 +++++ .../Component/JsonEncoder/CHANGELOG.md | 1 + .../CacheWarmer/EncoderDecoderCacheWarmer.php | 21 +++++++++++++------ .../DependencyInjection/EncodablePass.php | 15 +++++++------ .../EncoderDecoderCacheWarmerTest.php | 19 ++++++++++++++--- .../DependencyInjection/EncodablePassTest.php | 10 ++++----- 8 files changed, 56 insertions(+), 24 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 6d20ca653e668..3ef5de07097bb 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -746,8 +746,11 @@ static function (ChildDefinition $definition, AsPeriodicTask|AsCronTask $attribu } ); } - $container->registerAttributeForAutoconfiguration(JsonEncodable::class, static function (ChildDefinition $definition): void { - $definition->addTag('json_encoder.encodable'); + $container->registerAttributeForAutoconfiguration(JsonEncodable::class, static function (ChildDefinition $definition, JsonEncodable $attribute): void { + $definition->addTag('json_encoder.encodable', [ + 'object' => $attribute->asObject, + 'list' => $attribute->asList, + ]); $definition->addTag('container.excluded'); }); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/JsonEncoderTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/JsonEncoderTest.php index 93ca1fd6d7a23..b5410e1e1127b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/JsonEncoderTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/JsonEncoderTest.php @@ -62,6 +62,6 @@ public function testWarmupEncodableClasses() static::getContainer()->get('json_encoder.cache_warmer.encoder_decoder.alias')->warmUp(static::getContainer()->getParameter('kernel.cache_dir')); $this->assertFileExists($encodersDir); - $this->assertCount(1, glob($encodersDir.'/*')); + $this->assertCount(2, glob($encodersDir.'/*')); } } diff --git a/src/Symfony/Component/JsonEncoder/Attribute/JsonEncodable.php b/src/Symfony/Component/JsonEncoder/Attribute/JsonEncodable.php index f370009d2dcdf..b03346be2e36b 100644 --- a/src/Symfony/Component/JsonEncoder/Attribute/JsonEncodable.php +++ b/src/Symfony/Component/JsonEncoder/Attribute/JsonEncodable.php @@ -19,4 +19,9 @@ #[\Attribute(\Attribute::TARGET_CLASS)] final class JsonEncodable { + public function __construct( + public bool $asObject = true, + public bool $asList = true, + ) { + } } diff --git a/src/Symfony/Component/JsonEncoder/CHANGELOG.md b/src/Symfony/Component/JsonEncoder/CHANGELOG.md index 327d5f6cec3ef..6cc6bc5f6b52b 100644 --- a/src/Symfony/Component/JsonEncoder/CHANGELOG.md +++ b/src/Symfony/Component/JsonEncoder/CHANGELOG.md @@ -6,3 +6,4 @@ CHANGELOG * Introduce the component as experimental * Add native PHP lazy ghost support + * Allow to select the warmup of object and list in `JsonEncodable` and `json_encoder.encodable` diff --git a/src/Symfony/Component/JsonEncoder/CacheWarmer/EncoderDecoderCacheWarmer.php b/src/Symfony/Component/JsonEncoder/CacheWarmer/EncoderDecoderCacheWarmer.php index a01bb63794bfd..5ea39b3b96d04 100644 --- a/src/Symfony/Component/JsonEncoder/CacheWarmer/EncoderDecoderCacheWarmer.php +++ b/src/Symfony/Component/JsonEncoder/CacheWarmer/EncoderDecoderCacheWarmer.php @@ -33,10 +33,10 @@ final class EncoderDecoderCacheWarmer implements CacheWarmerInterface private DecoderGenerator $decoderGenerator; /** - * @param iterable $encodableClassNames + * @param iterable $encodable */ public function __construct( - private iterable $encodableClassNames, + private iterable $encodable, PropertyMetadataLoaderInterface $encodePropertyMetadataLoader, PropertyMetadataLoaderInterface $decodePropertyMetadataLoader, string $encodersDir, @@ -49,11 +49,20 @@ public function __construct( public function warmUp(string $cacheDir, ?string $buildDir = null): array { - foreach ($this->encodableClassNames as $className) { - $type = Type::object($className); + foreach ($this->encodable as $className => $encodable) { + if ($encodable['object']) { + $type = Type::object($className); - $this->warmUpEncoder($type); - $this->warmUpDecoders($type); + $this->warmUpEncoder($type); + $this->warmUpDecoders($type); + } + + if ($encodable['list']) { + $type = Type::list(Type::object($className)); + + $this->warmUpEncoder($type); + $this->warmUpDecoders($type); + } } return []; diff --git a/src/Symfony/Component/JsonEncoder/DependencyInjection/EncodablePass.php b/src/Symfony/Component/JsonEncoder/DependencyInjection/EncodablePass.php index 47fcd8940d1ea..7d0f2a3b27c45 100644 --- a/src/Symfony/Component/JsonEncoder/DependencyInjection/EncodablePass.php +++ b/src/Symfony/Component/JsonEncoder/DependencyInjection/EncodablePass.php @@ -15,7 +15,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; /** - * Sets the encodable classes to the services that need them. + * Sets the encodable metadata to the services that need them. * * @author Mathias Arlaud */ @@ -27,27 +27,30 @@ public function process(ContainerBuilder $container): void return; } - $encodableClassNames = []; + $encodable = []; // retrieve concrete services tagged with "json_encoder.encodable" tag foreach ($container->getDefinitions() as $id => $definition) { - if (!$definition->hasTag('json_encoder.encodable')) { + if (!$tag = ($definition->getTag('json_encoder.encodable')[0] ?? null)) { continue; } if (($className = $container->getDefinition($id)->getClass()) && !$container->getDefinition($id)->isAbstract()) { - $encodableClassNames[] = $className; + $encodable[$className] = [ + 'object' => $tag['object'], + 'list' => $tag['list'], + ]; } $container->removeDefinition($id); } $container->getDefinition('.json_encoder.cache_warmer.encoder_decoder') - ->replaceArgument(0, $encodableClassNames); + ->replaceArgument(0, $encodable); if ($container->hasDefinition('.json_encoder.cache_warmer.lazy_ghost')) { $container->getDefinition('.json_encoder.cache_warmer.lazy_ghost') - ->replaceArgument(0, $encodableClassNames); + ->replaceArgument(0, array_keys($encodable)); } } } diff --git a/src/Symfony/Component/JsonEncoder/Tests/CacheWarmer/EncoderDecoderCacheWarmerTest.php b/src/Symfony/Component/JsonEncoder/Tests/CacheWarmer/EncoderDecoderCacheWarmerTest.php index d0df4df12d5ce..e0882365ba521 100644 --- a/src/Symfony/Component/JsonEncoder/Tests/CacheWarmer/EncoderDecoderCacheWarmerTest.php +++ b/src/Symfony/Component/JsonEncoder/Tests/CacheWarmer/EncoderDecoderCacheWarmerTest.php @@ -15,6 +15,7 @@ use Symfony\Component\JsonEncoder\CacheWarmer\EncoderDecoderCacheWarmer; use Symfony\Component\JsonEncoder\Mapping\PropertyMetadataLoader; use Symfony\Component\JsonEncoder\Tests\Fixtures\Model\ClassicDummy; +use Symfony\Component\JsonEncoder\Tests\Fixtures\Model\DummyWithNameAttributes; use Symfony\Component\TypeInfo\TypeResolver\TypeResolver; class EncoderDecoderCacheWarmerTest extends TestCase @@ -42,24 +43,36 @@ protected function setUp(): void public function testWarmUp() { - $this->cacheWarmer()->warmUp('useless'); + $this->cacheWarmer([ + ClassicDummy::class => ['object' => true, 'list' => true], + DummyWithNameAttributes::class => ['object' => true, 'list' => false], + ])->warmUp('useless'); $this->assertSame([ + \sprintf('%s/5acb3571777e02a2712fb9a9126a338f.json.php', $this->encodersDir), \sprintf('%s/d147026bb5d25e5012afcdc1543cf097.json.php', $this->encodersDir), + \sprintf('%s/de878efdd0bf652bdd72d1dc95f6d80d.json.php', $this->encodersDir), ], glob($this->encodersDir.'/*')); $this->assertSame([ + \sprintf('%s/5acb3571777e02a2712fb9a9126a338f.json.php', $this->decodersDir), + \sprintf('%s/5acb3571777e02a2712fb9a9126a338f.json.stream.php', $this->decodersDir), \sprintf('%s/d147026bb5d25e5012afcdc1543cf097.json.php', $this->decodersDir), \sprintf('%s/d147026bb5d25e5012afcdc1543cf097.json.stream.php', $this->decodersDir), + \sprintf('%s/de878efdd0bf652bdd72d1dc95f6d80d.json.php', $this->decodersDir), + \sprintf('%s/de878efdd0bf652bdd72d1dc95f6d80d.json.stream.php', $this->decodersDir), ], glob($this->decodersDir.'/*')); } - private function cacheWarmer(): EncoderDecoderCacheWarmer + /** + * @param array $encodableClasses + */ + private function cacheWarmer(array $encodableClasses = []): EncoderDecoderCacheWarmer { $typeResolver = TypeResolver::create(); return new EncoderDecoderCacheWarmer( - [ClassicDummy::class], + $encodableClasses, new PropertyMetadataLoader($typeResolver), new PropertyMetadataLoader($typeResolver), $this->encodersDir, diff --git a/src/Symfony/Component/JsonEncoder/Tests/DependencyInjection/EncodablePassTest.php b/src/Symfony/Component/JsonEncoder/Tests/DependencyInjection/EncodablePassTest.php index 55ad1c036a130..36a7938e66b5a 100644 --- a/src/Symfony/Component/JsonEncoder/Tests/DependencyInjection/EncodablePassTest.php +++ b/src/Symfony/Component/JsonEncoder/Tests/DependencyInjection/EncodablePassTest.php @@ -25,8 +25,8 @@ public function testSetEncodableClassNames() $container->register('.json_encoder.cache_warmer.encoder_decoder')->setArguments([null]); $container->register('.json_encoder.cache_warmer.lazy_ghost')->setArguments([null]); - $container->register('encodable')->setClass('Foo')->addTag('json_encoder.encodable'); - $container->register('abstractEncodable')->setClass('Bar')->addTag('json_encoder.encodable')->setAbstract(true); + $container->register('encodable')->setClass('Foo')->addTag('json_encoder.encodable', ['object' => true, 'list' => true]); + $container->register('abstractEncodable')->setClass('Bar')->addTag('json_encoder.encodable', ['object' => true, 'list' => true])->setAbstract(true); $container->register('notEncodable')->setClass('Baz'); $pass = new EncodablePass(); @@ -35,9 +35,7 @@ public function testSetEncodableClassNames() $encoderDecoderCacheWarmer = $container->getDefinition('.json_encoder.cache_warmer.encoder_decoder'); $lazyGhostCacheWarmer = $container->getDefinition('.json_encoder.cache_warmer.lazy_ghost'); - $expectedEncodableClassNames = ['Foo']; - - $this->assertSame($expectedEncodableClassNames, $encoderDecoderCacheWarmer->getArgument(0)); - $this->assertSame($expectedEncodableClassNames, $lazyGhostCacheWarmer->getArgument(0)); + $this->assertSame(['Foo' => ['object' => true, 'list' => true]], $encoderDecoderCacheWarmer->getArgument(0)); + $this->assertSame(['Foo'], $lazyGhostCacheWarmer->getArgument(0)); } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy