diff --git a/CacheWarmer/AbstractPhpFileCacheWarmer.php b/CacheWarmer/AbstractPhpFileCacheWarmer.php index a18faae7d..5ab1a50fd 100644 --- a/CacheWarmer/AbstractPhpFileCacheWarmer.php +++ b/CacheWarmer/AbstractPhpFileCacheWarmer.php @@ -48,7 +48,7 @@ public function warmUp(string $cacheDir, ?string $buildDir = null): array // the ArrayAdapter stores the values serialized // to avoid mutation of the data after it was written to the cache // so here we un-serialize the values first - $values = array_map(fn ($val) => null !== $val ? unserialize($val) : null, $arrayAdapter->getValues()); + $values = array_map(static fn ($val) => null !== $val ? unserialize($val) : null, $arrayAdapter->getValues()); return $this->warmUpPhpArrayAdapter(new PhpArrayAdapter($this->phpArrayFile, new NullAdapter()), $values); } diff --git a/CacheWarmer/ConfigBuilderCacheWarmer.php b/CacheWarmer/ConfigBuilderCacheWarmer.php index 6f29a7b74..57e330b0d 100644 --- a/CacheWarmer/ConfigBuilderCacheWarmer.php +++ b/CacheWarmer/ConfigBuilderCacheWarmer.php @@ -50,7 +50,7 @@ public function warmUp(string $cacheDir, ?string $buildDir = null): array if ($this->kernel instanceof Kernel) { /** @var ContainerBuilder $container */ - $container = \Closure::bind(function (Kernel $kernel) { + $container = \Closure::bind(static function (Kernel $kernel) { $containerBuilder = $kernel->getContainerBuilder(); $kernel->prepareContainer($containerBuilder); diff --git a/CacheWarmer/ValidatorCacheWarmer.php b/CacheWarmer/ValidatorCacheWarmer.php index c167d1415..7728f0aca 100644 --- a/CacheWarmer/ValidatorCacheWarmer.php +++ b/CacheWarmer/ValidatorCacheWarmer.php @@ -70,7 +70,7 @@ protected function doWarmUp(string $cacheDir, ArrayAdapter $arrayAdapter, ?strin protected function warmUpPhpArrayAdapter(PhpArrayAdapter $phpArrayAdapter, array $values): array { // make sure we don't cache null values - $values = array_filter($values, fn ($val) => null !== $val); + $values = array_filter($values, static fn ($val) => null !== $val); return parent::warmUpPhpArrayAdapter($phpArrayAdapter, $values); } diff --git a/Command/AbstractConfigCommand.php b/Command/AbstractConfigCommand.php index fc3433c2d..41320becf 100644 --- a/Command/AbstractConfigCommand.php +++ b/Command/AbstractConfigCommand.php @@ -35,7 +35,7 @@ protected function listBundles(OutputInterface|StyleInterface $output): void $rows = []; $bundles = $this->getApplication()->getKernel()->getBundles(); - usort($bundles, fn ($bundleA, $bundleB) => strcmp($bundleA->getName(), $bundleB->getName())); + usort($bundles, static fn ($bundleA, $bundleB) => strcmp($bundleA->getName(), $bundleB->getName())); foreach ($bundles as $bundle) { $extension = $bundle->getContainerExtension(); diff --git a/Command/CachePoolListCommand.php b/Command/CachePoolListCommand.php index 6aedfb0c0..264aff2ef 100644 --- a/Command/CachePoolListCommand.php +++ b/Command/CachePoolListCommand.php @@ -48,7 +48,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); - $io->table(['Pool name'], array_map(fn ($pool) => [$pool], $this->poolNames)); + $io->table(['Pool name'], array_map(static fn ($pool) => [$pool], $this->poolNames)); return 0; } diff --git a/Command/DebugAutowiringCommand.php b/Command/DebugAutowiringCommand.php index 5c1869c6a..c81271ef2 100644 --- a/Command/DebugAutowiringCommand.php +++ b/Command/DebugAutowiringCommand.php @@ -73,7 +73,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int if ($search = $input->getArgument('search')) { $searchNormalized = preg_replace('/[^a-zA-Z0-9\x7f-\xff $]++/', '', $search); - $serviceIds = array_filter($serviceIds, fn ($serviceId) => false !== stripos(str_replace('\\', '', $serviceId), $searchNormalized) && !str_starts_with($serviceId, '.')); + $serviceIds = array_filter($serviceIds, static fn ($serviceId) => false !== stripos(str_replace('\\', '', $serviceId), $searchNormalized) && !str_starts_with($serviceId, '.')); if (!$serviceIds) { $errorIo->error(\sprintf('No autowirable classes or interfaces found matching "%s"', $search)); diff --git a/Command/EventDispatcherDebugCommand.php b/Command/EventDispatcherDebugCommand.php index 43766ed92..ab1e9a0ad 100644 --- a/Command/EventDispatcherDebugCommand.php +++ b/Command/EventDispatcherDebugCommand.php @@ -64,6 +64,7 @@ protected function configure(): void The --format option specifies the format of the command output: php %command.full_name% --format=json + EOF ) ; diff --git a/Command/RouterDebugCommand.php b/Command/RouterDebugCommand.php index 3daf865b3..8fca6c5a1 100644 --- a/Command/RouterDebugCommand.php +++ b/Command/RouterDebugCommand.php @@ -65,6 +65,7 @@ protected function configure(): void The --format option specifies the format of the command output: php %command.full_name% --format=json + EOF ) ; diff --git a/Command/SecretsListCommand.php b/Command/SecretsListCommand.php index 9057f58d1..76f69cc8e 100644 --- a/Command/SecretsListCommand.php +++ b/Command/SecretsListCommand.php @@ -71,7 +71,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $rows = []; $dump = new Dumper($output); - $dump = fn ($v) => null === $v ? '******' : $dump($v); + $dump = static fn ($v) => null === $v ? '******' : $dump($v); foreach ($secrets as $name => $value) { $rows[$name] = [$name, $dump($value)]; diff --git a/Command/TranslationExtractCommand.php b/Command/TranslationExtractCommand.php index 32f19fbe4..83e8eed79 100644 --- a/Command/TranslationExtractCommand.php +++ b/Command/TranslationExtractCommand.php @@ -228,8 +228,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int $list = array_merge( array_diff($allKeys, $newKeys), - array_map(fn ($id) => \sprintf('%s', $id), $newKeys), - array_map(fn ($id) => \sprintf('%s', $id), array_keys($operation->getObsoleteMessages($domain))) + array_map(static fn ($id) => \sprintf('%s', $id), $newKeys), + array_map(static fn ($id) => \sprintf('%s', $id), array_keys($operation->getObsoleteMessages($domain))) ); $domainMessagesCount = \count($list); @@ -494,9 +494,11 @@ private function getRootCodePaths(KernelInterface $kernel): array private function removeNoFillTranslations(MessageCatalogueInterface $operation): void { - foreach ($operation->all('messages') as $key => $message) { - if (str_starts_with($message, self::NO_FILL_PREFIX)) { - $operation->set($key, '', 'messages'); + foreach ($operation->getDomains() as $domain) { + foreach ($operation->all($domain) as $key => $message) { + if (str_starts_with($message, self::NO_FILL_PREFIX)) { + $operation->set($key, '', $domain); + } } } } diff --git a/Command/XliffLintCommand.php b/Command/XliffLintCommand.php index 9bbe39db1..02cf0f527 100644 --- a/Command/XliffLintCommand.php +++ b/Command/XliffLintCommand.php @@ -36,7 +36,7 @@ public function __construct() return $default($directory); }; - $isReadableProvider = fn ($fileOrDirectory, $default) => str_starts_with($fileOrDirectory, '@') || $default($fileOrDirectory); + $isReadableProvider = static fn ($fileOrDirectory, $default) => str_starts_with($fileOrDirectory, '@') || $default($fileOrDirectory); parent::__construct(null, $directoryIteratorProvider, $isReadableProvider); } diff --git a/Command/YamlLintCommand.php b/Command/YamlLintCommand.php index 5948add7c..b2ab87423 100644 --- a/Command/YamlLintCommand.php +++ b/Command/YamlLintCommand.php @@ -35,7 +35,7 @@ public function __construct() return $default($directory); }; - $isReadableProvider = fn ($fileOrDirectory, $default) => str_starts_with($fileOrDirectory, '@') || $default($fileOrDirectory); + $isReadableProvider = static fn ($fileOrDirectory, $default) => str_starts_with($fileOrDirectory, '@') || $default($fileOrDirectory); parent::__construct(null, $directoryIteratorProvider, $isReadableProvider); } diff --git a/Console/Descriptor/Descriptor.php b/Console/Descriptor/Descriptor.php index e76b74247..305dc0d8d 100644 --- a/Console/Descriptor/Descriptor.php +++ b/Console/Descriptor/Descriptor.php @@ -243,7 +243,7 @@ protected function sortTaggedServicesByPriority(array $services): array } } } - uasort($maxPriority, fn ($a, $b) => $b <=> $a); + uasort($maxPriority, static fn ($a, $b) => $b <=> $a); return array_keys($maxPriority); } @@ -260,7 +260,7 @@ protected function sortTagsByPriority(array $tags): array protected function sortByPriority(array $tag): array { - usort($tag, fn ($a, $b) => ($b['priority'] ?? 0) <=> ($a['priority'] ?? 0)); + usort($tag, static fn ($a, $b) => ($b['priority'] ?? 0) <=> ($a['priority'] ?? 0)); return $tag; } @@ -353,7 +353,7 @@ protected function getServiceEdges(ContainerBuilder $container, string $serviceI { try { return array_values(array_unique(array_map( - fn (ServiceReferenceGraphEdge $edge) => $edge->getSourceNode()->getId(), + static fn (ServiceReferenceGraphEdge $edge) => $edge->getSourceNode()->getId(), $container->getCompiler()->getServiceReferenceGraph()->getNode($serviceId)->getInEdges() ))); } catch (InvalidArgumentException $exception) { diff --git a/Console/Descriptor/JsonDescriptor.php b/Console/Descriptor/JsonDescriptor.php index cfae075ed..f4454c4f7 100644 --- a/Console/Descriptor/JsonDescriptor.php +++ b/Console/Descriptor/JsonDescriptor.php @@ -329,7 +329,7 @@ private function getEventDispatcherListenersData(EventDispatcherInterface $event $data[] = $l; } } else { - $registeredListeners = \array_key_exists('events', $options) ? array_combine($options['events'], array_map(fn ($event) => $eventDispatcher->getListeners($event), $options['events'])) : $eventDispatcher->getListeners(); + $registeredListeners = \array_key_exists('events', $options) ? array_combine($options['events'], array_map(static fn ($event) => $eventDispatcher->getListeners($event), $options['events'])) : $eventDispatcher->getListeners(); ksort($registeredListeners); foreach ($registeredListeners as $eventListened => $eventListeners) { diff --git a/Console/Descriptor/MarkdownDescriptor.php b/Console/Descriptor/MarkdownDescriptor.php index faa92e918..ab6fede39 100644 --- a/Console/Descriptor/MarkdownDescriptor.php +++ b/Console/Descriptor/MarkdownDescriptor.php @@ -324,7 +324,7 @@ protected function describeEventDispatcherListeners(EventDispatcherInterface $ev $registeredListeners = $eventDispatcher->getListeners($event); } else { // Try to see if "events" exists - $registeredListeners = \array_key_exists('events', $options) ? array_combine($options['events'], array_map(fn ($event) => $eventDispatcher->getListeners($event), $options['events'])) : $eventDispatcher->getListeners(); + $registeredListeners = \array_key_exists('events', $options) ? array_combine($options['events'], array_map(static fn ($event) => $eventDispatcher->getListeners($event), $options['events'])) : $eventDispatcher->getListeners(); } $this->write(\sprintf('# %s', $title)."\n"); diff --git a/Console/Descriptor/TextDescriptor.php b/Console/Descriptor/TextDescriptor.php index 69e4b395c..3944891c5 100644 --- a/Console/Descriptor/TextDescriptor.php +++ b/Console/Descriptor/TextDescriptor.php @@ -96,13 +96,13 @@ protected function describeRouteCollection(RouteCollection $routes, array $optio if ($shouldShowScheme) { $tableHeaders[] = 'Scheme'; } else { - array_walk($tableRows, function (&$row) { unset($row['Scheme']); }); + array_walk($tableRows, static function (&$row) { unset($row['Scheme']); }); } if ($shouldShowHost) { $tableHeaders[] = 'Host'; } else { - array_walk($tableRows, function (&$row) { unset($row['Host']); }); + array_walk($tableRows, static function (&$row) { unset($row['Host']); }); } $tableHeaders[] = 'Path'; @@ -564,7 +564,7 @@ protected function describeEventDispatcherListeners(EventDispatcherInterface $ev } else { $title .= ' Grouped by Event'; // Try to see if "events" exists - $registeredListeners = \array_key_exists('events', $options) ? array_combine($options['events'], array_map(fn ($event) => $eventDispatcher->getListeners($event), $options['events'])) : $eventDispatcher->getListeners(); + $registeredListeners = \array_key_exists('events', $options) ? array_combine($options['events'], array_map(static fn ($event) => $eventDispatcher->getListeners($event), $options['events'])) : $eventDispatcher->getListeners(); } $options['output']->title($title); @@ -622,7 +622,7 @@ private function formatMethods(array $methods): string } return implode('|', array_map( - fn (string $method): string => \sprintf('%s', self::VERB_COLORS[$method] ?? 'default', $method), + static fn (string $method): string => \sprintf('%s', self::VERB_COLORS[$method] ?? 'default', $method), $methods )); } diff --git a/Console/Descriptor/XmlDescriptor.php b/Console/Descriptor/XmlDescriptor.php index 08ef443f1..1d4e82351 100644 --- a/Console/Descriptor/XmlDescriptor.php +++ b/Console/Descriptor/XmlDescriptor.php @@ -511,7 +511,7 @@ private function getEventDispatcherListenersDocument(EventDispatcherInterface $e $this->appendEventListenerDocument($eventDispatcher, $event, $eventDispatcherXML, $registeredListeners); } else { // Try to see if "events" exists - $registeredListeners = \array_key_exists('events', $options) ? array_combine($options['events'], array_map(fn ($event) => $eventDispatcher->getListeners($event), $options['events'])) : $eventDispatcher->getListeners(); + $registeredListeners = \array_key_exists('events', $options) ? array_combine($options['events'], array_map(static fn ($event) => $eventDispatcher->getListeners($event), $options['events'])) : $eventDispatcher->getListeners(); ksort($registeredListeners); foreach ($registeredListeners as $eventListened => $eventListeners) { diff --git a/Controller/AbstractController.php b/Controller/AbstractController.php index c07c0c055..6d634c01a 100644 --- a/Controller/AbstractController.php +++ b/Controller/AbstractController.php @@ -306,7 +306,7 @@ protected function stream(string $view, array $parameters = [], ?StreamedRespons $twig = $this->container->get('twig'); - $callback = function () use ($twig, $view, $parameters) { + $callback = static function () use ($twig, $view, $parameters) { $twig->display($view, $parameters); }; diff --git a/Controller/ControllerHelper.php b/Controller/ControllerHelper.php index 424ab9262..86adbcfed 100644 --- a/Controller/ControllerHelper.php +++ b/Controller/ControllerHelper.php @@ -299,7 +299,7 @@ public function stream(string $view, array $parameters = [], ?StreamedResponse $ $twig = $this->container->get('twig'); - $callback = function () use ($twig, $view, $parameters) { + $callback = static function () use ($twig, $view, $parameters) { $twig->display($view, $parameters); }; diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 1e32389e5..e329277a3 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -772,7 +772,7 @@ private function addSessionSection(ArrayNodeDefinition $rootNode): void ->end() ->scalarNode('name') ->validate() - ->ifTrue(function ($v) { + ->ifTrue(static function ($v) { parse_str($v, $parsed); return implode('&', array_keys($parsed)) !== (string) $v; @@ -862,21 +862,15 @@ private function addAssetsSection(ArrayNodeDefinition $rootNode, callable $enabl ->end() ->end() ->validate() - ->ifTrue(function ($v) { - return isset($v['version_strategy']) && isset($v['version']); - }) + ->ifTrue(static fn ($v) => isset($v['version_strategy']) && isset($v['version'])) ->thenInvalid('You cannot use both "version_strategy" and "version" at the same time under "assets".') ->end() ->validate() - ->ifTrue(function ($v) { - return isset($v['version_strategy']) && isset($v['json_manifest_path']); - }) + ->ifTrue(static fn ($v) => isset($v['version_strategy']) && isset($v['json_manifest_path'])) ->thenInvalid('You cannot use both "version_strategy" and "json_manifest_path" at the same time under "assets".') ->end() ->validate() - ->ifTrue(function ($v) { - return isset($v['version']) && isset($v['json_manifest_path']); - }) + ->ifTrue(static fn ($v) => isset($v['version']) && isset($v['json_manifest_path'])) ->thenInvalid('You cannot use both "version" and "json_manifest_path" at the same time under "assets".') ->end() ->children() @@ -906,21 +900,15 @@ private function addAssetsSection(ArrayNodeDefinition $rootNode, callable $enabl ->end() ->end() ->validate() - ->ifTrue(function ($v) { - return isset($v['version_strategy']) && isset($v['version']); - }) + ->ifTrue(static fn ($v) => isset($v['version_strategy']) && isset($v['version'])) ->thenInvalid('You cannot use both "version_strategy" and "version" at the same time under "assets" packages.') ->end() ->validate() - ->ifTrue(function ($v) { - return isset($v['version_strategy']) && isset($v['json_manifest_path']); - }) + ->ifTrue(static fn ($v) => isset($v['version_strategy']) && isset($v['json_manifest_path'])) ->thenInvalid('You cannot use both "version_strategy" and "json_manifest_path" at the same time under "assets" packages.') ->end() ->validate() - ->ifTrue(function ($v) { - return isset($v['version']) && isset($v['json_manifest_path']); - }) + ->ifTrue(static fn ($v) => isset($v['version']) && isset($v['json_manifest_path'])) ->thenInvalid('You cannot use both "version" and "json_manifest_path" at the same time under "assets" packages.') ->end() ->end() @@ -1250,7 +1238,7 @@ private function addSerializerSection(ArrayNodeDefinition $rootNode, callable $e ->normalizeKeys(false) ->validate() ->ifTrue(fn () => $this->debug && class_exists(JsonParser::class)) - ->then(fn (array $v) => $v + [JsonDecode::DETAILED_ERROR_MESSAGES => true]) + ->then(static fn (array $v) => $v + [JsonDecode::DETAILED_ERROR_MESSAGES => true]) ->end() ->defaultValue([]) ->prototype('variable')->end() @@ -1292,14 +1280,14 @@ private function addSerializerSection(ArrayNodeDefinition $rootNode, callable $e ->end() ->end() ->validate() - ->ifTrue(fn ($v) => isset($v['default'])) + ->ifTrue(static fn ($v) => isset($v['default'])) ->thenInvalid('"default" is a reserved name.') ->end() ->end() ->end() ->validate() ->ifTrue(fn ($v) => $this->debug && class_exists(JsonParser::class) && !isset($v['default_context'][JsonDecode::DETAILED_ERROR_MESSAGES])) - ->then(function ($v) { + ->then(static function ($v) { $v['default_context'][JsonDecode::DETAILED_ERROR_MESSAGES] = true; return $v; @@ -1345,8 +1333,8 @@ private function addPropertyInfoSection(ArrayNodeDefinition $rootNode, callable ->end() ->end() ->validate() - ->ifTrue(fn ($v) => $v['property_info']['enabled'] && !isset($v['property_info']['with_constructor_extractor'])) - ->then(function ($v) { + ->ifTrue(static fn ($v) => $v['property_info']['enabled'] && !isset($v['property_info']['with_constructor_extractor'])) + ->then(static function ($v) { $v['property_info']['with_constructor_extractor'] = false; trigger_deprecation('symfony/framework-bundle', '7.3', 'Not setting the "property_info.with_constructor_extractor" option explicitly is deprecated because its default value will change in version 8.0.'); @@ -1460,7 +1448,7 @@ private function addCacheSection(ArrayNodeDefinition $rootNode, callable $willBe ->end() ->end() ->validate() - ->ifTrue(fn ($v) => isset($v['cache.app']) || isset($v['cache.system'])) + ->ifTrue(static fn ($v) => isset($v['cache.app']) || isset($v['cache.system'])) ->thenInvalid('"cache.app" and "cache.system" are reserved names') ->end() ->end() @@ -1485,7 +1473,7 @@ private function addPhpErrorsSection(ArrayNodeDefinition $rootNode): void ->defaultTrue() ->beforeNormalization() ->ifArray() - ->then(function (array $v): array { + ->then(static function (array $v): array { if (!($v[0]['type'] ?? false)) { return $v; } @@ -1501,7 +1489,7 @@ private function addPhpErrorsSection(ArrayNodeDefinition $rootNode): void }) ->end() ->validate() - ->ifTrue(fn ($v) => !(\is_int($v) || \is_bool($v) || \is_array($v))) + ->ifTrue(static fn ($v) => !(\is_int($v) || \is_bool($v) || \is_array($v))) ->thenInvalid('The "php_errors.log" parameter should be either an integer, a boolean, or an array') ->end() ->end() @@ -1530,7 +1518,7 @@ private function addExceptionsSection(ArrayNodeDefinition $rootNode): void ->scalarNode('log_level') ->info('The level of log message. Null to let Symfony decide.') ->validate() - ->ifTrue(fn ($v) => null !== $v && !\in_array($v, $logLevels, true)) + ->ifTrue(static fn ($v) => null !== $v && !\in_array($v, $logLevels, true)) ->thenInvalid(\sprintf('The log level is not valid. Pick one among "%s".', implode('", "', $logLevels))) ->end() ->defaultNull() @@ -1538,11 +1526,11 @@ private function addExceptionsSection(ArrayNodeDefinition $rootNode): void ->scalarNode('status_code') ->info('The status code of the response. Null or 0 to let Symfony decide.') ->beforeNormalization() - ->ifTrue(fn ($v) => 0 === $v) - ->then(fn ($v) => null) + ->ifTrue(static fn ($v) => 0 === $v) + ->then(static fn ($v) => null) ->end() ->validate() - ->ifTrue(fn ($v) => null !== $v && ($v < 100 || $v > 599)) + ->ifTrue(static fn ($v) => null !== $v && ($v < 100 || $v > 599)) ->thenInvalid('The status code is not valid. Pick a value between 100 and 599.') ->end() ->defaultNull() @@ -1699,12 +1687,12 @@ private function addMessengerSection(ArrayNodeDefinition $rootNode, callable $en ->info('Messenger configuration') ->{$enableIfStandalone('symfony/messenger', MessageBusInterface::class)}() ->validate() - ->ifTrue(fn ($v) => isset($v['buses']) && \count($v['buses']) > 1 && null === $v['default_bus']) + ->ifTrue(static fn ($v) => isset($v['buses']) && \count($v['buses']) > 1 && null === $v['default_bus']) ->thenInvalid('You must specify the "default_bus" if you define more than one bus.') ->end() ->validate() - ->ifTrue(fn ($v) => isset($v['buses']) && null !== $v['default_bus'] && !isset($v['buses'][$v['default_bus']])) - ->then(fn ($v) => throw new InvalidConfigurationException(\sprintf('The specified default bus "%s" is not configured. Available buses are "%s".', $v['default_bus'], implode('", "', array_keys($v['buses']))))) + ->ifTrue(static fn ($v) => isset($v['buses']) && null !== $v['default_bus'] && !isset($v['buses'][$v['default_bus']])) + ->then(static fn ($v) => throw new InvalidConfigurationException(\sprintf('The specified default bus "%s" is not configured. Available buses are "%s".', $v['default_bus'], implode('", "', array_keys($v['buses']))))) ->end() ->children() ->arrayNode('routing') @@ -1712,7 +1700,7 @@ private function addMessengerSection(ArrayNodeDefinition $rootNode, callable $en ->useAttributeAsKey('message_class') ->beforeNormalization() ->ifArray() - ->then(function ($config) { + ->then(static function ($config) { // If XML config with only one routing attribute if (2 === \count($config) && isset($config['message-class']) && isset($config['sender'])) { $config = [0 => $config]; @@ -1726,9 +1714,7 @@ private function addMessengerSection(ArrayNodeDefinition $rootNode, callable $en ]; } else { $newConfig[$v['message-class']]['senders'] = array_map( - function ($a) { - return \is_string($a) ? $a : $a['service']; - }, + static fn ($a) => \is_string($a) ? $a : $a['service'], array_values($v['sender']) ); } @@ -2344,7 +2330,7 @@ private function addMailerSection(ArrayNodeDefinition $rootNode, callable $enabl ->info('Mailer configuration') ->{$enableIfStandalone('symfony/mailer', Mailer::class)}() ->validate() - ->ifTrue(fn ($v) => isset($v['dsn']) && \count($v['transports'])) + ->ifTrue(static fn ($v) => isset($v['dsn']) && \count($v['transports'])) ->thenInvalid('"dsn" and "transports" cannot be used together.') ->end() ->children() @@ -2466,9 +2452,7 @@ private function addMailerSection(ArrayNodeDefinition $rootNode, callable $enabl }) ->end() ->validate() - ->ifTrue(function ($v) { - return \extension_loaded('openssl') && null !== $v && !\defined('OPENSSL_CIPHER_'.$v); - }) + ->ifTrue(static fn ($v) => \extension_loaded('openssl') && null !== $v && !\defined('OPENSSL_CIPHER_'.$v)) ->thenInvalid('You must provide a valid cipher.') ->end() ->end() @@ -2699,7 +2683,7 @@ private function addHtmlSanitizerSection(ArrayNodeDefinition $rootNode, callable ->ifArray()->then(static fn ($n) => $n['attribute'] ?? $n) ->end() ->validate() - ->ifTrue(fn ($n): bool => !\is_string($n) && !\is_array($n)) + ->ifTrue(static fn ($n): bool => !\is_string($n) && !\is_array($n)) ->thenInvalid('The value must be either a string or an array of strings.') ->end() ->end() diff --git a/DependencyInjection/FrameworkExtension.php b/DependencyInjection/FrameworkExtension.php index 631f99b7e..7fd6b1dea 100644 --- a/DependencyInjection/FrameworkExtension.php +++ b/DependencyInjection/FrameworkExtension.php @@ -1727,7 +1727,7 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder $finder = Finder::create() ->followLinks() ->files() - ->filter(fn (\SplFileInfo $file) => 2 <= substr_count($file->getBasename(), '.') && preg_match('/\.\w+$/', $file->getBasename())) + ->filter(static fn (\SplFileInfo $file) => 2 <= substr_count($file->getBasename(), '.') && preg_match('/\.\w+$/', $file->getBasename())) ->in($dir) ->sortByName() ; @@ -1750,7 +1750,7 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder 'resource_files' => $files, 'scanned_directories' => $scannedDirectories = array_merge($dirs, $nonExistingDirs), 'cache_vary' => [ - 'scanned_directories' => array_map(fn ($dir) => str_starts_with($dir, $projectDir.'/') ? substr($dir, 1 + \strlen($projectDir)) : $dir, $scannedDirectories), + 'scanned_directories' => array_map(static fn ($dir) => str_starts_with($dir, $projectDir.'/') ? substr($dir, 1 + \strlen($projectDir)) : $dir, $scannedDirectories), ], ] ); @@ -1908,7 +1908,7 @@ private function registerValidationConfiguration(array $config, ContainerBuilder private function registerValidatorMapping(ContainerBuilder $container, array $config, array &$files): void { - $fileRecorder = function ($extension, $path) use (&$files) { + $fileRecorder = static function ($extension, $path) use (&$files) { $files['yaml' === $extension ? 'yml' : $extension][] = $path; }; @@ -2153,7 +2153,7 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder $container->removeDefinition('serializer.mapping.attribute_services_loader'); } - $fileRecorder = function ($extension, $path) use (&$serializerLoaders) { + $fileRecorder = static function ($extension, $path) use (&$serializerLoaders) { $definition = new Definition(\in_array($extension, ['yaml', 'yml'], true) ? YamlFileLoader::class : XmlFileLoader::class, [$path]); $serializerLoaders[] = $definition; }; @@ -3056,56 +3056,52 @@ private function registerMailerConfiguration(array $config, ContainerBuilder $co } $classToServices = [ - MailerBridge\AhaSend\Transport\AhaSendTransportFactory::class => 'mailer.transport_factory.ahasend', - MailerBridge\Azure\Transport\AzureTransportFactory::class => 'mailer.transport_factory.azure', - MailerBridge\Brevo\Transport\BrevoTransportFactory::class => 'mailer.transport_factory.brevo', - MailerBridge\Google\Transport\GmailTransportFactory::class => 'mailer.transport_factory.gmail', - MailerBridge\Infobip\Transport\InfobipTransportFactory::class => 'mailer.transport_factory.infobip', - MailerBridge\MailerSend\Transport\MailerSendTransportFactory::class => 'mailer.transport_factory.mailersend', - MailerBridge\Mailgun\Transport\MailgunTransportFactory::class => 'mailer.transport_factory.mailgun', - MailerBridge\Mailjet\Transport\MailjetTransportFactory::class => 'mailer.transport_factory.mailjet', - MailerBridge\Mailomat\Transport\MailomatTransportFactory::class => 'mailer.transport_factory.mailomat', - MailerBridge\MailPace\Transport\MailPaceTransportFactory::class => 'mailer.transport_factory.mailpace', - MailerBridge\Mailchimp\Transport\MandrillTransportFactory::class => 'mailer.transport_factory.mailchimp', - MailerBridge\MicrosoftGraph\Transport\MicrosoftGraphTransportFactory::class => 'mailer.transport_factory.microsoftgraph', - MailerBridge\Postal\Transport\PostalTransportFactory::class => 'mailer.transport_factory.postal', - MailerBridge\Postmark\Transport\PostmarkTransportFactory::class => 'mailer.transport_factory.postmark', - MailerBridge\Mailtrap\Transport\MailtrapTransportFactory::class => 'mailer.transport_factory.mailtrap', - MailerBridge\Resend\Transport\ResendTransportFactory::class => 'mailer.transport_factory.resend', - MailerBridge\Scaleway\Transport\ScalewayTransportFactory::class => 'mailer.transport_factory.scaleway', - MailerBridge\Sendgrid\Transport\SendgridTransportFactory::class => 'mailer.transport_factory.sendgrid', - MailerBridge\Amazon\Transport\SesTransportFactory::class => 'mailer.transport_factory.amazon', - MailerBridge\Sweego\Transport\SweegoTransportFactory::class => 'mailer.transport_factory.sweego', + MailerBridge\AhaSend\Transport\AhaSendTransportFactory::class => ['symfony/aha-send-mailer', 'mailer.transport_factory.ahasend'], + MailerBridge\Azure\Transport\AzureTransportFactory::class => ['symfony/azure-mailer', 'mailer.transport_factory.azure'], + MailerBridge\Brevo\Transport\BrevoTransportFactory::class => ['symfony/brevo-mailer', 'mailer.transport_factory.brevo'], + MailerBridge\Google\Transport\GmailTransportFactory::class => ['symfony/google-mailer', 'mailer.transport_factory.gmail'], + MailerBridge\Infobip\Transport\InfobipTransportFactory::class => ['symfony/infobip-mailer', 'mailer.transport_factory.infobip'], + MailerBridge\MailerSend\Transport\MailerSendTransportFactory::class => ['symfony/mailer-send-mailer', 'mailer.transport_factory.mailersend'], + MailerBridge\Mailgun\Transport\MailgunTransportFactory::class => ['symfony/mailgun-mailer', 'mailer.transport_factory.mailgun'], + MailerBridge\Mailjet\Transport\MailjetTransportFactory::class => ['symfony/mailjet-mailer', 'mailer.transport_factory.mailjet'], + MailerBridge\Mailomat\Transport\MailomatTransportFactory::class => ['symfony/mailomat-mailer', 'mailer.transport_factory.mailomat'], + MailerBridge\MailPace\Transport\MailPaceTransportFactory::class => ['symfony/mail-pace-mailer', 'mailer.transport_factory.mailpace'], + MailerBridge\Mailchimp\Transport\MandrillTransportFactory::class => ['symfony/mailchimp-mailer', 'mailer.transport_factory.mailchimp'], + MailerBridge\MicrosoftGraph\Transport\MicrosoftGraphTransportFactory::class => ['symfony/microsoft-graph-mailer', 'mailer.transport_factory.microsoftgraph'], + MailerBridge\Postal\Transport\PostalTransportFactory::class => ['symfony/postal-mailer', 'mailer.transport_factory.postal'], + MailerBridge\Postmark\Transport\PostmarkTransportFactory::class => ['symfony/postmark-mailer', 'mailer.transport_factory.postmark'], + MailerBridge\Mailtrap\Transport\MailtrapTransportFactory::class => ['symfony/mailtrap-mailer', 'mailer.transport_factory.mailtrap'], + MailerBridge\Resend\Transport\ResendTransportFactory::class => ['symfony/resend-mailer', 'mailer.transport_factory.resend'], + MailerBridge\Scaleway\Transport\ScalewayTransportFactory::class => ['symfony/scaleway-mailer', 'mailer.transport_factory.scaleway'], + MailerBridge\Sendgrid\Transport\SendgridTransportFactory::class => ['symfony/sendgrid-mailer', 'mailer.transport_factory.sendgrid'], + MailerBridge\Amazon\Transport\SesTransportFactory::class => ['symfony/amazon-mailer', 'mailer.transport_factory.amazon'], + MailerBridge\Sweego\Transport\SweegoTransportFactory::class => ['symfony/sweego-mailer', 'mailer.transport_factory.sweego'], ]; - foreach ($classToServices as $class => $service) { - $package = substr($service, \strlen('mailer.transport_factory.')); - - if (!ContainerBuilder::willBeAvailable(\sprintf('symfony/%s-mailer', 'gmail' === $package ? 'google' : $package), $class, ['symfony/framework-bundle', 'symfony/mailer'])) { + foreach ($classToServices as $class => [$package, $service]) { + if (!ContainerBuilder::willBeAvailable($package, $class, ['symfony/framework-bundle', 'symfony/mailer'])) { $container->removeDefinition($service); } } if ($webhookEnabled) { $webhookRequestParsers = [ - MailerBridge\AhaSend\Webhook\AhaSendRequestParser::class => 'mailer.webhook.request_parser.ahasend', - MailerBridge\Brevo\Webhook\BrevoRequestParser::class => 'mailer.webhook.request_parser.brevo', - MailerBridge\MailerSend\Webhook\MailerSendRequestParser::class => 'mailer.webhook.request_parser.mailersend', - MailerBridge\Mailchimp\Webhook\MailchimpRequestParser::class => 'mailer.webhook.request_parser.mailchimp', - MailerBridge\Mailgun\Webhook\MailgunRequestParser::class => 'mailer.webhook.request_parser.mailgun', - MailerBridge\Mailjet\Webhook\MailjetRequestParser::class => 'mailer.webhook.request_parser.mailjet', - MailerBridge\Mailomat\Webhook\MailomatRequestParser::class => 'mailer.webhook.request_parser.mailomat', - MailerBridge\Postmark\Webhook\PostmarkRequestParser::class => 'mailer.webhook.request_parser.postmark', - MailerBridge\Mailtrap\Webhook\MailtrapRequestParser::class => 'mailer.webhook.request_parser.mailtrap', - MailerBridge\Resend\Webhook\ResendRequestParser::class => 'mailer.webhook.request_parser.resend', - MailerBridge\Sendgrid\Webhook\SendgridRequestParser::class => 'mailer.webhook.request_parser.sendgrid', - MailerBridge\Sweego\Webhook\SweegoRequestParser::class => 'mailer.webhook.request_parser.sweego', + MailerBridge\AhaSend\Webhook\AhaSendRequestParser::class => ['symfony/aha-send-mailer', 'mailer.webhook.request_parser.ahasend'], + MailerBridge\Brevo\Webhook\BrevoRequestParser::class => ['symfony/brevo-mailer', 'mailer.webhook.request_parser.brevo'], + MailerBridge\MailerSend\Webhook\MailerSendRequestParser::class => ['symfony/mailer-send-mailer', 'mailer.webhook.request_parser.mailersend'], + MailerBridge\Mailchimp\Webhook\MailchimpRequestParser::class => ['symfony/mailchimp-mailer', 'mailer.webhook.request_parser.mailchimp'], + MailerBridge\Mailgun\Webhook\MailgunRequestParser::class => ['symfony/mailgun-mailer', 'mailer.webhook.request_parser.mailgun'], + MailerBridge\Mailjet\Webhook\MailjetRequestParser::class => ['symfony/mailjet-mailer', 'mailer.webhook.request_parser.mailjet'], + MailerBridge\Mailomat\Webhook\MailomatRequestParser::class => ['symfony/mailomat-mailer', 'mailer.webhook.request_parser.mailomat'], + MailerBridge\Postmark\Webhook\PostmarkRequestParser::class => ['symfony/postmark-mailer', 'mailer.webhook.request_parser.postmark'], + MailerBridge\Mailtrap\Webhook\MailtrapRequestParser::class => ['symfony/mailtrap-mailer', 'mailer.webhook.request_parser.mailtrap'], + MailerBridge\Resend\Webhook\ResendRequestParser::class => ['symfony/resend-mailer', 'mailer.webhook.request_parser.resend'], + MailerBridge\Sendgrid\Webhook\SendgridRequestParser::class => ['symfony/sendgrid-mailer', 'mailer.webhook.request_parser.sendgrid'], + MailerBridge\Sweego\Webhook\SweegoRequestParser::class => ['symfony/sweego-mailer', 'mailer.webhook.request_parser.sweego'], ]; - foreach ($webhookRequestParsers as $class => $service) { - $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'])) { + foreach ($webhookRequestParsers as $class => [$package, $service]) { + if (!ContainerBuilder::willBeAvailable($package, $class, ['symfony/framework-bundle', 'symfony/mailer'])) { $container->removeDefinition($service); } } @@ -3245,105 +3241,103 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $ ->addTag('texter.transport_factory'); $classToServices = [ - NotifierBridge\AllMySms\AllMySmsTransportFactory::class => 'notifier.transport_factory.all-my-sms', - NotifierBridge\AmazonSns\AmazonSnsTransportFactory::class => 'notifier.transport_factory.amazon-sns', - NotifierBridge\Bandwidth\BandwidthTransportFactory::class => 'notifier.transport_factory.bandwidth', - NotifierBridge\Bluesky\BlueskyTransportFactory::class => 'notifier.transport_factory.bluesky', - NotifierBridge\Brevo\BrevoTransportFactory::class => 'notifier.transport_factory.brevo', - NotifierBridge\Chatwork\ChatworkTransportFactory::class => 'notifier.transport_factory.chatwork', - NotifierBridge\Clickatell\ClickatellTransportFactory::class => 'notifier.transport_factory.clickatell', - NotifierBridge\ClickSend\ClickSendTransportFactory::class => 'notifier.transport_factory.click-send', - NotifierBridge\ContactEveryone\ContactEveryoneTransportFactory::class => 'notifier.transport_factory.contact-everyone', - NotifierBridge\Discord\DiscordTransportFactory::class => 'notifier.transport_factory.discord', - NotifierBridge\Engagespot\EngagespotTransportFactory::class => 'notifier.transport_factory.engagespot', - NotifierBridge\Esendex\EsendexTransportFactory::class => 'notifier.transport_factory.esendex', - NotifierBridge\Expo\ExpoTransportFactory::class => 'notifier.transport_factory.expo', - NotifierBridge\Firebase\FirebaseTransportFactory::class => 'notifier.transport_factory.firebase', - NotifierBridge\FortySixElks\FortySixElksTransportFactory::class => 'notifier.transport_factory.forty-six-elks', - NotifierBridge\FreeMobile\FreeMobileTransportFactory::class => 'notifier.transport_factory.free-mobile', - NotifierBridge\GatewayApi\GatewayApiTransportFactory::class => 'notifier.transport_factory.gateway-api', - NotifierBridge\GoIp\GoIpTransportFactory::class => 'notifier.transport_factory.go-ip', - NotifierBridge\GoogleChat\GoogleChatTransportFactory::class => 'notifier.transport_factory.google-chat', - NotifierBridge\Infobip\InfobipTransportFactory::class => 'notifier.transport_factory.infobip', - NotifierBridge\Iqsms\IqsmsTransportFactory::class => 'notifier.transport_factory.iqsms', - NotifierBridge\Isendpro\IsendproTransportFactory::class => 'notifier.transport_factory.isendpro', - NotifierBridge\JoliNotif\JoliNotifTransportFactory::class => 'notifier.transport_factory.joli-notif', - NotifierBridge\KazInfoTeh\KazInfoTehTransportFactory::class => 'notifier.transport_factory.kaz-info-teh', - NotifierBridge\LightSms\LightSmsTransportFactory::class => 'notifier.transport_factory.light-sms', - NotifierBridge\LineBot\LineBotTransportFactory::class => 'notifier.transport_factory.line-bot', - NotifierBridge\LineNotify\LineNotifyTransportFactory::class => 'notifier.transport_factory.line-notify', - NotifierBridge\LinkedIn\LinkedInTransportFactory::class => 'notifier.transport_factory.linked-in', - NotifierBridge\Lox24\Lox24TransportFactory::class => 'notifier.transport_factory.lox24', - NotifierBridge\Mailjet\MailjetTransportFactory::class => 'notifier.transport_factory.mailjet', - NotifierBridge\Mastodon\MastodonTransportFactory::class => 'notifier.transport_factory.mastodon', - NotifierBridge\Matrix\MatrixTransportFactory::class => 'notifier.transport_factory.matrix', - NotifierBridge\Mattermost\MattermostTransportFactory::class => 'notifier.transport_factory.mattermost', - NotifierBridge\Mercure\MercureTransportFactory::class => 'notifier.transport_factory.mercure', - NotifierBridge\MessageBird\MessageBirdTransportFactory::class => 'notifier.transport_factory.message-bird', - NotifierBridge\MessageMedia\MessageMediaTransportFactory::class => 'notifier.transport_factory.message-media', - NotifierBridge\MicrosoftTeams\MicrosoftTeamsTransportFactory::class => 'notifier.transport_factory.microsoft-teams', - NotifierBridge\Mobyt\MobytTransportFactory::class => 'notifier.transport_factory.mobyt', - NotifierBridge\Novu\NovuTransportFactory::class => 'notifier.transport_factory.novu', - NotifierBridge\Ntfy\NtfyTransportFactory::class => 'notifier.transport_factory.ntfy', - NotifierBridge\Octopush\OctopushTransportFactory::class => 'notifier.transport_factory.octopush', - NotifierBridge\OneSignal\OneSignalTransportFactory::class => 'notifier.transport_factory.one-signal', - NotifierBridge\OrangeSms\OrangeSmsTransportFactory::class => 'notifier.transport_factory.orange-sms', - NotifierBridge\OvhCloud\OvhCloudTransportFactory::class => 'notifier.transport_factory.ovh-cloud', - NotifierBridge\PagerDuty\PagerDutyTransportFactory::class => 'notifier.transport_factory.pager-duty', - NotifierBridge\Plivo\PlivoTransportFactory::class => 'notifier.transport_factory.plivo', - NotifierBridge\Primotexto\PrimotextoTransportFactory::class => 'notifier.transport_factory.primotexto', - NotifierBridge\Pushover\PushoverTransportFactory::class => 'notifier.transport_factory.pushover', - NotifierBridge\Pushy\PushyTransportFactory::class => 'notifier.transport_factory.pushy', - NotifierBridge\Redlink\RedlinkTransportFactory::class => 'notifier.transport_factory.redlink', - NotifierBridge\RingCentral\RingCentralTransportFactory::class => 'notifier.transport_factory.ring-central', - NotifierBridge\RocketChat\RocketChatTransportFactory::class => 'notifier.transport_factory.rocket-chat', - NotifierBridge\Sendberry\SendberryTransportFactory::class => 'notifier.transport_factory.sendberry', - NotifierBridge\Sipgate\SipgateTransportFactory::class => 'notifier.transport_factory.sipgate', - NotifierBridge\SimpleTextin\SimpleTextinTransportFactory::class => 'notifier.transport_factory.simple-textin', - NotifierBridge\Sevenio\SevenIoTransportFactory::class => 'notifier.transport_factory.sevenio', - NotifierBridge\Sinch\SinchTransportFactory::class => 'notifier.transport_factory.sinch', - NotifierBridge\Slack\SlackTransportFactory::class => 'notifier.transport_factory.slack', - NotifierBridge\Sms77\Sms77TransportFactory::class => 'notifier.transport_factory.sms77', - NotifierBridge\Smsapi\SmsapiTransportFactory::class => 'notifier.transport_factory.smsapi', - NotifierBridge\SmsBiuras\SmsBiurasTransportFactory::class => 'notifier.transport_factory.sms-biuras', - NotifierBridge\Smsbox\SmsboxTransportFactory::class => 'notifier.transport_factory.smsbox', - NotifierBridge\Smsc\SmscTransportFactory::class => 'notifier.transport_factory.smsc', - NotifierBridge\SmsFactor\SmsFactorTransportFactory::class => 'notifier.transport_factory.sms-factor', - NotifierBridge\Smsmode\SmsmodeTransportFactory::class => 'notifier.transport_factory.smsmode', - NotifierBridge\SmsSluzba\SmsSluzbaTransportFactory::class => 'notifier.transport_factory.sms-sluzba', - NotifierBridge\Smsense\SmsenseTransportFactory::class => 'notifier.transport_factory.smsense', - NotifierBridge\SpotHit\SpotHitTransportFactory::class => 'notifier.transport_factory.spot-hit', - NotifierBridge\Sweego\SweegoTransportFactory::class => 'notifier.transport_factory.sweego', - NotifierBridge\Telegram\TelegramTransportFactory::class => 'notifier.transport_factory.telegram', - NotifierBridge\Telnyx\TelnyxTransportFactory::class => 'notifier.transport_factory.telnyx', - NotifierBridge\Termii\TermiiTransportFactory::class => 'notifier.transport_factory.termii', - NotifierBridge\TurboSms\TurboSmsTransportFactory::class => 'notifier.transport_factory.turbo-sms', - NotifierBridge\Twilio\TwilioTransportFactory::class => 'notifier.transport_factory.twilio', - NotifierBridge\Twitter\TwitterTransportFactory::class => 'notifier.transport_factory.twitter', - NotifierBridge\Unifonic\UnifonicTransportFactory::class => 'notifier.transport_factory.unifonic', - NotifierBridge\Vonage\VonageTransportFactory::class => 'notifier.transport_factory.vonage', - NotifierBridge\Yunpian\YunpianTransportFactory::class => 'notifier.transport_factory.yunpian', - NotifierBridge\Zendesk\ZendeskTransportFactory::class => 'notifier.transport_factory.zendesk', - NotifierBridge\Zulip\ZulipTransportFactory::class => 'notifier.transport_factory.zulip', + NotifierBridge\AllMySms\AllMySmsTransportFactory::class => ['symfony/all-my-sms-notifier', 'notifier.transport_factory.all-my-sms'], + NotifierBridge\AmazonSns\AmazonSnsTransportFactory::class => ['symfony/amazon-sns-notifier', 'notifier.transport_factory.amazon-sns'], + NotifierBridge\Bandwidth\BandwidthTransportFactory::class => ['symfony/bandwidth-notifier', 'notifier.transport_factory.bandwidth'], + NotifierBridge\Bluesky\BlueskyTransportFactory::class => ['symfony/bluesky-notifier', 'notifier.transport_factory.bluesky'], + NotifierBridge\Brevo\BrevoTransportFactory::class => ['symfony/brevo-notifier', 'notifier.transport_factory.brevo'], + NotifierBridge\Chatwork\ChatworkTransportFactory::class => ['symfony/chatwork-notifier', 'notifier.transport_factory.chatwork'], + NotifierBridge\Clickatell\ClickatellTransportFactory::class => ['symfony/clickatell-notifier', 'notifier.transport_factory.clickatell'], + NotifierBridge\ClickSend\ClickSendTransportFactory::class => ['symfony/click-send-notifier', 'notifier.transport_factory.click-send'], + NotifierBridge\ContactEveryone\ContactEveryoneTransportFactory::class => ['symfony/contact-everyone-notifier', 'notifier.transport_factory.contact-everyone'], + NotifierBridge\Discord\DiscordTransportFactory::class => ['symfony/discord-notifier', 'notifier.transport_factory.discord'], + NotifierBridge\Engagespot\EngagespotTransportFactory::class => ['symfony/engagespot-notifier', 'notifier.transport_factory.engagespot'], + NotifierBridge\Esendex\EsendexTransportFactory::class => ['symfony/esendex-notifier', 'notifier.transport_factory.esendex'], + NotifierBridge\Expo\ExpoTransportFactory::class => ['symfony/expo-notifier', 'notifier.transport_factory.expo'], + NotifierBridge\Firebase\FirebaseTransportFactory::class => ['symfony/firebase-notifier', 'notifier.transport_factory.firebase'], + NotifierBridge\FortySixElks\FortySixElksTransportFactory::class => ['symfony/forty-six-elks-notifier', 'notifier.transport_factory.forty-six-elks'], + NotifierBridge\FreeMobile\FreeMobileTransportFactory::class => ['symfony/free-mobile-notifier', 'notifier.transport_factory.free-mobile'], + NotifierBridge\GatewayApi\GatewayApiTransportFactory::class => ['symfony/gateway-api-notifier', 'notifier.transport_factory.gateway-api'], + NotifierBridge\GoIp\GoIpTransportFactory::class => ['symfony/go-ip-notifier', 'notifier.transport_factory.go-ip'], + NotifierBridge\GoogleChat\GoogleChatTransportFactory::class => ['symfony/google-chat-notifier', 'notifier.transport_factory.google-chat'], + NotifierBridge\Infobip\InfobipTransportFactory::class => ['symfony/infobip-notifier', 'notifier.transport_factory.infobip'], + NotifierBridge\Iqsms\IqsmsTransportFactory::class => ['symfony/iqsms-notifier', 'notifier.transport_factory.iqsms'], + NotifierBridge\Isendpro\IsendproTransportFactory::class => ['symfony/isendpro-notifier', 'notifier.transport_factory.isendpro'], + NotifierBridge\JoliNotif\JoliNotifTransportFactory::class => ['symfony/joli-notif-notifier', 'notifier.transport_factory.joli-notif'], + NotifierBridge\KazInfoTeh\KazInfoTehTransportFactory::class => ['symfony/kaz-info-teh-notifier', 'notifier.transport_factory.kaz-info-teh'], + NotifierBridge\LightSms\LightSmsTransportFactory::class => ['symfony/light-sms-notifier', 'notifier.transport_factory.light-sms'], + NotifierBridge\LineBot\LineBotTransportFactory::class => ['symfony/line-bot-notifier', 'notifier.transport_factory.line-bot'], + NotifierBridge\LineNotify\LineNotifyTransportFactory::class => ['symfony/line-notify-notifier', 'notifier.transport_factory.line-notify'], + NotifierBridge\LinkedIn\LinkedInTransportFactory::class => ['symfony/linked-in-notifier', 'notifier.transport_factory.linked-in'], + NotifierBridge\Lox24\Lox24TransportFactory::class => ['symfony/lox24-notifier', 'notifier.transport_factory.lox24'], + NotifierBridge\Mailjet\MailjetTransportFactory::class => ['symfony/mailjet-notifier', 'notifier.transport_factory.mailjet'], + NotifierBridge\Mastodon\MastodonTransportFactory::class => ['symfony/mastodon-notifier', 'notifier.transport_factory.mastodon'], + NotifierBridge\Matrix\MatrixTransportFactory::class => ['symfony/matrix-notifier', 'notifier.transport_factory.matrix'], + NotifierBridge\Mattermost\MattermostTransportFactory::class => ['symfony/mattermost-notifier', 'notifier.transport_factory.mattermost'], + NotifierBridge\Mercure\MercureTransportFactory::class => ['symfony/mercure-notifier', 'notifier.transport_factory.mercure'], + NotifierBridge\MessageBird\MessageBirdTransportFactory::class => ['symfony/message-bird-notifier', 'notifier.transport_factory.message-bird'], + NotifierBridge\MessageMedia\MessageMediaTransportFactory::class => ['symfony/message-media-notifier', 'notifier.transport_factory.message-media'], + NotifierBridge\MicrosoftTeams\MicrosoftTeamsTransportFactory::class => ['symfony/microsoft-teams-notifier', 'notifier.transport_factory.microsoft-teams'], + NotifierBridge\Mobyt\MobytTransportFactory::class => ['symfony/mobyt-notifier', 'notifier.transport_factory.mobyt'], + NotifierBridge\Novu\NovuTransportFactory::class => ['symfony/novu-notifier', 'notifier.transport_factory.novu'], + NotifierBridge\Ntfy\NtfyTransportFactory::class => ['symfony/ntfy-notifier', 'notifier.transport_factory.ntfy'], + NotifierBridge\Octopush\OctopushTransportFactory::class => ['symfony/octopush-notifier', 'notifier.transport_factory.octopush'], + NotifierBridge\OneSignal\OneSignalTransportFactory::class => ['symfony/one-signal-notifier', 'notifier.transport_factory.one-signal'], + NotifierBridge\OrangeSms\OrangeSmsTransportFactory::class => ['symfony/orange-sms-notifier', 'notifier.transport_factory.orange-sms'], + NotifierBridge\OvhCloud\OvhCloudTransportFactory::class => ['symfony/ovh-cloud-notifier', 'notifier.transport_factory.ovh-cloud'], + NotifierBridge\PagerDuty\PagerDutyTransportFactory::class => ['symfony/pager-duty-notifier', 'notifier.transport_factory.pager-duty'], + NotifierBridge\Plivo\PlivoTransportFactory::class => ['symfony/plivo-notifier', 'notifier.transport_factory.plivo'], + NotifierBridge\Primotexto\PrimotextoTransportFactory::class => ['symfony/primotexto-notifier', 'notifier.transport_factory.primotexto'], + NotifierBridge\Pushover\PushoverTransportFactory::class => ['symfony/pushover-notifier', 'notifier.transport_factory.pushover'], + NotifierBridge\Pushy\PushyTransportFactory::class => ['symfony/pushy-notifier', 'notifier.transport_factory.pushy'], + NotifierBridge\Redlink\RedlinkTransportFactory::class => ['symfony/redlink-notifier', 'notifier.transport_factory.redlink'], + NotifierBridge\RingCentral\RingCentralTransportFactory::class => ['symfony/ring-central-notifier', 'notifier.transport_factory.ring-central'], + NotifierBridge\RocketChat\RocketChatTransportFactory::class => ['symfony/rocket-chat-notifier', 'notifier.transport_factory.rocket-chat'], + NotifierBridge\Sendberry\SendberryTransportFactory::class => ['symfony/sendberry-notifier', 'notifier.transport_factory.sendberry'], + NotifierBridge\Sipgate\SipgateTransportFactory::class => ['symfony/sipgate-notifier', 'notifier.transport_factory.sipgate'], + NotifierBridge\SimpleTextin\SimpleTextinTransportFactory::class => ['symfony/simple-textin-notifier', 'notifier.transport_factory.simple-textin'], + NotifierBridge\Sevenio\SevenIoTransportFactory::class => ['symfony/sevenio-notifier', 'notifier.transport_factory.sevenio'], + NotifierBridge\Sinch\SinchTransportFactory::class => ['symfony/sinch-notifier', 'notifier.transport_factory.sinch'], + NotifierBridge\Slack\SlackTransportFactory::class => ['symfony/slack-notifier', 'notifier.transport_factory.slack'], + NotifierBridge\Sms77\Sms77TransportFactory::class => ['symfony/sms77-notifier', 'notifier.transport_factory.sms77'], + NotifierBridge\Smsapi\SmsapiTransportFactory::class => ['symfony/smsapi-notifier', 'notifier.transport_factory.smsapi'], + NotifierBridge\SmsBiuras\SmsBiurasTransportFactory::class => ['symfony/sms-biuras-notifier', 'notifier.transport_factory.sms-biuras'], + NotifierBridge\Smsbox\SmsboxTransportFactory::class => ['symfony/smsbox-notifier', 'notifier.transport_factory.smsbox'], + NotifierBridge\Smsc\SmscTransportFactory::class => ['symfony/smsc-notifier', 'notifier.transport_factory.smsc'], + NotifierBridge\SmsFactor\SmsFactorTransportFactory::class => ['symfony/sms-factor-notifier', 'notifier.transport_factory.sms-factor'], + NotifierBridge\Smsmode\SmsmodeTransportFactory::class => ['symfony/smsmode-notifier', 'notifier.transport_factory.smsmode'], + NotifierBridge\SmsSluzba\SmsSluzbaTransportFactory::class => ['symfony/sms-sluzba-notifier', 'notifier.transport_factory.sms-sluzba'], + NotifierBridge\Smsense\SmsenseTransportFactory::class => ['symfony/smsense-notifier', 'notifier.transport_factory.smsense'], + NotifierBridge\SpotHit\SpotHitTransportFactory::class => ['symfony/spot-hit-notifier', 'notifier.transport_factory.spot-hit'], + NotifierBridge\Sweego\SweegoTransportFactory::class => ['symfony/sweego-notifier', 'notifier.transport_factory.sweego'], + NotifierBridge\Telegram\TelegramTransportFactory::class => ['symfony/telegram-notifier', 'notifier.transport_factory.telegram'], + NotifierBridge\Telnyx\TelnyxTransportFactory::class => ['symfony/telnyx-notifier', 'notifier.transport_factory.telnyx'], + NotifierBridge\Termii\TermiiTransportFactory::class => ['symfony/termii-notifier', 'notifier.transport_factory.termii'], + NotifierBridge\TurboSms\TurboSmsTransportFactory::class => ['symfony/turbo-sms-notifier', 'notifier.transport_factory.turbo-sms'], + NotifierBridge\Twilio\TwilioTransportFactory::class => ['symfony/twilio-notifier', 'notifier.transport_factory.twilio'], + NotifierBridge\Twitter\TwitterTransportFactory::class => ['symfony/twitter-notifier', 'notifier.transport_factory.twitter'], + NotifierBridge\Unifonic\UnifonicTransportFactory::class => ['symfony/unifonic-notifier', 'notifier.transport_factory.unifonic'], + NotifierBridge\Vonage\VonageTransportFactory::class => ['symfony/vonage-notifier', 'notifier.transport_factory.vonage'], + NotifierBridge\Yunpian\YunpianTransportFactory::class => ['symfony/yunpian-notifier', 'notifier.transport_factory.yunpian'], + NotifierBridge\Zendesk\ZendeskTransportFactory::class => ['symfony/zendesk-notifier', 'notifier.transport_factory.zendesk'], + NotifierBridge\Zulip\ZulipTransportFactory::class => ['symfony/zulip-notifier', 'notifier.transport_factory.zulip'], ]; $parentPackages = ['symfony/framework-bundle', 'symfony/notifier']; - foreach ($classToServices as $class => $service) { - $package = substr($service, \strlen('notifier.transport_factory.')); - - if (!ContainerBuilder::willBeAvailable(\sprintf('symfony/%s-notifier', $package), $class, $parentPackages)) { + foreach ($classToServices as $class => [$package, $service]) { + if (!ContainerBuilder::willBeAvailable($package, $class, $parentPackages)) { $container->removeDefinition($service); } } 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]) + $container->getDefinition('notifier.transport_factory.mercure') ->replaceArgument(0, new Reference(HubRegistry::class)) ->replaceArgument(1, new Reference('event_dispatcher', ContainerBuilder::NULL_ON_INVALID_REFERENCE)) ->addArgument(new Reference('http_client', ContainerBuilder::NULL_ON_INVALID_REFERENCE)); } elseif (ContainerBuilder::willBeAvailable('symfony/mercure-notifier', NotifierBridge\Mercure\MercureTransportFactory::class, $parentPackages)) { - $container->removeDefinition($classToServices[NotifierBridge\Mercure\MercureTransportFactory::class]); + $container->removeDefinition('notifier.transport_factory.mercure'); } // don't use ContainerBuilder::willBeAvailable() as these are not needed in production @@ -3369,7 +3363,7 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $ } if (ContainerBuilder::willBeAvailable('symfony/bluesky-notifier', NotifierBridge\Bluesky\BlueskyTransportFactory::class, ['symfony/framework-bundle', 'symfony/notifier'])) { - $container->getDefinition($classToServices[NotifierBridge\Bluesky\BlueskyTransportFactory::class]) + $container->getDefinition('notifier.transport_factory.bluesky') ->addArgument(new Reference('logger')) ->addArgument(new Reference('clock', ContainerBuilder::NULL_ON_INVALID_REFERENCE)); } @@ -3387,17 +3381,15 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $ $loader->load('notifier_webhook.php'); $webhookRequestParsers = [ - NotifierBridge\Lox24\Webhook\Lox24RequestParser::class => 'notifier.webhook.request_parser.lox24', - NotifierBridge\Smsbox\Webhook\SmsboxRequestParser::class => 'notifier.webhook.request_parser.smsbox', - NotifierBridge\Sweego\Webhook\SweegoRequestParser::class => 'notifier.webhook.request_parser.sweego', - NotifierBridge\Twilio\Webhook\TwilioRequestParser::class => 'notifier.webhook.request_parser.twilio', - NotifierBridge\Vonage\Webhook\VonageRequestParser::class => 'notifier.webhook.request_parser.vonage', + NotifierBridge\Lox24\Webhook\Lox24RequestParser::class => ['symfony/lox24-notifier', 'notifier.webhook.request_parser.lox24'], + NotifierBridge\Smsbox\Webhook\SmsboxRequestParser::class => ['symfony/smsbox-notifier', 'notifier.webhook.request_parser.smsbox'], + NotifierBridge\Sweego\Webhook\SweegoRequestParser::class => ['symfony/sweego-notifier', 'notifier.webhook.request_parser.sweego'], + NotifierBridge\Twilio\Webhook\TwilioRequestParser::class => ['symfony/twilio-notifier', 'notifier.webhook.request_parser.twilio'], + NotifierBridge\Vonage\Webhook\VonageRequestParser::class => ['symfony/vonage-notifier', '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'])) { + foreach ($webhookRequestParsers as $class => [$package, $service]) { + if (!ContainerBuilder::willBeAvailable($package, $class, ['symfony/framework-bundle', 'symfony/notifier'])) { $container->removeDefinition($service); } } diff --git a/FrameworkBundle.php b/FrameworkBundle.php index b892a825d..7b1566035 100644 --- a/FrameworkBundle.php +++ b/FrameworkBundle.php @@ -127,6 +127,12 @@ public function boot(): void if ($this->container->hasParameter('kernel.trust_x_sendfile_type_header') && $this->container->getParameter('kernel.trust_x_sendfile_type_header')) { BinaryFileResponse::trustXSendfileTypeHeader(); } + + // Instantiate the mime_types service so its setDefault() call fires. + // The service is made public by AddMimeTypeGuesserPass only when custom guessers are tagged. + if ($this->container->has('mime_types')) { + $this->container->get('mime_types'); + } } public function build(ContainerBuilder $container): void diff --git a/Kernel/MicroKernelTrait.php b/Kernel/MicroKernelTrait.php index bb94808b4..4f68d4eb4 100644 --- a/Kernel/MicroKernelTrait.php +++ b/Kernel/MicroKernelTrait.php @@ -47,7 +47,7 @@ trait MicroKernelTrait * * $container->parameters()->set('halloween', 'lot of fun'); */ - private function configureContainer(ContainerConfigurator $container, LoaderInterface $loader, ContainerBuilder $builder): void + private function configureContainer(ContainerConfigurator $container): void { $configDir = preg_replace('{/config$}', '/{config}', $this->getConfigDir()); diff --git a/KernelBrowser.php b/KernelBrowser.php index dec0c698c..272c74915 100644 --- a/KernelBrowser.php +++ b/KernelBrowser.php @@ -84,7 +84,7 @@ public function getSession(): ?SessionInterface $session->start(); if (!$cookie instanceof Cookie) { - $domains = array_unique(array_map(fn (Cookie $cookie) => $cookie->getName() === $session->getName() ? $cookie->getDomain() : '', $cookieJar->all())) ?: ['']; + $domains = array_unique(array_map(static fn (Cookie $cookie) => $cookie->getName() === $session->getName() ? $cookie->getDomain() : '', $cookieJar->all())) ?: ['']; foreach ($domains as $domain) { $cookieJar->set(new Cookie($session->getName(), $session->getId(), domain: $domain)); } diff --git a/Resources/config/routing/errors.php b/Resources/config/routing/errors.php index 36a46dee4..724f7bf52 100644 --- a/Resources/config/routing/errors.php +++ b/Resources/config/routing/errors.php @@ -12,7 +12,7 @@ use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; use Symfony\Component\Routing\Loader\XmlFileLoader; -return function (RoutingConfigurator $routes): void { +return static function (RoutingConfigurator $routes): void { foreach (debug_backtrace() as $trace) { if (isset($trace['object']) && $trace['object'] instanceof XmlFileLoader && 'doImport' === $trace['function']) { if (__DIR__ === dirname(realpath($trace['args'][3]))) { diff --git a/Resources/config/routing/webhook.php b/Resources/config/routing/webhook.php index 177606b26..dc07d7f93 100644 --- a/Resources/config/routing/webhook.php +++ b/Resources/config/routing/webhook.php @@ -12,7 +12,7 @@ use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; use Symfony\Component\Routing\Loader\XmlFileLoader; -return function (RoutingConfigurator $routes): void { +return static function (RoutingConfigurator $routes): void { foreach (debug_backtrace() as $trace) { if (isset($trace['object']) && $trace['object'] instanceof XmlFileLoader && 'doImport' === $trace['function']) { if (__DIR__ === dirname(realpath($trace['args'][3]))) { diff --git a/Tests/CacheWarmer/SerializerCacheWarmerTest.php b/Tests/CacheWarmer/SerializerCacheWarmerTest.php index 5c19d2a3f..7bb588a18 100644 --- a/Tests/CacheWarmer/SerializerCacheWarmerTest.php +++ b/Tests/CacheWarmer/SerializerCacheWarmerTest.php @@ -137,7 +137,7 @@ public function testClassAutoloadException() $warmer = new SerializerCacheWarmer([new YamlFileLoader(__DIR__.'/../Fixtures/Serialization/Resources/does_not_exist.yaml')], $file); - spl_autoload_register($classLoader = function ($class) use ($mappedClass) { + spl_autoload_register($classLoader = static function ($class) use ($mappedClass) { if ($class === $mappedClass) { throw new \DomainException('This exception should be caught by the warmer.'); } diff --git a/Tests/CacheWarmer/ValidatorCacheWarmerTest.php b/Tests/CacheWarmer/ValidatorCacheWarmerTest.php index 01d70d3a1..dad86a76e 100644 --- a/Tests/CacheWarmer/ValidatorCacheWarmerTest.php +++ b/Tests/CacheWarmer/ValidatorCacheWarmerTest.php @@ -156,7 +156,7 @@ public function testClassAutoloadException() $validatorBuilder->addYamlMapping(__DIR__.'/../Fixtures/Validation/Resources/does_not_exist.yaml'); $warmer = new ValidatorCacheWarmer($validatorBuilder, $file); - spl_autoload_register($classloader = function ($class) use ($mappedClass) { + spl_autoload_register($classloader = static function ($class) use ($mappedClass) { if ($class === $mappedClass) { throw new \DomainException('This exception should be caught by the warmer.'); } diff --git a/Tests/Command/CacheClearCommand/CacheClearCommandTest.php b/Tests/Command/CacheClearCommand/CacheClearCommandTest.php index 753c39cc8..9c64ee91a 100644 --- a/Tests/Command/CacheClearCommand/CacheClearCommandTest.php +++ b/Tests/Command/CacheClearCommand/CacheClearCommandTest.php @@ -121,7 +121,7 @@ public function testCacheIsWarmedWithOldContainer() // BUT without "kernel.build_dir" parameter (like an old dumped container) $kernel->boot(); $container = $kernel->getContainer(); - \Closure::bind(function (Container $class) { + \Closure::bind(static function (Container $class) { unset($class->loadedDynamicParameters['kernel.build_dir']); unset($class->parameters['kernel.build_dir']); }, null, $container::class)($container); diff --git a/Tests/Command/CachePoolInvalidateTagsCommandTest.php b/Tests/Command/CachePoolInvalidateTagsCommandTest.php index d0286b7e1..e78f3ad28 100644 --- a/Tests/Command/CachePoolInvalidateTagsCommandTest.php +++ b/Tests/Command/CachePoolInvalidateTagsCommandTest.php @@ -132,7 +132,7 @@ public function testCommandFailsIfInvalidatingTagsFails() private function createCommand(array $services): CachePoolInvalidateTagsCommand { return new CachePoolInvalidateTagsCommand( - new ServiceLocator(array_map(fn ($service) => fn () => $service, $services)) + new ServiceLocator(array_map(static fn ($service) => static fn () => $service, $services)) ); } } diff --git a/Tests/Command/EventDispatcherDebugCommandTest.php b/Tests/Command/EventDispatcherDebugCommandTest.php index 7dc1e0dc6..88a8dc37d 100644 --- a/Tests/Command/EventDispatcherDebugCommandTest.php +++ b/Tests/Command/EventDispatcherDebugCommandTest.php @@ -42,14 +42,14 @@ public static function provideCompletionSuggestions(): iterable private function createCommandCompletionTester(): CommandCompletionTester { $dispatchers = new ServiceLocator([ - 'event_dispatcher' => function () { + 'event_dispatcher' => static function () { $dispatcher = new EventDispatcher(); $dispatcher->addListener(MessageEvent::class, 'var_dump'); $dispatcher->addListener('console.command', 'var_dump'); return $dispatcher; }, - 'other_event_dispatcher' => function () { + 'other_event_dispatcher' => static function () { $dispatcher = new EventDispatcher(); $dispatcher->addListener('other_event', 'var_dump'); $dispatcher->addListener('App\OtherEvent', 'var_dump'); diff --git a/Tests/Command/TranslationDebugCommandTest.php b/Tests/Command/TranslationDebugCommandTest.php index 8bbd0ad5a..ec23f61bf 100644 --- a/Tests/Command/TranslationDebugCommandTest.php +++ b/Tests/Command/TranslationDebugCommandTest.php @@ -178,7 +178,7 @@ private function createCommand(array $extractedMessages = [], array $loadedMessa $extractor ->method('extract') ->willReturnCallback( - function ($path, $catalogue) use ($extractedMessages) { + static function ($path, $catalogue) use ($extractedMessages) { $catalogue->add($extractedMessages); } ); @@ -188,7 +188,7 @@ function ($path, $catalogue) use ($extractedMessages) { $loader ->method('read') ->willReturnCallback( - function ($path, $catalogue) use ($loadedMessages) { + static function ($path, $catalogue) use ($loadedMessages) { $catalogue->add($loadedMessages); } ); @@ -250,7 +250,7 @@ public function testComplete(array $input, array $expectedSuggestions) $extractor ->method('extract') ->willReturnCallback( - function ($path, $catalogue) use ($extractedMessagesWithDomains) { + static function ($path, $catalogue) use ($extractedMessagesWithDomains) { foreach ($extractedMessagesWithDomains as $domain => $message) { $catalogue->add($message, $domain); } diff --git a/Tests/Command/TranslationExtractCommandCompletionTest.php b/Tests/Command/TranslationExtractCommandCompletionTest.php index 78a053939..8fd58971d 100644 --- a/Tests/Command/TranslationExtractCommandCompletionTest.php +++ b/Tests/Command/TranslationExtractCommandCompletionTest.php @@ -76,7 +76,7 @@ private function createCommandCompletionTester($extractedMessages = [], $loadedM $extractor ->method('extract') ->willReturnCallback( - function ($path, $catalogue) use ($extractedMessages) { + static function ($path, $catalogue) use ($extractedMessages) { foreach ($extractedMessages as $domain => $messages) { $catalogue->add($messages, $domain); } @@ -87,7 +87,7 @@ function ($path, $catalogue) use ($extractedMessages) { $loader ->method('read') ->willReturnCallback( - function ($path, $catalogue) use ($loadedMessages) { + static function ($path, $catalogue) use ($loadedMessages) { $catalogue->add($loadedMessages); } ); diff --git a/Tests/Command/TranslationExtractCommandTest.php b/Tests/Command/TranslationExtractCommandTest.php index d129e2cd6..79a425b5a 100644 --- a/Tests/Command/TranslationExtractCommandTest.php +++ b/Tests/Command/TranslationExtractCommandTest.php @@ -183,6 +183,9 @@ public function testRemoveNoFillTranslationsMethod($noFillCounter, $messages) { // Preparing mock $operation = $this->createMock(MessageCatalogueInterface::class); + $operation + ->method('getDomains') + ->willReturn(['messages']); $operation ->method('all') ->willReturnMap([ @@ -199,6 +202,39 @@ public function testRemoveNoFillTranslationsMethod($noFillCounter, $messages) $method->invokeArgs($translationUpdate, [$operation]); } + public function testRemoveNoFillTranslationsAcrossAllDomains() + { + $operation = $this->createMock(MessageCatalogueInterface::class); + $operation + ->method('getDomains') + ->willReturn(['messages', 'validators', 'validators+intl-icu']); + $operation + ->method('all') + ->willReturnMap([ + ['messages', ['greeting' => "\0NoFill\0Hello"]], + ['validators', ['err' => 'plain error']], + ['validators+intl-icu', ['desc' => "\0NoFill\0Description is mandatory"]], + ]); + + $calls = []; + $operation + ->expects($this->exactly(2)) + ->method('set') + ->willReturnCallback(static function ($id, $translation, $domain) use (&$calls): void { + $calls[] = [$id, $translation, $domain]; + }); + + $translationUpdate = $this->createStub(TranslationExtractCommand::class); + $reflection = new \ReflectionObject($translationUpdate); + $method = $reflection->getMethod('removeNoFillTranslations'); + $method->invokeArgs($translationUpdate, [$operation]); + + $this->assertSame([ + ['greeting', '', 'messages'], + ['desc', '', 'validators+intl-icu'], + ], $calls); + } + public static function removeNoFillProvider(): array { return [ @@ -239,7 +275,7 @@ private function createCommandTester($extractedMessages = [], $loadedMessages = $extractor ->method('extract') ->willReturnCallback( - function ($path, $catalogue) use ($extractedMessages) { + static function ($path, $catalogue) use ($extractedMessages) { foreach ($extractedMessages as $domain => $messages) { $catalogue->add($messages, $domain); } @@ -250,7 +286,7 @@ function ($path, $catalogue) use ($extractedMessages) { $loader ->method('read') ->willReturnCallback( - function ($path, $catalogue) use ($loadedMessages) { + static function ($path, $catalogue) use ($loadedMessages) { $catalogue->add($loadedMessages); } ); diff --git a/Tests/Console/ApplicationTest.php b/Tests/Console/ApplicationTest.php index cf62550d7..8a7c724a6 100644 --- a/Tests/Console/ApplicationTest.php +++ b/Tests/Console/ApplicationTest.php @@ -135,7 +135,7 @@ public function testRunOnlyWarnsOnUnregistrableCommand() $kernel ->method('getBundles') ->willReturn([$this->createBundleMock( - [(new Command('fine'))->setCode(function (InputInterface $input, OutputInterface $output): int { + [(new Command('fine'))->setCode(static function (InputInterface $input, OutputInterface $output): int { $output->write('fine'); return 0; @@ -167,7 +167,7 @@ public function testRegistrationErrorsAreDisplayedOnCommandNotFound() $kernel ->method('getBundles') ->willReturn([$this->createBundleMock( - [(new Command(null))->setCode(function (InputInterface $input, OutputInterface $output): int { + [(new Command(null))->setCode(static function (InputInterface $input, OutputInterface $output): int { $output->write('fine'); return 0; @@ -201,7 +201,7 @@ public function testRunOnlyWarnsOnUnregistrableCommandAtTheEnd() $kernel ->method('getBundles') ->willReturn([$this->createBundleMock( - [(new Command('fine'))->setCode(function (InputInterface $input, OutputInterface $output): int { + [(new Command('fine'))->setCode(static function (InputInterface $input, OutputInterface $output): int { $output->write('fine'); return 0; @@ -288,7 +288,7 @@ private function createBundleMock(array $commands) $bundle ->expects($this->once()) ->method('registerCommands') - ->willReturnCallback(function (Application $application) use ($commands) { + ->willReturnCallback(static function (Application $application) use ($commands) { $application->addCommands($commands); }) ; diff --git a/Tests/Console/Descriptor/ObjectsProvider.php b/Tests/Console/Descriptor/ObjectsProvider.php index 07c66e9c8..b365fb2d2 100644 --- a/Tests/Console/Descriptor/ObjectsProvider.php +++ b/Tests/Console/Descriptor/ObjectsProvider.php @@ -312,7 +312,7 @@ public static function getEventDispatchers() $eventDispatcher = new EventDispatcher(); $eventDispatcher->addListener('event1', 'var_dump', 255); - $eventDispatcher->addListener('event1', fn () => 'Closure', -1); + $eventDispatcher->addListener('event1', static fn () => 'Closure', -1); $eventDispatcher->addListener('event2', new CallableClass()); return ['event_dispatcher_1' => $eventDispatcher]; @@ -325,7 +325,7 @@ public static function getCallables(): array 'callable_2' => ['Symfony\\Bundle\\FrameworkBundle\\Tests\\Console\\Descriptor\\CallableClass', 'staticMethod'], 'callable_3' => [new CallableClass(), 'method'], 'callable_4' => 'Symfony\\Bundle\\FrameworkBundle\\Tests\\Console\\Descriptor\\CallableClass::staticMethod', - 'callable_6' => fn () => 'Closure', + 'callable_6' => static fn () => 'Closure', 'callable_7' => new CallableClass(), 'callable_from_callable' => (new CallableClass())(...), ]; diff --git a/Tests/Controller/AbstractControllerTest.php b/Tests/Controller/AbstractControllerTest.php index 9d3545539..acb31b02f 100644 --- a/Tests/Controller/AbstractControllerTest.php +++ b/Tests/Controller/AbstractControllerTest.php @@ -119,7 +119,7 @@ public function testForward() $requestStack->push($request); $kernel = $this->createMock(HttpKernelInterface::class); - $kernel->expects($this->once())->method('handle')->willReturnCallback(fn (Request $request) => new Response($request->getRequestFormat().'--'.$request->getLocale())); + $kernel->expects($this->once())->method('handle')->willReturnCallback(static fn (Request $request) => new Response($request->getRequestFormat().'--'.$request->getLocale())); $container = new Container(); $container->set('request_stack', $requestStack); @@ -689,8 +689,8 @@ public function testSendEarlyHints() $controller->setContainer($container); $response = $controller->sendEarlyHints([ - (new Link(href: '/style.css'))->withAttribute('as', 'stylesheet'), - (new Link(href: '/script.js'))->withAttribute('as', 'script'), + (new Link(null, '/style.css'))->withAttribute('as', 'stylesheet'), + (new Link(null, '/script.js'))->withAttribute('as', 'script'), ]); $this->assertSame('; rel="preload"; as="stylesheet",; rel="preload"; as="script"', $response->headers->get('Link')); diff --git a/Tests/Controller/TemplateControllerTest.php b/Tests/Controller/TemplateControllerTest.php index 1d98f4f8e..34ce1d4ed 100644 --- a/Tests/Controller/TemplateControllerTest.php +++ b/Tests/Controller/TemplateControllerTest.php @@ -111,8 +111,8 @@ public function testHeaders() $twig = new Environment($loader); $controller = new TemplateController($twig); - $this->assertSame('image/svg+xml', $controller->templateAction($templateName, headers: ['Content-Type' => 'image/svg+xml'])->headers->get('Content-Type')); - $this->assertSame('image/svg+xml', $controller($templateName, headers: ['Content-Type' => 'image/svg+xml'])->headers->get('Content-Type')); + $this->assertSame('image/svg+xml', $controller->templateAction($templateName, null, null, null, [], 200, ['Content-Type' => 'image/svg+xml'])->headers->get('Content-Type')); + $this->assertSame('image/svg+xml', $controller($templateName, null, null, null, [], 200, ['Content-Type' => 'image/svg+xml'])->headers->get('Content-Type')); $this->assertNull($controller->templateAction($templateName)->headers->get('Content-Type')); $this->assertNull($controller($templateName)->headers->get('Content-Type')); diff --git a/Tests/DependencyInjection/Compiler/UnusedTagsPassTest.php b/Tests/DependencyInjection/Compiler/UnusedTagsPassTest.php index b6021fbdd..0951fc209 100644 --- a/Tests/DependencyInjection/Compiler/UnusedTagsPassTest.php +++ b/Tests/DependencyInjection/Compiler/UnusedTagsPassTest.php @@ -44,7 +44,7 @@ public function testMissingKnownTags() private function getKnownTags(): array { $tags = \Closure::bind( - fn () => UnusedTagsPass::KNOWN_TAGS, + static fn () => UnusedTagsPass::KNOWN_TAGS, null, UnusedTagsPass::class )(); diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php index 703f6ab5f..22f6d3e11 100644 --- a/Tests/DependencyInjection/ConfigurationTest.php +++ b/Tests/DependencyInjection/ConfigurationTest.php @@ -240,7 +240,7 @@ public function testInvalidAssetsConfiguration(array $assetConfig, $expectedMess public static function provideInvalidAssetConfigurationTests(): iterable { // helper to turn config into embedded package config - $createPackageConfig = fn (array $packageConfig) => [ + $createPackageConfig = static fn (array $packageConfig) => [ 'base_urls' => '//example.com', 'version' => 1, 'packages' => [ diff --git a/Tests/DependencyInjection/FrameworkExtensionTestCase.php b/Tests/DependencyInjection/FrameworkExtensionTestCase.php index ee7e70394..26f1c3f93 100644 --- a/Tests/DependencyInjection/FrameworkExtensionTestCase.php +++ b/Tests/DependencyInjection/FrameworkExtensionTestCase.php @@ -223,7 +223,7 @@ public function testAllowedHttpMethodOverride() public function testAllowedHttpMethodOverrideWithSpecificMethods() { - $container = $this->createContainerFromClosure(function ($container) { + $container = $this->createContainerFromClosure(static function ($container) { $container->loadFromExtension('framework', [ 'annotations' => false, 'http_method_override' => true, @@ -969,7 +969,7 @@ public function testMessengerServicesRemovedWhenDisabled() $container = $this->createContainerFromFile('messenger_disabled'); $messengerDefinitions = array_filter( $container->getDefinitions(), - fn ($name) => str_starts_with($name, 'messenger.'), + static fn ($name) => str_starts_with($name, 'messenger.'), \ARRAY_FILTER_USE_KEY ); @@ -1071,7 +1071,7 @@ public function testMessengerMultipleFailureTransports() 'transport_3' => new Reference('messenger.transport.failure_transport_3'), ]; - $failureTransportsReferences = array_map(function (ServiceClosureArgument $serviceClosureArgument) { + $failureTransportsReferences = array_map(static function (ServiceClosureArgument $serviceClosureArgument) { $values = $serviceClosureArgument->getValues(); return array_shift($values); @@ -1112,7 +1112,7 @@ public function testMessengerMultipleFailureTransportsWithGlobalFailureTransport 'transport_3' => new Reference('messenger.transport.failure_transport_3'), ]; - $failureTransportsReferences = array_map(function (ServiceClosureArgument $serviceClosureArgument) { + $failureTransportsReferences = array_map(static function (ServiceClosureArgument $serviceClosureArgument) { $values = $serviceClosureArgument->getValues(); return array_shift($values); @@ -1186,7 +1186,7 @@ public function testMessengerTransports() 'schedule' => new Reference('messenger.transport.failed'), ]; - $failureTransportsReferences = array_map(function (ServiceClosureArgument $serviceClosureArgument) { + $failureTransportsReferences = array_map(static function (ServiceClosureArgument $serviceClosureArgument) { $values = $serviceClosureArgument->getValues(); return array_shift($values); @@ -1422,7 +1422,7 @@ public function testTranslator() $nonExistingDirectories = array_filter( $options['scanned_directories'], - fn ($directory) => !file_exists($directory) + static fn ($directory) => !file_exists($directory) ); $this->assertNotEmpty($nonExistingDirectories, 'FrameworkBundle should pass non existing directories to Translator'); @@ -1531,7 +1531,7 @@ public function testAnnotations() $this->expectException(InvalidConfigurationException::class); $this->expectExceptionMessage('Invalid configuration for path "framework.annotations": Enabling the doctrine/annotations integration is not supported anymore.'); - $this->createContainerFromClosure(function (ContainerBuilder $container) { + $this->createContainerFromClosure(static function (ContainerBuilder $container) { $container->loadFromExtension('framework', [ 'annotations' => true, ]); @@ -2584,7 +2584,7 @@ public function testLocaleSwitcherServiceRegistered() $this->assertSame('kernel.locale_aware', $switcherDef->getArgument(1)->getTag()); $this->assertEquals(new Reference('router.request_context', ContainerBuilder::IGNORE_ON_INVALID_REFERENCE), $switcherDef->getArgument(2)); - $localeAwareServices = array_map(fn (Reference $r) => (string) $r, $switcherDef->getArgument(1)->getValues()); + $localeAwareServices = array_map(static fn (Reference $r) => (string) $r, $switcherDef->getArgument(1)->getValues()); $this->assertNotContains('translation.locale_switcher', $localeAwareServices); } @@ -2870,7 +2870,7 @@ public function testJsonStreamerEnabled() public function testObjectMapperEnabled() { - $container = $this->createContainerFromClosure(function (ContainerBuilder $container) { + $container = $this->createContainerFromClosure(static function (ContainerBuilder $container) { $container->loadFromExtension('framework', []); }); $this->assertTrue($container->has('object_mapper')); diff --git a/Tests/DependencyInjection/PhpFrameworkExtensionTest.php b/Tests/DependencyInjection/PhpFrameworkExtensionTest.php index dcd5d347c..03d1b9b0e 100644 --- a/Tests/DependencyInjection/PhpFrameworkExtensionTest.php +++ b/Tests/DependencyInjection/PhpFrameworkExtensionTest.php @@ -38,7 +38,7 @@ protected function loadFromFile(ContainerBuilder $container, $file) public function testAssetsCannotHavePathAndUrl() { $this->expectException(\LogicException::class); - $this->createContainerFromClosure(function ($container) { + $this->createContainerFromClosure(static function ($container) { $container->loadFromExtension('framework', [ 'annotations' => false, 'http_method_override' => false, @@ -55,7 +55,7 @@ public function testAssetsCannotHavePathAndUrl() public function testAssetPackageCannotHavePathAndUrl() { $this->expectException(\LogicException::class); - $this->createContainerFromClosure(function ($container) { + $this->createContainerFromClosure(static function ($container) { $container->loadFromExtension('framework', [ 'annotations' => false, 'http_method_override' => false, @@ -77,7 +77,7 @@ public function testWorkflowValidationStateMachine() { $this->expectException(InvalidDefinitionException::class); $this->expectExceptionMessage('A transition from a place/state must have an unique name. Multiple transitions named "a_to_b" from place/state "a" were found on StateMachine "article".'); - $this->createContainerFromClosure(function (ContainerBuilder $container) { + $this->createContainerFromClosure(static function (ContainerBuilder $container) { $container->loadFromExtension('framework', [ 'annotations' => false, 'http_method_override' => false, @@ -112,7 +112,7 @@ public function testWorkflowValidationCustomBroken(string $class, string $messag { $this->expectException(InvalidConfigurationException::class); $this->expectExceptionMessage($message); - $this->createContainerFromClosure(function ($container) use ($class) { + $this->createContainerFromClosure(static function ($container) use ($class) { $container->loadFromExtension('framework', [ 'annotations' => false, 'http_method_override' => false, @@ -154,7 +154,7 @@ public static function provideWorkflowValidationCustomTests() public function testWorkflowDefaultMarkingStoreDefinition() { - $container = $this->createContainerFromClosure(function ($container) { + $container = $this->createContainerFromClosure(static function ($container) { $container->loadFromExtension('framework', [ 'annotations' => false, 'http_method_override' => false, @@ -215,7 +215,7 @@ public function testWorkflowDefaultMarkingStoreDefinition() public function testRateLimiterLockFactoryWithLockDisabled() { try { - $this->createContainerFromClosure(function (ContainerBuilder $container) { + $this->createContainerFromClosure(static function (ContainerBuilder $container) { $container->loadFromExtension('framework', [ 'annotations' => false, 'http_method_override' => false, @@ -236,7 +236,7 @@ public function testRateLimiterLockFactoryWithLockDisabled() public function testRateLimiterAutoLockFactoryWithLockEnabled() { - $container = $this->createContainerFromClosure(function (ContainerBuilder $container) { + $container = $this->createContainerFromClosure(static function (ContainerBuilder $container) { $container->loadFromExtension('framework', [ 'annotations' => false, 'http_method_override' => false, @@ -255,7 +255,7 @@ public function testRateLimiterAutoLockFactoryWithLockEnabled() public function testRateLimiterAutoLockFactoryWithLockDisabled() { - $container = $this->createContainerFromClosure(function (ContainerBuilder $container) { + $container = $this->createContainerFromClosure(static function (ContainerBuilder $container) { $container->loadFromExtension('framework', [ 'annotations' => false, 'http_method_override' => false, @@ -276,7 +276,7 @@ public function testRateLimiterAutoLockFactoryWithLockDisabled() public function testRateLimiterDisableLockFactory() { - $container = $this->createContainerFromClosure(function (ContainerBuilder $container) { + $container = $this->createContainerFromClosure(static function (ContainerBuilder $container) { $container->loadFromExtension('framework', [ 'annotations' => false, 'http_method_override' => false, @@ -297,7 +297,7 @@ public function testRateLimiterDisableLockFactory() public function testRateLimiterIsTagged() { - $container = $this->createContainerFromClosure(function (ContainerBuilder $container) { + $container = $this->createContainerFromClosure(static function (ContainerBuilder $container) { $container->loadFromExtension('framework', [ 'annotations' => false, 'http_method_override' => false, @@ -321,7 +321,7 @@ public function testRateLimiterCompoundPolicy() $this->markTestSkipped('CompoundRateLimiterFactory is not available.'); } - $container = $this->createContainerFromClosure(function (ContainerBuilder $container) { + $container = $this->createContainerFromClosure(static function (ContainerBuilder $container) { $container->loadFromExtension('framework', [ 'annotations' => false, 'http_method_override' => false, @@ -368,7 +368,7 @@ public function testRateLimiterCompoundPolicyNoLimiters() } $this->expectException(\LogicException::class); - $this->createContainerFromClosure(function ($container) { + $this->createContainerFromClosure(static function ($container) { $container->loadFromExtension('framework', [ 'annotations' => false, 'http_method_override' => false, @@ -388,7 +388,7 @@ public function testRateLimiterCompoundPolicyInvalidLimiters() } $this->expectException(\LogicException::class); - $this->createContainerFromClosure(function ($container) { + $this->createContainerFromClosure(static function ($container) { $container->loadFromExtension('framework', [ 'annotations' => false, 'http_method_override' => false, @@ -406,7 +406,7 @@ public function testValidatorEmailValidationMode(string $mode) { $this->expectNotToPerformAssertions(); - $this->createContainerFromClosure(function (ContainerBuilder $container) use ($mode) { + $this->createContainerFromClosure(static function (ContainerBuilder $container) use ($mode) { $container->loadFromExtension('framework', [ 'annotations' => false, 'http_method_override' => false, @@ -429,7 +429,7 @@ public static function emailValidationModeProvider() public function testMessengerSigningSerializerWiring() { - $container = $this->createContainerFromClosure(function (ContainerBuilder $container) { + $container = $this->createContainerFromClosure(static function (ContainerBuilder $container) { $container->register('signed_handler', 'stdClass') ->addTag('messenger.message_handler', ['handles' => DummyMessage::class, 'sign' => true]); diff --git a/Tests/Fixtures/ObjectMapper/CollectionSource.php b/Tests/Fixtures/ObjectMapper/CollectionSource.php new file mode 100644 index 000000000..6c6fe6a5c --- /dev/null +++ b/Tests/Fixtures/ObjectMapper/CollectionSource.php @@ -0,0 +1,28 @@ + + * + * 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\ObjectMapper; + +use Symfony\Component\ObjectMapper\Attribute\Map; +use Symfony\Component\ObjectMapper\Transform\MapCollection; + +#[Map(target: CollectionTarget::class)] +final class CollectionSource +{ + /** + * @param CollectionSourceItem[] $items + */ + public function __construct( + #[Map(transform: MapCollection::class)] + public array $items, + ) { + } +} diff --git a/Tests/Fixtures/ObjectMapper/CollectionSourceItem.php b/Tests/Fixtures/ObjectMapper/CollectionSourceItem.php new file mode 100644 index 000000000..8b84859c3 --- /dev/null +++ b/Tests/Fixtures/ObjectMapper/CollectionSourceItem.php @@ -0,0 +1,28 @@ + + * + * 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\ObjectMapper; + +use Symfony\Component\ObjectMapper\Attribute\Map; + +#[Map(target: CollectionTargetItem::class)] +final class CollectionSourceItem +{ + public function __construct( + private string $name, + ) { + } + + public function getName(): string + { + return $this->name; + } +} diff --git a/Tests/Fixtures/ObjectMapper/CollectionTarget.php b/Tests/Fixtures/ObjectMapper/CollectionTarget.php new file mode 100644 index 000000000..cb5fb881b --- /dev/null +++ b/Tests/Fixtures/ObjectMapper/CollectionTarget.php @@ -0,0 +1,18 @@ + + * + * 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\ObjectMapper; + +final class CollectionTarget +{ + /** @var CollectionTargetItem[] */ + public array $items; +} diff --git a/Tests/Fixtures/ObjectMapper/CollectionTargetItem.php b/Tests/Fixtures/ObjectMapper/CollectionTargetItem.php new file mode 100644 index 000000000..84ade6901 --- /dev/null +++ b/Tests/Fixtures/ObjectMapper/CollectionTargetItem.php @@ -0,0 +1,27 @@ + + * + * 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\ObjectMapper; + +final class CollectionTargetItem +{ + private string $name; + + public function setName(string $name): void + { + $this->name = $name; + } + + public function getName(): string + { + return $this->name; + } +} diff --git a/Tests/Functional/AbstractWebTestCase.php b/Tests/Functional/AbstractWebTestCase.php index 17ff5ed73..fce333120 100644 --- a/Tests/Functional/AbstractWebTestCase.php +++ b/Tests/Functional/AbstractWebTestCase.php @@ -36,12 +36,13 @@ public static function tearDownAfterClass(): void protected static function deleteTmpDir() { - if (!file_exists($dir = sys_get_temp_dir().'/'.static::getVarDir())) { - return; + $fs = new Filesystem(); + + if (file_exists($dir = sys_get_temp_dir().'/'.static::getVarDir())) { + $fs->remove($dir); } - $fs = new Filesystem(); - $fs->remove($dir); + $fs->remove(__DIR__.'/app/config/reference.php'); } protected static function getKernelClass(): string diff --git a/Tests/Functional/Bundle/TestBundle/MimeType/CustomMimeTypeGuesser.php b/Tests/Functional/Bundle/TestBundle/MimeType/CustomMimeTypeGuesser.php new file mode 100644 index 000000000..97451a7ef --- /dev/null +++ b/Tests/Functional/Bundle/TestBundle/MimeType/CustomMimeTypeGuesser.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\MimeType; + +use Symfony\Component\Mime\MimeTypeGuesserInterface; + +class CustomMimeTypeGuesser implements MimeTypeGuesserInterface +{ + public const FAKE_MIME_TYPE = 'application/x-test-custom-guesser'; + + public function isGuesserSupported(): bool + { + return true; + } + + public function guessMimeType(string $path): ?string + { + return self::FAKE_MIME_TYPE; + } +} diff --git a/Tests/Functional/CacheAttributeListenerTest.php b/Tests/Functional/CacheAttributeListenerTest.php index e6eb93eba..69b37743d 100644 --- a/Tests/Functional/CacheAttributeListenerTest.php +++ b/Tests/Functional/CacheAttributeListenerTest.php @@ -25,7 +25,7 @@ public function testAnonimousUserWithEtag() { $client = self::createClient(['test_case' => 'CacheAttributeListener']); - $client->request('GET', '/', server: ['HTTP_IF_NONE_MATCH' => \sprintf('"%s"', hash('sha256', '12345'))]); + $client->request('GET', '/', [], [], ['HTTP_IF_NONE_MATCH' => \sprintf('"%s"', hash('sha256', '12345'))]); self::assertTrue($client->getResponse()->isRedirect('http://localhost/login')); } @@ -44,7 +44,7 @@ public function testLoggedInUserWithEtag() $client = self::createClient(['test_case' => 'CacheAttributeListener']); $client->loginUser(new InMemoryUser('the-username', 'the-password', ['ROLE_USER'])); - $client->request('GET', '/', server: ['HTTP_IF_NONE_MATCH' => \sprintf('"%s"', hash('sha256', '12345'))]); + $client->request('GET', '/', [], [], ['HTTP_IF_NONE_MATCH' => \sprintf('"%s"', hash('sha256', '12345'))]); $response = $client->getResponse(); diff --git a/Tests/Functional/HttpClientTest.php b/Tests/Functional/HttpClientTest.php index fcce53704..5280e5de7 100644 --- a/Tests/Functional/HttpClientTest.php +++ b/Tests/Functional/HttpClientTest.php @@ -24,13 +24,13 @@ public function testHttpClientAssertions() $client->request('GET', '/http_client_call'); $this->assertHttpClientRequest('https://symfony.com/'); - $this->assertHttpClientRequest('https://symfony.com/', httpClientId: 'symfony.http_client'); - $this->assertHttpClientRequest('https://symfony.com/', 'POST', 'foo', httpClientId: 'symfony.http_client'); - $this->assertHttpClientRequest('https://symfony.com/', 'POST', ['foo' => 'bar'], httpClientId: 'symfony.http_client'); - $this->assertHttpClientRequest('https://symfony.com/', 'POST', ['foo' => 'bar'], httpClientId: 'symfony.http_client'); + $this->assertHttpClientRequest('https://symfony.com/', 'GET', null, [], 'symfony.http_client'); + $this->assertHttpClientRequest('https://symfony.com/', 'POST', 'foo', [], 'symfony.http_client'); + $this->assertHttpClientRequest('https://symfony.com/', 'POST', ['foo' => 'bar'], [], 'symfony.http_client'); + $this->assertHttpClientRequest('https://symfony.com/', 'POST', ['foo' => 'bar'], [], 'symfony.http_client'); $this->assertHttpClientRequest('https://symfony.com/', 'POST', ['foo' => 'bar'], ['X-Test-Header' => 'foo'], 'symfony.http_client'); - $this->assertHttpClientRequest('https://symfony.com/doc/current/index.html', httpClientId: 'symfony.http_client'); - $this->assertNotHttpClientRequest('https://laravel.com', httpClientId: 'symfony.http_client'); + $this->assertHttpClientRequest('https://symfony.com/doc/current/index.html', 'GET', null, [], 'symfony.http_client'); + $this->assertNotHttpClientRequest('https://laravel.com', 'GET', 'symfony.http_client'); $this->assertHttpClientRequestCount(6, 'symfony.http_client'); } diff --git a/Tests/Functional/KernelTestCaseFreshCacheTest.php b/Tests/Functional/KernelTestCaseFreshCacheTest.php index a65f68833..fd9f4d224 100644 --- a/Tests/Functional/KernelTestCaseFreshCacheTest.php +++ b/Tests/Functional/KernelTestCaseFreshCacheTest.php @@ -43,7 +43,7 @@ public function testContainerIsRebuiltWhenTrackedFileAppears() static::ensureKernelShutdown(); // Create the tracked file between boots - @mkdir(\dirname(self::$trackedFile), 0777, true); + @mkdir(\dirname(self::$trackedFile), 0o777, true); file_put_contents(self::$trackedFile, 'placeholder'); // Reboot: should detect the resource change and rebuild the container diff --git a/Tests/Functional/MimeTypeGuesserBootTest.php b/Tests/Functional/MimeTypeGuesserBootTest.php new file mode 100644 index 000000000..89556d98f --- /dev/null +++ b/Tests/Functional/MimeTypeGuesserBootTest.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Functional; + +use PHPUnit\Framework\Attributes\Group; +use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\MimeType\CustomMimeTypeGuesser; +use Symfony\Component\Mime\MimeTypes; + +#[Group('functional')] +class MimeTypeGuesserBootTest extends AbstractWebTestCase +{ + /** + * Verifies that booting the kernel eagerly instantiates the "mime_types" service, + * so that MimeTypes::setDefault() fires before any code calls MimeTypes::getDefault(). + * + * Without this, File::getMimeType() (and any other static call site) silently + * falls back to a fresh, default-only MimeTypes instance, dropping every guesser + * tagged "mime.mime_type_guesser" in the container. + */ + public function testCustomGuesserIsAppliedAfterKernelBootEvenWithoutExplicitContainerLookup() + { + // Reset the MimeTypes static default so any prior test cannot leak its instance + // into this one. Replace it with a fresh, default-only MimeTypes — mimicking the + // "no DI container has touched it yet" runtime state described in the bug report. + $defaultProperty = new \ReflectionProperty(MimeTypes::class, 'default'); + $defaultProperty->setValue(null, new MimeTypes()); + + $kernel = static::createKernel(['test_case' => 'MimeType', 'root_config' => 'config.yml']); + $kernel->boot(); + + // Intentionally do NOT call $kernel->getContainer()->get('mime_types') — + // the bug being covered is that nothing in the request lifecycle fetches + // it, leaving MimeTypes::getDefault() pointing at a fresh, default-only + // instance that ignores every container-tagged guesser. + $this->assertSame(CustomMimeTypeGuesser::FAKE_MIME_TYPE, MimeTypes::getDefault()->guessMimeType(__FILE__)); + } +} diff --git a/Tests/Functional/ObjectMapperTest.php b/Tests/Functional/ObjectMapperTest.php index e314ee1b0..597abb529 100644 --- a/Tests/Functional/ObjectMapperTest.php +++ b/Tests/Functional/ObjectMapperTest.php @@ -11,6 +11,9 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Functional; +use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\ObjectMapper\CollectionSource; +use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\ObjectMapper\CollectionSourceItem; +use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\ObjectMapper\CollectionTarget; use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\ObjectMapper\ObjectMapped; use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\ObjectMapper\ObjectToBeMapped; @@ -28,4 +31,22 @@ public function testObjectMapper() $mapped = $objectMapper->map(new ObjectToBeMapped()); $this->assertSame($mapped->a, 'transformed'); } + + public function testMapCollectionUsesContainerObjectMapper() + { + static::bootKernel(['test_case' => 'ObjectMapper']); + + $objectMapper = static::getContainer()->get('object_mapper.alias'); + $source = new CollectionSource([ + new CollectionSourceItem('foo'), + new CollectionSourceItem('bar'), + ]); + + /** @var CollectionTarget $mapped */ + $mapped = $objectMapper->map($source); + + $this->assertCount(2, $mapped->items); + $this->assertSame('foo', $mapped->items[0]->getName()); + $this->assertSame('bar', $mapped->items[1]->getName()); + } } diff --git a/Tests/Functional/app/MimeType/bundles.php b/Tests/Functional/app/MimeType/bundles.php new file mode 100644 index 000000000..15ff182c6 --- /dev/null +++ b/Tests/Functional/app/MimeType/bundles.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Bundle\FrameworkBundle\FrameworkBundle; +use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestBundle; + +return [ + new FrameworkBundle(), + new TestBundle(), +]; diff --git a/Tests/Functional/app/MimeType/config.yml b/Tests/Functional/app/MimeType/config.yml new file mode 100644 index 000000000..0074474a0 --- /dev/null +++ b/Tests/Functional/app/MimeType/config.yml @@ -0,0 +1,3 @@ +imports: + - { resource: ../config/default.yml } + - { resource: services.yml } diff --git a/Tests/Functional/app/MimeType/services.yml b/Tests/Functional/app/MimeType/services.yml new file mode 100644 index 000000000..d6c7e3846 --- /dev/null +++ b/Tests/Functional/app/MimeType/services.yml @@ -0,0 +1,6 @@ +services: + _defaults: + public: true + + Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\MimeType\CustomMimeTypeGuesser: + tags: ['mime.mime_type_guesser'] diff --git a/Tests/Functional/app/ObjectMapper/config.yml b/Tests/Functional/app/ObjectMapper/config.yml index 3e3bd8702..e76600505 100644 --- a/Tests/Functional/app/ObjectMapper/config.yml +++ b/Tests/Functional/app/ObjectMapper/config.yml @@ -7,3 +7,5 @@ services: public: true Symfony\Bundle\FrameworkBundle\Tests\Fixtures\ObjectMapper\TransformCallable: autoconfigure: true + Symfony\Component\ObjectMapper\Transform\MapCollection: + autoconfigure: true diff --git a/Tests/Secrets/SodiumVaultTest.php b/Tests/Secrets/SodiumVaultTest.php index 6d050386b..48f55e04a 100644 --- a/Tests/Secrets/SodiumVaultTest.php +++ b/Tests/Secrets/SodiumVaultTest.php @@ -92,7 +92,7 @@ public function testEmptySecretEnvVar() $envVars['MY_SECRET'] = (string) $envVars['MY_SECRET']; $this->assertSame(['MY_SECRET' => ''], $envVars); - $vault = new SodiumVault($this->secretsDir, LazyString::fromCallable(fn () => ''), 'MY_SECRET'); + $vault = new SodiumVault($this->secretsDir, LazyString::fromCallable(static fn () => ''), 'MY_SECRET'); $envVars = $vault->loadEnvVars(); $envVars['MY_SECRET'] = (string) $envVars['MY_SECRET']; $this->assertSame(['MY_SECRET' => ''], $envVars); diff --git a/composer.json b/composer.json index 72b8a1b0a..1c6a021a9 100644 --- a/composer.json +++ b/composer.json @@ -54,7 +54,7 @@ "symfony/lock": "^6.4|^7.0|^8.0", "symfony/mailer": "^6.4|^7.0|^8.0", "symfony/messenger": "^7.4|^8.0", - "symfony/mime": "^6.4|^7.0|^8.0", + "symfony/mime": "^6.4.37|^7.4.9|^8.0.9", "symfony/notifier": "^6.4|^7.0|^8.0", "symfony/object-mapper": "^7.3|^8.0", "symfony/process": "^6.4|^7.0|^8.0", @@ -94,7 +94,7 @@ "symfony/lock": "<6.4", "symfony/mailer": "<6.4", "symfony/messenger": "<7.4", - "symfony/mime": "<6.4", + "symfony/mime": "<6.4.37|>=7.0,<7.4.9|>=8.0,<8.0.9", "symfony/property-info": "<6.4", "symfony/property-access": "<6.4", "symfony/runtime": "<6.4.13|>=7.0,<7.1.6", diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 067a87c3a..a7cde67a2 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,7 +1,7 @@ - + trigger_deprecation Doctrine\Deprecations\Deprecation::trigger Doctrine\Deprecations\Deprecation::triggerIfCalledFromOutside