From 8728589b0f89ecbcfc8b814537e691f64450d56e Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Tue, 20 Jun 2023 21:43:52 +0200 Subject: [PATCH] Add type-hints and return types --- bundles/configuration.rst | 4 +- cache.rst | 6 +-- components/cache.rst | 4 +- components/cache/cache_invalidation.rst | 2 +- components/cache/cache_items.rst | 2 +- components/cache/cache_pools.rst | 2 +- components/config/definition.rst | 2 +- components/console/events.rst | 14 ++--- .../console/helpers/debug_formatter.rst | 2 +- components/console/helpers/processhelper.rst | 2 +- components/console/helpers/progressbar.rst | 2 +- components/console/helpers/questionhelper.rst | 52 +++++++++---------- components/console/single_command_tool.rst | 2 +- components/dom_crawler.rst | 8 +-- components/event_dispatcher.rst | 2 +- .../event_dispatcher/immutable_dispatcher.rst | 3 +- components/expression_language.rst | 8 +-- components/finder.rst | 4 +- components/form.rst | 2 +- components/http_foundation.rst | 2 +- components/http_kernel.rst | 2 +- components/options_resolver.rst | 22 ++++---- components/process.rst | 6 +-- components/runtime.rst | 32 ++++++------ components/serializer.rst | 6 +-- components/string.rst | 6 +-- components/var_dumper.rst | 6 +-- configuration.rst | 4 +- .../front_controllers_and_kernel.rst | 2 +- configuration/multiple_kernels.rst | 4 +- configuration/override_dir_structure.rst | 2 +- configuration/secrets.rst | 2 +- console/input.rst | 2 +- console/lazy_commands.rst | 6 ++- console/style.rst | 4 +- controller/error_pages.rst | 2 +- controller/service.rst | 2 +- create_framework/event_dispatcher.rst | 6 +-- .../http_kernel_httpkernel_class.rst | 2 +- create_framework/templating.rst | 6 +-- doctrine/custom_dql_functions.rst | 4 +- doctrine/dbal.rst | 4 +- doctrine/multiple_entity_managers.rst | 4 +- doctrine/resolve_target_entity.rst | 2 +- form/bootstrap4.rst | 2 +- form/create_custom_field_type.rst | 2 +- form/data_based_validation.rst | 4 +- form/dynamic_form_modification.rst | 18 +++---- form/events.rst | 2 +- form/form_themes.rst | 4 +- forms.rst | 2 +- http_cache.rst | 2 +- http_client.rst | 14 ++--- logging.rst | 6 +-- logging/channels_handlers.rst | 4 +- logging/formatter.rst | 2 +- logging/handlers.rst | 2 +- logging/monolog_console.rst | 2 +- logging/monolog_email.rst | 6 +-- logging/monolog_exclude_http_codes.rst | 2 +- logging/processors.rst | 2 +- mailer.rst | 4 +- migration.rst | 4 +- notifier.rst | 6 +-- quick_tour/the_architecture.rst | 2 +- reference/configuration/doctrine.rst | 4 +- reference/configuration/security.rst | 14 ++--- reference/configuration/twig.rst | 6 +-- reference/constraints/Callback.rst | 2 +- reference/forms/types/choice.rst | 10 ++-- reference/forms/types/collection.rst | 2 +- reference/forms/types/entity.rst | 4 +- .../forms/types/options/choice_attr.rst.inc | 4 +- .../forms/types/options/choice_filter.rst.inc | 4 +- .../forms/types/options/choice_label.rst.inc | 2 +- .../forms/types/options/choice_loader.rst.inc | 4 +- .../choice_translation_parameters.rst.inc | 2 +- .../forms/types/options/choice_value.rst.inc | 2 +- .../types/options/preferred_choices.rst.inc | 2 +- .../types/options/validation_groups.rst.inc | 2 +- routing.rst | 46 ++++++++-------- routing/custom_route_loader.rst | 8 +-- security.rst | 8 +-- security/access_control.rst | 8 +-- security/access_denied_handler.rst | 4 +- security/access_token.rst | 8 +-- security/custom_authenticator.rst | 6 +-- security/entry_point.rst | 4 +- security/firewall_restriction.rst | 8 +-- security/force_https.rst | 2 +- security/form_login.rst | 10 ++-- security/impersonating_user.rst | 10 ++-- security/ldap.rst | 8 +-- security/login_link.rst | 14 ++--- security/passwords.rst | 12 ++--- security/remember_me.rst | 10 ++-- security/user_checkers.rst | 4 +- security/voters.rst | 6 +-- templates.rst | 12 ++--- testing.rst | 2 +- testing/dom_crawler.rst | 6 ++- translation.rst | 2 +- 102 files changed, 312 insertions(+), 305 deletions(-) diff --git a/bundles/configuration.rst b/bundles/configuration.rst index 6933f7eb794..bc9efc1e0b9 100644 --- a/bundles/configuration.rst +++ b/bundles/configuration.rst @@ -85,7 +85,7 @@ can add some configuration that looks like this: // config/packages/acme_social.php use Symfony\Config\AcmeSocialConfig; - return static function (AcmeSocialConfig $acmeSocial) { + return static function (AcmeSocialConfig $acmeSocial): void { $acmeSocial->twitter() ->clientId(123) ->clientSecret('your_secret'); @@ -394,7 +394,7 @@ logic to the bundle class directly:: // config/definition.php use Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator; - return static function (DefinitionConfigurator $definition) { + return static function (DefinitionConfigurator $definition): void { $definition->rootNode() ->children() ->scalarNode('foo')->defaultValue('bar')->end() diff --git a/cache.rst b/cache.rst index f9d7175cf41..bddec08cbc8 100644 --- a/cache.rst +++ b/cache.rst @@ -10,7 +10,7 @@ The following example shows a typical usage of the cache:: use Symfony\Contracts\Cache\ItemInterface; // The callable will only be executed on a cache miss. - $value = $pool->get('my_cache_key', function (ItemInterface $item) { + $value = $pool->get('my_cache_key', function (ItemInterface $item): string { $item->expiresAfter(3600); // ... do some HTTP request or heavy computations @@ -557,13 +557,13 @@ the same key could be invalidated with one function call:: public function someMethod() { - $value0 = $this->myCachePool->get('item_0', function (ItemInterface $item) { + $value0 = $this->myCachePool->get('item_0', function (ItemInterface $item): string { $item->tag(['foo', 'bar']); return 'debug'; }); - $value1 = $this->myCachePool->get('item_1', function (ItemInterface $item) { + $value1 = $this->myCachePool->get('item_1', function (ItemInterface $item): string { $item->tag('foo'); return 'debug'; diff --git a/components/cache.rst b/components/cache.rst index 66514b6c898..20fa2426876 100644 --- a/components/cache.rst +++ b/components/cache.rst @@ -65,7 +65,7 @@ generate and return the value:: use Symfony\Contracts\Cache\ItemInterface; // The callable will only be executed on a cache miss. - $value = $cache->get('my_cache_key', function (ItemInterface $item) { + $value = $cache->get('my_cache_key', function (ItemInterface $item): string { $item->expiresAfter(3600); // ... do some HTTP request or heavy computations @@ -115,7 +115,7 @@ recompute:: use Symfony\Contracts\Cache\ItemInterface; $beta = 1.0; - $value = $cache->get('my_cache_key', function (ItemInterface $item) { + $value = $cache->get('my_cache_key', function (ItemInterface $item): string { $item->expiresAfter(3600); $item->tag(['tag_0', 'tag_1']); diff --git a/components/cache/cache_invalidation.rst b/components/cache/cache_invalidation.rst index 1005d2d09a7..da88ea6273e 100644 --- a/components/cache/cache_invalidation.rst +++ b/components/cache/cache_invalidation.rst @@ -24,7 +24,7 @@ To attach tags to cached items, you need to use the :method:`Symfony\\Contracts\\Cache\\ItemInterface::tag` method that is implemented by cache items:: - $item = $cache->get('cache_key', function (ItemInterface $item) { + $item = $cache->get('cache_key', function (ItemInterface $item): string { // [...] // add one or more tags $item->tag('tag_1'); diff --git a/components/cache/cache_items.rst b/components/cache/cache_items.rst index 9f020a39de9..715dc0c4401 100644 --- a/components/cache/cache_items.rst +++ b/components/cache/cache_items.rst @@ -27,7 +27,7 @@ The only way to create cache items is via cache pools. When using the Cache Contracts, they are passed as arguments to the recomputation callback:: // $cache pool object was created before - $productsCount = $cache->get('stats.products_count', function (ItemInterface $item) { + $productsCount = $cache->get('stats.products_count', function (ItemInterface $item): string { // [...] }); diff --git a/components/cache/cache_pools.rst b/components/cache/cache_pools.rst index 8d05cd268d5..0a7e966badc 100644 --- a/components/cache/cache_pools.rst +++ b/components/cache/cache_pools.rst @@ -38,7 +38,7 @@ and deleting cache items using only two methods and a callback:: $cache = new FilesystemAdapter(); // The callable will only be executed on a cache miss. - $value = $cache->get('my_cache_key', function (ItemInterface $item) { + $value = $cache->get('my_cache_key', function (ItemInterface $item): string { $item->expiresAfter(3600); // ... do some HTTP request or heavy computations diff --git a/components/config/definition.rst b/components/config/definition.rst index 5c8cc0dc0e0..8dab6d2163e 100644 --- a/components/config/definition.rst +++ b/components/config/definition.rst @@ -737,7 +737,7 @@ By changing a string value into an associative array with ``name`` as the key:: ->arrayNode('connection') ->beforeNormalization() ->ifString() - ->then(function ($v) { return ['name' => $v]; }) + ->then(function (string $v): array { return ['name' => $v]; }) ->end() ->children() ->scalarNode('name')->isRequired()->end() diff --git a/components/console/events.rst b/components/console/events.rst index 01b81d5a708..5e6f58a593f 100644 --- a/components/console/events.rst +++ b/components/console/events.rst @@ -33,7 +33,7 @@ dispatched. Listeners receive a use Symfony\Component\Console\ConsoleEvents; use Symfony\Component\Console\Event\ConsoleCommandEvent; - $dispatcher->addListener(ConsoleEvents::COMMAND, function (ConsoleCommandEvent $event) { + $dispatcher->addListener(ConsoleEvents::COMMAND, function (ConsoleCommandEvent $event): void { // gets the input instance $input = $event->getInput(); @@ -64,7 +64,7 @@ C/C++ standard:: use Symfony\Component\Console\ConsoleEvents; use Symfony\Component\Console\Event\ConsoleCommandEvent; - $dispatcher->addListener(ConsoleEvents::COMMAND, function (ConsoleCommandEvent $event) { + $dispatcher->addListener(ConsoleEvents::COMMAND, function (ConsoleCommandEvent $event): void { // gets the command to be executed $command = $event->getCommand(); @@ -97,7 +97,7 @@ Listeners receive a use Symfony\Component\Console\ConsoleEvents; use Symfony\Component\Console\Event\ConsoleErrorEvent; - $dispatcher->addListener(ConsoleEvents::ERROR, function (ConsoleErrorEvent $event) { + $dispatcher->addListener(ConsoleEvents::ERROR, function (ConsoleErrorEvent $event): void { $output = $event->getOutput(); $command = $event->getCommand(); @@ -131,7 +131,7 @@ Listeners receive a use Symfony\Component\Console\ConsoleEvents; use Symfony\Component\Console\Event\ConsoleTerminateEvent; - $dispatcher->addListener(ConsoleEvents::TERMINATE, function (ConsoleTerminateEvent $event) { + $dispatcher->addListener(ConsoleEvents::TERMINATE, function (ConsoleTerminateEvent $event): void { // gets the output $output = $event->getOutput(); @@ -170,11 +170,11 @@ Listeners receive a use Symfony\Component\Console\ConsoleEvents; use Symfony\Component\Console\Event\ConsoleSignalEvent; - $dispatcher->addListener(ConsoleEvents::SIGNAL, function (ConsoleSignalEvent $event) { - + $dispatcher->addListener(ConsoleEvents::SIGNAL, function (ConsoleSignalEvent $event): void { + // gets the signal number $signal = $event->getHandlingSignal(); - + if (\SIGINT === $signal) { echo "bye bye!"; } diff --git a/components/console/helpers/debug_formatter.rst b/components/console/helpers/debug_formatter.rst index a5567fe63ed..b2f6e9dfbde 100644 --- a/components/console/helpers/debug_formatter.rst +++ b/components/console/helpers/debug_formatter.rst @@ -78,7 +78,7 @@ using // ... $process = new Process(...); - $process->run(function ($type, $buffer) use ($output, $debugFormatter, $process) { + $process->run(function (string $type, string $buffer) use ($output, $debugFormatter, $process): void { $output->writeln( $debugFormatter->progress( spl_object_hash($process), diff --git a/components/console/helpers/processhelper.rst b/components/console/helpers/processhelper.rst index ef462cef731..51dbd016a0e 100644 --- a/components/console/helpers/processhelper.rst +++ b/components/console/helpers/processhelper.rst @@ -69,7 +69,7 @@ A custom process callback can be passed as the fourth argument. Refer to the use Symfony\Component\Process\Process; - $helper->run($output, $process, 'The process failed :(', function ($type, $data) { + $helper->run($output, $process, 'The process failed :(', function (string $type, string $data): void { if (Process::ERR === $type) { // ... do something with the stderr output } else { diff --git a/components/console/helpers/progressbar.rst b/components/console/helpers/progressbar.rst index 0dfb9b45a02..315b02a1d1b 100644 --- a/components/console/helpers/progressbar.rst +++ b/components/console/helpers/progressbar.rst @@ -336,7 +336,7 @@ that displays the number of remaining steps:: ProgressBar::setPlaceholderFormatterDefinition( 'remaining_steps', - function (ProgressBar $progressBar, OutputInterface $output) { + function (ProgressBar $progressBar, OutputInterface $output): int { return $progressBar->getMaxSteps() - $progressBar->getProgress(); } ); diff --git a/components/console/helpers/questionhelper.rst b/components/console/helpers/questionhelper.rst index eed00d74711..5729c112af1 100644 --- a/components/console/helpers/questionhelper.rst +++ b/components/console/helpers/questionhelper.rst @@ -82,9 +82,9 @@ if you want to know a bundle name, you can add this to your command:: $question = new Question('Please enter the name of the bundle', 'AcmeDemoBundle'); $bundleName = $helper->ask($input, $output, $question); - + // ... do something with the bundleName - + return Command::SUCCESS; } @@ -120,7 +120,7 @@ from a predefined list:: $output->writeln('You have just selected: '.$color); // ... do something with the color - + return Command::SUCCESS; } @@ -158,7 +158,7 @@ this use :method:`Symfony\\Component\\Console\\Question\\ChoiceQuestion::setMult $colors = $helper->ask($input, $output, $question); $output->writeln('You have just selected: ' . implode(', ', $colors)); - + return Command::SUCCESS; } @@ -187,9 +187,9 @@ will be autocompleted as the user types:: $question->setAutocompleterValues($bundles); $bundleName = $helper->ask($input, $output, $question); - + // ... do something with the bundleName - + return Command::SUCCESS; } @@ -217,7 +217,7 @@ provide a callback function to dynamically generate suggestions:: // where files and dirs can be found $foundFilesAndDirs = @scandir($inputPath) ?: []; - return array_map(function ($dirOrFile) use ($inputPath) { + return array_map(function (string $dirOrFile) use ($inputPath): void { return $inputPath.$dirOrFile; }, $foundFilesAndDirs); }; @@ -226,9 +226,9 @@ provide a callback function to dynamically generate suggestions:: $question->setAutocompleterCallback($callback); $filePath = $helper->ask($input, $output, $question); - + // ... do something with the filePath - + return Command::SUCCESS; } @@ -250,9 +250,9 @@ You can also specify if you want to not trim the answer by setting it directly w $question->setTrimmable(false); // if the users inputs 'elsa ' it will not be trimmed and you will get 'elsa ' as value $name = $helper->ask($input, $output, $question); - + // ... do something with the name - + return Command::SUCCESS; } @@ -276,9 +276,9 @@ the response to a question should allow multiline answers by passing ``true`` to $question->setMultiline(true); $answer = $helper->ask($input, $output, $question); - + // ... do something with the answer - + return Command::SUCCESS; } @@ -304,9 +304,9 @@ convenient for passwords:: $question->setHiddenFallback(false); $password = $helper->ask($input, $output, $question); - + // ... do something with the password - + return Command::SUCCESS; } @@ -338,7 +338,7 @@ convenient for passwords:: QuestionHelper::disableStty(); // ... - + return Command::SUCCESS; } @@ -361,15 +361,15 @@ method:: $helper = $this->getHelper('question'); $question = new Question('Please enter the name of the bundle', 'AcmeDemoBundle'); - $question->setNormalizer(function ($value) { + $question->setNormalizer(function (string $value): string { // $value can be null here return $value ? trim($value) : ''; }); $bundleName = $helper->ask($input, $output, $question); - + // ... do something with the bundleName - + return Command::SUCCESS; } @@ -399,7 +399,7 @@ method:: $helper = $this->getHelper('question'); $question = new Question('Please enter the name of the bundle', 'AcmeDemoBundle'); - $question->setValidator(function ($answer) { + $question->setValidator(function (string $answer): string { if (!is_string($answer) || 'Bundle' !== substr($answer, -6)) { throw new \RuntimeException( 'The name of the bundle should be suffixed with \'Bundle\'' @@ -411,9 +411,9 @@ method:: $question->setMaxAttempts(2); $bundleName = $helper->ask($input, $output, $question); - + // ... do something with the bundleName - + return Command::SUCCESS; } @@ -459,10 +459,10 @@ You can also use a validator with a hidden question:: $helper = $this->getHelper('question'); $question = new Question('Please enter your password'); - $question->setNormalizer(function ($value) { + $question->setNormalizer(function (?string $value): string { return $value ?? ''; }); - $question->setValidator(function ($value) { + $question->setValidator(function (string $value): void { if ('' === trim($value)) { throw new \Exception('The password cannot be empty'); } @@ -473,9 +473,9 @@ You can also use a validator with a hidden question:: $question->setMaxAttempts(20); $password = $helper->ask($input, $output, $question); - + // ... do something with the password - + return Command::SUCCESS; } diff --git a/components/console/single_command_tool.rst b/components/console/single_command_tool.rst index a6c458afb94..97cb09bf030 100644 --- a/components/console/single_command_tool.rst +++ b/components/console/single_command_tool.rst @@ -20,7 +20,7 @@ it is possible to remove this need by declaring a single command application:: ->setVersion('1.0.0') // Optional ->addArgument('foo', InputArgument::OPTIONAL, 'The directory') ->addOption('bar', null, InputOption::VALUE_REQUIRED) - ->setCode(function (InputInterface $input, OutputInterface $output) { + ->setCode(function (InputInterface $input, OutputInterface $output): int { // output arguments and options }) ->run(); diff --git a/components/dom_crawler.rst b/components/dom_crawler.rst index fd9b47a1d59..b7038e5088f 100644 --- a/components/dom_crawler.rst +++ b/components/dom_crawler.rst @@ -89,9 +89,9 @@ An anonymous function can be used to filter with more complex criteria:: $crawler = $crawler ->filter('body > p') - ->reduce(function (Crawler $node, $i) { + ->reduce(function (Crawler $node, $i): bool { // filters every other node - return ($i % 2) == 0; + return ($i % 2) === 0; }); To remove a node, the anonymous function must return ``false``. @@ -242,7 +242,7 @@ Call an anonymous function on each node of the list:: use Symfony\Component\DomCrawler\Crawler; // ... - $nodeValues = $crawler->filter('p')->each(function (Crawler $node, $i) { + $nodeValues = $crawler->filter('p')->each(function (Crawler $node, $i): string { return $node->text(); }); @@ -252,7 +252,7 @@ The result is an array of values returned by the anonymous function calls. When using nested crawler, beware that ``filterXPath()`` is evaluated in the context of the crawler:: - $crawler->filterXPath('parent')->each(function (Crawler $parentCrawler, $i) { + $crawler->filterXPath('parent')->each(function (Crawler $parentCrawler, $i): avoid { // DON'T DO THIS: direct child can not be found $subCrawler = $parentCrawler->filterXPath('sub-tag/sub-child-tag'); diff --git a/components/event_dispatcher.rst b/components/event_dispatcher.rst index f545d9802b7..68d7a5f39e6 100644 --- a/components/event_dispatcher.rst +++ b/components/event_dispatcher.rst @@ -147,7 +147,7 @@ The ``addListener()`` method takes up to three arguments: use Symfony\Contracts\EventDispatcher\Event; - $dispatcher->addListener('acme.foo.action', function (Event $event) { + $dispatcher->addListener('acme.foo.action', function (Event $event): void { // will be executed when the acme.foo.action event is dispatched }); diff --git a/components/event_dispatcher/immutable_dispatcher.rst b/components/event_dispatcher/immutable_dispatcher.rst index 0a930352bfe..a6a98c47f37 100644 --- a/components/event_dispatcher/immutable_dispatcher.rst +++ b/components/event_dispatcher/immutable_dispatcher.rst @@ -13,9 +13,10 @@ To use it, first create a normal ``EventDispatcher`` dispatcher and register some listeners or subscribers:: use Symfony\Component\EventDispatcher\EventDispatcher; + use Symfony\Contracts\EventDispatcher\Event; $dispatcher = new EventDispatcher(); - $dispatcher->addListener('foo.action', function ($event) { + $dispatcher->addListener('foo.action', function (Event $event): void { // ... }); diff --git a/components/expression_language.rst b/components/expression_language.rst index 3f79c57707d..f936efdb112 100644 --- a/components/expression_language.rst +++ b/components/expression_language.rst @@ -284,9 +284,9 @@ Example:: use Symfony\Component\ExpressionLanguage\ExpressionLanguage; $expressionLanguage = new ExpressionLanguage(); - $expressionLanguage->register('lowercase', function ($str) { + $expressionLanguage->register('lowercase', function ($str): string { return sprintf('(is_string(%1$s) ? strtolower(%1$s) : %1$s)', $str); - }, function ($arguments, $str) { + }, function ($arguments, $str): string { if (!is_string($str)) { return $str; } @@ -325,9 +325,9 @@ register:: public function getFunctions() { return [ - new ExpressionFunction('lowercase', function ($str) { + new ExpressionFunction('lowercase', function ($str): string { return sprintf('(is_string(%1$s) ? strtolower(%1$s) : %1$s)', $str); - }, function ($arguments, $str) { + }, function ($arguments, $str): string { if (!is_string($str)) { return $str; } diff --git a/components/finder.rst b/components/finder.rst index a1809521419..27dd6709b6d 100644 --- a/components/finder.rst +++ b/components/finder.rst @@ -351,7 +351,7 @@ Sort the results by name, extension, size or type (directories first, then files function (e.g. ``file1.txt``, ``file10.txt``, ``file2.txt``). Pass ``true`` as its argument to use PHP's `natural sort order`_ algorithm instead (e.g. ``file1.txt``, ``file2.txt``, ``file10.txt``). - + The ``sortByCaseInsensitiveName()`` method uses the case insensitive :phpfunction:`strcasecmp` PHP function. Pass ``true`` as its argument to use PHP's case insensitive `natural sort order`_ algorithm instead (i.e. the @@ -367,7 +367,7 @@ Sort the files and directories by the last accessed, changed or modified time:: You can also define your own sorting algorithm with the ``sort()`` method:: - $finder->sort(function (\SplFileInfo $a, \SplFileInfo $b) { + $finder->sort(function (\SplFileInfo $a, \SplFileInfo $b): int { return strcmp($a->getRealPath(), $b->getRealPath()); }); diff --git a/components/form.rst b/components/form.rst index 2f7b874d7bf..79763fcacbe 100644 --- a/components/form.rst +++ b/components/form.rst @@ -204,7 +204,7 @@ to bootstrap or access Twig and add the :class:`Symfony\\Bridge\\Twig\\Extension ])); $formEngine = new TwigRendererEngine([$defaultFormTheme], $twig); $twig->addRuntimeLoader(new FactoryRuntimeLoader([ - FormRenderer::class => function () use ($formEngine, $csrfManager) { + FormRenderer::class => function () use ($formEngine, $csrfManager): FormRenderer { return new FormRenderer($formEngine, $csrfManager); }, ])); diff --git a/components/http_foundation.rst b/components/http_foundation.rst index ae5db2bee91..ee1ae532f87 100644 --- a/components/http_foundation.rst +++ b/components/http_foundation.rst @@ -555,7 +555,7 @@ represented by a PHP callable instead of a string:: use Symfony\Component\HttpFoundation\StreamedResponse; $response = new StreamedResponse(); - $response->setCallback(function () { + $response->setCallback(function (): void { var_dump('Hello World'); flush(); sleep(2); diff --git a/components/http_kernel.rst b/components/http_kernel.rst index 067bf17a998..2bb972e057a 100644 --- a/components/http_kernel.rst +++ b/components/http_kernel.rst @@ -630,7 +630,7 @@ else that can be used to create a working example:: $routes = new RouteCollection(); $routes->add('hello', new Route('/hello/{name}', [ - '_controller' => function (Request $request) { + '_controller' => function (Request $request): Response { return new Response( sprintf("Hello %s", $request->get('name')) ); diff --git a/components/options_resolver.rst b/components/options_resolver.rst index fb459f3d9cd..1f9b1b9567f 100644 --- a/components/options_resolver.rst +++ b/components/options_resolver.rst @@ -370,7 +370,7 @@ For options with more complicated validation schemes, pass a closure which returns ``true`` for acceptable values and ``false`` for invalid values:: // ... - $resolver->setAllowedValues('transport', function ($value) { + $resolver->setAllowedValues('transport', function (string $value): bool { // return true or false }); @@ -412,7 +412,7 @@ option. You can configure a normalizer by calling { // ... - $resolver->setNormalizer('host', function (Options $options, $value) { + $resolver->setNormalizer('host', function (Options $options, string $value): string { if ('http://' !== substr($value, 0, 7)) { $value = 'http://'.$value; } @@ -433,7 +433,7 @@ if you need to use other options during normalization:: public function configureOptions(OptionsResolver $resolver) { // ... - $resolver->setNormalizer('host', function (Options $options, $value) { + $resolver->setNormalizer('host', function (Options $options, string $value): string { if ('http://' !== substr($value, 0, 7) && 'https://' !== substr($value, 0, 8)) { if ('ssl' === $options['encryption']) { $value = 'https://'.$value; @@ -475,7 +475,7 @@ these options, you can return the desired default value:: // ... $resolver->setDefault('encryption', null); - $resolver->setDefault('port', function (Options $options) { + $resolver->setDefault('port', function (Options $options): int { if ('ssl' === $options['encryption']) { return 465; } @@ -518,7 +518,7 @@ the closure:: { parent::configureOptions($resolver); - $resolver->setDefault('host', function (Options $options, $previousValue) { + $resolver->setDefault('host', function (Options $options, string $previousValue): string { if ('ssl' === $options['encryption']) { return 'secure.example.org'; } @@ -654,7 +654,7 @@ default value:: public function configureOptions(OptionsResolver $resolver) { - $resolver->setDefault('spool', function (OptionsResolver $spoolResolver) { + $resolver->setDefault('spool', function (OptionsResolver $spoolResolver): void { $spoolResolver->setDefaults([ 'type' => 'file', 'path' => '/path/to/spool', @@ -690,7 +690,7 @@ to the closure to access to them:: public function configureOptions(OptionsResolver $resolver) { $resolver->setDefault('sandbox', false); - $resolver->setDefault('spool', function (OptionsResolver $spoolResolver, Options $parent) { + $resolver->setDefault('spool', function (OptionsResolver $spoolResolver, Options $parent): void { $spoolResolver->setDefaults([ 'type' => $parent['sandbox'] ? 'memory' : 'file', // ... @@ -713,13 +713,13 @@ In same way, parent options can access to the nested options as normal arrays:: public function configureOptions(OptionsResolver $resolver) { - $resolver->setDefault('spool', function (OptionsResolver $spoolResolver) { + $resolver->setDefault('spool', function (OptionsResolver $spoolResolver): void { $spoolResolver->setDefaults([ 'type' => 'file', // ... ]); }); - $resolver->setDefault('profiling', function (Options $options) { + $resolver->setDefault('profiling', function (Options $options): void { return 'file' === $options['spool']['type']; }); } @@ -740,7 +740,7 @@ with ``host``, ``database``, ``user`` and ``password`` each. The best way to implement this is to define the ``connections`` option as prototype:: - $resolver->setDefault('connections', function (OptionsResolver $connResolver) { + $resolver->setDefault('connections', function (OptionsResolver $connResolver): void { $connResolver ->setPrototype(true) ->setRequired(['host', 'database']) @@ -820,7 +820,7 @@ the option:: ->setDefault('encryption', null) ->setDefault('port', null) ->setAllowedTypes('port', ['null', 'int']) - ->setDeprecated('port', 'acme/package', '1.2', function (Options $options, $value) { + ->setDeprecated('port', 'acme/package', '1.2', function (Options $options, ?int $value): string { if (null === $value) { return 'Passing "null" to option "port" is deprecated, pass an integer instead.'; } diff --git a/components/process.rst b/components/process.rst index fbd0e041582..91c43b096cd 100644 --- a/components/process.rst +++ b/components/process.rst @@ -189,7 +189,7 @@ anonymous function to the use Symfony\Component\Process\Process; $process = new Process(['ls', '-lsa']); - $process->run(function ($type, $buffer) { + $process->run(function ($type, $buffer): void { if (Process::ERR === $type) { echo 'ERR > '.$buffer; } else { @@ -267,7 +267,7 @@ in the output and its type:: $process = new Process(['ls', '-lsa']); $process->start(); - $process->wait(function ($type, $buffer) { + $process->wait(function ($type, $buffer): void { if (Process::ERR === $type) { echo 'ERR > '.$buffer; } else { @@ -286,7 +286,7 @@ process and checks its output to wait until its fully initialized:: // ... do other things // waits until the given anonymous function returns true - $process->waitUntil(function ($type, $output) { + $process->waitUntil(function ($type, $output): bool { return $output === 'Ready. Waiting for commands...'; }); diff --git a/components/runtime.rst b/components/runtime.rst index 7706602017e..9f6882a8450 100644 --- a/components/runtime.rst +++ b/components/runtime.rst @@ -27,7 +27,7 @@ to look like this:: require_once dirname(__DIR__).'/vendor/autoload_runtime.php'; - return function (array $context) { + return function (array $context): Kernel { return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']); }; @@ -61,7 +61,7 @@ To make a console application, the bootstrap code would look like:: require_once dirname(__DIR__).'/vendor/autoload_runtime.php'; - return function (array $context) { + return function (array $context): Application { $kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']); // returning an "Application" makes the Runtime run a Console @@ -112,12 +112,13 @@ Resolvable Arguments The closure returned from the front-controller may have zero or more arguments:: // public/index.php + use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; require_once dirname(__DIR__).'/vendor/autoload_runtime.php'; - return function (InputInterface $input, OutputInterface $output) { + return function (InputInterface $input, OutputInterface $output): Application { // ... }; @@ -162,7 +163,7 @@ a number of different applications are supported:: require_once dirname(__DIR__).'/vendor/autoload_runtime.php'; - return function () { + return static function (): Kernel { return new Kernel('prod', false); }; @@ -181,7 +182,7 @@ The ``SymfonyRuntime`` can handle these applications: require_once dirname(__DIR__).'/vendor/autoload_runtime.php'; - return function () { + return static function (): Response { return new Response('Hello world'); }; @@ -195,8 +196,8 @@ The ``SymfonyRuntime`` can handle these applications: require_once dirname(__DIR__).'/vendor/autoload_runtime.php'; - return function (Command $command) { - $command->setCode(function (InputInterface $input, OutputInterface $output) { + return static function (Command $command): Command { + $command->setCode(static function (InputInterface $input, OutputInterface $output): void { $output->write('Hello World'); }); @@ -214,9 +215,9 @@ The ``SymfonyRuntime`` can handle these applications: require_once dirname(__DIR__).'/vendor/autoload_runtime.php'; - return function (array $context) { + return static function (array $context): Application { $command = new Command('hello'); - $command->setCode(function (InputInterface $input, OutputInterface $output) { + $command->setCode(static function (InputInterface $input, OutputInterface $output): void { $output->write('Hello World'); }); @@ -239,7 +240,7 @@ applications: require_once dirname(__DIR__).'/vendor/autoload_runtime.php'; - return function () { + return static function (): RunnerInterface { return new class implements RunnerInterface { public function run(): int { @@ -257,8 +258,8 @@ applications: // public/index.php require_once dirname(__DIR__).'/vendor/autoload_runtime.php'; - return function () { - $app = function() { + return static function (): callable { + $app = static function(): int { echo 'Hello World'; return 0; @@ -273,7 +274,7 @@ applications: require_once dirname(__DIR__).'/vendor/autoload_runtime.php'; - return function () { + return function (): void { echo 'Hello world'; }; @@ -393,6 +394,7 @@ However, a ReactPHP application will need some special logic to *run*. That logi is added in a new class implementing :class:`Symfony\\Component\\Runtime\\RunnerInterface`:: use Psr\Http\Message\ServerRequestInterface; + use Psr\Http\Message\ResponseInterface; use Psr\Http\Server\RequestHandlerInterface; use React\EventLoop\Factory as ReactFactory; use React\Http\Server as ReactHttpServer; @@ -415,7 +417,7 @@ is added in a new class implementing :class:`Symfony\\Component\\Runtime\\Runner // configure ReactPHP to correctly handle the PSR-15 application $server = new ReactHttpServer( $loop, - function (ServerRequestInterface $request) use ($application) { + function (ServerRequestInterface $request) use ($application): ResponseInterface { return $application->handle($request); } ); @@ -462,7 +464,7 @@ The end user will now be able to create front controller like:: require_once dirname(__DIR__).'/vendor/autoload_runtime.php'; - return function (array $context) { + return function (array $context): SomeCustomPsr15Application { return new SomeCustomPsr15Application(); }; diff --git a/components/serializer.rst b/components/serializer.rst index e08bd5c1f07..352f81b527d 100644 --- a/components/serializer.rst +++ b/components/serializer.rst @@ -723,7 +723,7 @@ When serializing, you can set a callback to format a specific object property:: $encoder = new JsonEncoder(); // all callback parameters are optional (you can omit the ones you don't use) - $dateCallback = function ($innerObject, $outerObject, string $attributeName, string $format = null, array $context = []) { + $dateCallback = function (object $innerObject, object $outerObject, string $attributeName, string $format = null, array $context = []): string { return $innerObject instanceof \DateTime ? $innerObject->format(\DateTime::ISO8601) : ''; }; @@ -1381,7 +1381,7 @@ having unique identifiers:: $encoder = new JsonEncoder(); $defaultContext = [ - AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => function ($object, $format, $context) { + AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => function (object $object, string $format, array $context): string { return $object->getName(); }, ]; @@ -1519,7 +1519,7 @@ having unique identifiers:: $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); // all callback parameters are optional (you can omit the ones you don't use) - $maxDepthHandler = function ($innerObject, $outerObject, string $attributeName, string $format = null, array $context = []) { + $maxDepthHandler = function (object $innerObject, object $outerObject, string $attributeName, string $format = null, array $context = []): string { return '/foos/'.$innerObject->id; }; diff --git a/components/string.rst b/components/string.rst index d294cdacd31..bea4705ff05 100644 --- a/components/string.rst +++ b/components/string.rst @@ -352,7 +352,7 @@ Methods to Search and Replace // replaces all occurrences of the given regular expression u('(+1) 206-555-0100')->replaceMatches('/[^A-Za-z0-9]++/', ''); // '12065550100' // you can pass a callable as the second argument to perform advanced replacements - u('123')->replaceMatches('/\d/', function ($match) { + u('123')->replaceMatches('/\d/', function (string $match): string { return '['.$match[0].']'; }); // result = '[1][2][3]' @@ -461,7 +461,7 @@ class that allows to store a string whose value is only generated when you need use Symfony\Component\String\LazyString; - $lazyString = LazyString::fromCallable(function () { + $lazyString = LazyString::fromCallable(function (): string { // Compute the string value... $value = ...; @@ -518,7 +518,7 @@ that only includes safe ASCII characters:: // $slug = '10-percent-or-5-euro' // for more dynamic substitutions, pass a PHP closure instead of an array - $slugger = new AsciiSlugger('en', function ($string, $locale) { + $slugger = new AsciiSlugger('en', function (string $string, string $locale): string { return str_replace('❤️', 'love', $string); }); diff --git a/components/var_dumper.rst b/components/var_dumper.rst index ccde974b9e5..face02f8484 100644 --- a/components/var_dumper.rst +++ b/components/var_dumper.rst @@ -169,7 +169,7 @@ Outside a Symfony application, use the :class:`Symfony\\Component\\VarDumper\\Du 'source' => new SourceContextProvider(), ]); - VarDumper::setHandler(function ($var) use ($cloner, $dumper) { + VarDumper::setHandler(function (mixed $var) use ($cloner, $dumper): ?string { $dumper->dump($cloner->cloneVar($var)); }); @@ -481,7 +481,7 @@ like this:: use Symfony\Component\VarDumper\Dumper\HtmlDumper; use Symfony\Component\VarDumper\VarDumper; - VarDumper::setHandler(function ($var) { + VarDumper::setHandler(function (mixed $var): ?string { $cloner = new VarCloner(); $dumper = 'cli' === PHP_SAPI ? new CliDumper() : new HtmlDumper(); @@ -599,7 +599,7 @@ For example, to get a dump as a string in a variable, you can do:: $dumper->dump( $cloner->cloneVar($variable), - function ($line, $depth) use (&$output) { + function (int $line, int $depth) use (&$output): void { // A negative depth means "end of dump" if ($depth >= 0) { // Adds a two spaces indentation to the line diff --git a/configuration.rst b/configuration.rst index b7ccac2ece7..72b567f5a62 100644 --- a/configuration.rst +++ b/configuration.rst @@ -489,7 +489,7 @@ files directly in the ``config/packages/`` directory. use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Config\WebpackEncoreConfig; - return static function (WebpackEncoreConfig $webpackEncore, ContainerConfigurator $container) { + return static function (WebpackEncoreConfig $webpackEncore, ContainerConfigurator $container): void { $webpackEncore ->outputPath('%kernel.project_dir%/public/build') ->strictMode(true) @@ -1090,7 +1090,7 @@ namespace ``Symfony\Config``:: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->firewall('main') ->pattern('^/*') ->lazy(true) diff --git a/configuration/front_controllers_and_kernel.rst b/configuration/front_controllers_and_kernel.rst index 2da948dbe55..b55f66afc33 100644 --- a/configuration/front_controllers_and_kernel.rst +++ b/configuration/front_controllers_and_kernel.rst @@ -186,7 +186,7 @@ parameter used, for example, to turn Twig's debug mode on: // config/packages/twig.php use Symfony\Config\TwigConfig; - return static function (TwigConfig $twig) { + return static function (TwigConfig $twig): void { // ... $twig->debug('%kernel.debug%'); }; diff --git a/configuration/multiple_kernels.rst b/configuration/multiple_kernels.rst index 9464fcf39f7..edfcb371864 100644 --- a/configuration/multiple_kernels.rst +++ b/configuration/multiple_kernels.rst @@ -244,7 +244,7 @@ application:: use Shared\Kernel; // ... - return function (array $context) { + return function (array $context): Kernel { return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG'], $context['APP_ID']); }; @@ -259,7 +259,7 @@ the application ID to run under CLI context:: use Shared\Kernel; // ... - return function (InputInterface $input, array $context) { + return function (InputInterface $input, array $context): Application { $kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG'], $input->getParameterOption(['--id', '-i'], $context['APP_ID'])); $application = new Application($kernel); diff --git a/configuration/override_dir_structure.rst b/configuration/override_dir_structure.rst index 4fb5524a2aa..e0d27a52b8c 100644 --- a/configuration/override_dir_structure.rst +++ b/configuration/override_dir_structure.rst @@ -190,7 +190,7 @@ for multiple directories): // config/packages/twig.php use Symfony\Config\TwigConfig; - return static function (TwigConfig $twig) { + return static function (TwigConfig $twig): void { $twig->defaultPath('%kernel.project_dir%/resources/views'); }; diff --git a/configuration/secrets.rst b/configuration/secrets.rst index bd52ea0895a..8afb6d02683 100644 --- a/configuration/secrets.rst +++ b/configuration/secrets.rst @@ -139,7 +139,7 @@ If you stored a ``DATABASE_PASSWORD`` secret, you can reference it by: // config/packages/doctrine.php use Symfony\Config\DoctrineConfig; - return static function (DoctrineConfig $doctrine) { + return static function (DoctrineConfig $doctrine): void { $doctrine->dbal() ->connection('default') ->password(env('DATABASE_PASSWORD')) diff --git a/console/input.rst b/console/input.rst index 2815fe1b543..2e6d9a1a438 100644 --- a/console/input.rst +++ b/console/input.rst @@ -337,7 +337,7 @@ To achieve this, use the 5th argument of ``addArgument()``/``addOption``:: InputArgument::IS_ARRAY, 'Who do you want to greet (separate multiple names with a space)?', null, - function (CompletionInput $input) { + function (CompletionInput $input): array { // the value the user already typed, e.g. when typing "app:greet Fa" before // pressing Tab, this will contain "Fa" $currentValue = $input->getCompletionValue(); diff --git a/console/lazy_commands.rst b/console/lazy_commands.rst index 6d1f245eb75..f76e3fc29a5 100644 --- a/console/lazy_commands.rst +++ b/console/lazy_commands.rst @@ -15,10 +15,11 @@ which will be responsible for returning ``Command`` instances:: use App\Command\HeavyCommand; use Symfony\Component\Console\Application; + use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\CommandLoader\FactoryCommandLoader; $commandLoader = new FactoryCommandLoader([ - 'app:heavy' => function () { return new HeavyCommand(); }, + 'app:heavy' => function (): Command { return new HeavyCommand(); }, ]); $application = new Application(); @@ -45,10 +46,11 @@ The :class:`Symfony\\Component\\Console\\CommandLoader\\FactoryCommandLoader` class provides a way of getting commands lazily loaded as it takes an array of ``Command`` factories as its only constructor argument:: + use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\CommandLoader\FactoryCommandLoader; $commandLoader = new FactoryCommandLoader([ - 'app:foo' => function () { return new FooCommand(); }, + 'app:foo' => function (): Command { return new FooCommand(); }, 'app:bar' => [BarCommand::class, 'create'], ]); diff --git a/console/style.rst b/console/style.rst index ec641440186..3b3af53b678 100644 --- a/console/style.rst +++ b/console/style.rst @@ -275,7 +275,7 @@ User Input Methods In case you need to validate the given value, pass a callback validator as the third argument:: - $io->ask('Number of workers to start', '1', function ($number) { + $io->ask('Number of workers to start', '1', function (string $number): int { if (!is_numeric($number)) { throw new \RuntimeException('You must type a number.'); } @@ -292,7 +292,7 @@ User Input Methods In case you need to validate the given value, pass a callback validator as the second argument:: - $io->askHidden('What is your password?', function ($password) { + $io->askHidden('What is your password?', function (string $password): string { if (empty($password)) { throw new \RuntimeException('Password cannot be empty.'); } diff --git a/controller/error_pages.rst b/controller/error_pages.rst index d28c51cce99..8493d65c2f4 100644 --- a/controller/error_pages.rst +++ b/controller/error_pages.rst @@ -178,7 +178,7 @@ automatically when installing ``symfony/framework-bundle``): // config/routes/framework.php use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return function (RoutingConfigurator $routes): void { if ('dev' === $routes->env()) { $routes->import('@FrameworkBundle/Resources/config/routing/errors.xml') ->prefix('/_error') diff --git a/controller/service.rst b/controller/service.rst index 5b629ca978e..33aef36d64d 100644 --- a/controller/service.rst +++ b/controller/service.rst @@ -100,7 +100,7 @@ a service like: ``App\Controller\HelloController::index``: use App\Controller\HelloController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return function (RoutingConfigurator $routes): void { $routes->add('hello', '/hello') ->controller([HelloController::class, 'index']) ->methods(['GET']) diff --git a/create_framework/event_dispatcher.rst b/create_framework/event_dispatcher.rst index 63457fe8462..e4921097a33 100644 --- a/create_framework/event_dispatcher.rst +++ b/create_framework/event_dispatcher.rst @@ -117,7 +117,7 @@ the registration of a listener for the ``response`` event:: use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); - $dispatcher->addListener('response', function (Simplex\ResponseEvent $event) { + $dispatcher->addListener('response', function (Simplex\ResponseEvent $event): void { $response = $event->getResponse(); if ($response->isRedirection() @@ -156,7 +156,7 @@ So far so good, but let's add another listener on the same event. Let's say that we want to set the ``Content-Length`` of the Response if it is not already set:: - $dispatcher->addListener('response', function (Simplex\ResponseEvent $event) { + $dispatcher->addListener('response', function (Simplex\ResponseEvent $event): void { $response = $event->getResponse(); $headers = $response->headers; @@ -174,7 +174,7 @@ a positive number; negative numbers can be used for low priority listeners. Here, we want the ``Content-Length`` listener to be executed last, so change the priority to ``-255``:: - $dispatcher->addListener('response', function (Simplex\ResponseEvent $event) { + $dispatcher->addListener('response', function (Simplex\ResponseEvent $event): void { $response = $event->getResponse(); $headers = $response->headers; diff --git a/create_framework/http_kernel_httpkernel_class.rst b/create_framework/http_kernel_httpkernel_class.rst index 0f4e565b084..fdb2a0b3f5d 100644 --- a/create_framework/http_kernel_httpkernel_class.rst +++ b/create_framework/http_kernel_httpkernel_class.rst @@ -69,7 +69,7 @@ Our code is now much more concise and surprisingly more robust and more powerful than ever. For instance, use the built-in ``ErrorListener`` to make your error management configurable:: - $errorHandler = function (Symfony\Component\ErrorHandler\Exception\FlattenException $exception) { + $errorHandler = function (Symfony\Component\ErrorHandler\Exception\FlattenException $exception): Response { $msg = 'Something went wrong! ('.$exception->getMessage().')'; return new Response($msg, $exception->getStatusCode()); diff --git a/create_framework/templating.rst b/create_framework/templating.rst index 6fca67d84a1..908a17f2a8e 100644 --- a/create_framework/templating.rst +++ b/create_framework/templating.rst @@ -74,7 +74,7 @@ can still use the ``render_template()`` to render a template:: $routes->add('hello', new Routing\Route('/hello/{name}', [ 'name' => 'World', - '_controller' => function ($request) { + '_controller' => function (Request $request): string { return render_template($request); } ])); @@ -84,7 +84,7 @@ you can even pass additional arguments to the template:: $routes->add('hello', new Routing\Route('/hello/{name}', [ 'name' => 'World', - '_controller' => function ($request) { + '_controller' => function (Request $request): Response { // $foo will be available in the template $request->attributes->set('foo', 'bar'); @@ -157,7 +157,7 @@ framework does not need to be modified in any way, create a new $routes = new Routing\RouteCollection(); $routes->add('leap_year', new Routing\Route('/is_leap_year/{year}', [ 'year' => null, - '_controller' => function ($request) { + '_controller' => function (Request $request): Response { if (is_leap_year($request->attributes->get('year'))) { return new Response('Yep, this is a leap year!'); } diff --git a/doctrine/custom_dql_functions.rst b/doctrine/custom_dql_functions.rst index f615ad1fcd5..1b3aa4aa185 100644 --- a/doctrine/custom_dql_functions.rst +++ b/doctrine/custom_dql_functions.rst @@ -56,7 +56,7 @@ In Symfony, you can register your custom DQL functions as follows: use App\DQL\StringFunction; use Symfony\Config\DoctrineConfig; - return static function (DoctrineConfig $doctrine) { + return static function (DoctrineConfig $doctrine): void { $defaultDql = $doctrine->orm() ->entityManager('default') // ... @@ -123,7 +123,7 @@ In Symfony, you can register your custom DQL functions as follows: use App\DQL\DatetimeFunction; use Symfony\Config\DoctrineConfig; - return static function (DoctrineConfig $doctrine) { + return static function (DoctrineConfig $doctrine): void { $doctrine->orm() // ... ->entityManager('example_manager') diff --git a/doctrine/dbal.rst b/doctrine/dbal.rst index 544428a9691..a400cee0324 100644 --- a/doctrine/dbal.rst +++ b/doctrine/dbal.rst @@ -104,7 +104,7 @@ mapping types, read Doctrine's `Custom Mapping Types`_ section of their document use App\Type\CustomSecond; use Symfony\Config\DoctrineConfig; - return static function (DoctrineConfig $doctrine) { + return static function (DoctrineConfig $doctrine): void { $dbal = $doctrine->dbal(); $dbal->type('custom_first')->class(CustomFirst::class); $dbal->type('custom_second')->class(CustomSecond::class); @@ -153,7 +153,7 @@ mapping type: // config/packages/doctrine.php use Symfony\Config\DoctrineConfig; - return static function (DoctrineConfig $doctrine) { + return static function (DoctrineConfig $doctrine): void { $dbalDefault = $doctrine->dbal() ->connection('default'); $dbalDefault->mappingType('enum', 'string'); diff --git a/doctrine/multiple_entity_managers.rst b/doctrine/multiple_entity_managers.rst index 081239bcd9f..85ac329f411 100644 --- a/doctrine/multiple_entity_managers.rst +++ b/doctrine/multiple_entity_managers.rst @@ -111,7 +111,7 @@ The following configuration code shows how you can configure two entity managers // config/packages/doctrine.php use Symfony\Config\DoctrineConfig; - return static function (DoctrineConfig $doctrine) { + return static function (DoctrineConfig $doctrine): void { // Connections: $doctrine->dbal() ->connection('default') @@ -120,7 +120,7 @@ The following configuration code shows how you can configure two entity managers ->connection('customer') ->url(env('CUSTOMER_DATABASE_URL')->resolve()); $doctrine->dbal()->defaultConnection('default'); - + // Entity Managers: $doctrine->orm()->defaultEntityManager('default'); $defaultEntityManager = $doctrine->orm()->entityManager('default'); diff --git a/doctrine/resolve_target_entity.rst b/doctrine/resolve_target_entity.rst index 81de0c75ff0..fcb977fc47f 100644 --- a/doctrine/resolve_target_entity.rst +++ b/doctrine/resolve_target_entity.rst @@ -134,7 +134,7 @@ about the replacement: use App\Model\InvoiceSubjectInterface; use Symfony\Config\DoctrineConfig; - return static function (DoctrineConfig $doctrine) { + return static function (DoctrineConfig $doctrine): void { $orm = $doctrine->orm(); // ... $orm->resolveTargetEntity(InvoiceSubjectInterface::class, Customer::class); diff --git a/form/bootstrap4.rst b/form/bootstrap4.rst index bbcd0819369..eef016aa58a 100644 --- a/form/bootstrap4.rst +++ b/form/bootstrap4.rst @@ -57,7 +57,7 @@ configuration: // config/packages/twig.php use Symfony\Config\TwigConfig; - return static function (TwigConfig $twig) { + return static function (TwigConfig $twig): void { $twig->formThemes(['bootstrap_4_layout.html.twig']); // ... diff --git a/form/create_custom_field_type.rst b/form/create_custom_field_type.rst index 6729e0974ad..0d200114ef4 100644 --- a/form/create_custom_field_type.rst +++ b/form/create_custom_field_type.rst @@ -395,7 +395,7 @@ rest of files): // config/packages/twig.php use Symfony\Config\TwigConfig; - return static function (TwigConfig $twig) { + return static function (TwigConfig $twig): void { $twig->formThemes([ 'form/custom_types.html.twig', '...', diff --git a/form/data_based_validation.rst b/form/data_based_validation.rst index 400b4f3ff9a..b01bea10b16 100644 --- a/form/data_based_validation.rst +++ b/form/data_based_validation.rst @@ -32,7 +32,7 @@ example). You can also define whole logic inline by using a ``Closure``:: public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ - 'validation_groups' => function (FormInterface $form) { + 'validation_groups' => function (FormInterface $form): array { $data = $form->getData(); if (Client::TYPE_PERSON == $data->getType()) { @@ -56,7 +56,7 @@ of the entity as well you have to adjust the option as follows:: public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ - 'validation_groups' => function (FormInterface $form) { + 'validation_groups' => function (FormInterface $form): array { $data = $form->getData(); if (Client::TYPE_PERSON == $data->getType()) { diff --git a/form/dynamic_form_modification.rst b/form/dynamic_form_modification.rst index 0911a40f999..77772b24c5f 100644 --- a/form/dynamic_form_modification.rst +++ b/form/dynamic_form_modification.rst @@ -93,7 +93,7 @@ creating that particular field is delegated to an event listener:: { $builder->add('price'); - $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) { + $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event): void { // ... adding the name field if needed }); } @@ -109,7 +109,7 @@ the event listener might look like the following:: public function buildForm(FormBuilderInterface $builder, array $options): void { // ... - $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) { + $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event): void { $product = $event->getData(); $form = $event->getForm(); @@ -220,7 +220,7 @@ Using an event listener, your form might look like this:: ->add('subject', TextType::class) ->add('body', TextareaType::class) ; - $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) { + $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event): void { // ... add a choice list of friends of the current application user }); } @@ -282,7 +282,7 @@ security helper to fill in the listener logic:: ); } - $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($user) { + $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($user): void { if (null !== $event->getData()->getFriend()) { // we don't need to add the friend field because // the message will be addressed to a fixed friend @@ -294,7 +294,7 @@ security helper to fill in the listener logic:: $formOptions = [ 'class' => User::class, 'choice_label' => 'fullName', - 'query_builder' => function (UserRepository $userRepository) use ($user) { + 'query_builder' => function (UserRepository $userRepository) use ($user): void { // call a method on your repository that returns the query builder // return $userRepository->createFriendsQueryBuilder($user); }, @@ -392,7 +392,7 @@ sport like this:: $builder->addEventListener( FormEvents::PRE_SET_DATA, - function (FormEvent $event) { + function (FormEvent $event): void { $form = $event->getForm(); // this would be your entity, i.e. SportMeetup @@ -455,7 +455,7 @@ The type would now look like:: ]) ; - $formModifier = function (FormInterface $form, Sport $sport = null) { + $formModifier = function (FormInterface $form, Sport $sport = null): void { $positions = null === $sport ? [] : $sport->getAvailablePositions(); $form->add('position', EntityType::class, [ @@ -467,7 +467,7 @@ The type would now look like:: $builder->addEventListener( FormEvents::PRE_SET_DATA, - function (FormEvent $event) use ($formModifier) { + function (FormEvent $event) use ($formModifier): void { // this would be your entity, i.e. SportMeetup $data = $event->getData(); @@ -477,7 +477,7 @@ The type would now look like:: $builder->get('sport')->addEventListener( FormEvents::POST_SUBMIT, - function (FormEvent $event) use ($formModifier) { + function (FormEvent $event) use ($formModifier): void { // It's important here to fetch $event->getForm()->getData(), as // $event->getData() will get you the client data (that is, the ID) $sport = $event->getForm()->getData(); diff --git a/form/events.rst b/form/events.rst index 6114cbd0c9c..a238ecec17d 100644 --- a/form/events.rst +++ b/form/events.rst @@ -16,7 +16,7 @@ register an event listener to the ``FormEvents::PRE_SUBMIT`` event as follows:: use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvents; - $listener = function (FormEvent $event) { + $listener = function (FormEvent $event): void { // ... }; diff --git a/form/form_themes.rst b/form/form_themes.rst index a2a778988dd..2346e7961cd 100644 --- a/form/form_themes.rst +++ b/form/form_themes.rst @@ -89,7 +89,7 @@ want to use another theme for all the forms of your app, configure it in the // config/packages/twig.php use Symfony\Config\TwigConfig; - return static function (TwigConfig $twig) { + return static function (TwigConfig $twig): void { $twig->formThemes([ 'bootstrap_5_horizontal_layout.html.twig', ]); @@ -514,7 +514,7 @@ you want to apply the theme globally to all forms, define the // config/packages/twig.php use Symfony\Config\TwigConfig; - return static function (TwigConfig $twig) { + return static function (TwigConfig $twig): void { $twig->formThemes([ 'form/my_theme.html.twig', ]); diff --git a/forms.rst b/forms.rst index 9a673dc4fc6..169d9f8220d 100644 --- a/forms.rst +++ b/forms.rst @@ -352,7 +352,7 @@ can set this option to generate forms compatible with the Bootstrap 5 CSS framew // config/packages/twig.php use Symfony\Config\TwigConfig; - return static function (TwigConfig $twig) { + return static function (TwigConfig $twig): void { $twig->formThemes(['bootstrap_5_layout.html.twig']); // ... diff --git a/http_cache.rst b/http_cache.rst index ee273079a6a..71a05bfad41 100644 --- a/http_cache.rst +++ b/http_cache.rst @@ -104,7 +104,7 @@ Use the ``framework.http_cache`` option to enable the proxy for the // config/packages/framework.php use Symfony\Config\FrameworkConfig; - return static function (FrameworkConfig $framework, string $env) { + return static function (FrameworkConfig $framework, string $env): void { if ('prod' === $env) { $framework->httpCache()->enabled(true); } diff --git a/http_client.rst b/http_client.rst index b0a58670133..68d1d361138 100644 --- a/http_client.rst +++ b/http_client.rst @@ -1535,12 +1535,12 @@ Then you're ready to go:: $request = $httpClient->createRequest('GET', 'https://my.api.com/'); $promise = $httpClient->sendAsyncRequest($request) ->then( - function (ResponseInterface $response) { + function (ResponseInterface $response): ResponseInterface { echo 'Got status '.$response->getStatusCode(); return $response; }, - function (\Throwable $exception) { + function (\Throwable $exception): never { echo 'Error: '.$exception->getMessage(); throw $exception; @@ -1656,7 +1656,7 @@ processing the stream of chunks as they come back from the network:: { // process and/or change the $method, $url and/or $options as needed - $passthru = function (ChunkInterface $chunk, AsyncContext $context) { + $passthru = function (ChunkInterface $chunk, AsyncContext $context): \Generator { // do what you want with chunks, e.g. split them // in smaller chunks, group them, skip some, etc. @@ -1746,7 +1746,7 @@ responses dynamically when it's called:: use Symfony\Component\HttpClient\MockHttpClient; use Symfony\Component\HttpClient\Response\MockResponse; - $callback = function ($method, $url, $options) { + $callback = function ($method, $url, $options): MockResponse { return new MockResponse('...'); }; @@ -1757,13 +1757,13 @@ You can also pass a list of callbacks if you need to perform specific assertions on the request before returning the mocked response:: $expectedRequests = [ - function ($method, $url, $options) { + function ($method, $url, $options): MockResponse { $this->assertSame('GET', $method); $this->assertSame('https://example.com/api/v1/customer', $url); return new MockResponse('...'); }, - function ($method, $url, $options) { + function ($method, $url, $options): MockResponse { $this->assertSame('POST', $method); $this->assertSame('https://example.com/api/v1/customer/1/products', $url); @@ -1807,7 +1807,7 @@ The responses provided to the mock client don't have to be instances of However, using ``MockResponse`` allows simulating chunked responses and timeouts:: - $body = function () { + $body = function (): \Generator { yield 'hello'; // empty strings are turned into timeouts so that they are easy to test yield ''; diff --git a/logging.rst b/logging.rst index c546701f78d..ecc14a9b8b0 100644 --- a/logging.rst +++ b/logging.rst @@ -156,7 +156,7 @@ to write logs using the :phpfunction:`syslog` function: // config/packages/prod/monolog.php use Symfony\Config\MonologConfig; - return static function (MonologConfig $monolog) { + return static function (MonologConfig $monolog): void { // this "file_log" key could be anything $monolog->handler('file_log') ->type('stream') @@ -255,7 +255,7 @@ one of the messages reaches an ``action_level``. Take this example: // config/packages/prod/monolog.php use Symfony\Config\MonologConfig; - return static function (MonologConfig $monolog) { + return static function (MonologConfig $monolog): void { $monolog->handler('filter_for_errors') ->type('fingers_crossed') // if *one* log is error or higher, pass *all* to file_log @@ -350,7 +350,7 @@ option of your handler to ``rotating_file``: // config/packages/prod/monolog.php use Symfony\Config\MonologConfig; - return static function (MonologConfig $monolog) { + return static function (MonologConfig $monolog): void { $monolog->handler('main') ->type('rotating_file') ->path('%kernel.logs_dir%/%kernel.environment%.log') diff --git a/logging/channels_handlers.rst b/logging/channels_handlers.rst index 3e607d825ce..3b21f7f08a2 100644 --- a/logging/channels_handlers.rst +++ b/logging/channels_handlers.rst @@ -77,7 +77,7 @@ can do it in any (or all) environments: // config/packages/prod/monolog.php use Symfony\Config\MonologConfig; - return static function (MonologConfig $monolog) { + return static function (MonologConfig $monolog): void { $monolog->handler('security') ->type('stream') ->path('%kernel.logs_dir%/security.log') @@ -158,7 +158,7 @@ You can also configure additional channels without the need to tag your services // config/packages/prod/monolog.php use Symfony\Config\MonologConfig; - return static function (MonologConfig $monolog) { + return static function (MonologConfig $monolog): void { $monolog->channels(['foo', 'bar', 'foo_bar']); }; diff --git a/logging/formatter.rst b/logging/formatter.rst index ffddbd1ed72..6f2bfc7906c 100644 --- a/logging/formatter.rst +++ b/logging/formatter.rst @@ -48,7 +48,7 @@ configure your handler to use it: // config/packages/prod/monolog.php (and/or config/packages/dev/monolog.php) use Symfony\Config\MonologConfig; - return static function (MonologConfig $monolog) { + return static function (MonologConfig $monolog): void { $monolog->handler('file') ->type('stream') ->level('debug') diff --git a/logging/handlers.rst b/logging/handlers.rst index ef4c8990d48..d44e3ab18a3 100644 --- a/logging/handlers.rst +++ b/logging/handlers.rst @@ -123,7 +123,7 @@ Then reference it in the Monolog configuration: use Symfony\Bridge\Monolog\Handler\ElasticsearchLogstashHandler; use Symfony\Config\MonologConfig; - return static function (MonologConfig $monolog) { + return static function (MonologConfig $monolog): void { $monolog->handler('es') ->type('service') ->id(ElasticsearchLogstashHandler::class) diff --git a/logging/monolog_console.rst b/logging/monolog_console.rst index 75f2aa51d32..ad06cfabbff 100644 --- a/logging/monolog_console.rst +++ b/logging/monolog_console.rst @@ -117,7 +117,7 @@ The Monolog console handler is enabled by default: // config/packages/dev/monolog.php use Symfony\Config\MonologConfig; - return static function (MonologConfig $monolog) { + return static function (MonologConfig $monolog): void { $monolog->handler('console') ->type('console') ->processPsr3Messages(false) diff --git a/logging/monolog_email.rst b/logging/monolog_email.rst index e6da3dbeb51..3610b3c1b4c 100644 --- a/logging/monolog_email.rst +++ b/logging/monolog_email.rst @@ -97,7 +97,7 @@ it is broken down. // config/packages/prod/monolog.php use Symfony\Config\MonologConfig; - return static function (MonologConfig $monolog) { + return static function (MonologConfig $monolog): void { $mainHandler = $monolog->handler('main') ->type('fingers_crossed') // 500 errors are logged at the critical level @@ -176,7 +176,7 @@ You can adjust the time period using the ``time`` option: // config/packages/prod/monolog.php use Symfony\Config\MonologConfig; - return static function (MonologConfig $monolog) { + return static function (MonologConfig $monolog): void { // ... $monolog->handler('deduplicated') @@ -285,7 +285,7 @@ get logged on the server as well as the emails being sent: // config/packages/prod/monolog.php use Symfony\Config\MonologConfig; - return static function (MonologConfig $monolog) { + return static function (MonologConfig $monolog): void { $monolog->handler('main') ->type('fingers_crossed') ->actionLevel('critical') diff --git a/logging/monolog_exclude_http_codes.rst b/logging/monolog_exclude_http_codes.rst index a49dcfe8e1f..810abdd5b9f 100644 --- a/logging/monolog_exclude_http_codes.rst +++ b/logging/monolog_exclude_http_codes.rst @@ -46,7 +46,7 @@ logging these HTTP codes based on the MonologBundle configuration: // config/packages/prod/monolog.php use Symfony\Config\MonologConfig; - return static function (MonologConfig $monolog) { + return static function (MonologConfig $monolog): void { $mainHandler = $monolog->handler('main') // ... ->type('fingers_crossed') diff --git a/logging/processors.rst b/logging/processors.rst index 0ff2e88ea78..dc60faf84b1 100644 --- a/logging/processors.rst +++ b/logging/processors.rst @@ -150,7 +150,7 @@ Finally, set the formatter to be used on whatever handler you want: // config/packages/prod/monolog.php use Symfony\Config\MonologConfig; - return static function (MonologConfig $monolog) { + return static function (MonologConfig $monolog): void { $monolog->handler('main') ->type('stream') ->path('%kernel.logs_dir%/%kernel.environment%.log') diff --git a/mailer.rst b/mailer.rst index f1528a81bc0..895ba2a7262 100644 --- a/mailer.rst +++ b/mailer.rst @@ -813,7 +813,7 @@ image files as usual. First, to simplify things, define a Twig namespace called // config/packages/twig.php use Symfony\Config\TwigConfig; - return static function (TwigConfig $twig) { + return static function (TwigConfig $twig): void { // ... // point this wherever your images live @@ -922,7 +922,7 @@ called ``styles`` that points to the directory where ``email.css`` lives: // config/packages/twig.php use Symfony\Config\TwigConfig; - return static function (TwigConfig $twig) { + return static function (TwigConfig $twig): void { // ... // point this wherever your css files live diff --git a/migration.rst b/migration.rst index 551004eb14c..4c1286125da 100644 --- a/migration.rst +++ b/migration.rst @@ -458,10 +458,10 @@ which script to call and wrap the output in a response class:: class LegacyController { - public function loadLegacyScript(string $requestPath, string $legacyScript) + public function loadLegacyScript(string $requestPath, string $legacyScript): StreamedResponse { return new StreamedResponse( - function () use ($requestPath, $legacyScript) { + function () use ($requestPath, $legacyScript): string { $_SERVER['PHP_SELF'] = $requestPath; $_SERVER['SCRIPT_NAME'] = $requestPath; $_SERVER['SCRIPT_FILENAME'] = $legacyScript; diff --git a/notifier.rst b/notifier.rst index 9a20b816ab9..84b74d7bcf1 100644 --- a/notifier.rst +++ b/notifier.rst @@ -881,7 +881,7 @@ dispatched. Listeners receive a use Symfony\Component\Notifier\Event\MessageEvent; - $dispatcher->addListener(MessageEvent::class, function (MessageEvent $event) { + $dispatcher->addListener(MessageEvent::class, function (MessageEvent $event): void { // gets the message instance $message = $event->getMessage(); @@ -904,7 +904,7 @@ Listeners receive a use Symfony\Component\Notifier\Event\FailedMessageEvent; - $dispatcher->addListener(FailedMessageEvent::class, function (FailedMessageEvent $event) { + $dispatcher->addListener(FailedMessageEvent::class, function (FailedMessageEvent $event): void { // gets the message instance $message = $event->getMessage(); @@ -927,7 +927,7 @@ is dispatched. Listeners receive a use Symfony\Component\Notifier\Event\SentMessageEvent; - $dispatcher->addListener(SentMessageEvent::class, function (SentMessageEvent $event) { + $dispatcher->addListener(SentMessageEvent::class, function (SentMessageEvent $event): void { // gets the message instance $message = $event->getOriginalMessage(); diff --git a/quick_tour/the_architecture.rst b/quick_tour/the_architecture.rst index f11d148e383..34413aec55e 100644 --- a/quick_tour/the_architecture.rst +++ b/quick_tour/the_architecture.rst @@ -280,7 +280,7 @@ using the special ``when@`` keyword: use Symfony\Config\FrameworkConfig; - return static function (FrameworkConfig $framework, ContainerConfigurator $container) { + return static function (FrameworkConfig $framework, ContainerConfigurator $container): void { $framework->router() ->utf8(true) ; diff --git a/reference/configuration/doctrine.rst b/reference/configuration/doctrine.rst index 71f8968c35a..672aabc0ebd 100644 --- a/reference/configuration/doctrine.rst +++ b/reference/configuration/doctrine.rst @@ -353,7 +353,7 @@ directory instead: use Symfony\Config\DoctrineConfig; - return static function (DoctrineConfig $doctrine) { + return static function (DoctrineConfig $doctrine): void { $emDefault = $doctrine->orm()->entityManager('default'); $emDefault->autoMapping(true); @@ -413,7 +413,7 @@ namespace in the ``src/Entity`` directory and gives them an ``App`` alias use Symfony\Config\DoctrineConfig; - return static function (DoctrineConfig $doctrine) { + return static function (DoctrineConfig $doctrine): void { $emDefault = $doctrine->orm()->entityManager('default'); $emDefault->autoMapping(true); diff --git a/reference/configuration/security.rst b/reference/configuration/security.rst index 5d4ac3189ae..33bfc9e687a 100644 --- a/reference/configuration/security.rst +++ b/reference/configuration/security.rst @@ -149,7 +149,7 @@ application: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... // 'main' is the name of the firewall (can be chosen freely) @@ -572,7 +572,7 @@ The security configuration should be: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $mainFirewall = $security->firewall('main'); $mainFirewall->lazy(true); $mainFirewall->jsonLogin() @@ -697,7 +697,7 @@ X.509 Authentication // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $mainFirewall = $security->firewall('main'); $mainFirewall->x509() ->provider('your_user_provider') @@ -768,7 +768,7 @@ Remote User Authentication // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $mainFirewall = $security->firewall('main'); $mainFirewall->remoteUser() ->provider('your_user_provider') @@ -849,7 +849,7 @@ multiple firewalls, the "context" could actually be shared: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->firewall('somename') // ... ->context('my_context') @@ -911,7 +911,7 @@ the session must not be used when authenticating users: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $mainFirewall = $security->firewall('main'); $mainFirewall->stateless(true); // ... @@ -970,7 +970,7 @@ Firewalls can configure a list of required badges that must be present on the au // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $mainFirewall = $security->firewall('main'); $mainFirewall->requiredBadges(['CsrfTokenBadge', 'My\Badge']); // ... diff --git a/reference/configuration/twig.rst b/reference/configuration/twig.rst index 0117e4efc7c..cc079da6745 100644 --- a/reference/configuration/twig.rst +++ b/reference/configuration/twig.rst @@ -226,7 +226,7 @@ The value of this option can be a regular expression, a glob, or a string: // config/packages/twig.php use Symfony\Config\TwigConfig; - return static function (TwigConfig $twig) { + return static function (TwigConfig $twig): void { $twig->fileNamePattern([ '*.twig', 'specific_file.html', @@ -277,7 +277,7 @@ all the forms of the application: // config/packages/twig.php use Symfony\Config\TwigConfig; - return static function (TwigConfig $twig) { + return static function (TwigConfig $twig): void { $twig->formThemes([ 'bootstrap_5_layout.html.twig', 'form/my_theme.html.twig', @@ -412,7 +412,7 @@ the directory defined in the :ref:`default_path option path('email/default/templates', null); diff --git a/reference/constraints/Callback.rst b/reference/constraints/Callback.rst index 89a5bb5a8e2..62184f805cd 100644 --- a/reference/constraints/Callback.rst +++ b/reference/constraints/Callback.rst @@ -237,7 +237,7 @@ constructor of the Callback constraint:: { public static function loadValidatorMetadata(ClassMetadata $metadata) { - $callback = function ($object, ExecutionContextInterface $context, $payload) { + $callback = function ($object, ExecutionContextInterface $context, $payload): void { // ... }; diff --git a/reference/forms/types/choice.rst b/reference/forms/types/choice.rst index 941654f5593..32640195c6e 100644 --- a/reference/forms/types/choice.rst +++ b/reference/forms/types/choice.rst @@ -73,21 +73,21 @@ method:: // a callback to return the label for a given choice // if a placeholder is used, its empty value (null) may be passed but // its label is defined by its own "placeholder" option - 'choice_label' => function (?Category $category) { + 'choice_label' => function (?Category $category): string { return $category ? strtoupper($category->getName()) : ''; }, // returns the html attributes for each option input (may be radio/checkbox) - 'choice_attr' => function (?Category $category) { + 'choice_attr' => function (?Category $category): array { return $category ? ['class' => 'category_'.strtolower($category->getName())] : []; }, // every option can use a string property path or any callable that get // passed each choice as argument, but it may not be needed - 'group_by' => function () { + 'group_by' => function (): string { // randomly assign things into 2 groups - return rand(0, 1) == 1 ? 'Group A' : 'Group B'; + return rand(0, 1) === 1 ? 'Group A' : 'Group B'; }, // a callback to return whether a category is preferred - 'preferred_choices' => function (?Category $category) { + 'preferred_choices' => function (?Category $category): bool { return $category && 100 < $category->getArticleCounts(); }, ]); diff --git a/reference/forms/types/collection.rst b/reference/forms/types/collection.rst index 7030db2f7ed..c18c558dbdc 100644 --- a/reference/forms/types/collection.rst +++ b/reference/forms/types/collection.rst @@ -160,7 +160,7 @@ the value is removed from the collection. For example:: $builder->add('users', CollectionType::class, [ // ... - 'delete_empty' => function (User $user = null) { + 'delete_empty' => function (User $user = null): bool { return null === $user || empty($user->getFirstName()); }, ]); diff --git a/reference/forms/types/entity.rst b/reference/forms/types/entity.rst index 884ab26a0d0..a524e3e02d0 100644 --- a/reference/forms/types/entity.rst +++ b/reference/forms/types/entity.rst @@ -58,7 +58,7 @@ the `query_builder`_ option:: $builder->add('users', EntityType::class, [ 'class' => User::class, - 'query_builder' => function (EntityRepository $er) { + 'query_builder' => function (EntityRepository $er): QueryBuilder { return $er->createQueryBuilder('u') ->orderBy('u.username', 'ASC'); }, @@ -124,7 +124,7 @@ method. You can also pass a callback function for more control:: $builder->add('category', EntityType::class, [ 'class' => Category::class, - 'choice_label' => function ($category) { + 'choice_label' => function (Category $category): string { return $category->getDisplayName(); } ]); diff --git a/reference/forms/types/options/choice_attr.rst.inc b/reference/forms/types/options/choice_attr.rst.inc index 38a97a6cd36..db5a47f4109 100644 --- a/reference/forms/types/options/choice_attr.rst.inc +++ b/reference/forms/types/options/choice_attr.rst.inc @@ -33,7 +33,7 @@ If an array, the keys of the ``choices`` array must be used as keys:: 'No' => false, 'Maybe' => null, ], - 'choice_attr' => function ($choice, $key, $value) { + 'choice_attr' => function ($choice, string $key, mixed $value) { // adds a class like attending_yes, attending_no, etc return ['class' => 'attending_'.strtolower($key)]; }, @@ -49,7 +49,7 @@ If an array, the keys of the ``choices`` array must be used as keys:: // ... $builder->add('choices', ChoiceType::class, [ - 'choice_attr' => ChoiceList::attr($this, function (?Category $category) { + 'choice_attr' => ChoiceList::attr($this, function (?Category $category): array { return $category ? ['data-uuid' => $category->getUuid()] : []; }), ]); diff --git a/reference/forms/types/options/choice_filter.rst.inc b/reference/forms/types/options/choice_filter.rst.inc index b220d12fd1d..235e1d84ed9 100644 --- a/reference/forms/types/options/choice_filter.rst.inc +++ b/reference/forms/types/options/choice_filter.rst.inc @@ -37,7 +37,7 @@ define a callable that takes each choice as the only argument and must return ->add('country', CountryType::class, [ // if the AddressType "allowed_countries" option is passed, // use it to create a filter - 'choice_filter' => $allowedCountries ? function ($countryCode) use ($allowedCountries) { + 'choice_filter' => $allowedCountries ? function ($countryCode) use ($allowedCountries): bool { return in_array($countryCode, $allowedCountries, true); } : null, @@ -69,7 +69,7 @@ The option can be a callable or a property path when choices are objects:: 'choice_filter' => $allowedCountries ? ChoiceList::filter( // pass the type as first argument $this, - function ($countryCode) use ($allowedCountries) { + function (string $countryCode) use ($allowedCountries): bool { return in_array($countryCode, $allowedCountries, true); }, // pass the option that makes the filter "vary" to compute a unique hash diff --git a/reference/forms/types/options/choice_label.rst.inc b/reference/forms/types/options/choice_label.rst.inc index 33b5ccbfc54..8fedf4cb88c 100644 --- a/reference/forms/types/options/choice_label.rst.inc +++ b/reference/forms/types/options/choice_label.rst.inc @@ -16,7 +16,7 @@ more control:: 'no' => false, 'maybe' => null, ], - 'choice_label' => function ($choice, $key, $value) { + 'choice_label' => function ($choice, string $key, mixed $value): TranslatableMessage|string { if (true === $choice) { return 'Definitely!'; } diff --git a/reference/forms/types/options/choice_loader.rst.inc b/reference/forms/types/options/choice_loader.rst.inc index 67062c56ada..5dec1b6cede 100644 --- a/reference/forms/types/options/choice_loader.rst.inc +++ b/reference/forms/types/options/choice_loader.rst.inc @@ -17,7 +17,7 @@ if you want to take advantage of lazy loading:: // ... $builder->add('loaded_choices', ChoiceType::class, [ - 'choice_loader' => new CallbackChoiceLoader(function () { + 'choice_loader' => new CallbackChoiceLoader(static function (): array { return StaticClass::getConstants(); }), ]); @@ -57,7 +57,7 @@ better performance:: // you can pass your own loader as well, depending on other options 'some_key' => null, - 'choice_loader' => function (Options $options) { + 'choice_loader' => function (Options $options): array { return ChoiceList::loader( // pass the instance of the type or type extension which is // currently configuring the choice list as first argument diff --git a/reference/forms/types/options/choice_translation_parameters.rst.inc b/reference/forms/types/options/choice_translation_parameters.rst.inc index c1bad6dc336..09c063c2d2b 100644 --- a/reference/forms/types/options/choice_translation_parameters.rst.inc +++ b/reference/forms/types/options/choice_translation_parameters.rst.inc @@ -54,7 +54,7 @@ You can specify the placeholder values as follows:: 'form.order.yes' => true, 'form.order.no' => false, ], - 'choice_translation_parameters' => function ($choice, $key, $value) { + 'choice_translation_parameters' => function ($choice, string $key, mixed $value): array { if (false === $choice) { return []; } diff --git a/reference/forms/types/options/choice_value.rst.inc b/reference/forms/types/options/choice_value.rst.inc index 13bc324cd2a..4b3668074a9 100644 --- a/reference/forms/types/options/choice_value.rst.inc +++ b/reference/forms/types/options/choice_value.rst.inc @@ -15,7 +15,7 @@ If you pass a callable, it will receive one argument: the choice itself. When us the :doc:`/reference/forms/types/entity`, the argument will be the entity object for each choice or ``null`` in a placeholder is used, which you need to handle:: - 'choice_value' => function (?MyOptionEntity $entity) { + 'choice_value' => function (?MyOptionEntity $entity): string { return $entity ? $entity->getId() : ''; }, diff --git a/reference/forms/types/options/preferred_choices.rst.inc b/reference/forms/types/options/preferred_choices.rst.inc index 8cb1278136d..479bb7e3663 100644 --- a/reference/forms/types/options/preferred_choices.rst.inc +++ b/reference/forms/types/options/preferred_choices.rst.inc @@ -33,7 +33,7 @@ be especially useful if your values are objects:: '1 week' => new \DateTime('+1 week'), '1 month' => new \DateTime('+1 month'), ], - 'preferred_choices' => function ($choice, $key, $value) { + 'preferred_choices' => function ($choice, $key, $value): bool { // prefer options within 3 days return $choice <= new \DateTime('+3 days'); }, diff --git a/reference/forms/types/options/validation_groups.rst.inc b/reference/forms/types/options/validation_groups.rst.inc index 90f79bede75..c5fe70b6d67 100644 --- a/reference/forms/types/options/validation_groups.rst.inc +++ b/reference/forms/types/options/validation_groups.rst.inc @@ -34,7 +34,7 @@ the option. Symfony will then pass the form when calling it:: public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'validation_groups' => function (FormInterface $form) { + 'validation_groups' => function (FormInterface $form): array { $entity = $form->getData(); return $entity->isUser() ? ['User'] : ['Company']; diff --git a/routing.rst b/routing.rst index d06a4c3f864..721a239d98e 100644 --- a/routing.rst +++ b/routing.rst @@ -143,7 +143,7 @@ the ``BlogController``: use App\Controller\BlogController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return function (RoutingConfigurator $routes): void { $routes->add('blog_list', '/blog') // the controller value has the format [controller_class, method_name] ->controller([BlogController::class, 'list']) @@ -229,7 +229,7 @@ Use the ``methods`` option to restrict the verbs each route should respond to: use App\Controller\BlogApiController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return function (RoutingConfigurator $routes): void { $routes->add('api_post_show', '/api/posts/{id}') ->controller([BlogApiController::class, 'show']) ->methods(['GET', 'HEAD']) @@ -341,7 +341,7 @@ arbitrary matching logic: use App\Controller\DefaultController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return function (RoutingConfigurator $routes): void { $routes->add('contact', '/contact') ->controller([DefaultController::class, 'contact']) ->condition('context.getMethod() in ["GET", "HEAD"] and request.headers.get("User-Agent") matches "/firefox/i"') @@ -535,7 +535,7 @@ For example, the route to display the blog post contents is defined as ``/blog/{ use App\Controller\BlogController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return function (RoutingConfigurator $routes): void { $routes->add('blog_show', '/blog/{slug}') ->controller([BlogController::class, 'show']) ; @@ -625,7 +625,7 @@ the ``{page}`` parameter using the ``requirements`` option: use App\Controller\BlogController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->add('blog_list', '/blog/{page}') ->controller([BlogController::class, 'list']) ->requirements(['page' => '\d+']) @@ -729,7 +729,7 @@ concise, but it can decrease route readability when requirements are complex: use App\Controller\BlogController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->add('blog_list', '/blog/{page<\d+>}') ->controller([BlogController::class, 'list']) ; @@ -806,7 +806,7 @@ other configuration formats they are defined with the ``defaults`` option: use App\Controller\BlogController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->add('blog_list', '/blog/{page}') ->controller([BlogController::class, 'list']) ->defaults(['page' => 1]) @@ -881,7 +881,7 @@ parameter: use App\Controller\BlogController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->add('blog_list', '/blog/{page<\d+>?1}') ->controller([BlogController::class, 'list']) ; @@ -1078,7 +1078,7 @@ and in route imports. Symfony defines some special attributes with the same name use App\Controller\ArticleController; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->add('article_show', '/articles/{_locale}/search.{_format}') ->controller([ArticleController::class, 'search']) ->locale('en') @@ -1148,7 +1148,7 @@ the controllers of the routes: use App\Controller\BlogController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->add('blog_index', '/blog/{page}') ->controller([BlogController::class, 'index']) ->defaults([ @@ -1219,7 +1219,7 @@ A possible solution is to change the parameter requirements to be more permissiv use App\Controller\DefaultController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->add('share', '/share/{token}') ->controller([DefaultController::class, 'share']) ->requirements([ @@ -1277,7 +1277,7 @@ Route alias allow you to have multiple name for the same route: // config/routes.php use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->alias('new_route_name', 'original_route_name'); }; @@ -1452,7 +1452,7 @@ when importing the routes. // config/routes/annotations.php use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->import( '../../src/Controller/', 'annotation', @@ -1526,7 +1526,7 @@ defined in the class annotation. // config/routes/annotations.php use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->import('../../src/Controller/', 'annotation') // the second argument is the $trailingSlashOnRoot option ->prefix('/blog', false) @@ -1678,7 +1678,7 @@ Use the ``RedirectController`` to redirect to other routes and URLs: use Symfony\Bundle\FrameworkBundle\Controller\RedirectController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->add('doc_shortcut', '/doc') ->controller(RedirectController::class) ->defaults([ @@ -1803,7 +1803,7 @@ host name: use App\Controller\MainController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->add('mobile_homepage', '/') ->controller([MainController::class, 'mobileHomepage']) ->host('m.example.com') @@ -1892,7 +1892,7 @@ multi-tenant applications) and these parameters can be validated too with use App\Controller\MainController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->add('mobile_homepage', '/') ->controller([MainController::class, 'mobileHomepage']) ->host('{subdomain}.example.com') @@ -1999,7 +1999,7 @@ avoids the need for duplicating routes, which also reduces the potential bugs: use App\Controller\CompanyController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->add('about_us', [ 'en' => '/about-us', 'nl' => '/over-ons', @@ -2059,7 +2059,7 @@ with a locale. This can be done by defining a different prefix for each locale // config/routes/annotations.php use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->import('../../src/Controller/', 'annotation') ->prefix([ // don't prefix URLs for English, the default locale @@ -2103,7 +2103,7 @@ locale. // config/routes/annotations.php use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->import('../../src/Controller/', 'annotation') ->host([ 'en' => 'https://www.example.com', @@ -2170,7 +2170,7 @@ session shouldn't be used when matching a request: use App\Controller\MainController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->add('homepage', '/') ->controller([MainController::class, 'homepage']) ->stateless() @@ -2544,7 +2544,7 @@ each route explicitly: use App\Controller\SecurityController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->add('login', '/login') ->controller([SecurityController::class, 'login']) ->schemes(['https']) @@ -2603,7 +2603,7 @@ defined as annotations: // config/routes/annotations.php use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->import('../../src/Controller/', 'annotation') ->schemes(['https']) ; diff --git a/routing/custom_route_loader.rst b/routing/custom_route_loader.rst index 830e1d64320..5caf51e8213 100644 --- a/routing/custom_route_loader.rst +++ b/routing/custom_route_loader.rst @@ -83,7 +83,7 @@ Symfony provides several route loaders for the most common needs: // config/routes.php use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { // loads routes from the given routing file stored in some bundle $routes->import('@AcmeBundle/Resources/config/routing.yaml'); @@ -175,7 +175,7 @@ Take these lines from the ``routes.yaml``: // config/routes.php use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->import('../src/Controller', 'attribute'); }; @@ -229,7 +229,7 @@ and configure the service and method to call: // config/routes.php use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->import('admin_route_loader::loadRoutes', 'service'); }; @@ -413,7 +413,7 @@ What remains to do is adding a few lines to the routing configuration: // config/routes.php use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return static function (RoutingConfigurator $routes): void { $routes->import('.', 'extra'); }; diff --git a/security.rst b/security.rst index 8d33ff682e6..59a237130e9 100644 --- a/security.rst +++ b/security.rst @@ -272,7 +272,7 @@ for a user provider in your security configuration: use App\Entity\User; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->provider('app_user_provider') @@ -402,7 +402,7 @@ have done this for you: use App\Entity\User; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... // Use native password hasher, which auto-selects and migrates the best @@ -535,7 +535,7 @@ will be able to authenticate (e.g. login form, API token, etc). // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->firewall('dev') ->pattern('^/(_(profiler|wdt)|css|images|js)/') @@ -735,7 +735,7 @@ Then, enable the form login authenticator using the ``form_login`` setting: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $mainFirewall = $security->firewall('main'); diff --git a/security/access_control.rst b/security/access_control.rst index cd1f8f276d6..abba217702f 100644 --- a/security/access_control.rst +++ b/security/access_control.rst @@ -314,7 +314,7 @@ pattern so that it is only accessible by requests from the local server itself: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->accessControl() @@ -402,7 +402,7 @@ key: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->accessControl() @@ -480,7 +480,7 @@ access those URLs via a specific port. This could be useful for example for // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->accessControl() @@ -534,7 +534,7 @@ the user will be redirected to ``https``: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->accessControl() diff --git a/security/access_denied_handler.rst b/security/access_denied_handler.rst index 745c68da79d..5671b0538a1 100644 --- a/security/access_denied_handler.rst +++ b/security/access_denied_handler.rst @@ -89,7 +89,7 @@ Now, configure this service ID as the entry point for the firewall: use App\Security\AuthenticationEntryPoint; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->firewall('main') // .... ->entryPoint(AuthenticationEntryPoint::class) @@ -165,7 +165,7 @@ configure it under your firewall: use App\Security\AccessDeniedHandler; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->firewall('main') // .... ->accessDeniedHandler(AccessDeniedHandler::class) diff --git a/security/access_token.rst b/security/access_token.rst index d2b2ab4f6a0..c1e1a40db3d 100644 --- a/security/access_token.rst +++ b/security/access_token.rst @@ -64,7 +64,7 @@ digital signature, etc.). use App\Security\AccessTokenHandler; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->firewall('main') ->accessToken() ->tokenHandler(AccessTokenHandler::class) @@ -193,7 +193,7 @@ You can also create a custom extractor. The class must implement use App\Security\CustomTokenExtractor; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->firewall('main') ->accessToken() ->tokenHandler(AccessTokenHandler::class) @@ -252,7 +252,7 @@ important**: the first in the list is called first. use App\Security\CustomTokenExtractor; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->firewall('main') ->accessToken() ->tokenHandler(AccessTokenHandler::class) @@ -326,7 +326,7 @@ and configure the service ID as the ``success_handler``: use App\Security\Authentication\AuthenticationSuccessHandler; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->firewall('main') ->accessToken() ->tokenHandler(AccessTokenHandler::class) diff --git a/security/custom_authenticator.rst b/security/custom_authenticator.rst index f817bb159de..76e2fc1b291 100644 --- a/security/custom_authenticator.rst +++ b/security/custom_authenticator.rst @@ -120,7 +120,7 @@ The authenticator can be enabled using the ``custom_authenticators`` setting: use App\Security\ApiKeyAuthenticator; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->enableAuthenticatorManager(true); // .... @@ -239,7 +239,7 @@ using :ref:`the user provider `:: // ... return new Passport( - new UserBadge($email, function (string $userIdentifier) { + new UserBadge($email, function (string $userIdentifier): ?User { return $this->userRepository->findOneBy(['email' => $userIdentifier]); }), $credentials @@ -269,7 +269,7 @@ The following credential classes are supported by default: // If this function returns anything else than `true`, the credentials // are marked as invalid. // The $credentials parameter is equal to the next argument of this class - function ($credentials, UserInterface $user) { + function (string $credentials, UserInterface $user): bool { return $user->getApiToken() === $credentials; }, diff --git a/security/entry_point.rst b/security/entry_point.rst index c69c6ed647d..e99a4039fcb 100644 --- a/security/entry_point.rst +++ b/security/entry_point.rst @@ -63,7 +63,7 @@ You can configure this using the ``entry_point`` setting: use App\Security\SocialConnectAuthenticator; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->enableAuthenticatorManager(true); // .... @@ -154,7 +154,7 @@ split the configuration into two separate firewalls: use App\Security\LoginFormAuthenticator; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $apiFirewall = $security->firewall('api'); $apiFirewall ->pattern('^/api') diff --git a/security/firewall_restriction.rst b/security/firewall_restriction.rst index dcf6a1a5f4d..be0237c0e39 100644 --- a/security/firewall_restriction.rst +++ b/security/firewall_restriction.rst @@ -63,7 +63,7 @@ if the request path matches the configured ``pattern``. // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // .... $security->firewall('secured_area') @@ -122,7 +122,7 @@ only initialize if the host from the request matches against the configuration. // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // .... $security->firewall('secured_area') @@ -182,7 +182,7 @@ the provided HTTP methods. // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // .... $security->firewall('secured_area') @@ -241,7 +241,7 @@ If the above options don't fit your needs you can configure any service implemen use App\Security\CustomRequestMatcher; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // .... $security->firewall('secured_area') diff --git a/security/force_https.rst b/security/force_https.rst index 817adbdb50f..cbcfcb46147 100644 --- a/security/force_https.rst +++ b/security/force_https.rst @@ -51,7 +51,7 @@ access control: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // .... $security->accessControl() diff --git a/security/form_login.rst b/security/form_login.rst index 84fe1aec6c1..2b5eba96340 100644 --- a/security/form_login.rst +++ b/security/form_login.rst @@ -65,7 +65,7 @@ a relative/absolute URL or a Symfony route name: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->firewall('main') @@ -123,7 +123,7 @@ previously requested URL and always redirect to the default page: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->firewall('main') @@ -211,7 +211,7 @@ parameter is included in the request, you may use the value of the // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->firewall('main') @@ -278,7 +278,7 @@ option to define a new target via a relative/absolute URL or a Symfony route nam // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->firewall('main') @@ -355,7 +355,7 @@ redirects can be customized using the ``target_path_parameter`` and // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->firewall('main') diff --git a/security/impersonating_user.rst b/security/impersonating_user.rst index c6e7e7ee2ae..ec18491005a 100644 --- a/security/impersonating_user.rst +++ b/security/impersonating_user.rst @@ -54,7 +54,7 @@ listener: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->firewall('main') // ... @@ -113,7 +113,7 @@ as the value to the current URL: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->firewall('main') // ... @@ -229,7 +229,7 @@ also adjust the query parameter name via the ``parameter`` setting: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->firewall('main') // ... @@ -291,7 +291,7 @@ This feature allows you to control the redirection target route via ``target_rou // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->firewall('main') // ... @@ -347,7 +347,7 @@ be called): // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->firewall('main') // ... diff --git a/security/ldap.rst b/security/ldap.rst index 44c2193ff38..b2f5a3e753c 100644 --- a/security/ldap.rst +++ b/security/ldap.rst @@ -184,7 +184,7 @@ use the ``ldap`` user provider. use Symfony\Component\Ldap\Ldap; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->provider('ldap_users') ->ldap() ->service(Ldap::class) @@ -406,7 +406,7 @@ Configuration example for form login use Symfony\Component\Ldap\Ldap; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->firewall('main') ->formLoginLdap() ->service(Ldap::class) @@ -460,7 +460,7 @@ Configuration example for HTTP Basic use Symfony\Component\Ldap\Ldap; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->firewall('main') ->stateless(true) ->formLoginLdap() @@ -520,7 +520,7 @@ Configuration example for form login and query_string use Symfony\Component\Ldap\Ldap; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->firewall('main') ->stateless(true) ->formLoginLdap() diff --git a/security/login_link.rst b/security/login_link.rst index 76f6c767617..14affeb47cd 100644 --- a/security/login_link.rst +++ b/security/login_link.rst @@ -62,7 +62,7 @@ under the firewall. You must configure a ``check_route`` and // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->firewall('main') ->loginLink() ->checkRoute('login_check') @@ -126,7 +126,7 @@ intercept requests to this route: use App\Controller\DefaultController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return function (RoutingConfigurator $routes): void { // ... $routes->add('login_check', '/login_check'); }; @@ -364,7 +364,7 @@ seconds). You can customize this using the ``lifetime`` option: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->firewall('main') ->loginLink() ->checkRoute('login_check') @@ -449,7 +449,7 @@ You can add more properties to the ``hash`` by using the // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->firewall('main') ->loginLink() ->checkRoute('login_check') @@ -521,7 +521,7 @@ cache. Enable this support by setting the ``max_uses`` option: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->firewall('main') ->loginLink() ->checkRoute('login_check') @@ -594,7 +594,7 @@ the authenticator only handle HTTP POST methods: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->firewall('main') ->loginLink() ->checkRoute('login_check') @@ -740,7 +740,7 @@ Then, configure this service ID as the ``success_handler``: use App\Security\Authentication\AuthenticationSuccessHandler; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->firewall('main') ->loginLink() ->checkRoute('login_check') diff --git a/security/passwords.rst b/security/passwords.rst index 2cafc024ce3..c4248ee4eea 100644 --- a/security/passwords.rst +++ b/security/passwords.rst @@ -71,7 +71,7 @@ optionally some *algorithm options*: use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... // auto hasher with default options for the User class (and children) @@ -179,7 +179,7 @@ Further in this article, you can find a use App\Entity\User; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... // Use your user class name here @@ -369,7 +369,7 @@ on the new hasher to point to the old, legacy hasher(s): // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->passwordHasher('legacy') ->algorithm('sha256') @@ -588,7 +588,7 @@ cost. This can be done with named hashers: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->passwordHasher('harsh') ->algorithm('auto') @@ -685,7 +685,7 @@ you must register a service for it in order to use it as a named hasher: use App\Security\Hasher\MyCustomPasswordHasher; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->passwordHasher('app_hasher') ->id(MyCustomPasswordHasher::class) @@ -903,7 +903,7 @@ Now, define a password hasher using the ``id`` setting: use App\Security\Hasher\CustomVerySecureHasher; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->passwordHasher('app_hasher') // the service ID of your custom hasher (the FQCN using the default services.yaml) diff --git a/security/remember_me.rst b/security/remember_me.rst index 3faa9b1e47a..83b16c33a93 100644 --- a/security/remember_me.rst +++ b/security/remember_me.rst @@ -62,7 +62,7 @@ the session lasts using a cookie with the ``remember_me`` firewall option: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->firewall('main') // ... @@ -184,7 +184,7 @@ allow users to opt-out. In these cases, you can use the // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->firewall('main') // ... @@ -347,7 +347,7 @@ are fetched from the user object using the // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->firewall('main') // ... @@ -431,7 +431,7 @@ You can enable the doctrine token provider using the ``doctrine`` setting: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->firewall('main') // ... @@ -520,7 +520,7 @@ Then, configure the service ID of your custom token provider as ``service``: use App\Security\RememberMe\CustomTokenProvider; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->firewall('main') // ... diff --git a/security/user_checkers.rst b/security/user_checkers.rst index b0324a4d393..99cdfe04076 100644 --- a/security/user_checkers.rst +++ b/security/user_checkers.rst @@ -105,7 +105,7 @@ is the service id of your user checker: use App\Security\UserChecker; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->firewall('main') ->pattern('^/') @@ -244,7 +244,7 @@ Once your checker services are tagged, next you will need configure your firewal // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { // ... $security->firewall('api') ->pattern('^/api') diff --git a/security/voters.rst b/security/voters.rst index 21df144e7bc..0f47a4cdd7a 100644 --- a/security/voters.rst +++ b/security/voters.rst @@ -318,7 +318,7 @@ security configuration: // config/packages/security.php use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->accessDecisionManager() ->strategy('unanimous') ->allowIfAllAbstain(false) @@ -365,7 +365,7 @@ option to use a custom service (your service must implement the use App\Security\MyCustomAccessDecisionStrategy; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->accessDecisionManager() ->strategyService(MyCustomAccessDecisionStrategy::class) // ... @@ -412,7 +412,7 @@ must implement the :class:`Symfony\\Component\\Security\\Core\\Authorization\\Ac use App\Security\MyCustomAccessDecisionManager; use Symfony\Config\SecurityConfig; - return static function (SecurityConfig $security) { + return static function (SecurityConfig $security): void { $security->accessDecisionManager() ->service(MyCustomAccessDecisionManager::class) // ... diff --git a/templates.rst b/templates.rst index 5f59c91f59a..182f3d759a6 100644 --- a/templates.rst +++ b/templates.rst @@ -244,7 +244,7 @@ Consider the following routing configuration: use App\Controller\BlogController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return function (RoutingConfigurator $routes): void { $routes->add('blog_index', '/') ->controller([BlogController::class, 'index']) ; @@ -432,7 +432,7 @@ inside the main Twig configuration file: // config/packages/twig.php use Symfony\Config\TwigConfig; - return static function (TwigConfig $twig) { + return static function (TwigConfig $twig): void { // ... $twig->global('ga_tracking')->value('UA-xxxxx-x'); @@ -491,7 +491,7 @@ in container parameters `: use function Symfony\Component\DependencyInjection\Loader\Configurator\service; use Symfony\Config\TwigConfig; - return static function (TwigConfig $twig) { + return static function (TwigConfig $twig): void { // ... $twig->global('uuid')->value(service('App\Generator\UuidGenerator')); @@ -709,7 +709,7 @@ provided by Symfony: use Symfony\Bundle\FrameworkBundle\Controller\TemplateController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return function (RoutingConfigurator $routes): void { $routes->add('acme_privacy', '/privacy') ->controller(TemplateController::class) ->defaults([ @@ -1321,7 +1321,7 @@ the ``value`` is the Twig namespace, which is explained later: // config/packages/twig.php use Symfony\Config\TwigConfig; - return static function (TwigConfig $twig) { + return static function (TwigConfig $twig): void { // ... // directories are relative to the project root dir (but you @@ -1377,7 +1377,7 @@ configuration to define a namespace for each template directory: // config/packages/twig.php use Symfony\Config\TwigConfig; - return static function (TwigConfig $twig) { + return static function (TwigConfig $twig): void { // ... $twig->path('email/default/templates', 'email'); diff --git a/testing.rst b/testing.rst index 6bdafc1c32e..da91d81cf7b 100644 --- a/testing.rst +++ b/testing.rst @@ -187,7 +187,7 @@ code to production: // config/packages/test/twig.php use Symfony\Config\TwigConfig; - return static function (TwigConfig $twig) { + return static function (TwigConfig $twig): void { $twig->strictVariables(true); }; diff --git a/testing/dom_crawler.rst b/testing/dom_crawler.rst index 65669698539..139d94efdd9 100644 --- a/testing/dom_crawler.rst +++ b/testing/dom_crawler.rst @@ -48,10 +48,12 @@ narrow down your node selection by chaining the method calls:: $crawler ->filter('h1') - ->reduce(function ($node, $i) { + ->reduce(function ($node, int $i): bool { if (!$node->attr('class')) { return false; } + + return true; }) ->first() ; @@ -86,6 +88,6 @@ The Crawler can extract information from the nodes:: $info = $crawler->extract(['_text', 'href']); // executes a lambda for each node and return an array of results - $data = $crawler->each(function ($node, $i) { + $data = $crawler->each(function ($node, int $i): string { return $node->attr('href'); }); diff --git a/translation.rst b/translation.rst index 9842e561f1d..22969db3457 100644 --- a/translation.rst +++ b/translation.rst @@ -854,7 +854,7 @@ A better policy is to include the locale in the URL using the use App\Controller\ContactController; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; - return function (RoutingConfigurator $routes) { + return function (RoutingConfigurator $routes): void { $routes->add('contact', '/{_locale}/contact') ->controller([ContactController::class, 'index']) ->requirements([