diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 5f2d77a453eaf..d4dafb2aa0029 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,6 +1,6 @@
| Q | A
| ------------- | ---
-| Branch? | 7.3 for features / 6.4, and 7.2 for bug fixes
+| Branch? | 7.4 for features / 6.4, 7.2, or 7.3 for bug fixes
| Bug fix? | yes/no
| New feature? | yes/no
| Deprecations? | yes/no
diff --git a/.github/expected-missing-return-types.diff b/.github/expected-missing-return-types.diff
index d48f4ff600dbe..a9b6f3b22ca03 100644
--- a/.github/expected-missing-return-types.diff
+++ b/.github/expected-missing-return-types.diff
@@ -8923,6 +8923,23 @@ diff --git a/src/Symfony/Component/Intl/Data/Bundle/Writer/BundleWriterInterface
- public function write(string $path, string $locale, mixed $data);
+ public function write(string $path, string $locale, mixed $data): void;
}
+diff --git a/src/Symfony/Component/Intl/Transliterator/EmojiTransliterator.php b/src/Symfony/Component/Intl/Transliterator/EmojiTransliterator.php
+--- a/src/Symfony/Component/Intl/Transliterator/EmojiTransliterator.php
++++ b/src/Symfony/Component/Intl/Transliterator/EmojiTransliterator.php
+@@ -74,5 +74,5 @@ if (!class_exists(\Transliterator::class)) {
+ */
+ #[\ReturnTypeWillChange]
+- public function getErrorCode(): int|false
++ public function getErrorCode(): int
+ {
+ return isset($this->transliterator) ? $this->transliterator->getErrorCode() : 0;
+@@ -83,5 +83,5 @@ if (!class_exists(\Transliterator::class)) {
+ */
+ #[\ReturnTypeWillChange]
+- public function getErrorMessage(): string|false
++ public function getErrorMessage(): string
+ {
+ return isset($this->transliterator) ? $this->transliterator->getErrorMessage() : '';
diff --git a/src/Symfony/Component/Intl/Util/IntlTestHelper.php b/src/Symfony/Component/Intl/Util/IntlTestHelper.php
--- a/src/Symfony/Component/Intl/Util/IntlTestHelper.php
+++ b/src/Symfony/Component/Intl/Util/IntlTestHelper.php
diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml
index 40da4746f4fbe..677e6e6a30d91 100644
--- a/.github/workflows/scorecards.yml
+++ b/.github/workflows/scorecards.yml
@@ -6,7 +6,7 @@ on:
schedule:
- cron: '34 4 * * 6'
push:
- branches: [ "7.3" ]
+ branches: [ "7.4" ]
# Declare default permissions as read only.
permissions: read-all
diff --git a/CHANGELOG-6.4.md b/CHANGELOG-6.4.md
index 7eb354e2603a5..78e2a5e01dec1 100644
--- a/CHANGELOG-6.4.md
+++ b/CHANGELOG-6.4.md
@@ -7,6 +7,25 @@ in 6.4 minor versions.
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v6.4.0...v6.4.1
+* 6.4.22 (2025-05-29)
+
+ * bug #60549 [Translation] Add intl-icu fallback for MessageCatalogue metadata (pontus-mp)
+ * bug #60571 [ErrorHandler] Do not transform file to link if it does not exist (lyrixx)
+ * bug #60494 [Messenger] fix: Add argument as integer (overexpOG)
+ * bug #60524 [Notifier] Fix Clicksend transport (BafS)
+ * bug #60478 [Validator] add missing `$extensions` and `$extensionsMessage` to the `Image` constraint (xabbuh)
+ * bug #60423 [DependencyInjection] Make `DefinitionErrorExceptionPass` consider `IGNORE_ON_UNINITIALIZED_REFERENCE` and `RUNTIME_EXCEPTION_ON_INVALID_REFERENCE` the same (MatTheCat)
+ * bug #60421 [VarExporter] Fixed lazy-loading ghost objects generation with property hooks (cheack)
+ * bug #60266 [Security] Exclude remember_me from default login authenticators (santysisi)
+ * bug #60400 [Config] Fix generated comment for multiline "info" (GromNaN)
+ * bug #60260 [Serializer] Prevent `Cannot traverse an already closed generator` error by materializing Traversable input (santysisi)
+ * bug #60292 [HttpFoundation] Encode path in `X-Accel-Redirect` header (Athorcis)
+ * bug #60379 [Security] Avoid failing when PersistentRememberMeHandler handles a malformed cookie (Seldaek)
+ * bug #60373 [FrameworkBundle] Ensure `Email` class exists before using it (Kocal)
+ * bug #60365 [FrameworkBundle] ensure that all supported e-mail validation modes can be configured (xabbuh)
+ * bug #60350 [Security][LoginLink] Throw `InvalidLoginLinkException` on invalid parameters (davidszkiba)
+ * bug #60340 [String] fix EmojiTransliterator return type compatibility with PHP 8.5 (xabbuh)
+
* 6.4.21 (2025-05-02)
* bug #60288 [VarExporter] dump default value for property hooks if present (xabbuh)
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index ee2cb2a40889b..3e7f5ec2b6e78 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -30,9 +30,9 @@ The Symfony Connect username in parenthesis allows to get more information
- Kris Wallsmith (kriswallsmith)
- Jakub Zalas (jakubzalas)
- Yonel Ceruto (yonelceruto)
+ - HypeMC (hypemc)
- Hugo Hamon (hhamon)
- Tobias Nyholm (tobias)
- - HypeMC (hypemc)
- Jérôme Tamarelle (gromnan)
- Antoine Lamirault (alamirault)
- Samuel ROZE (sroze)
@@ -96,8 +96,8 @@ The Symfony Connect username in parenthesis allows to get more information
- Henrik Bjørnskov (henrikbjorn)
- Ruud Kamphuis (ruudk)
- David Buchmann (dbu)
- - Andrej Hudec (pulzarraider)
- Tomas Norkūnas (norkunas)
+ - Andrej Hudec (pulzarraider)
- Jáchym Toušek (enumag)
- Hubert Lenoir (hubert_lenoir)
- Christian Raue
@@ -160,12 +160,13 @@ The Symfony Connect username in parenthesis allows to get more information
- Włodzimierz Gajda (gajdaw)
- Javier Spagnoletti (phansys)
- Adrien Brault (adrienbrault)
+ - Florent Morselli (spomky_)
+ - soyuka
- Florian Voutzinos (florianv)
- Teoh Han Hui (teohhanhui)
- Przemysław Bogusz (przemyslaw-bogusz)
- Colin Frei
- excelwebzone
- - Florent Morselli (spomky_)
- Paráda József (paradajozsef)
- Maximilian Beckers (maxbeckers)
- Baptiste Clavié (talus)
@@ -175,17 +176,16 @@ The Symfony Connect username in parenthesis allows to get more information
- Dāvis Zālītis (k0d3r1s)
- Gordon Franke (gimler)
- Malte Schlüter (maltemaltesich)
- - soyuka
- jeremyFreeAgent (jeremyfreeagent)
- Michael Babker (mbabker)
- Alexis Lefebvre
+ - Hugo Alliaume (kocal)
- Christopher Hertel (chertel)
- Joshua Thijssen
- Vasilij Dusko
- Daniel Wehner (dawehner)
- Robert Schönthal (digitalkaoz)
- Smaine Milianni (ismail1432)
- - Hugo Alliaume (kocal)
- François-Xavier de Guillebon (de-gui_f)
- Andreas Schempp (aschempp)
- noniagriconomie
@@ -255,6 +255,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Alessandro Lai (jean85)
- 77web
- Gocha Ossinkine (ossinkine)
+ - matlec
- Jesse Rushlow (geeshoe)
- Matthieu Ouellette-Vachon (maoueh)
- Michał Pipa (michal.pipa)
@@ -286,7 +287,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Clément JOBEILI (dator)
- Andreas Möller (localheinz)
- Marek Štípek (maryo)
- - matlec
- Daniel Espendiller
- Arnaud PETITPAS (apetitpa)
- Michael Käfer (michael_kaefer)
@@ -310,6 +310,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Patrick Landolt (scube)
- Karoly Gossler (connorhu)
- Timo Bakx (timobakx)
+ - Quentin Devos
- Giorgio Premi
- Alan Poulain (alanpoulain)
- Ruben Gonzalez (rubenrua)
@@ -337,6 +338,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Nikolay Labinskiy (e-moe)
- Martin Schuhfuß (usefulthink)
- apetitpa
+ - wkania
- Guilliam Xavier
- Pierre Minnieur (pminnieur)
- Dominique Bongiraud
@@ -377,6 +379,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Pascal Montoya
- Julien Brochet
- François Pluchino (francoispluchino)
+ - W0rma
- Tristan Darricau (tristandsensio)
- Jan Sorgalla (jsor)
- henrikbjorn
@@ -401,7 +404,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Zan Baldwin (zanbaldwin)
- Tim Goudriaan (codedmonkey)
- BoShurik
- - Quentin Devos
- Adam Prager (padam87)
- Benoît Burnichon (bburnichon)
- maxime.steinhausser
@@ -428,7 +430,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Uwe Jäger (uwej711)
- javaDeveloperKid
- Chris Smith (cs278)
- - W0rma
- Lynn van der Berg (kjarli)
- Michaël Perrin (michael.perrin)
- Eugene Leonovich (rybakit)
@@ -438,6 +439,7 @@ The Symfony Connect username in parenthesis allows to get more information
- GordonsLondon
- Ray
- Philipp Cordes (corphi)
+ - Fabien S (bafs)
- Chekote
- Thomas Adam
- Anderson Müller
@@ -471,6 +473,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Marcos Sánchez
- Emanuele Panzeri (thepanz)
- Zmey
+ - Santiago San Martin (santysisi)
- Kim Hemsø Rasmussen (kimhemsoe)
- Maximilian Reichel (phramz)
- Samaël Villette (samadu61)
@@ -498,6 +501,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Manuel Kießling (manuelkiessling)
- Alexey Kopytko (sanmai)
- Warxcell (warxcell)
+ - SiD (plbsid)
- Atsuhiro KUBO (iteman)
- rudy onfroy (ronfroy)
- Serkan Yildiz (srknyldz)
@@ -507,7 +511,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Gabor Toth (tgabi333)
- realmfoo
- Joppe De Cuyper (joppedc)
- - Fabien S (bafs)
- Simon Podlipsky (simpod)
- Thomas Tourlourat (armetiz)
- Andrey Esaulov (andremaha)
@@ -612,7 +615,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Alex (aik099)
- Kieran Brahney
- Fabien Villepinte
- - SiD (plbsid)
- Greg Thornton (xdissent)
- Alex Bowers
- Kev
@@ -638,6 +640,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Ivan Sarastov (isarastov)
- flack (flack)
- Shein Alexey
+ - Link1515
- Joe Lencioni
- Daniel Tschinder
- Diego Agulló (aeoris)
@@ -758,6 +761,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Jérémy REYNAUD (babeuloula)
- Faizan Akram Dar (faizanakram)
- Arkadius Stefanski (arkadius)
+ - Andy Palmer (andyexeter)
- Jonas Flodén (flojon)
- AnneKir
- Tobias Weichart
@@ -781,6 +785,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Giso Stallenberg (gisostallenberg)
- Rob Bast
- Roberto Espinoza (respinoza)
+ - Steven RENAUX (steven_renaux)
- Marvin Feldmann (breyndotechse)
- Soufian EZ ZANTAR (soezz)
- Marek Zajac
@@ -867,7 +872,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Dariusz Ruminski
- Bahman Mehrdad (bahman)
- Romain Gautier (mykiwi)
- - Link1515
- Matthieu Bontemps
- Erik Trapman
- De Cock Xavier (xdecock)
@@ -1010,7 +1014,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Jonas Elfering
- Mihai Stancu
- Nahuel Cuesta (ncuesta)
- - Santiago San Martin
- Chris Boden (cboden)
- EStyles (insidestyles)
- Christophe Villeger (seragan)
@@ -1065,7 +1068,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Pierrick VIGNAND (pierrick)
- Alex Bogomazov (alebo)
- aaa2000 (aaa2000)
- - Andy Palmer (andyexeter)
- Andrew Neil Forster (krciga22)
- Stefan Warman (warmans)
- Tristan Maindron (tmaindron)
@@ -1865,6 +1867,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Philipp Fritsche
- Léon Gersen
- tarlepp
+ - Giuseppe Arcuti
- Dustin Wilson
- Benjamin Paap (benjaminpaap)
- Claus Due (namelesscoder)
@@ -1958,7 +1961,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Bruno MATEU
- Jeremy Bush
- Lucas Bäuerle
- - Steven RENAUX (steven_renaux)
- Laurens Laman
- Thomason, James
- Dario Savella
@@ -2195,6 +2197,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Tim Ward
- Adiel Cristo (arcristo)
- Christian Flach (cmfcmf)
+ - Dennis Jaschinski (d.jaschinski)
- Fabian Kropfhamer (fabiank)
- Jeffrey Cafferata (jcidnl)
- Junaid Farooq (junaidfarooq)
@@ -2264,6 +2267,7 @@ The Symfony Connect username in parenthesis allows to get more information
- wivaku
- Markus Reinhold
- Jingyu Wang
+ - es
- steveYeah
- Asrorbek (asrorbek)
- Samy D (dinduks)
@@ -2278,6 +2282,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Alan Scott
- Juanmi Rodriguez Cerón
- twifty
+ - David Szkiba
- Andy Raines
- François Poguet
- Anthony Ferrara
@@ -2296,6 +2301,7 @@ The Symfony Connect username in parenthesis allows to get more information
- xdavidwu
- Benjamin RICHARD
- Raphaël Droz
+ - Vladimir Pakhomchik
- pdommelen
- Eric Stern
- ShiraNai7
@@ -2710,6 +2716,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Marcel Siegert
- ryunosuke
- Bruno BOUTAREL
+ - Athorcis
- John Stevenson
- everyx
- Richard Heine
@@ -2767,6 +2774,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Abdouarrahmane FOUAD (fabdouarrahmane)
- Jakub Janata (janatjak)
- Jm Aribau (jmaribau)
+ - Maciej Paprocki (maciekpaprocki)
- Matthew Foster (mfoster)
- Paul Seiffert (seiffert)
- Vasily Khayrulin (sirian)
@@ -3114,6 +3122,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Darryl Hein (xmmedia)
- Vladimir Sadicov (xtech)
- Marcel Berteler
+ - Ruud Seberechts
- sdkawata
- Frederik Schmitt
- Peter van Dommelen
@@ -3151,6 +3160,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Pierre Rineau
- Florian Morello
- Maxim Lovchikov
+ - ivelin vasilev
- adenkejawen
- Florent SEVESTRE (aniki-taicho)
- Ari Pringle (apringle)
@@ -3327,6 +3337,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Kevin Verschaeve (keversc)
- Kevin Herrera (kherge)
- Kubicki Kamil (kubik)
+ - Lauris Binde (laurisb)
- Luis Ramón López López (lrlopez)
- Vladislav Nikolayev (luxemate)
- Martin Mandl (m2mtech)
@@ -3372,7 +3383,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Youpie
- Jason Stephens
- Korvin Szanto
- - wkania
- srsbiz
- Taylan Kasap
- Michael Orlitzky
@@ -3585,6 +3595,7 @@ The Symfony Connect username in parenthesis allows to get more information
- mieszko4
- Steve Preston
- ibasaw
+ - koyolgecen
- Wojciech Skorodecki
- Kevin Frantz
- Neophy7e
@@ -3614,6 +3625,7 @@ The Symfony Connect username in parenthesis allows to get more information
- satalaondrej
- Matthias Dötsch
- jonmldr
+ - Nowfel2501
- Yevgen Kovalienia
- Lebnik
- Shude
@@ -3635,6 +3647,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Egor Gorbachev
- Julian Krzefski
- Derek Stephen McLean
+ - PatrickRedStar
- Norman Soetbeer
- zorn
- Yuriy Potemkin
@@ -3744,6 +3757,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Brandon Kelly (brandonkelly)
- Choong Wei Tjeng (choonge)
- Bermon Clément (chou666)
+ - Chris Shennan (chrisshennan)
- Citia (citia)
- Kousuke Ebihara (co3k)
- Loïc Vernet (coil)
@@ -3906,6 +3920,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Romain
- Xavier REN
- Kevin Meijer
+ - Ignacio Alveal
- max
- Alexander Bauer (abauer)
- Ahmad Mayahi (ahmadmayahi)
diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineFooType.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineFooType.php
index 93e9818f4383c..6619f911ae1e0 100644
--- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineFooType.php
+++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineFooType.php
@@ -41,7 +41,7 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform): ?str
throw new ConversionException(sprintf('Expected "%s", got "%s"', 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\Foo', get_debug_type($value)));
}
- return $foo->bar;
+ return $value->bar;
}
public function convertToPHPValue($value, AbstractPlatform $platform): ?Foo
diff --git a/src/Symfony/Bridge/Twig/Extension/WebLinkExtension.php b/src/Symfony/Bridge/Twig/Extension/WebLinkExtension.php
index 11eca517c5d69..c8640a4ea5f00 100644
--- a/src/Symfony/Bridge/Twig/Extension/WebLinkExtension.php
+++ b/src/Symfony/Bridge/Twig/Extension/WebLinkExtension.php
@@ -46,7 +46,7 @@ public function getFunctions(): array
/**
* Adds a "Link" HTTP header.
*
- * @param string $rel The relation type (e.g. "preload", "prefetch", "prerender" or "dns-prefetch")
+ * @param string $rel The relation type (e.g. "preload", "prefetch", or "dns-prefetch")
* @param array $attributes The attributes of this link (e.g. "['as' => true]", "['pr' => 0.5]")
*
* @return string The relation URI
@@ -117,7 +117,11 @@ public function prefetch(string $uri, array $attributes = []): string
}
/**
- * Indicates to the client that it should prerender this resource .
+ * Indicates to the client that it should prerender this resource.
+ *
+ * This feature is deprecated and superseded by the Speculation Rules API.
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/rel/prerender
*
* @param array $attributes The attributes of this link (e.g. "['as' => true]", "['pr' => 0.5]")
*
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
index cb52a0704fd99..bae8967a8b723 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
@@ -45,6 +45,7 @@
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Translation\Translator;
use Symfony\Component\Uid\Factory\UuidFactory;
+use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Validation;
use Symfony\Component\Webhook\Controller\WebhookController;
use Symfony\Component\WebLink\HttpHeaderSerializer;
@@ -1066,7 +1067,7 @@ private function addValidationSection(ArrayNodeDefinition $rootNode, callable $e
->validate()->castToArray()->end()
->end()
->scalarNode('translation_domain')->defaultValue('validators')->end()
- ->enumNode('email_validation_mode')->values(['html5', 'loose', 'strict'])->end()
+ ->enumNode('email_validation_mode')->values((class_exists(Email::class) ? Email::VALIDATION_MODES : ['html5-allow-no-tld', 'html5', 'strict']) + ['loose'])->end()
->arrayNode('mapping')
->addDefaultsIfNotSet()
->fixXmlConfig('path')
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index f585b5bbb784b..68386120e06b1 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -735,7 +735,7 @@ static function (ChildDefinition $definition, AsPeriodicTask|AsCronTask $attribu
$container->getDefinition('config_cache_factory')->setArguments([]);
}
- if (!$config['disallow_search_engine_index'] ?? false) {
+ if (!$config['disallow_search_engine_index']) {
$container->removeDefinition('disallow_search_engine_index_response_listener');
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer.php
index 7a3a95739b0f2..f1dc560ab76f8 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer.php
@@ -45,7 +45,6 @@
tagged_iterator('mailer.transport_factory'),
])
- ->set('mailer.default_transport', TransportInterface::class)
->alias('mailer.default_transport', 'mailer.transports')
->alias(TransportInterface::class, 'mailer.default_transport')
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/PhpFrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/PhpFrameworkExtensionTest.php
index 53268ffd283d8..e5cc8522aafb4 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/PhpFrameworkExtensionTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/PhpFrameworkExtensionTest.php
@@ -17,6 +17,7 @@
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
+use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Workflow\Exception\InvalidDefinitionException;
class PhpFrameworkExtensionTest extends FrameworkExtensionTestCase
@@ -245,4 +246,31 @@ public function testRateLimiterLockFactory()
$container->getDefinition('limiter.without_lock')->getArgument(2);
}
+
+ /**
+ * @dataProvider emailValidationModeProvider
+ */
+ public function testValidatorEmailValidationMode(string $mode)
+ {
+ $this->expectNotToPerformAssertions();
+
+ $this->createContainerFromClosure(function (ContainerBuilder $container) use ($mode) {
+ $container->loadFromExtension('framework', [
+ 'annotations' => false,
+ 'http_method_override' => false,
+ 'handle_all_throwables' => true,
+ 'php_errors' => ['log' => true],
+ 'validation' => [
+ 'email_validation_mode' => $mode,
+ ],
+ ]);
+ });
+ }
+
+ public static function emailValidationModeProvider()
+ {
+ foreach (Email::VALIDATION_MODES as $mode) {
+ yield [$mode];
+ }
+ }
}
diff --git a/src/Symfony/Bundle/SecurityBundle/Security.php b/src/Symfony/Bundle/SecurityBundle/Security.php
index acb30adba8adf..6b5286f2ea868 100644
--- a/src/Symfony/Bundle/SecurityBundle/Security.php
+++ b/src/Symfony/Bundle/SecurityBundle/Security.php
@@ -188,8 +188,7 @@ private function getAuthenticator(?string $authenticatorName, string $firewallNa
$firewallAuthenticatorLocator = $this->authenticators[$firewallName];
if (!$authenticatorName) {
- $authenticatorIds = array_keys($firewallAuthenticatorLocator->getProvidedServices());
-
+ $authenticatorIds = array_filter(array_keys($firewallAuthenticatorLocator->getProvidedServices()), fn (string $authenticatorId) => $authenticatorId !== \sprintf('security.authenticator.remember_me.%s', $firewallName));
if (!$authenticatorIds) {
throw new LogicException(sprintf('No authenticator was found for the firewall "%s".', $firewallName));
}
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/SecurityTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/SecurityTest.php
index 35bd329b2297e..c150730c2a8cb 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/SecurityTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/SecurityTest.php
@@ -155,7 +155,10 @@ public function testLogin()
$firewallAuthenticatorLocator
->expects($this->once())
->method('getProvidedServices')
- ->willReturn(['security.authenticator.custom.dev' => $authenticator])
+ ->willReturn([
+ 'security.authenticator.custom.dev' => $authenticator,
+ 'security.authenticator.remember_me.main' => $authenticator
+ ])
;
$firewallAuthenticatorLocator
->expects($this->once())
@@ -274,6 +277,49 @@ public function testLoginWithoutRequestContext()
$security->login($user);
}
+ public function testLoginFailsWhenTooManyAuthenticatorsFound()
+ {
+ $request = new Request();
+ $authenticator = $this->createMock(AuthenticatorInterface::class);
+ $requestStack = $this->createMock(RequestStack::class);
+ $firewallMap = $this->createMock(FirewallMap::class);
+ $firewall = new FirewallConfig('main', 'main');
+ $userAuthenticator = $this->createMock(UserAuthenticatorInterface::class);
+ $user = $this->createMock(UserInterface::class);
+ $userChecker = $this->createMock(UserCheckerInterface::class);
+
+ $container = $this->createMock(ContainerInterface::class);
+ $container
+ ->expects($this->atLeastOnce())
+ ->method('get')
+ ->willReturnMap([
+ ['request_stack', $requestStack],
+ ['security.firewall.map', $firewallMap],
+ ['security.authenticator.managers_locator', $this->createContainer('main', $userAuthenticator)],
+ ['security.user_checker_locator', $this->createContainer('main', $userChecker)],
+ ])
+ ;
+
+ $requestStack->expects($this->once())->method('getCurrentRequest')->willReturn($request);
+ $firewallMap->expects($this->once())->method('getFirewallConfig')->willReturn($firewall);
+
+ $firewallAuthenticatorLocator = $this->createMock(ServiceProviderInterface::class);
+ $firewallAuthenticatorLocator
+ ->expects($this->once())
+ ->method('getProvidedServices')
+ ->willReturn([
+ 'security.authenticator.custom.main' => $authenticator,
+ 'security.authenticator.other.main' => $authenticator
+ ])
+ ;
+
+ $security = new Security($container, ['main' => $firewallAuthenticatorLocator]);
+
+ $this->expectException(\LogicException::class);
+ $this->expectExceptionMessage('Too many authenticators were found for the current firewall "main". You must provide an instance of "Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface" to login programmatically. The available authenticators for the firewall "main" are "security.authenticator.custom.main" ,"security.authenticator.other.main');
+ $security->login($user);
+ }
+
public function testLogout()
{
$request = new Request();
diff --git a/src/Symfony/Component/Config/Builder/ConfigBuilderGenerator.php b/src/Symfony/Component/Config/Builder/ConfigBuilderGenerator.php
index d43d814ebd38b..9649c8d82cbb9 100644
--- a/src/Symfony/Component/Config/Builder/ConfigBuilderGenerator.php
+++ b/src/Symfony/Component/Config/Builder/ConfigBuilderGenerator.php
@@ -413,39 +413,39 @@ private function getComment(BaseNode $node): string
{
$comment = '';
if ('' !== $info = (string) $node->getInfo()) {
- $comment .= ' * '.$info."\n";
+ $comment .= $info."\n";
}
if (!$node instanceof ArrayNode) {
foreach ((array) ($node->getExample() ?? []) as $example) {
- $comment .= ' * @example '.$example."\n";
+ $comment .= '@example '.$example."\n";
}
if ('' !== $default = $node->getDefaultValue()) {
- $comment .= ' * @default '.(null === $default ? 'null' : var_export($default, true))."\n";
+ $comment .= '@default '.(null === $default ? 'null' : var_export($default, true))."\n";
}
if ($node instanceof EnumNode) {
- $comment .= sprintf(' * @param ParamConfigurator|%s $value', implode('|', array_unique(array_map(fn ($a) => !$a instanceof \UnitEnum ? var_export($a, true) : '\\'.ltrim(var_export($a, true), '\\'), $node->getValues()))))."\n";
+ $comment .= sprintf('@param ParamConfigurator|%s $value', implode('|', array_unique(array_map(fn ($a) => !$a instanceof \UnitEnum ? var_export($a, true) : '\\'.ltrim(var_export($a, true), '\\'), $node->getValues()))))."\n";
} else {
$parameterTypes = $this->getParameterTypes($node);
- $comment .= ' * @param ParamConfigurator|'.implode('|', $parameterTypes).' $value'."\n";
+ $comment .= '@param ParamConfigurator|'.implode('|', $parameterTypes).' $value'."\n";
}
} else {
foreach ((array) ($node->getExample() ?? []) as $example) {
- $comment .= ' * @example '.json_encode($example)."\n";
+ $comment .= '@example '.json_encode($example)."\n";
}
if ($node->hasDefaultValue() && [] != $default = $node->getDefaultValue()) {
- $comment .= ' * @default '.json_encode($default)."\n";
+ $comment .= '@default '.json_encode($default)."\n";
}
}
if ($node->isDeprecated()) {
- $comment .= ' * @deprecated '.$node->getDeprecation($node->getName(), $node->getParent()->getName())['message']."\n";
+ $comment .= '@deprecated '.$node->getDeprecation($node->getName(), $node->getParent()->getName())['message']."\n";
}
- return $comment;
+ return $comment ? ' * '.str_replace("\n", "\n * ", rtrim($comment, "\n"))."\n" : '';
}
/**
diff --git a/src/Symfony/Component/Config/Tests/Builder/Fixtures/NodeInitialValues.php b/src/Symfony/Component/Config/Tests/Builder/Fixtures/NodeInitialValues.php
index 153af57be9b5b..5c1259c20edd8 100644
--- a/src/Symfony/Component/Config/Tests/Builder/Fixtures/NodeInitialValues.php
+++ b/src/Symfony/Component/Config/Tests/Builder/Fixtures/NodeInitialValues.php
@@ -38,7 +38,13 @@ public function getConfigTreeBuilder(): TreeBuilder
->arrayPrototype()
->fixXmlConfig('option')
->children()
- ->scalarNode('dsn')->end()
+ ->scalarNode('dsn')
+ ->info(<<<'INFO'
+ The DSN to use. This is a required option.
+ The info is used to describe the DSN,
+ it can be multi-line.
+ INFO)
+ ->end()
->scalarNode('serializer')->defaultNull()->end()
->arrayNode('options')
->normalizeKeys(false)
diff --git a/src/Symfony/Component/Config/Tests/Builder/Fixtures/NodeInitialValues/Symfony/Config/NodeInitialValues/Messenger/TransportsConfig.php b/src/Symfony/Component/Config/Tests/Builder/Fixtures/NodeInitialValues/Symfony/Config/NodeInitialValues/Messenger/TransportsConfig.php
index b9d8b48db3556..6a98166eccc94 100644
--- a/src/Symfony/Component/Config/Tests/Builder/Fixtures/NodeInitialValues/Symfony/Config/NodeInitialValues/Messenger/TransportsConfig.php
+++ b/src/Symfony/Component/Config/Tests/Builder/Fixtures/NodeInitialValues/Symfony/Config/NodeInitialValues/Messenger/TransportsConfig.php
@@ -16,6 +16,9 @@ class TransportsConfig
private $_usedProperties = [];
/**
+ * The DSN to use. This is a required option.
+ * The info is used to describe the DSN,
+ * it can be multi-line.
* @default null
* @param ParamConfigurator|mixed $value
* @return $this
diff --git a/src/Symfony/Component/Console/Tests/SignalRegistry/SignalMapTest.php b/src/Symfony/Component/Console/Tests/SignalRegistry/SignalMapTest.php
index f4e320477d4be..3a0c49bb01e21 100644
--- a/src/Symfony/Component/Console/Tests/SignalRegistry/SignalMapTest.php
+++ b/src/Symfony/Component/Console/Tests/SignalRegistry/SignalMapTest.php
@@ -18,15 +18,13 @@ class SignalMapTest extends TestCase
{
/**
* @requires extension pcntl
- *
- * @testWith [2, "SIGINT"]
- * [9, "SIGKILL"]
- * [15, "SIGTERM"]
- * [31, "SIGSYS"]
*/
- public function testSignalExists(int $signal, string $expected)
+ public function testSignalExists()
{
- $this->assertSame($expected, SignalMap::getSignalName($signal));
+ $this->assertSame('SIGINT', SignalMap::getSignalName(\SIGINT));
+ $this->assertSame('SIGKILL', SignalMap::getSignalName(\SIGKILL));
+ $this->assertSame('SIGTERM', SignalMap::getSignalName(\SIGTERM));
+ $this->assertSame('SIGSYS', SignalMap::getSignalName(\SIGSYS));
}
public function testSignalDoesNotExist()
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/DefinitionErrorExceptionPass.php b/src/Symfony/Component/DependencyInjection/Compiler/DefinitionErrorExceptionPass.php
index b6a2cf907ee9b..204401cd2c8ee 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/DefinitionErrorExceptionPass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/DefinitionErrorExceptionPass.php
@@ -65,7 +65,10 @@ protected function processValue(mixed $value, bool $isRoot = false): mixed
}
if ($value instanceof Reference && $this->currentId !== $targetId = (string) $value) {
- if (ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE === $value->getInvalidBehavior()) {
+ if (
+ ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE === $value->getInvalidBehavior()
+ || ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $value->getInvalidBehavior()
+ ) {
$this->sourceReferences[$targetId][$this->currentId] ??= true;
} else {
$this->sourceReferences[$targetId][$this->currentId] = false;
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/DefinitionErrorExceptionPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/DefinitionErrorExceptionPassTest.php
index 9ab5c27fcf763..5ed7be315114a 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/DefinitionErrorExceptionPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/DefinitionErrorExceptionPassTest.php
@@ -64,6 +64,9 @@ public function testSkipNestedErrors()
$container->register('foo', 'stdClass')
->addArgument(new Reference('bar', ContainerBuilder::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE));
+ $container->register('baz', 'stdClass')
+ ->addArgument(new Reference('bar', ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE));
+
$pass = new DefinitionErrorExceptionPass();
$pass->process($container);
diff --git a/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php b/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php
index 032f194d2f542..2572a8abd6694 100644
--- a/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php
+++ b/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php
@@ -231,6 +231,10 @@ private function formatFile(string $file, int $line, ?string $text = null): stri
$text .= ' at line '.$line;
}
+ if (!file_exists($file)) {
+ return $text;
+ }
+
$link = $this->fileLinkFormat->format($file, $line);
return sprintf('%s', $this->escape($link), $text);
diff --git a/src/Symfony/Component/Form/Extension/Core/Type/WeekType.php b/src/Symfony/Component/Form/Extension/Core/Type/WeekType.php
index 8027a41a99cd8..778cc2aeb0b7b 100644
--- a/src/Symfony/Component/Form/Extension/Core/Type/WeekType.php
+++ b/src/Symfony/Component/Form/Extension/Core/Type/WeekType.php
@@ -42,7 +42,6 @@ public function buildForm(FormBuilderInterface $builder, array $options)
} else {
$yearOptions = $weekOptions = [
'error_bubbling' => true,
- 'empty_data' => '',
];
// when the form is compound the entries of the array are ignored in favor of children data
// so we need to handle the cascade setting here
diff --git a/src/Symfony/Component/Form/Tests/Fixtures/TestExtension.php b/src/Symfony/Component/Form/Tests/Fixtures/TestExtension.php
index 44725a69c71a5..2704ee5303ad2 100644
--- a/src/Symfony/Component/Form/Tests/Fixtures/TestExtension.php
+++ b/src/Symfony/Component/Form/Tests/Fixtures/TestExtension.php
@@ -34,7 +34,7 @@ public function addType(FormTypeInterface $type)
public function getType($name): FormTypeInterface
{
- return $this->types[$name] ?? null;
+ return $this->types[$name];
}
public function hasType($name): bool
diff --git a/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php
index 41a244b818836..c22f283cba444 100644
--- a/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php
+++ b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php
@@ -229,7 +229,7 @@ public function prepare(Request $request): static
$path = $location.substr($path, \strlen($pathPrefix));
// Only set X-Accel-Redirect header if a valid URI can be produced
// as nginx does not serve arbitrary file paths.
- $this->headers->set($type, $path);
+ $this->headers->set($type, rawurlencode($path));
$this->maxlen = 0;
break;
}
diff --git a/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php
index c7d47a4d70a35..8f298b77f7218 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php
@@ -314,7 +314,15 @@ public function testXAccelMapping($realpath, $mapping, $virtual)
$property->setValue($response, $file);
$response->prepare($request);
- $this->assertEquals($virtual, $response->headers->get('X-Accel-Redirect'));
+ $header = $response->headers->get('X-Accel-Redirect');
+
+ if ($virtual) {
+ // Making sure the path doesn't contain characters unsupported by nginx
+ $this->assertMatchesRegularExpression('/^([^?%]|%[0-9A-F]{2})*$/', $header);
+ $header = rawurldecode($header);
+ }
+
+ $this->assertEquals($virtual, $header);
}
public function testDeleteFileAfterSend()
@@ -361,6 +369,7 @@ public static function getSampleXAccelMappings()
['/home/Foo/bar.txt', '/var/www/=/files/,/home/Foo/=/baz/', '/baz/bar.txt'],
['/home/Foo/bar.txt', '"/var/www/"="/files/", "/home/Foo/"="/baz/"', '/baz/bar.txt'],
['/tmp/bar.txt', '"/var/www/"="/files/", "/home/Foo/"="/baz/"', null],
+ ['/var/www/var/www/files/foo%.txt', '/var/www/=/files/', '/files/var/www/files/foo%.txt'],
];
}
diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php
index 7a4807ecf721e..f1aa0ebeab928 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php
@@ -604,7 +604,6 @@ public function testGetUri()
$server['REDIRECT_QUERY_STRING'] = 'query=string';
$server['REDIRECT_URL'] = '/path/info';
- $server['SCRIPT_NAME'] = '/index.php';
$server['QUERY_STRING'] = 'query=string';
$server['REQUEST_URI'] = '/path/info?toto=test&1=1';
$server['SCRIPT_NAME'] = '/index.php';
@@ -731,7 +730,6 @@ public function testGetUriForPath()
$server['REDIRECT_QUERY_STRING'] = 'query=string';
$server['REDIRECT_URL'] = '/path/info';
- $server['SCRIPT_NAME'] = '/index.php';
$server['QUERY_STRING'] = 'query=string';
$server['REQUEST_URI'] = '/path/info?toto=test&1=1';
$server['SCRIPT_NAME'] = '/index.php';
diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php
index 3ea14b47ed5e1..bd7589173013e 100644
--- a/src/Symfony/Component/HttpKernel/Kernel.php
+++ b/src/Symfony/Component/HttpKernel/Kernel.php
@@ -76,11 +76,11 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
*/
private static array $freshCache = [];
- public const VERSION = '6.4.21';
- public const VERSION_ID = 60421;
+ public const VERSION = '6.4.22';
+ public const VERSION_ID = 60422;
public const MAJOR_VERSION = 6;
public const MINOR_VERSION = 4;
- public const RELEASE_VERSION = 21;
+ public const RELEASE_VERSION = 22;
public const EXTRA_VERSION = '';
public const END_OF_MAINTENANCE = '11/2026';
diff --git a/src/Symfony/Component/Intl/Tests/Transliterator/EmojiTransliteratorTest.php b/src/Symfony/Component/Intl/Tests/Transliterator/EmojiTransliteratorTest.php
index a01bb0d2f9b8e..38b218db7225b 100644
--- a/src/Symfony/Component/Intl/Tests/Transliterator/EmojiTransliteratorTest.php
+++ b/src/Symfony/Component/Intl/Tests/Transliterator/EmojiTransliteratorTest.php
@@ -189,6 +189,6 @@ public function testGetErrorMessageWithUninitializedTransliterator()
{
$transliterator = EmojiTransliterator::create('emoji-en');
- $this->assertFalse($transliterator->getErrorMessage());
+ $this->assertSame('', $transliterator->getErrorMessage());
}
}
diff --git a/src/Symfony/Component/Intl/Transliterator/EmojiTransliterator.php b/src/Symfony/Component/Intl/Transliterator/EmojiTransliterator.php
index 7b8391ca43e0d..b28f5441c8951 100644
--- a/src/Symfony/Component/Intl/Transliterator/EmojiTransliterator.php
+++ b/src/Symfony/Component/Intl/Transliterator/EmojiTransliterator.php
@@ -70,14 +70,22 @@ public function createInverse(): self
return self::create($this->id, self::REVERSE);
}
+ /**
+ * @return int
+ */
+ #[\ReturnTypeWillChange]
public function getErrorCode(): int|false
{
return isset($this->transliterator) ? $this->transliterator->getErrorCode() : 0;
}
+ /**
+ * @return string
+ */
+ #[\ReturnTypeWillChange]
public function getErrorMessage(): string|false
{
- return isset($this->transliterator) ? $this->transliterator->getErrorMessage() : false;
+ return isset($this->transliterator) ? $this->transliterator->getErrorMessage() : '';
}
public static function listIDs(): array
diff --git a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/Connection.php b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/Connection.php
index 0ae1bff21d7c8..061bbcb47d124 100644
--- a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/Connection.php
+++ b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/Connection.php
@@ -31,6 +31,7 @@ class Connection
'x-max-length-bytes',
'x-max-priority',
'x-message-ttl',
+ 'x-delivery-limit',
];
/**
diff --git a/src/Symfony/Component/Notifier/Bridge/ClickSend/ClickSendTransport.php b/src/Symfony/Component/Notifier/Bridge/ClickSend/ClickSendTransport.php
index 0e5bd147d3f61..f60e4e23ee3f9 100644
--- a/src/Symfony/Component/Notifier/Bridge/ClickSend/ClickSendTransport.php
+++ b/src/Symfony/Component/Notifier/Bridge/ClickSend/ClickSendTransport.php
@@ -87,7 +87,7 @@ protected function doSend(MessageInterface $message): SentMessage
$response = $this->client->request('POST', $endpoint, [
'auth_basic' => [$this->apiUsername, $this->apiKey],
- 'json' => array_filter($options),
+ 'json' => ['messages' => [array_filter($options)]],
]);
try {
diff --git a/src/Symfony/Component/Notifier/Bridge/ClickSend/Tests/ClickSendTransportTest.php b/src/Symfony/Component/Notifier/Bridge/ClickSend/Tests/ClickSendTransportTest.php
index 166bb10d8a8dc..ba7923a7fa231 100644
--- a/src/Symfony/Component/Notifier/Bridge/ClickSend/Tests/ClickSendTransportTest.php
+++ b/src/Symfony/Component/Notifier/Bridge/ClickSend/Tests/ClickSendTransportTest.php
@@ -63,10 +63,14 @@ public function testNoInvalidArgumentExceptionIsThrownIfFromIsValid(string $from
$response = $this->createMock(ResponseInterface::class);
$response->expects(self::exactly(2))->method('getStatusCode')->willReturn(200);
$response->expects(self::once())->method('getContent')->willReturn('');
- $client = new MockHttpClient(function (string $method, string $url) use ($response): ResponseInterface {
+ $client = new MockHttpClient(function (string $method, string $url, array $options) use ($response): ResponseInterface {
self::assertSame('POST', $method);
self::assertSame('https://rest.clicksend.com/v3/sms/send', $url);
+ $body = json_decode($options['body'], true);
+ self::assertIsArray($body);
+ self::assertArrayHasKey('messages', $body);
+
return $response;
});
$transport = $this->createTransport($client, $from);
diff --git a/src/Symfony/Component/Routing/Tests/Loader/ObjectLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/ObjectLoaderTest.php
index f3536f1fc56d8..18d8c919a2d73 100644
--- a/src/Symfony/Component/Routing/Tests/Loader/ObjectLoaderTest.php
+++ b/src/Symfony/Component/Routing/Tests/Loader/ObjectLoaderTest.php
@@ -104,7 +104,7 @@ public function supports(mixed $resource, ?string $type = null): bool
protected function getObject(string $id): object
{
- return $this->loaderMap[$id] ?? null;
+ return $this->loaderMap[$id];
}
}
diff --git a/src/Symfony/Component/Runtime/Tests/phpt/application.php b/src/Symfony/Component/Runtime/Tests/phpt/application.php
index 1e1014e9f3e5a..ca2de555edfb7 100644
--- a/src/Symfony/Component/Runtime/Tests/phpt/application.php
+++ b/src/Symfony/Component/Runtime/Tests/phpt/application.php
@@ -18,8 +18,10 @@
return function (array $context) {
$command = new Command('go');
- $command->setCode(function (InputInterface $input, OutputInterface $output) use ($context) {
+ $command->setCode(function (InputInterface $input, OutputInterface $output) use ($context): int {
$output->write('OK Application '.$context['SOME_VAR']);
+
+ return 0;
});
$app = new Application();
diff --git a/src/Symfony/Component/Runtime/Tests/phpt/command.php b/src/Symfony/Component/Runtime/Tests/phpt/command.php
index 3a5fa11e00000..e307d195b113e 100644
--- a/src/Symfony/Component/Runtime/Tests/phpt/command.php
+++ b/src/Symfony/Component/Runtime/Tests/phpt/command.php
@@ -19,7 +19,9 @@
return function (Command $command, InputInterface $input, OutputInterface $output, array $context) {
$command->addOption('hello', 'e', InputOption::VALUE_REQUIRED, 'How should I greet?', 'OK');
- return $command->setCode(function () use ($input, $output, $context) {
+ return $command->setCode(function () use ($input, $output, $context): int {
$output->write($input->getOption('hello').' Command '.$context['SOME_VAR']);
+
+ return 0;
});
};
diff --git a/src/Symfony/Component/Runtime/Tests/phpt/dotenv_overload_command_debug_exists_0_to_1.php b/src/Symfony/Component/Runtime/Tests/phpt/dotenv_overload_command_debug_exists_0_to_1.php
index af6409dda62bc..2968e37ea02f4 100644
--- a/src/Symfony/Component/Runtime/Tests/phpt/dotenv_overload_command_debug_exists_0_to_1.php
+++ b/src/Symfony/Component/Runtime/Tests/phpt/dotenv_overload_command_debug_exists_0_to_1.php
@@ -20,6 +20,8 @@
require __DIR__.'/autoload.php';
-return static fn (Command $command, OutputInterface $output, array $context): Command => $command->setCode(static function () use ($output, $context): void {
+return static fn (Command $command, OutputInterface $output, array $context): Command => $command->setCode(static function () use ($output, $context): int {
$output->writeln($context['DEBUG_ENABLED']);
+
+ return 0;
});
diff --git a/src/Symfony/Component/Runtime/Tests/phpt/dotenv_overload_command_debug_exists_1_to_0.php b/src/Symfony/Component/Runtime/Tests/phpt/dotenv_overload_command_debug_exists_1_to_0.php
index 78a0bf29448b8..1f2fa3590e16f 100644
--- a/src/Symfony/Component/Runtime/Tests/phpt/dotenv_overload_command_debug_exists_1_to_0.php
+++ b/src/Symfony/Component/Runtime/Tests/phpt/dotenv_overload_command_debug_exists_1_to_0.php
@@ -20,6 +20,8 @@
require __DIR__.'/autoload.php';
-return static fn (Command $command, OutputInterface $output, array $context): Command => $command->setCode(static function () use ($output, $context): void {
+return static fn (Command $command, OutputInterface $output, array $context): Command => $command->setCode(static function () use ($output, $context): int {
$output->writeln($context['DEBUG_MODE']);
+
+ return 0;
});
diff --git a/src/Symfony/Component/Runtime/Tests/phpt/dotenv_overload_command_env_exists.php b/src/Symfony/Component/Runtime/Tests/phpt/dotenv_overload_command_env_exists.php
index 3e72372e5af06..8587f20f2382b 100644
--- a/src/Symfony/Component/Runtime/Tests/phpt/dotenv_overload_command_env_exists.php
+++ b/src/Symfony/Component/Runtime/Tests/phpt/dotenv_overload_command_env_exists.php
@@ -20,6 +20,8 @@
require __DIR__.'/autoload.php';
-return static fn (Command $command, OutputInterface $output, array $context): Command => $command->setCode(static function () use ($output, $context): void {
+return static fn (Command $command, OutputInterface $output, array $context): Command => $command->setCode(static function () use ($output, $context): int {
$output->writeln($context['ENV_MODE']);
+
+ return 0;
});
diff --git a/src/Symfony/Component/Runtime/Tests/phpt/dotenv_overload_command_no_debug.php b/src/Symfony/Component/Runtime/Tests/phpt/dotenv_overload_command_no_debug.php
index 3fe4f44d7967b..4ab7694298f95 100644
--- a/src/Symfony/Component/Runtime/Tests/phpt/dotenv_overload_command_no_debug.php
+++ b/src/Symfony/Component/Runtime/Tests/phpt/dotenv_overload_command_no_debug.php
@@ -19,6 +19,8 @@
require __DIR__.'/autoload.php';
-return static fn (Command $command, OutputInterface $output, array $context): Command => $command->setCode(static function () use ($output, $context): void {
+return static fn (Command $command, OutputInterface $output, array $context): Command => $command->setCode(static function () use ($output, $context): int {
$output->writeln($context['DEBUG_ENABLED']);
+
+ return 0;
});
diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.be.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.be.xlf
index 194392935fcc1..6478e2a15caf7 100644
--- a/src/Symfony/Component/Security/Core/Resources/translations/security.be.xlf
+++ b/src/Symfony/Component/Security/Core/Resources/translations/security.be.xlf
@@ -76,7 +76,7 @@
Too many failed login attempts, please try again in %minutes% minutes.
- Занадта шмат няўдалых спробаў уваходу, калі ласка, паспрабуйце зноў праз %minutes% хвіліну.|Занадта шмат няўдалых спробаў уваходу, калі ласка, паспрабуйце зноў праз %minutes% хвіліны.|Занадта шмат няўдалых спробаў уваходу, калі ласка, паспрабуйце зноў праз %minutes% хвілін.
+ Занадта вялікая колькасць няўдалых спробаў уваходу. Калі ласка, паспрабуйце зноў праз %minutes% хвіліну.|Занадта вялікая колькасць няўдалых спробаў уваходу. Калі ласка, паспрабуйце зноў праз %minutes% хвіліны.|Занадта вялікая колькасць няўдалых спробаў уваходу. Калі ласка, паспрабуйце зноў праз %minutes% хвілін.