diff --git a/Console/Application.php b/Console/Application.php index b4ec379a7..daa6c7026 100644 --- a/Console/Application.php +++ b/Console/Application.php @@ -158,7 +158,7 @@ public function all(string $namespace = null): array public function getLongVersion(): string { - return parent::getLongVersion().sprintf(' (env: %s, debug: %s) #StandWithUkraine https://sf.to/ukraine', $this->kernel->getEnvironment(), $this->kernel->isDebug() ? 'true' : 'false'); + return parent::getLongVersion().sprintf(' (env: %s, debug: %s)', $this->kernel->getEnvironment(), $this->kernel->isDebug() ? 'true' : 'false'); } public function add(Command $command): ?Command diff --git a/Controller/AbstractController.php b/Controller/AbstractController.php index a3aa21de1..dd65afce1 100644 --- a/Controller/AbstractController.php +++ b/Controller/AbstractController.php @@ -108,7 +108,7 @@ protected function generateUrl(string $route, array $parameters = [], int $refer /** * Forwards the request to another controller. * - * @param string $controller The controller name (a string like Bundle\BlogBundle\Controller\PostController::indexAction) + * @param string $controller The controller name (a string like "App\Controller\PostController::index" or "App\Controller\PostController" if it is invokable) */ protected function forward(string $controller, array $path = [], array $query = []): Response { diff --git a/DependencyInjection/FrameworkExtension.php b/DependencyInjection/FrameworkExtension.php index 95c8d8fa1..132a6329e 100644 --- a/DependencyInjection/FrameworkExtension.php +++ b/DependencyInjection/FrameworkExtension.php @@ -1906,21 +1906,23 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder $container->getDefinition('serializer.name_converter.metadata_aware')->setArgument(1, new Reference($config['name_converter'])); } + $defaultContext = $config['default_context'] ?? []; + + if ($defaultContext) { + $container->setParameter('serializer.default_context', $defaultContext); + } + if (isset($config['circular_reference_handler']) && $config['circular_reference_handler']) { $arguments = $container->getDefinition('serializer.normalizer.object')->getArguments(); - $context = ($arguments[6] ?? []) + ['circular_reference_handler' => new Reference($config['circular_reference_handler'])]; + $context = ($arguments[6] ?? $defaultContext) + ['circular_reference_handler' => new Reference($config['circular_reference_handler'])]; $container->getDefinition('serializer.normalizer.object')->setArgument(5, null); $container->getDefinition('serializer.normalizer.object')->setArgument(6, $context); } if ($config['max_depth_handler'] ?? false) { - $defaultContext = $container->getDefinition('serializer.normalizer.object')->getArgument(6); - $defaultContext += ['max_depth_handler' => new Reference($config['max_depth_handler'])]; - $container->getDefinition('serializer.normalizer.object')->replaceArgument(6, $defaultContext); - } - - if (isset($config['default_context']) && $config['default_context']) { - $container->setParameter('serializer.default_context', $config['default_context']); + $arguments = $container->getDefinition('serializer.normalizer.object')->getArguments(); + $context = ($arguments[6] ?? $defaultContext) + ['max_depth_handler' => new Reference($config['max_depth_handler'])]; + $container->getDefinition('serializer.normalizer.object')->setArgument(6, $context); } } @@ -2583,13 +2585,15 @@ private function registerMailerConfiguration(array $config, ContainerBuilder $co if ($webhookEnabled) { $webhookRequestParsers = [ + MailerBridge\Brevo\Webhook\BrevoRequestParser::class => 'mailer.webhook.request_parser.brevo', MailerBridge\Mailgun\Webhook\MailgunRequestParser::class => 'mailer.webhook.request_parser.mailgun', + MailerBridge\Mailjet\Webhook\MailjetRequestParser::class => 'mailer.webhook.request_parser.mailjet', MailerBridge\Postmark\Webhook\PostmarkRequestParser::class => 'mailer.webhook.request_parser.postmark', MailerBridge\Sendgrid\Webhook\SendgridRequestParser::class => 'mailer.webhook.request_parser.sendgrid', ]; foreach ($webhookRequestParsers as $class => $service) { - $package = substr($service, \strlen('mailer.transport_factory.')); + $package = substr($service, \strlen('mailer.webhook.request_parser.')); if (!ContainerBuilder::willBeAvailable(sprintf('symfony/%s-mailer', 'gmail' === $package ? 'google' : $package), $class, ['symfony/framework-bundle', 'symfony/mailer'])) { $container->removeDefinition($service); @@ -2772,7 +2776,9 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $ if (ContainerBuilder::willBeAvailable('symfony/mercure-notifier', NotifierBridge\Mercure\MercureTransportFactory::class, $parentPackages) && ContainerBuilder::willBeAvailable('symfony/mercure-bundle', MercureBundle::class, $parentPackages) && \in_array(MercureBundle::class, $container->getParameter('kernel.bundles'), true)) { $container->getDefinition($classToServices[NotifierBridge\Mercure\MercureTransportFactory::class]) - ->replaceArgument('$registry', new Reference(HubRegistry::class)); + ->replaceArgument('$registry', new Reference(HubRegistry::class)) + ->replaceArgument('$client', new Reference('http_client', ContainerBuilder::NULL_ON_INVALID_REFERENCE)) + ->replaceArgument('$dispatcher', new Reference('event_dispatcher', ContainerBuilder::NULL_ON_INVALID_REFERENCE)); } elseif (ContainerBuilder::willBeAvailable('symfony/mercure-notifier', NotifierBridge\Mercure\MercureTransportFactory::class, $parentPackages)) { $container->removeDefinition($classToServices[NotifierBridge\Mercure\MercureTransportFactory::class]); } @@ -2780,13 +2786,17 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $ if (ContainerBuilder::willBeAvailable('symfony/fake-chat-notifier', NotifierBridge\FakeChat\FakeChatTransportFactory::class, ['symfony/framework-bundle', 'symfony/notifier', 'symfony/mailer'])) { $container->getDefinition($classToServices[NotifierBridge\FakeChat\FakeChatTransportFactory::class]) ->replaceArgument('$mailer', new Reference('mailer')) - ->replaceArgument('$logger', new Reference('logger')); + ->replaceArgument('$logger', new Reference('logger')) + ->replaceArgument('$client', new Reference('http_client', ContainerBuilder::NULL_ON_INVALID_REFERENCE)) + ->replaceArgument('$dispatcher', new Reference('event_dispatcher', ContainerBuilder::NULL_ON_INVALID_REFERENCE)); } if (ContainerBuilder::willBeAvailable('symfony/fake-sms-notifier', NotifierBridge\FakeSms\FakeSmsTransportFactory::class, ['symfony/framework-bundle', 'symfony/notifier', 'symfony/mailer'])) { $container->getDefinition($classToServices[NotifierBridge\FakeSms\FakeSmsTransportFactory::class]) ->replaceArgument('$mailer', new Reference('mailer')) - ->replaceArgument('$logger', new Reference('logger')); + ->replaceArgument('$logger', new Reference('logger')) + ->replaceArgument('$client', new Reference('http_client', ContainerBuilder::NULL_ON_INVALID_REFERENCE)) + ->replaceArgument('$dispatcher', new Reference('event_dispatcher', ContainerBuilder::NULL_ON_INVALID_REFERENCE)); } if (isset($config['admin_recipients'])) { @@ -2800,6 +2810,19 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $ if ($webhookEnabled) { $loader->load('notifier_webhook.php'); + + $webhookRequestParsers = [ + NotifierBridge\Twilio\Webhook\TwilioRequestParser::class => 'notifier.webhook.request_parser.twilio', + NotifierBridge\Vonage\Webhook\VonageRequestParser::class => 'notifier.webhook.request_parser.vonage', + ]; + + foreach ($webhookRequestParsers as $class => $service) { + $package = substr($service, \strlen('notifier.webhook.request_parser.')); + + if (!ContainerBuilder::willBeAvailable(sprintf('symfony/%s-notifier', $package), $class, ['symfony/framework-bundle', 'symfony/notifier'])) { + $container->removeDefinition($service); + } + } } } diff --git a/EventListener/ConsoleProfilerListener.php b/EventListener/ConsoleProfilerListener.php index d3fc38106..c2a71d0a7 100644 --- a/EventListener/ConsoleProfilerListener.php +++ b/EventListener/ConsoleProfilerListener.php @@ -42,7 +42,8 @@ public function __construct( private readonly Profiler $profiler, private readonly RequestStack $requestStack, private readonly Stopwatch $stopwatch, - private readonly UrlGeneratorInterface $urlGenerator, + private readonly bool $cliMode, + private readonly ?UrlGeneratorInterface $urlGenerator = null, ) { $this->profiles = new \SplObjectStorage(); $this->parents = new \SplObjectStorage(); @@ -59,6 +60,10 @@ public static function getSubscribedEvents(): array public function initialize(ConsoleCommandEvent $event): void { + if (!$this->cliMode) { + return; + } + $input = $event->getInput(); if (!$input->hasOption('profile') || !$input->getOption('profile')) { $this->profiler->disable(); @@ -78,12 +83,16 @@ public function initialize(ConsoleCommandEvent $event): void public function catch(ConsoleErrorEvent $event): void { + if (!$this->cliMode) { + return; + } + $this->error = $event->getError(); } public function profile(ConsoleTerminateEvent $event): void { - if (!$this->profiler->isEnabled()) { + if (!$this->cliMode || !$this->profiler->isEnabled()) { return; } @@ -131,12 +140,14 @@ public function profile(ConsoleTerminateEvent $event): void $p = $this->profiles[$r]; $this->profiler->saveProfile($p); - $token = $p->getToken(); - $output?->writeln(sprintf( - 'See profile %s', - $this->urlGenerator->generate('_profiler', ['token' => $token], UrlGeneratorInterface::ABSOLUTE_URL), - $token - )); + if ($this->urlGenerator && $output) { + $token = $p->getToken(); + $output->writeln(sprintf( + 'See profile %s', + $this->urlGenerator->generate('_profiler', ['token' => $token], UrlGeneratorInterface::ABSOLUTE_URL), + $token + )); + } } $this->profiles = new \SplObjectStorage(); diff --git a/Resources/config/mailer_webhook.php b/Resources/config/mailer_webhook.php index 30ea50dad..bb487b36c 100644 --- a/Resources/config/mailer_webhook.php +++ b/Resources/config/mailer_webhook.php @@ -11,8 +11,12 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator; +use Symfony\Component\Mailer\Bridge\Brevo\RemoteEvent\BrevoPayloadConverter; +use Symfony\Component\Mailer\Bridge\Brevo\Webhook\BrevoRequestParser; use Symfony\Component\Mailer\Bridge\Mailgun\RemoteEvent\MailgunPayloadConverter; use Symfony\Component\Mailer\Bridge\Mailgun\Webhook\MailgunRequestParser; +use Symfony\Component\Mailer\Bridge\Mailjet\RemoteEvent\MailjetPayloadConverter; +use Symfony\Component\Mailer\Bridge\Mailjet\Webhook\MailjetRequestParser; use Symfony\Component\Mailer\Bridge\Postmark\RemoteEvent\PostmarkPayloadConverter; use Symfony\Component\Mailer\Bridge\Postmark\Webhook\PostmarkRequestParser; use Symfony\Component\Mailer\Bridge\Sendgrid\RemoteEvent\SendgridPayloadConverter; @@ -20,11 +24,21 @@ return static function (ContainerConfigurator $container) { $container->services() + ->set('mailer.payload_converter.brevo', BrevoPayloadConverter::class) + ->set('mailer.webhook.request_parser.brevo', BrevoRequestParser::class) + ->args([service('mailer.payload_converter.brevo')]) + ->alias(BrevoRequestParser::class, 'mailer.webhook.request_parser.brevo') + ->set('mailer.payload_converter.mailgun', MailgunPayloadConverter::class) ->set('mailer.webhook.request_parser.mailgun', MailgunRequestParser::class) ->args([service('mailer.payload_converter.mailgun')]) ->alias(MailgunRequestParser::class, 'mailer.webhook.request_parser.mailgun') + ->set('mailer.payload_converter.mailjet', MailjetPayloadConverter::class) + ->set('mailer.webhook.request_parser.mailjet', MailjetRequestParser::class) + ->args([service('mailer.payload_converter.mailjet')]) + ->alias(MailjetRequestParser::class, 'mailer.webhook.request_parser.mailjet') + ->set('mailer.payload_converter.postmark', PostmarkPayloadConverter::class) ->set('mailer.webhook.request_parser.postmark', PostmarkRequestParser::class) ->args([service('mailer.payload_converter.postmark')]) diff --git a/Resources/config/notifier_webhook.php b/Resources/config/notifier_webhook.php index 87dfc6c6a..fc541fd99 100644 --- a/Resources/config/notifier_webhook.php +++ b/Resources/config/notifier_webhook.php @@ -12,10 +12,14 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator; use Symfony\Component\Notifier\Bridge\Twilio\Webhook\TwilioRequestParser; +use Symfony\Component\Notifier\Bridge\Vonage\Webhook\VonageRequestParser; return static function (ContainerConfigurator $container) { $container->services() ->set('notifier.webhook.request_parser.twilio', TwilioRequestParser::class) ->alias(TwilioRequestParser::class, 'notifier.webhook.request_parser.twilio') + + ->set('notifier.webhook.request_parser.vonage', VonageRequestParser::class) + ->alias(VonageRequestParser::class, 'notifier.webhook.request_parser.vonage') ; }; diff --git a/Resources/config/profiling.php b/Resources/config/profiling.php index ec764d837..eaef79597 100644 --- a/Resources/config/profiling.php +++ b/Resources/config/profiling.php @@ -43,7 +43,8 @@ service('profiler'), service('.virtual_request_stack'), service('debug.stopwatch'), - service('router'), + param('kernel.runtime_mode.cli'), + service('router')->nullOnInvalid(), ]) ->tag('kernel.event_subscriber') diff --git a/Resources/config/schema/symfony-1.0.xsd b/Resources/config/schema/symfony-1.0.xsd index 72a2aacda..57cc92334 100644 --- a/Resources/config/schema/symfony-1.0.xsd +++ b/Resources/config/schema/symfony-1.0.xsd @@ -953,6 +953,7 @@ + diff --git a/Tests/DependencyInjection/FrameworkExtensionTestCase.php b/Tests/DependencyInjection/FrameworkExtensionTestCase.php index 460c899e3..4bd3c481f 100644 --- a/Tests/DependencyInjection/FrameworkExtensionTestCase.php +++ b/Tests/DependencyInjection/FrameworkExtensionTestCase.php @@ -40,6 +40,7 @@ use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Exception\LogicException; use Symfony\Component\DependencyInjection\Loader\ClosureLoader; +use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\EventDispatcher\EventDispatcherInterface; @@ -1693,7 +1694,7 @@ public function testCachePoolServices() ->replaceArgument(0, $expectedSeed) ->replaceArgument(1, 12), (new ChildDefinition('cache.adapter.redis')) - ->replaceArgument(0, new Reference('.cache_connection.kYdiLgf')) + ->replaceArgument(0, new Reference('.cache_connection.'.(\count((new \ReflectionMethod(ContainerConfigurator::class, 'extension'))->getParameters()) > 2 ? 'U5HliuY' : 'kYdiLgf'))) ->replaceArgument(1, $expectedSeed) ->replaceArgument(2, 12), ], diff --git a/Tests/Fixtures/Serializer/CircularReferenceHandler.php b/Tests/Fixtures/Serializer/CircularReferenceHandler.php new file mode 100644 index 000000000..b4e402a04 --- /dev/null +++ b/Tests/Fixtures/Serializer/CircularReferenceHandler.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Serializer; + +class CircularReferenceHandler +{ + public function __invoke() + { + } +} diff --git a/Tests/Fixtures/Serializer/MaxDepthHandler.php b/Tests/Fixtures/Serializer/MaxDepthHandler.php new file mode 100644 index 000000000..f76fb3db8 --- /dev/null +++ b/Tests/Fixtures/Serializer/MaxDepthHandler.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Serializer; + +class MaxDepthHandler +{ + public function __invoke() + { + } +} diff --git a/Tests/Functional/app/Serializer/config.yml b/Tests/Functional/app/Serializer/config.yml index e35d5fa28..987cc384c 100644 --- a/Tests/Functional/app/Serializer/config.yml +++ b/Tests/Functional/app/Serializer/config.yml @@ -6,6 +6,8 @@ framework: translator: true serializer: enabled: true + circular_reference_handler: Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Serializer\CircularReferenceHandler + max_depth_handler: Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Serializer\MaxDepthHandler default_context: enable_max_depth: true fake_context_option: foo @@ -63,3 +65,7 @@ services: serializer.encoder.csv.alias: alias: serializer.encoder.csv public: true + + Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Serializer\CircularReferenceHandler: ~ + + Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Serializer\MaxDepthHandler: ~