From 408da06829094b30d891e26271502d03e35658ca Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 7 Jun 2024 13:36:04 +0200 Subject: [PATCH 1/6] change notifier type for brevo from chatter to texter --- Resources/config/notifier_transports.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/config/notifier_transports.php b/Resources/config/notifier_transports.php index df9be94ed..5ddc9ae24 100644 --- a/Resources/config/notifier_transports.php +++ b/Resources/config/notifier_transports.php @@ -27,7 +27,6 @@ $chatterFactories = [ 'bluesky' => Bridge\Bluesky\BlueskyTransportFactory::class, - 'brevo' => Bridge\Brevo\BrevoTransportFactory::class, 'chatwork' => Bridge\Chatwork\ChatworkTransportFactory::class, 'discord' => Bridge\Discord\DiscordTransportFactory::class, 'fake-chat' => Bridge\FakeChat\FakeChatTransportFactory::class, @@ -59,6 +58,7 @@ $texterFactories = [ 'all-my-sms' => Bridge\AllMySms\AllMySmsTransportFactory::class, 'bandwidth' => Bridge\Bandwidth\BandwidthTransportFactory::class, + 'brevo' => Bridge\Brevo\BrevoTransportFactory::class, 'click-send' => Bridge\ClickSend\ClickSendTransportFactory::class, 'clickatell' => Bridge\Clickatell\ClickatellTransportFactory::class, 'contact-everyone' => Bridge\ContactEveryone\ContactEveryoneTransportFactory::class, From 18b84194424511fe541fc7962553ae423e4553c7 Mon Sep 17 00:00:00 2001 From: HypeMC Date: Fri, 31 May 2024 18:43:25 +0200 Subject: [PATCH 2/6] [FrameworkBundle] Fix setting default context for certain normalizers --- DependencyInjection/FrameworkExtension.php | 8 ++- Resources/config/serializer.php | 1 - Tests/Functional/AbstractWebTestCase.php | 2 +- Tests/Functional/SerializerTest.php | 70 ++++++++++++------- Tests/Functional/app/AppKernel.php | 5 ++ Tests/Functional/app/Serializer/config.yml | 45 ------------ .../app/Serializer/default_context.yaml | 59 ++++++++++++++++ 7 files changed, 115 insertions(+), 75 deletions(-) create mode 100644 Tests/Functional/app/Serializer/default_context.yaml diff --git a/DependencyInjection/FrameworkExtension.php b/DependencyInjection/FrameworkExtension.php index ebaed7c2b..71505f251 100644 --- a/DependencyInjection/FrameworkExtension.php +++ b/DependencyInjection/FrameworkExtension.php @@ -1859,18 +1859,20 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder } $arguments = $container->getDefinition('serializer.normalizer.object')->getArguments(); - $context = []; + $context = $arguments[6] ?? $defaultContext; if (isset($config['circular_reference_handler']) && $config['circular_reference_handler']) { - $context += ($arguments[6] ?? $defaultContext) + ['circular_reference_handler' => new Reference($config['circular_reference_handler'])]; + $context += ['circular_reference_handler' => new Reference($config['circular_reference_handler'])]; $container->getDefinition('serializer.normalizer.object')->setArgument(5, null); } if ($config['max_depth_handler'] ?? false) { - $context += ($arguments[6] ?? $defaultContext) + ['max_depth_handler' => new Reference($config['max_depth_handler'])]; + $context += ['max_depth_handler' => new Reference($config['max_depth_handler'])]; } $container->getDefinition('serializer.normalizer.object')->setArgument(6, $context); + + $container->getDefinition('serializer.normalizer.property')->setArgument(5, $defaultContext); } private function registerPropertyInfoConfiguration(ContainerBuilder $container, PhpFileLoader $loader) diff --git a/Resources/config/serializer.php b/Resources/config/serializer.php index 7762e5a64..2fb42027f 100644 --- a/Resources/config/serializer.php +++ b/Resources/config/serializer.php @@ -139,7 +139,6 @@ service('property_info')->ignoreOnInvalid(), service('serializer.mapping.class_discriminator_resolver')->ignoreOnInvalid(), null, - [], ]) ->alias(PropertyNormalizer::class, 'serializer.normalizer.property') diff --git a/Tests/Functional/AbstractWebTestCase.php b/Tests/Functional/AbstractWebTestCase.php index bce53b866..30ca91d1e 100644 --- a/Tests/Functional/AbstractWebTestCase.php +++ b/Tests/Functional/AbstractWebTestCase.php @@ -52,7 +52,7 @@ protected static function getKernelClass(): string protected static function createKernel(array $options = []): KernelInterface { - $class = self::getKernelClass(); + $class = static::getKernelClass(); if (!isset($options['test_case'])) { throw new \InvalidArgumentException('The option "test_case" must be set.'); diff --git a/Tests/Functional/SerializerTest.php b/Tests/Functional/SerializerTest.php index 9a6527b14..7ce9b0735 100644 --- a/Tests/Functional/SerializerTest.php +++ b/Tests/Functional/SerializerTest.php @@ -11,6 +11,10 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Functional; +use Symfony\Bundle\FrameworkBundle\Tests\Functional\app\AppKernel; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; + /** * @author Kévin Dunglas */ @@ -33,39 +37,55 @@ public function testDeserializeArrayOfObject() $this->assertEquals($expected, $result); } - /** - * @dataProvider provideNormalizersAndEncodersWithDefaultContextOption - */ - public function testNormalizersAndEncodersUseDefaultContextConfigOption(string $normalizerId) + public function testNormalizersAndEncodersUseDefaultContextConfigOption() { - static::bootKernel(['test_case' => 'Serializer']); + /** @var SerializerKernel $kernel */ + $kernel = static::bootKernel(['test_case' => 'Serializer', 'root_config' => 'default_context.yaml']); + + foreach ($kernel->normalizersAndEncoders as $normalizerOrEncoderId) { + $normalizerOrEncoder = static::getContainer()->get($normalizerOrEncoderId); - $normalizer = static::getContainer()->get($normalizerId); + $reflectionObject = new \ReflectionObject($normalizerOrEncoder); + $property = $reflectionObject->getProperty('defaultContext'); + $property->setAccessible(true); - $reflectionObject = new \ReflectionObject($normalizer); - $property = $reflectionObject->getProperty('defaultContext'); - $property->setAccessible(true); + $defaultContext = $property->getValue($normalizerOrEncoder); - $defaultContext = $property->getValue($normalizer); + self::assertArrayHasKey('fake_context_option', $defaultContext); + self::assertEquals('foo', $defaultContext['fake_context_option']); + } + } - self::assertArrayHasKey('fake_context_option', $defaultContext); - self::assertEquals('foo', $defaultContext['fake_context_option']); + protected static function getKernelClass(): string + { + return SerializerKernel::class; } +} + +class SerializerKernel extends AppKernel implements CompilerPassInterface +{ + public $normalizersAndEncoders = [ + 'serializer.normalizer.property.alias', // Special case as this normalizer isn't tagged + ]; - public static function provideNormalizersAndEncodersWithDefaultContextOption(): array + public function process(ContainerBuilder $container) { - return [ - ['serializer.normalizer.constraint_violation_list.alias'], - ['serializer.normalizer.dateinterval.alias'], - ['serializer.normalizer.datetime.alias'], - ['serializer.normalizer.json_serializable.alias'], - ['serializer.normalizer.problem.alias'], - ['serializer.normalizer.uid.alias'], - ['serializer.normalizer.object.alias'], - ['serializer.encoder.xml.alias'], - ['serializer.encoder.yaml.alias'], - ['serializer.encoder.csv.alias'], - ]; + $services = array_merge( + $container->findTaggedServiceIds('serializer.normalizer'), + $container->findTaggedServiceIds('serializer.encoder') + ); + foreach ($services as $serviceId => $attributes) { + $class = $container->getDefinition($serviceId)->getClass(); + if (null === $reflectionConstructor = (new \ReflectionClass($class))->getConstructor()) { + continue; + } + foreach ($reflectionConstructor->getParameters() as $reflectionParam) { + if ('array $defaultContext' === $reflectionParam->getType()->getName().' $'.$reflectionParam->getName()) { + $this->normalizersAndEncoders[] = $serviceId.'.alias'; + break; + } + } + } } } diff --git a/Tests/Functional/app/AppKernel.php b/Tests/Functional/app/AppKernel.php index 49fb0ca2e..0c3c9cc35 100644 --- a/Tests/Functional/app/AppKernel.php +++ b/Tests/Functional/app/AppKernel.php @@ -49,6 +49,11 @@ public function __construct($varDir, $testCase, $rootConfig, $environment, $debu parent::__construct($environment, $debug); } + protected function getContainerClass(): string + { + return parent::getContainerClass().substr(md5($this->rootConfig), -16); + } + public function registerBundles(): iterable { if (!file_exists($filename = $this->getProjectDir().'/'.$this->testCase.'/bundles.php')) { diff --git a/Tests/Functional/app/Serializer/config.yml b/Tests/Functional/app/Serializer/config.yml index f023f6341..c22edfcce 100644 --- a/Tests/Functional/app/Serializer/config.yml +++ b/Tests/Functional/app/Serializer/config.yml @@ -8,7 +8,6 @@ framework: max_depth_handler: Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Serializer\MaxDepthHandler default_context: enable_max_depth: true - fake_context_option: foo property_info: { enabled: true } services: @@ -16,50 +15,6 @@ services: alias: serializer public: true - serializer.normalizer.constraint_violation_list.alias: - alias: serializer.normalizer.constraint_violation_list - public: true - - serializer.normalizer.dateinterval.alias: - alias: serializer.normalizer.dateinterval - public: true - - serializer.normalizer.datetime.alias: - alias: serializer.normalizer.datetime - public: true - - serializer.normalizer.json_serializable.alias: - alias: serializer.normalizer.json_serializable - public: true - - serializer.normalizer.problem.alias: - alias: serializer.normalizer.problem - public: true - - serializer.normalizer.uid.alias: - alias: serializer.normalizer.uid - public: true - - serializer.normalizer.property.alias: - alias: serializer.normalizer.property - public: true - - serializer.normalizer.object.alias: - alias: serializer.normalizer.object - public: true - - serializer.encoder.xml.alias: - alias: serializer.encoder.xml - public: true - - serializer.encoder.yaml.alias: - alias: serializer.encoder.yaml - public: true - - serializer.encoder.csv.alias: - alias: serializer.encoder.csv - public: true - Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Serializer\CircularReferenceHandler: ~ Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Serializer\MaxDepthHandler: ~ diff --git a/Tests/Functional/app/Serializer/default_context.yaml b/Tests/Functional/app/Serializer/default_context.yaml new file mode 100644 index 000000000..de6114c5d --- /dev/null +++ b/Tests/Functional/app/Serializer/default_context.yaml @@ -0,0 +1,59 @@ +imports: + - { resource: ../config/default.yml } + +framework: + serializer: + enabled: true + circular_reference_handler: ~ # This must be null + max_depth_handler: ~ # This must be null + default_context: + fake_context_option: foo + +services: + serializer.normalizer.constraint_violation_list.alias: + alias: serializer.normalizer.constraint_violation_list + public: true + + serializer.normalizer.dateinterval.alias: + alias: serializer.normalizer.dateinterval + public: true + + serializer.normalizer.datetime.alias: + alias: serializer.normalizer.datetime + public: true + + serializer.normalizer.json_serializable.alias: + alias: serializer.normalizer.json_serializable + public: true + + serializer.normalizer.object.alias: + alias: serializer.normalizer.object + public: true + + serializer.normalizer.problem.alias: + alias: serializer.normalizer.problem + public: true + + serializer.normalizer.property.alias: + alias: serializer.normalizer.property + public: true + + serializer.normalizer.uid.alias: + alias: serializer.normalizer.uid + public: true + + serializer.encoder.csv.alias: + alias: serializer.encoder.csv + public: true + + serializer.encoder.json.alias: + alias: serializer.encoder.json + public: true + + serializer.encoder.xml.alias: + alias: serializer.encoder.xml + public: true + + serializer.encoder.yaml.alias: + alias: serializer.encoder.yaml + public: true From a2c2e3c06f37bc7db3f08e9d91d5b9d5fb0c5022 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 17 Jun 2024 23:57:43 +0200 Subject: [PATCH 3/6] inject the missing logger service --- DependencyInjection/FrameworkExtension.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/DependencyInjection/FrameworkExtension.php b/DependencyInjection/FrameworkExtension.php index 437d5402a..3c82b4b0c 100644 --- a/DependencyInjection/FrameworkExtension.php +++ b/DependencyInjection/FrameworkExtension.php @@ -2855,6 +2855,11 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $ ->addArgument(new Reference('http_client', ContainerBuilder::NULL_ON_INVALID_REFERENCE)); } + if (ContainerBuilder::willBeAvailable('symfony/bluesky-notifier', NotifierBridge\Bluesky\BlueskyTransportFactory::class, ['symfony/framework-bundle', 'symfony/notifier'])) { + $container->getDefinition($classToServices[NotifierBridge\Bluesky\BlueskyTransportFactory::class]) + ->addArgument(new Reference('logger')); + } + if (isset($config['admin_recipients'])) { $notifier = $container->getDefinition('notifier'); foreach ($config['admin_recipients'] as $i => $recipient) { From b3a0478da350dacaade8c3249682a57685045aac Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 22 Jun 2024 13:31:15 +0200 Subject: [PATCH 4/6] fix tests --- Tests/Functional/SerializerTest.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Tests/Functional/SerializerTest.php b/Tests/Functional/SerializerTest.php index 49019ab2a..9d75c5bf6 100644 --- a/Tests/Functional/SerializerTest.php +++ b/Tests/Functional/SerializerTest.php @@ -44,6 +44,10 @@ public function testNormalizersAndEncodersUseDefaultContextConfigOption() $kernel = static::bootKernel(['test_case' => 'Serializer', 'root_config' => 'default_context.yaml']); foreach ($kernel->normalizersAndEncoders as $normalizerOrEncoderId) { + if (!static::getContainer()->has($normalizerOrEncoderId)) { + continue; + } + $normalizerOrEncoder = static::getContainer()->get($normalizerOrEncoderId); $reflectionObject = new \ReflectionObject($normalizerOrEncoder); @@ -68,7 +72,7 @@ class SerializerKernel extends AppKernel implements CompilerPassInterface 'serializer.normalizer.property.alias', // Special case as this normalizer isn't tagged ]; - public function process(ContainerBuilder $container) + public function process(ContainerBuilder $container): void { $services = array_merge( $container->findTaggedServiceIds('serializer.normalizer'), From c1d1cb0e508e11639283e1e6f8918eef0fa524bd Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 26 Jun 2024 10:32:27 +0200 Subject: [PATCH 5/6] [FrameworkBundle] Throw runtime exception when trying to use asset-mapper while http-client is disabled --- DependencyInjection/FrameworkExtension.php | 10 ++++++---- Resources/config/asset_mapper.php | 8 +++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/DependencyInjection/FrameworkExtension.php b/DependencyInjection/FrameworkExtension.php index 6f7579f36..84dbeabe9 100644 --- a/DependencyInjection/FrameworkExtension.php +++ b/DependencyInjection/FrameworkExtension.php @@ -349,7 +349,7 @@ public function load(array $configs, ContainerBuilder $container) throw new LogicException('AssetMapper support cannot be enabled as the AssetMapper component is not installed. Try running "composer require symfony/asset-mapper".'); } - $this->registerAssetMapperConfiguration($config['asset_mapper'], $container, $loader, $this->readConfigEnabled('assets', $container, $config['assets'])); + $this->registerAssetMapperConfiguration($config['asset_mapper'], $container, $loader, $this->readConfigEnabled('assets', $container, $config['assets']), $this->readConfigEnabled('http_client', $container, $config['http_client'])); } else { $container->removeDefinition('cache.asset_mapper'); } @@ -1330,12 +1330,14 @@ private function registerAssetsConfiguration(array $config, ContainerBuilder $co } } - private function registerAssetMapperConfiguration(array $config, ContainerBuilder $container, PhpFileLoader $loader, bool $assetEnabled): void + private function registerAssetMapperConfiguration(array $config, ContainerBuilder $container, PhpFileLoader $loader, bool $assetEnabled, bool $httpClientEnabled): void { $loader->load('asset_mapper.php'); - if (!$assetEnabled) { - $container->removeDefinition('asset_mapper.asset_package'); + if (!$httpClientEnabled) { + $container->register('asset_mapper.http_client', HttpClientInterface::class) + ->addTag('container.error') + ->addError('You cannot use the AssetMapper integration since the HttpClient component is not enabled. Try enabling the "framework.http_client" config option.'); } $paths = $config['paths']; diff --git a/Resources/config/asset_mapper.php b/Resources/config/asset_mapper.php index b7ce65f03..404e7af18 100644 --- a/Resources/config/asset_mapper.php +++ b/Resources/config/asset_mapper.php @@ -54,6 +54,8 @@ ]) ->alias(AssetMapperInterface::class, 'asset_mapper') + ->alias('asset_mapper.http_client', 'http_client') + ->set('asset_mapper.mapped_asset_factory', MappedAssetFactory::class) ->args([ service('asset_mapper.public_assets_path_resolver'), @@ -197,7 +199,7 @@ ]) ->set('asset_mapper.importmap.resolver', JsDelivrEsmResolver::class) - ->args([service('http_client')]) + ->args([service('asset_mapper.http_client')]) ->set('asset_mapper.importmap.renderer', ImportMapRenderer::class) ->args([ @@ -212,12 +214,12 @@ ->set('asset_mapper.importmap.auditor', ImportMapAuditor::class) ->args([ service('asset_mapper.importmap.config_reader'), - service('http_client'), + service('asset_mapper.http_client'), ]) ->set('asset_mapper.importmap.update_checker', ImportMapUpdateChecker::class) ->args([ service('asset_mapper.importmap.config_reader'), - service('http_client'), + service('asset_mapper.http_client'), ]) ->set('asset_mapper.importmap.command.require', ImportMapRequireCommand::class) From 35d085dc18b494d20b75728ecb222543e760c515 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 27 Jun 2024 14:04:56 +0200 Subject: [PATCH 6/6] [FrameworkBundle] Fix warming up routes --- Routing/Router.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Routing/Router.php b/Routing/Router.php index 4dfb71e74..69428a1b7 100644 --- a/Routing/Router.php +++ b/Routing/Router.php @@ -69,7 +69,7 @@ public function getRouteCollection(): RouteCollection $this->collection->addResource(new ContainerParametersResource($this->collectedParameters)); try { - $containerFile = ($this->paramFetcher)('kernel.cache_dir').'/'.($this->paramFetcher)('kernel.container_class').'.php'; + $containerFile = ($this->paramFetcher)('kernel.build_dir').'/'.($this->paramFetcher)('kernel.container_class').'.php'; if (file_exists($containerFile)) { $this->collection->addResource(new FileResource($containerFile)); } else { @@ -84,14 +84,12 @@ public function getRouteCollection(): RouteCollection public function warmUp(string $cacheDir, ?string $buildDir = null): array { - if (!$buildDir) { - return []; + if (null === $currentDir = $this->getOption('cache_dir')) { + return []; // skip warmUp when router doesn't use cache } - $currentDir = $this->getOption('cache_dir'); - - // force cache generation in build_dir - $this->setOption('cache_dir', $buildDir); + // force cache generation + $this->setOption('cache_dir', $buildDir ?? $cacheDir); $this->getMatcher(); $this->getGenerator();