diff --git a/.github/expected-missing-return-types.diff b/.github/expected-missing-return-types.diff
index 36cf1d6177550..4b3c28e6a0338 100644
--- a/.github/expected-missing-return-types.diff
+++ b/.github/expected-missing-return-types.diff
@@ -22,7 +22,7 @@ diff --git a/src/Symfony/Component/BrowserKit/AbstractBrowser.php b/src/Symfony/
*/
- abstract protected function doRequest(object $request);
+ abstract protected function doRequest(object $request): object;
-
+
/**
@@ -451,5 +451,5 @@ abstract class AbstractBrowser
* @throws LogicException When this abstract class is not implemented
@@ -146,21 +146,21 @@ diff --git a/src/Symfony/Component/DependencyInjection/Extension/ExtensionInterf
*/
- public function load(array $configs, ContainerBuilder $container);
+ public function load(array $configs, ContainerBuilder $container): void;
-
+
/**
@@ -37,5 +37,5 @@ interface ExtensionInterface
* @return string
*/
- public function getNamespace();
+ public function getNamespace(): string;
-
+
/**
@@ -44,5 +44,5 @@ interface ExtensionInterface
* @return string|false
*/
- public function getXsdValidationBasePath();
+ public function getXsdValidationBasePath(): string|false;
-
+
/**
@@ -53,4 +53,4 @@ interface ExtensionInterface
* @return string
@@ -249,35 +249,35 @@ diff --git a/src/Symfony/Component/Form/FormTypeInterface.php b/src/Symfony/Comp
*/
- public function getParent();
+ public function getParent(): ?string;
-
+
/**
@@ -34,5 +34,5 @@ interface FormTypeInterface
* @return void
*/
- public function configureOptions(OptionsResolver $resolver);
+ public function configureOptions(OptionsResolver $resolver): void;
-
+
/**
@@ -48,5 +48,5 @@ interface FormTypeInterface
* @see FormTypeExtensionInterface::buildForm()
*/
- public function buildForm(FormBuilderInterface $builder, array $options);
+ public function buildForm(FormBuilderInterface $builder, array $options): void;
-
+
/**
@@ -66,5 +66,5 @@ interface FormTypeInterface
* @see FormTypeExtensionInterface::buildView()
*/
- public function buildView(FormView $view, FormInterface $form, array $options);
+ public function buildView(FormView $view, FormInterface $form, array $options): void;
-
+
/**
@@ -85,5 +85,5 @@ interface FormTypeInterface
* @see FormTypeExtensionInterface::finishView()
*/
- public function finishView(FormView $view, FormInterface $form, array $options);
+ public function finishView(FormView $view, FormInterface $form, array $options): void;
-
+
/**
@@ -95,4 +95,4 @@ interface FormTypeInterface
* @return string
@@ -324,26 +324,26 @@ diff --git a/src/Symfony/Component/HttpKernel/Bundle/BundleInterface.php b/src/S
*/
- public function boot();
+ public function boot(): void;
-
+
/**
@@ -35,5 +35,5 @@ interface BundleInterface
* @return void
*/
- public function shutdown();
+ public function shutdown(): void;
-
+
/**
@@ -44,5 +44,5 @@ interface BundleInterface
* @return void
*/
- public function build(ContainerBuilder $container);
+ public function build(ContainerBuilder $container): void;
-
+
/**
diff --git a/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php
--- a/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php
+++ b/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php
-@@ -101,5 +101,5 @@ abstract class DataCollector implements DataCollectorInterface
+@@ -113,5 +113,5 @@ abstract class DataCollector implements DataCollectorInterface
* @return void
*/
- public function reset()
@@ -358,7 +358,7 @@ diff --git a/src/Symfony/Component/HttpKernel/DataCollector/DataCollectorInterfa
*/
- public function collect(Request $request, Response $response, ?\Throwable $exception = null);
+ public function collect(Request $request, Response $response, ?\Throwable $exception = null): void;
-
+
/**
@@ -35,4 +35,4 @@ interface DataCollectorInterface extends ResetInterface
* @return string
@@ -383,38 +383,38 @@ diff --git a/src/Symfony/Component/HttpKernel/KernelInterface.php b/src/Symfony/
*/
- public function registerContainerConfiguration(LoaderInterface $loader);
+ public function registerContainerConfiguration(LoaderInterface $loader): void;
-
+
/**
@@ -44,5 +44,5 @@ interface KernelInterface extends HttpKernelInterface
* @return void
*/
- public function boot();
+ public function boot(): void;
-
+
/**
@@ -53,5 +53,5 @@ interface KernelInterface extends HttpKernelInterface
* @return void
*/
- public function shutdown();
+ public function shutdown(): void;
-
+
/**
diff --git a/src/Symfony/Component/Routing/Loader/AttributeClassLoader.php b/src/Symfony/Component/Routing/Loader/AttributeClassLoader.php
--- a/src/Symfony/Component/Routing/Loader/AttributeClassLoader.php
+++ b/src/Symfony/Component/Routing/Loader/AttributeClassLoader.php
-@@ -234,5 +234,5 @@ abstract class AttributeClassLoader implements LoaderInterface
+@@ -236,5 +236,5 @@ abstract class AttributeClassLoader implements LoaderInterface
* @return string
*/
- protected function getDefaultRouteName(\ReflectionClass $class, \ReflectionMethod $method)
+ protected function getDefaultRouteName(\ReflectionClass $class, \ReflectionMethod $method): string
{
$name = str_replace('\\', '_', $class->name).'_'.$method->name;
-@@ -333,5 +333,5 @@ abstract class AttributeClassLoader implements LoaderInterface
+@@ -335,5 +335,5 @@ abstract class AttributeClassLoader implements LoaderInterface
* @return void
*/
- abstract protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, object $annot);
+ abstract protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, object $annot): void;
-
+
/**
diff --git a/src/Symfony/Component/Security/Core/Authentication/RememberMe/TokenProviderInterface.php b/src/Symfony/Component/Security/Core/Authentication/RememberMe/TokenProviderInterface.php
--- a/src/Symfony/Component/Security/Core/Authentication/RememberMe/TokenProviderInterface.php
@@ -424,21 +424,21 @@ diff --git a/src/Symfony/Component/Security/Core/Authentication/RememberMe/Token
*/
- public function loadTokenBySeries(string $series);
+ public function loadTokenBySeries(string $series): PersistentTokenInterface;
-
+
/**
@@ -35,5 +35,5 @@ interface TokenProviderInterface
* @return void
*/
- public function deleteTokenBySeries(string $series);
+ public function deleteTokenBySeries(string $series): void;
-
+
/**
@@ -44,5 +44,5 @@ interface TokenProviderInterface
* @throws TokenNotFoundException if the token is not found
*/
- public function updateToken(string $series, #[\SensitiveParameter] string $tokenValue, \DateTimeInterface $lastUsed);
+ public function updateToken(string $series, #[\SensitiveParameter] string $tokenValue, \DateTimeInterface $lastUsed): void;
-
+
/**
@@ -51,4 +51,4 @@ interface TokenProviderInterface
* @return void
@@ -485,7 +485,7 @@ diff --git a/src/Symfony/Component/Translation/Extractor/ExtractorInterface.php
*/
- public function extract(string|iterable $resource, MessageCatalogue $catalogue);
+ public function extract(string|iterable $resource, MessageCatalogue $catalogue): void;
-
+
/**
@@ -36,4 +36,4 @@ interface ExtractorInterface
* @return void
@@ -501,7 +501,7 @@ diff --git a/src/Symfony/Component/Validator/ConstraintValidatorInterface.php b/
*/
- public function initialize(ExecutionContextInterface $context);
+ public function initialize(ExecutionContextInterface $context): void;
-
+
/**
@@ -31,4 +31,4 @@ interface ConstraintValidatorInterface
* @return void
@@ -518,6 +518,23 @@ diff --git a/src/Symfony/Component/VarDumper/Dumper/DataDumperInterface.php b/sr
- public function dump(Data $data);
+ public function dump(Data $data): ?string;
}
+diff --git a/src/Symfony/Component/VarExporter/Tests/ProxyHelperTest.php b/src/Symfony/Component/VarExporter/Tests/ProxyHelperTest.php
+--- a/src/Symfony/Component/VarExporter/Tests/ProxyHelperTest.php
++++ b/src/Symfony/Component/VarExporter/Tests/ProxyHelperTest.php
+@@ -172,5 +172,5 @@ class ProxyHelperTest extends TestCase
+ {
+ yield 'not type hinted __unserialize method' => [new class() {
+- public function __unserialize($array)
++ public function __unserialize($array): void
+ {
+ }
+@@ -192,5 +192,5 @@ class ProxyHelperTest extends TestCase
+
+ yield 'type hinted __unserialize method' => [new class() {
+- public function __unserialize(array $array)
++ public function __unserialize(array $array): void
+ {
+ }
diff --git a/src/Symfony/Contracts/Translation/LocaleAwareInterface.php b/src/Symfony/Contracts/Translation/LocaleAwareInterface.php
--- a/src/Symfony/Contracts/Translation/LocaleAwareInterface.php
+++ b/src/Symfony/Contracts/Translation/LocaleAwareInterface.php
@@ -526,7 +543,7 @@ diff --git a/src/Symfony/Contracts/Translation/LocaleAwareInterface.php b/src/Sy
*/
- public function setLocale(string $locale);
+ public function setLocale(string $locale): void;
-
+
/**
diff --git a/src/Symfony/Contracts/Translation/TranslatorTrait.php b/src/Symfony/Contracts/Translation/TranslatorTrait.php
--- a/src/Symfony/Contracts/Translation/TranslatorTrait.php
diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php
index b699003177332..589a3c8cf6b65 100644
--- a/.php-cs-fixer.dist.php
+++ b/.php-cs-fixer.dist.php
@@ -23,6 +23,8 @@
EOF;
return (new PhpCsFixer\Config())
+ // @see https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/pull/7777
+ ->setParallelConfig(PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect())
->setRules([
'@PHP71Migration' => true,
'@PHPUnit75Migration:risky' => true,
diff --git a/CHANGELOG-7.0.md b/CHANGELOG-7.0.md
index be632eae2db6f..5dbc2a701c8cd 100644
--- a/CHANGELOG-7.0.md
+++ b/CHANGELOG-7.0.md
@@ -7,6 +7,34 @@ in 7.0 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/v7.0.0...v7.0.1
+* 7.0.10 (2024-07-26)
+
+ * bug #57803 [FrameworkBundle] move adding detailed JSON error messages to the validate phase (xabbuh)
+ * bug #57815 [Console][PhpUnitBridge][VarDumper] Fix `NO_COLOR` empty value handling (alexandre-daubois)
+ * bug #57828 [Translation] Fix CSV escape char in `CsvFileLoader` on PHP >= 7.4 (alexandre-daubois)
+ * bug #57812 [Validator] treat uninitialized properties referenced by property paths as null (xabbuh)
+ * bug #57816 [DoctrineBridge] fix messenger bus dispatch inside an active transaction (IndraGunawan)
+ * bug #57799 [ErrorHandler][VarDumper] Remove PHP 8.4 deprecations (alexandre-daubois)
+ * bug #57772 [WebProfilerBundle] Add word wrap in tables in dialog to see all the text in workflow listeners dialog (SpartakusMd)
+ * bug #57802 [PropertyInfo] Fix nullable value returned from extractFromMutator on CollectionType (benjilebon)
+ * bug #57832 [DependencyInjection] Do not try to load default method name on interface (lyrixx)
+ * bug #57748 [SecurityBundle] use firewall-specific user checkers when manually logging in users (xabbuh)
+ * bug #57753 [ErrorHandler] restrict the maximum length of the X-Debug-Exception header (xabbuh)
+ * bug #57646 [Serializer] Raise correct exception in `ArrayDenormalizer` when called without a nested denormalizer (derrabus)
+ * bug #57674 [Cache] Improve `dbindex` DSN parameter parsing (constantable)
+ * bug #57678 [Validator] Add `setGroupProvider` to `AttributeLoader` (Maximilian Zumbansen)
+ * bug #57679 [WebProfilerBundle] Change incorrect check for the `stateless` request attribute (themasch)
+ * bug #57663 [Cache] use copy() instead of rename() on Windows (xabbuh)
+ * bug #57617 [PropertyInfo] Handle collection in PhpStan same as PhpDoc (mtarld)
+ * bug #54057 [Messenger] Passing actual `Envelope` to `WorkerMessageRetriedEvent` (daffoxdev)
+ * bug #57645 [Routing] Discard in-memory cache of routes when writing the file-based cache (mpdude)
+ * bug #57621 [Mailer] force HTTP 1.1 for Mailgun API requests (xabbuh)
+ * bug #57616 [String] Revert "Fixed u()->snake(), b()->snake() and s()->snake() methods" (nicolas-grekas)
+ * bug #57593 [SecurityBundle] Compare paths after realpath() has been applied to both (xabbuh)
+ * bug #57594 [String] Normalize underscores in snake() (xabbuh)
+ * bug #57585 [HttpFoundation] Fix MockArraySessionStorage to generate more conform ids (Seldaek)
+ * bug #57589 [FrameworkBundle] fix AssetMapper usage without assets enabled (xabbuh)
+
* 7.0.9 (2024-06-28)
* bug #57345 [DependencyInjection] Fix regression in ordering service locators by priority (longwave)
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 92dac23ccbd1c..8542f255df6a1 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -33,9 +33,9 @@ The Symfony Connect username in parenthesis allows to get more information
- Hugo Hamon (hhamon)
- Tobias Nyholm (tobias)
- Jérôme Tamarelle (gromnan)
+ - HypeMC (hypemc)
- Samuel ROZE (sroze)
- Antoine Lamirault (alamirault)
- - HypeMC (hypemc)
- Pascal Borreli (pborreli)
- Romain Neutron
- Joseph Bielawski (stloyd)
@@ -54,8 +54,8 @@ The Symfony Connect username in parenthesis allows to get more information
- Gabriel Ostrolucký (gadelat)
- Matthias Pigulla (mpdude)
- Jonathan Wage (jwage)
- - Valentin Udaltsov (vudaltsov)
- Vincent Langlet (deviling)
+ - Valentin Udaltsov (vudaltsov)
- Alexandre Salomé (alexandresalome)
- Grégoire Paris (greg0ire)
- William DURAND
@@ -72,11 +72,11 @@ The Symfony Connect username in parenthesis allows to get more information
- Pierre du Plessis (pierredup)
- David Maicher (dmaicher)
- Bulat Shakirzyanov (avalanche123)
+ - Mathias Arlaud (mtarld)
- Iltar van der Berg
- Miha Vrhovnik (mvrhov)
- Tomasz Kowalczyk (thunderer)
- Gary PEGEOT (gary-p)
- - Mathias Arlaud (mtarld)
- Saša Stamenković (umpirsky)
- Allison Guilhem (a_guilhem)
- Mathieu Piot (mpiot)
@@ -90,9 +90,9 @@ The Symfony Connect username in parenthesis allows to get more information
- Bilal Amarni (bamarni)
- Eriksen Costa
- Florin Patan (florinpatan)
+ - Dariusz Ruminski
- Vladimir Reznichenko (kalessil)
- Peter Rehm (rpet)
- - Dariusz Ruminski
- Henrik Bjørnskov (henrikbjorn)
- David Buchmann (dbu)
- Ruud Kamphuis (ruudk)
@@ -107,16 +107,16 @@ The Symfony Connect username in parenthesis allows to get more information
- Douglas Greenshields (shieldo)
- Frank A. Fiebig (fafiebig)
- Baldini
+ - Tomas Norkūnas (norkunas)
- Alex Pott
- Fran Moreno (franmomu)
- Charles Sarrazin (csarrazi)
- - Tomas Norkūnas (norkunas)
- Henrik Westphal (snc)
- Dariusz Górecki (canni)
- - Ener-Getick
- Hubert Lenoir (hubert_lenoir)
- - Graham Campbell (graham)
+ - Ener-Getick
- Antoine Makdessi (amakdessi)
+ - Graham Campbell (graham)
- Tugdual Saunier (tucksaun)
- Lee McDermott
- Brandon Turner
@@ -171,17 +171,17 @@ The Symfony Connect username in parenthesis allows to get more information
- Gordon Franke (gimler)
- Malte Schlüter (maltemaltesich)
- jeremyFreeAgent (jeremyfreeagent)
+ - Michael Babker (mbabker)
+ - Maximilian Beckers (maxbeckers)
+ - Valtteri R (valtzu)
- Joshua Thijssen
- Vasilij Dusko
- Daniel Wehner (dawehner)
- Maxime Helias (maxhelias)
- Robert Schönthal (digitalkaoz)
- Smaine Milianni (ismail1432)
- - Michael Babker (mbabker)
- François-Xavier de Guillebon (de-gui_f)
- - Maximilian Beckers (maxbeckers)
- noniagriconomie
- - Valtteri R (valtzu)
- Eric GELOEN (gelo)
- Gabriel Caruso
- Stefano Sala (stefano.sala)
@@ -405,6 +405,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Danny Berger (dpb587)
- Alif Rachmawadi
- Anton Chernikov (anton_ch1989)
+ - Stiven Llupa (sllupa)
- Pierre-Yves Lebecq (pylebecq)
- Benjamin Leveque (benji07)
- Jordan Samouh (jordansamouh)
@@ -438,6 +439,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Dane Powell
- Sebastien Morel (plopix)
- Christopher Davis (chrisguitarguy)
+ - Jonathan H. Wage
- Loïc Frémont (loic425)
- Matthieu Auger (matthieuauger)
- Sergey Belyshkin (sbelyshkin)
@@ -468,11 +470,11 @@ The Symfony Connect username in parenthesis allows to get more information
- Wouter Van Hecke
- Baptiste Lafontaine (magnetik)
- Iker Ibarguren (ikerib)
+ - Michael Hirschler (mvhirsch)
- Michael Holm (hollo)
- Blanchon Vincent (blanchonvincent)
- Christian Schmidt
- Ben Hakim
- - Stiven Llupa (sllupa)
- Marco Petersen (ocrampete16)
- Bohan Yang (brentybh)
- Vilius Grigaliūnas
@@ -520,7 +522,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Thierry T (lepiaf)
- Lorenz Schori
- Lukáš Holeczy (holicz)
- - Jonathan H. Wage
- Jeremy Livingston (jeremylivingston)
- ivan
- SUMIDA, Ippei (ippey_s)
@@ -541,7 +542,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Francesco Levorato
- Vitaliy Zakharov (zakharovvi)
- Tobias Sjösten (tobiassjosten)
- - Michael Hirschler (mvhirsch)
- Gyula Sallai (salla)
- Hendrik Luup (hluup)
- Inal DJAFAR (inalgnu)
@@ -582,6 +582,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Sanpi (sanpi)
- Eduardo Gulias (egulias)
- giulio de donato (liuggio)
+ - Ivan Mezinov
- ShinDarth
- Stéphane PY (steph_py)
- Cătălin Dan (dancatalin)
@@ -649,6 +650,7 @@ The Symfony Connect username in parenthesis allows to get more information
- quentin neyrat (qneyrat)
- Chris Tanaskoski (devristo)
- Steffen Roßkamp
+ - Andrey Lebedev (alebedev)
- Alexandru Furculita (afurculita)
- Michel Salib (michelsalib)
- Ben Roberts (benr77)
@@ -750,7 +752,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Roberto Espinoza (respinoza)
- Pierre Rineau
- Soufian EZ ZANTAR (soezz)
- - Ivan Mezinov
- Marek Zajac
- Adam Harvey
- ilyes kooli (skafandri)
@@ -764,6 +765,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Patrick Reimers (preimers)
- Brayden Williams (redstar504)
- insekticid
+ - Kieran Brahney
- Jérémy M (th3mouk)
- Trent Steel (trsteel88)
- boombatower
@@ -785,6 +787,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Matthew Grasmick
- Miroslav Šustek (sustmi)
- Pablo Díez (pablodip)
+ - Kev
- Kevin McBride
- Sergio Santoro
- Philipp Rieber (bicpi)
@@ -909,7 +912,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Ramunas Pabreza (doobas)
- Yuriy Vilks (igrizzli)
- Terje Bråten
- - Andrey Lebedev (alebedev)
- Sebastian Krebs
- Piotr Stankowski
- Pierre-Emmanuel Tanguy (petanguy)
@@ -1011,6 +1013,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Aurimas Niekis (gcds)
- Vincent Chalamon
- Matthieu Calie (matth--)
+ - Sem Schidler (xvilo)
- Benjamin Schoch (bschoch)
- Martins Sipenko
- Guilherme Augusto Henschel
@@ -1057,6 +1060,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Ivan Grigoriev (greedyivan)
- Johann Saunier (prophet777)
- Kevin SCHNEKENBURGER
+ - Geordie
- Fabien Salles (blacked)
- Andreas Erhard (andaris)
- alexpozzi
@@ -1135,11 +1139,11 @@ The Symfony Connect username in parenthesis allows to get more information
- Aleksandr Volochnev (exelenz)
- Robin van der Vleuten (robinvdvleuten)
- Grinbergs Reinis (shima5)
- - Kieran Brahney
- Klaus Silveira (klaussilveira)
- Michael Piecko (michael.piecko)
- Toni Peric (tperic)
- yclian
+ - Nicolas DOUSSON
- radar3301
- Aleksey Prilipko
- Jelle Raaijmakers (gmta)
@@ -1148,7 +1152,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Wybren Koelmans (wybren_koelmans)
- Roberto Nygaard
- victor-prdh
- - Kev
- Davide Borsatto (davide.borsatto)
- Florian Hermann (fhermann)
- zenas1210
@@ -1182,6 +1185,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Mathias Brodala (mbrodala)
- Robert Fischer (sandoba)
- Tarjei Huse (tarjei)
+ - Travis Carden (traviscarden)
- mfettig
- Besnik Br
- Issam Raouf (iraouf)
@@ -1243,6 +1247,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Volodymyr Panivko
- kick-the-bucket
- fedor.f
+ - roman joly (eltharin)
- Yosmany Garcia (yosmanyga)
- Jeremiasz Major
- Jibé Barth (jibbarth)
@@ -1262,6 +1267,7 @@ The Symfony Connect username in parenthesis allows to get more information
- possum
- Denis Zunke (donalberto)
- Adrien Roches (neirda24)
+ - Thomas Trautner (thomastr)
- _sir_kane (waly)
- Olivier Maisonneuve
- Gálik Pál
@@ -1292,6 +1298,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Zhuravlev Alexander (scif)
- Stefano Degenkamp (steef)
- James Michael DuPont
+ - Tinjo Schöni
- Carlos Buenosvinos (carlosbuenosvinos)
- Christian Gripp (core23)
- Jake (jakesoft)
@@ -1350,6 +1357,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Ana Raro
- Ana Raro
- Tony Malzhacker
+ - Cosmin Sandu
- Andreas Lutro (anlutro)
- DUPUCH (bdupuch)
- Cyril Quintin (cyqui)
@@ -1399,6 +1407,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Matthieu Mota (matthieumota)
- Maxime Pinot (maximepinot)
- Jean-Baptiste GOMOND (mjbgo)
+ - Jakub Podhorsky (podhy)
- abdul malik ikhsan (samsonasik)
- Henry Snoek (snoek09)
- Morgan Auchede
@@ -1430,6 +1439,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Johnson Page (jwpage)
- Kuba Werłos (kuba)
- Ruben Gonzalez (rubenruateltek)
+ - Mokhtar Tlili (sf-djuba)
- Michael Roterman (wtfzdotnet)
- Philipp Keck
- Pavol Tuka
@@ -1470,6 +1480,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Nicolas de Marqué (nicola)
- Thiago Cordeiro (thiagocordeiro)
- Matthieu Bontemps
+ - Ian Irlen
- Rootie
- Sébastien Santoro (dereckson)
- Daniel Alejandro Castro Arellano (lexcast)
@@ -1671,6 +1682,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Bruno Rodrigues de Araujo (brunosinister)
- Máximo Cuadros (mcuadros)
- Jacek Wilczyński (jacekwilczynski)
+ - Christoph Kappestein
- Camille Baronnet
- EXT - THERAGE Kevin
- tamirvs
@@ -1832,11 +1844,11 @@ The Symfony Connect username in parenthesis allows to get more information
- Peter Smeets (darkspartan)
- Julien Bianchi (jubianchi)
- Michael Dawart (mdawart)
- - Sem Schidler (xvilo)
- Robert Meijers
- Tijs Verkoyen
- James Sansbury
- Marcin Chwedziak
+ - Dan Kadera
- hjkl
- Dan Wilga
- Thijs Reijgersberg
@@ -2271,7 +2283,6 @@ The Symfony Connect username in parenthesis allows to get more information
- DidierLmn
- Pedro Silva
- Chihiro Adachi (chihiro-adachi)
- - Thomas Trautner (thomastr)
- Jeroen de Graaf
- Ulrik McArdle
- BiaDd
@@ -2292,6 +2303,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Fabian Haase
- roog
- parinz1234
+ - seho-nl
- Romain Geissler
- Martin Auswöger
- Adrien Moiruad
@@ -2396,6 +2408,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Raphael Hardt
- Ivan Nemets
- Qingshan Luo
+ - Michael Olšavský
- Ergie Gonzaga
- Matthew J Mucklo
- AnrDaemon
@@ -2501,6 +2514,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Nicolas Badey (nico-b)
- Olivier Scherler (oscherler)
- Flo Gleixner (redflo)
+ - Romain Jacquart (romainjacquart)
- Shane Preece (shane)
- Stephan Wentz (temp)
- Johannes Goslar
@@ -2680,7 +2694,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Flinsch
- Maciej Schmidt
- botbotbot
- - Cosmin Sandu
- tatankat
- Cláudio Cesar
- Timon van der Vorm
@@ -2846,7 +2859,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Boudry Julien
- amcastror
- Bram Van der Sype (brammm)
- - roman joly (eltharin)
- Guile (guile)
- Mark Beech (jaybizzle)
- Julien Moulin (lizjulien)
@@ -2907,6 +2919,7 @@ The Symfony Connect username in parenthesis allows to get more information
- J Bruni
- Alexey Prilipko
- vlakoff
+ - Anthony Tenneriello
- thib92
- Yiorgos Kalligeros
- Rudolf Ratusiński
@@ -2923,6 +2936,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Frédéric G. Marand (fgm)
- Freek Van der Herten (freekmurze)
- Luca Genuzio (genuzio)
+ - Ben Gamra Housseine (hbgamra)
- Andrew Marcinkevičius (ifdattic)
- Ioana Hazsda (ioana-hazsda)
- Jan Marek (janmarek)
@@ -3175,13 +3189,11 @@ The Symfony Connect username in parenthesis allows to get more information
- Olivier Laviale (olvlvl)
- Pierre Gasté (pierre_g)
- Pablo Monterde Perez (plebs)
- - Jakub Podhorsky (podhy)
- Pierre-Olivier Vares (povares)
- Jimmy Leger (redpanda)
- Ronny López (ronnylt)
- Julius (sakalys)
- Sébastien JEAN (sebastien76)
- - Mokhtar Tlili (sf-djuba)
- Dmitry (staratel)
- Marcin Szepczynski (szepczynski)
- Tito Miguel Costa (titomiguelcosta)
@@ -3193,7 +3205,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Yorkie Chadwick (yorkie76)
- Zakaria AMMOURA (zakariaamm)
- Maxime Aknin (3m1x4m)
- - Geordie
- Pavel Barton
- Exploit.cz
- GuillaumeVerdon
@@ -3203,7 +3214,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Youpie
- Jason Stephens
- srsbiz
- - Tinjo Schöni
- Taylan Kasap
- Michael Orlitzky
- Nicolas A. Bérard-Nault
diff --git a/src/Symfony/Bridge/Doctrine/Messenger/DoctrineOpenTransactionLoggerMiddleware.php b/src/Symfony/Bridge/Doctrine/Messenger/DoctrineOpenTransactionLoggerMiddleware.php
index 75187a1e490c5..76380154277c9 100644
--- a/src/Symfony/Bridge/Doctrine/Messenger/DoctrineOpenTransactionLoggerMiddleware.php
+++ b/src/Symfony/Bridge/Doctrine/Messenger/DoctrineOpenTransactionLoggerMiddleware.php
@@ -41,11 +41,12 @@ protected function handleForManager(EntityManagerInterface $entityManager, Envel
}
$this->isHandling = true;
+ $initialTransactionLevel = $entityManager->getConnection()->getTransactionNestingLevel();
try {
return $stack->next()->handle($envelope, $stack);
} finally {
- if ($entityManager->getConnection()->isTransactionActive()) {
+ if ($entityManager->getConnection()->getTransactionNestingLevel() > $initialTransactionLevel) {
$this->logger?->error('A handler opened a transaction but did not close it.', [
'message' => $envelope->getMessage(),
]);
diff --git a/src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrineOpenTransactionLoggerMiddlewareTest.php b/src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrineOpenTransactionLoggerMiddlewareTest.php
index 8d49caa38fa7e..56a5a6641bec9 100644
--- a/src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrineOpenTransactionLoggerMiddlewareTest.php
+++ b/src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrineOpenTransactionLoggerMiddlewareTest.php
@@ -51,9 +51,9 @@ public function log($level, $message, $context = []): void
public function testMiddlewareWrapsInTransactionAndFlushes()
{
- $this->connection->expects($this->exactly(1))
- ->method('isTransactionActive')
- ->willReturn(true, true, false)
+ $this->connection->expects($this->exactly(2))
+ ->method('getTransactionNestingLevel')
+ ->willReturn(0, 1)
;
$this->middleware->handle(new Envelope(new \stdClass()), $this->getStackMock());
diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php
index 8f000592c5b51..589a1d77f43c5 100644
--- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php
+++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php
@@ -407,7 +407,7 @@ private static function hasColorSupport(): bool
}
// Follow https://no-color.org/
- if (isset($_SERVER['NO_COLOR']) || false !== getenv('NO_COLOR')) {
+ if ('' !== ($_SERVER['NO_COLOR'] ?? getenv('NO_COLOR') ?: '')) {
return false;
}
diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/log_file.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/log_file.phpt
index 7f114ab5e2e5a..51f8d6cb1b21e 100644
--- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/log_file.phpt
+++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/log_file.phpt
@@ -2,7 +2,7 @@
Test DeprecationErrorHandler with log file
--FILE--
callCreateUploadedFile($uploadedFile);
$size = $symfonyUploadedFile->getSize();
- $uniqid = uniqid();
+ $uniqid = uniqid('', true);
$symfonyUploadedFile->move($this->tmpDir, $uniqid);
$this->assertEquals($uploadedFile->getSize(), $size);
@@ -198,7 +198,7 @@ public function testCreateUploadedFileWithError()
private function createUploadedFile(string $content, int $error, string $clientFileName, string $clientMediaType): UploadedFile
{
- $filePath = tempnam($this->tmpDir, uniqid());
+ $filePath = tempnam($this->tmpDir, uniqid('', true));
file_put_contents($filePath, $content);
return new UploadedFile($filePath, filesize($filePath), $error, $clientFileName, $clientMediaType);
diff --git a/src/Symfony/Bridge/PsrHttpMessage/Tests/Factory/PsrHttpFactoryTest.php b/src/Symfony/Bridge/PsrHttpMessage/Tests/Factory/PsrHttpFactoryTest.php
index 41629e8c69fc9..0c4122168449f 100644
--- a/src/Symfony/Bridge/PsrHttpMessage/Tests/Factory/PsrHttpFactoryTest.php
+++ b/src/Symfony/Bridge/PsrHttpMessage/Tests/Factory/PsrHttpFactoryTest.php
@@ -131,7 +131,7 @@ public function testGetContentCanBeCalledAfterRequestCreation()
private function createUploadedFile(string $content, string $originalName, string $mimeType, int $error): UploadedFile
{
- $path = tempnam($this->tmpDir, uniqid());
+ $path = tempnam($this->tmpDir, uniqid('', true));
file_put_contents($path, $content);
return new UploadedFile($path, $originalName, $mimeType, $error, true);
@@ -182,7 +182,7 @@ public function testCreateResponseFromStreamed()
public function testCreateResponseFromBinaryFile()
{
- $path = tempnam($this->tmpDir, uniqid());
+ $path = tempnam($this->tmpDir, uniqid('', true));
file_put_contents($path, 'Binary');
$response = new BinaryFileResponse($path);
@@ -194,7 +194,7 @@ public function testCreateResponseFromBinaryFile()
public function testCreateResponseFromBinaryFileWithRange()
{
- $path = tempnam($this->tmpDir, uniqid());
+ $path = tempnam($this->tmpDir, uniqid('', true));
file_put_contents($path, 'Binary');
$request = new Request();
diff --git a/src/Symfony/Bridge/PsrHttpMessage/Tests/Functional/CovertTest.php b/src/Symfony/Bridge/PsrHttpMessage/Tests/Functional/CovertTest.php
index b0ea766922db5..c350f2964d7d5 100644
--- a/src/Symfony/Bridge/PsrHttpMessage/Tests/Functional/CovertTest.php
+++ b/src/Symfony/Bridge/PsrHttpMessage/Tests/Functional/CovertTest.php
@@ -217,7 +217,7 @@ public static function responseProvider(): array
private static function createUploadedFile(string $content, string $originalName, string $mimeType, int $error): UploadedFile
{
- $path = tempnam(sys_get_temp_dir(), uniqid());
+ $path = tempnam(sys_get_temp_dir(), uniqid('', true));
file_put_contents($path, $content);
return new UploadedFile($path, $originalName, $mimeType, $error, true);
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/SecretsDecryptToLocalCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/SecretsDecryptToLocalCommand.php
index ac711e3dbd850..5945c16cc7c0e 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/SecretsDecryptToLocalCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/SecretsDecryptToLocalCommand.php
@@ -48,7 +48,7 @@ protected function configure(): void
%command.full_name%
-When the option --force is provided, secrets that already exist in the local vault are overriden.
+When the --force option is provided, secrets that already exist in the local vault are overridden.
%command.full_name% --force
EOF
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
index 6a006845f415d..1c7cfb1e8f8d6 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
@@ -1112,7 +1112,7 @@ private function addSerializerSection(ArrayNodeDefinition $rootNode, callable $e
->arrayNode('default_context')
->normalizeKeys(false)
->useAttributeAsKey('name')
- ->beforeNormalization()
+ ->validate()
->ifTrue(fn () => $this->debug && class_exists(JsonParser::class))
->then(fn (array $v) => $v + [JsonDecode::DETAILED_ERROR_MESSAGES => true])
->end()
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index 2b2fd4a0e739c..b6be95b06ac06 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -1308,6 +1308,10 @@ private function registerAssetMapperConfiguration(array $config, ContainerBuilde
{
$loader->load('asset_mapper.php');
+ if (!$assetEnabled) {
+ $container->removeDefinition('asset_mapper.asset_package');
+ }
+
if (!$httpClientEnabled) {
$container->register('asset_mapper.http_client', HttpClientInterface::class)
->addTag('container.error')
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ConfigBuilderCacheWarmerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ConfigBuilderCacheWarmerTest.php
index 294a3cd25c1de..66cf6b8d7f4c7 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ConfigBuilderCacheWarmerTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ConfigBuilderCacheWarmerTest.php
@@ -37,7 +37,7 @@ class ConfigBuilderCacheWarmerTest extends TestCase
protected function setUp(): void
{
- $this->varDir = sys_get_temp_dir().'/'.uniqid();
+ $this->varDir = sys_get_temp_dir().'/'.uniqid('', true);
$fs = new Filesystem();
$fs->mkdir($this->varDir);
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
index aed072dfba492..411e61274c1b3 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
@@ -13,6 +13,7 @@
use Doctrine\DBAL\Connection;
use PHPUnit\Framework\TestCase;
+use Seld\JsonLint\JsonParser;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Configuration;
use Symfony\Bundle\FullStack;
use Symfony\Component\Cache\Adapter\DoctrineAdapter;
@@ -566,6 +567,72 @@ public function testEnabledLockNeedsResources()
]);
}
+ public function testSerializerJsonDetailedErrorMessagesEnabledWhenDefaultContextIsConfigured()
+ {
+ $processor = new Processor();
+ $config = $processor->processConfiguration(new Configuration(true), [
+ [
+ 'http_method_override' => false,
+ 'handle_all_throwables' => true,
+ 'php_errors' => ['log' => true],
+ 'serializer' => [
+ 'default_context' => [
+ 'foo' => 'bar',
+ ],
+ ],
+ ],
+ ]);
+
+ $this->assertSame(['foo' => 'bar', JsonDecode::DETAILED_ERROR_MESSAGES => true], $config['serializer']['default_context'] ?? []);
+ }
+
+ public function testSerializerJsonDetailedErrorMessagesInDefaultContextCanBeDisabled()
+ {
+ $processor = new Processor();
+ $config = $processor->processConfiguration(new Configuration(true), [
+ [
+ 'http_method_override' => false,
+ 'handle_all_throwables' => true,
+ 'php_errors' => ['log' => true],
+ 'serializer' => [
+ 'default_context' => [
+ 'foo' => 'bar',
+ JsonDecode::DETAILED_ERROR_MESSAGES => false,
+ ],
+ ],
+ ],
+ ]);
+
+ $this->assertSame(['foo' => 'bar', JsonDecode::DETAILED_ERROR_MESSAGES => false], $config['serializer']['default_context'] ?? []);
+ }
+
+ public function testSerializerJsonDetailedErrorMessagesInDefaultContextCanBeDisabledWithSeveralConfigsBeingMerged()
+ {
+ $processor = new Processor();
+ $config = $processor->processConfiguration(new Configuration(true), [
+ [
+ 'http_method_override' => false,
+ 'handle_all_throwables' => true,
+ 'php_errors' => ['log' => true],
+ 'serializer' => [
+ 'default_context' => [
+ 'foo' => 'bar',
+ JsonDecode::DETAILED_ERROR_MESSAGES => false,
+ ],
+ ],
+ ],
+ [
+ 'serializer' => [
+ 'default_context' => [
+ 'foobar' => 'baz',
+ ],
+ ],
+ ],
+ ]);
+
+ $this->assertSame(['foo' => 'bar', JsonDecode::DETAILED_ERROR_MESSAGES => false, 'foobar' => 'baz'], $config['serializer']['default_context'] ?? []);
+ }
+
protected static function getBundleDefaultConfig()
{
return [
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/asset_mapper_without_assets.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/asset_mapper_without_assets.php
new file mode 100644
index 0000000000000..8a74333b19324
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/asset_mapper_without_assets.php
@@ -0,0 +1,10 @@
+loadFromExtension('framework', [
+ 'annotations' => false,
+ 'asset_mapper' => null,
+ 'assets' => false,
+ 'handle_all_throwables' => true,
+ 'http_method_override' => false,
+ 'php_errors' => ['log' => true],
+]);
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/asset_mapper_without_assets.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/asset_mapper_without_assets.xml
new file mode 100644
index 0000000000000..3976b1064222d
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/asset_mapper_without_assets.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/asset_mapper_without_assets.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/asset_mapper_without_assets.yml
new file mode 100644
index 0000000000000..51f302b668843
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/asset_mapper_without_assets.yml
@@ -0,0 +1,8 @@
+framework:
+ annotations: false
+ asset_mapper: ~
+ assets: false
+ handle_all_throwables: true
+ http_method_override: false
+ php_errors:
+ log: true
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php
index 845056799d27a..d0ed5542ad0a2 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php
@@ -2318,6 +2318,16 @@ public function testWebhookWithoutSerializer()
);
}
+ public function testAssetMapperWithoutAssets()
+ {
+ $container = $this->createContainerFromFile('asset_mapper_without_assets');
+
+ $this->assertTrue($container->has('asset_mapper'));
+ $this->assertFalse($container->has('asset_mapper.asset_package'));
+ $this->assertFalse($container->has('assets.packages'));
+ $this->assertFalse($container->has('assets._default_package'));
+ }
+
protected function createContainer(array $data = [])
{
return new ContainerBuilder(new EnvPlaceholderParameterBag(array_merge([
diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
index e5e37ed4e3401..c8cfc08e6ac60 100644
--- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
+++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
@@ -560,6 +560,9 @@ private function createFirewall(ContainerBuilder $container, string $id, array $
$container->setAlias('security.user_checker.'.$id, new Alias($firewall['user_checker'], false));
+ $userCheckerLocator = $container->getDefinition('security.user_checker_locator');
+ $userCheckerLocator->replaceArgument(0, array_merge($userCheckerLocator->getArgument(0), [$id => new ServiceClosureArgument(new Reference('security.user_checker.'.$id))]));
+
foreach ($this->getSortedFactories() as $factory) {
$key = str_replace('-', '_', $factory->getKey());
if ('custom_authenticators' !== $key && \array_key_exists($key, $firewall)) {
diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.php b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.php
index 8019058e9a55e..48112c993731a 100644
--- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.php
+++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.php
@@ -19,6 +19,7 @@
use Symfony\Bundle\SecurityBundle\Security\FirewallContext;
use Symfony\Bundle\SecurityBundle\Security\FirewallMap;
use Symfony\Bundle\SecurityBundle\Security\LazyFirewallContext;
+use Symfony\Component\DependencyInjection\ServiceLocator;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage;
use Symfony\Component\Ldap\Security\LdapUserProvider;
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver;
@@ -87,7 +88,7 @@
'security.authenticator.managers_locator' => service('security.authenticator.managers_locator')->ignoreOnInvalid(),
'request_stack' => service('request_stack'),
'security.firewall.map' => service('security.firewall.map'),
- 'security.user_checker' => service('security.user_checker'),
+ 'security.user_checker_locator' => service('security.user_checker_locator'),
'security.firewall.event_dispatcher_locator' => service('security.firewall.event_dispatcher_locator'),
'security.csrf.token_manager' => service('security.csrf.token_manager')->ignoreOnInvalid(),
]),
@@ -121,6 +122,8 @@
->args(['none'])
->set('security.user_checker', InMemoryUserChecker::class)
+ ->set('security.user_checker_locator', ServiceLocator::class)
+ ->args([[]])
->set('security.expression_language', ExpressionLanguage::class)
->args([service('cache.security_expression_language')->nullOnInvalid()])
diff --git a/src/Symfony/Bundle/SecurityBundle/Security.php b/src/Symfony/Bundle/SecurityBundle/Security.php
index c4b505d8981c7..e0aa00423923a 100644
--- a/src/Symfony/Bundle/SecurityBundle/Security.php
+++ b/src/Symfony/Bundle/SecurityBundle/Security.php
@@ -96,7 +96,8 @@ public function login(UserInterface $user, ?string $authenticatorName = null, ?s
$authenticator = $this->getAuthenticator($authenticatorName, $firewallName);
- $this->container->get('security.user_checker')->checkPreAuth($user);
+ $userCheckerLocator = $this->container->get('security.user_checker_locator');
+ $userCheckerLocator->get($firewallName)->checkPreAuth($user);
return $this->container->get('security.authenticator.managers_locator')->get($firewallName)->authenticateUser($user, $authenticator, $request, $badges);
}
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/SecurityTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/SecurityTest.php
index 045dfc70a7c5e..35bd329b2297e 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/SecurityTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/SecurityTest.php
@@ -142,7 +142,7 @@ public function testLogin()
['request_stack', $requestStack],
['security.firewall.map', $firewallMap],
['security.authenticator.managers_locator', $this->createContainer('main', $userAuthenticator)],
- ['security.user_checker', $userChecker],
+ ['security.user_checker_locator', $this->createContainer('main', $userChecker)],
])
;
@@ -188,7 +188,7 @@ public function testLoginReturnsAuthenticatorResponse()
['request_stack', $requestStack],
['security.firewall.map', $firewallMap],
['security.authenticator.managers_locator', $this->createContainer('main', $userAuthenticator)],
- ['security.user_checker', $userChecker],
+ ['security.user_checker_locator', $this->createContainer('main', $userChecker)],
])
;
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php
index 23895f70bb6ec..a7c0644fdd1bf 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php
+++ b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php
@@ -180,7 +180,7 @@ public function searchBarAction(Request $request): Response
$this->cspHandler?->disableCsp();
$session = null;
- if ($request->attributes->getBoolean('_stateless') && $request->hasSession()) {
+ if (!$request->attributes->getBoolean('_stateless') && $request->hasSession()) {
$session = $request->getSession();
}
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/workflow.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/workflow.html.twig
index 377b74f609f21..522d93da32430 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/workflow.html.twig
+++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/workflow.html.twig
@@ -60,6 +60,7 @@
dialog table td {
padding: .625em;
text-align: center;
+ word-wrap: break-word;
}
dialog table th {
diff --git a/src/Symfony/Component/AssetMapper/Tests/CompiledAssetMapperConfigReaderTest.php b/src/Symfony/Component/AssetMapper/Tests/CompiledAssetMapperConfigReaderTest.php
index 355bf838e1c25..8619c2b3719d4 100644
--- a/src/Symfony/Component/AssetMapper/Tests/CompiledAssetMapperConfigReaderTest.php
+++ b/src/Symfony/Component/AssetMapper/Tests/CompiledAssetMapperConfigReaderTest.php
@@ -23,8 +23,8 @@ class CompiledAssetMapperConfigReaderTest extends TestCase
protected function setUp(): void
{
$this->filesystem = new Filesystem();
- $this->writableRoot = __DIR__.'/../Fixtures/importmaps_for_writing';
- if (!file_exists(__DIR__.'/../Fixtures/importmaps_for_writing')) {
+ $this->writableRoot = __DIR__.'/../Fixtures/compiled_asset_mapper_config_reader';
+ if (!file_exists(__DIR__.'/../Fixtures/compiled_asset_mapper_config_reader')) {
$this->filesystem->mkdir($this->writableRoot);
}
// realpath to help path comparisons in the tests
diff --git a/src/Symfony/Component/AssetMapper/Tests/ImportMap/ImportMapConfigReaderTest.php b/src/Symfony/Component/AssetMapper/Tests/ImportMap/ImportMapConfigReaderTest.php
index fbfb8b4654664..a9737be5408fa 100644
--- a/src/Symfony/Component/AssetMapper/Tests/ImportMap/ImportMapConfigReaderTest.php
+++ b/src/Symfony/Component/AssetMapper/Tests/ImportMap/ImportMapConfigReaderTest.php
@@ -26,17 +26,14 @@ class ImportMapConfigReaderTest extends TestCase
protected function setUp(): void
{
$this->filesystem = new Filesystem();
- if (!file_exists(__DIR__.'/../Fixtures/importmaps_for_writing')) {
- $this->filesystem->mkdir(__DIR__.'/../Fixtures/importmaps_for_writing');
- }
- if (!file_exists(__DIR__.'/../Fixtures/importmaps_for_writing/assets')) {
- $this->filesystem->mkdir(__DIR__.'/../Fixtures/importmaps_for_writing/assets');
+ if (!file_exists(__DIR__.'/../Fixtures/importmap_config_reader/assets')) {
+ $this->filesystem->mkdir(__DIR__.'/../Fixtures/importmap_config_reader/assets');
}
}
protected function tearDown(): void
{
- $this->filesystem->remove(__DIR__.'/../Fixtures/importmaps_for_writing');
+ $this->filesystem->remove(__DIR__.'/../Fixtures/importmap_config_reader');
}
public function testGetEntriesAndWriteEntries()
@@ -63,7 +60,7 @@ public function testGetEntriesAndWriteEntries()
],
];
EOF;
- file_put_contents(__DIR__.'/../Fixtures/importmaps_for_writing/importmap.php', $importMap);
+ file_put_contents(__DIR__.'/../Fixtures/importmap_config_reader/importmap.php', $importMap);
$remotePackageStorage = $this->createMock(RemotePackageStorage::class);
$remotePackageStorage->expects($this->any())
@@ -72,7 +69,7 @@ public function testGetEntriesAndWriteEntries()
return '/path/to/vendor/'.$packageModuleSpecifier.'.'.$type->value;
});
$reader = new ImportMapConfigReader(
- __DIR__.'/../Fixtures/importmaps_for_writing/importmap.php',
+ __DIR__.'/../Fixtures/importmap_config_reader/importmap.php',
$remotePackageStorage,
);
$entries = $reader->getEntries();
@@ -100,11 +97,11 @@ public function testGetEntriesAndWriteEntries()
$this->assertSame('package/with_file.js', $packageWithFileEntry->packageModuleSpecifier);
// now save the original raw data from importmap.php and delete the file
- $originalImportMapData = (static fn () => include __DIR__.'/../Fixtures/importmaps_for_writing/importmap.php')();
- unlink(__DIR__.'/../Fixtures/importmaps_for_writing/importmap.php');
+ $originalImportMapData = (static fn () => eval('?>'.file_get_contents(__DIR__.'/../Fixtures/importmap_config_reader/importmap.php')))();
+ unlink(__DIR__.'/../Fixtures/importmap_config_reader/importmap.php');
// dump the entries back to the file
$reader->writeEntries($entries);
- $newImportMapData = (static fn () => include __DIR__.'/../Fixtures/importmaps_for_writing/importmap.php')();
+ $newImportMapData = (static fn () => eval('?>'.file_get_contents(__DIR__.'/../Fixtures/importmap_config_reader/importmap.php')))();
$this->assertSame($originalImportMapData, $newImportMapData);
}
diff --git a/src/Symfony/Component/AssetMapper/Tests/ImportMap/ImportMapGeneratorTest.php b/src/Symfony/Component/AssetMapper/Tests/ImportMap/ImportMapGeneratorTest.php
index deafa38e2cef8..24289ff3d6740 100644
--- a/src/Symfony/Component/AssetMapper/Tests/ImportMap/ImportMapGeneratorTest.php
+++ b/src/Symfony/Component/AssetMapper/Tests/ImportMap/ImportMapGeneratorTest.php
@@ -30,10 +30,9 @@ class ImportMapGeneratorTest extends TestCase
private AssetMapperInterface&MockObject $assetMapper;
private CompiledAssetMapperConfigReader&MockObject $compiledConfigReader;
private ImportMapConfigReader&MockObject $configReader;
- private ImportMapGenerator $importMapGenerator;
private Filesystem $filesystem;
- private static string $writableRoot = __DIR__.'/../Fixtures/importmaps_for_writing';
+ private static string $writableRoot = __DIR__.'/../Fixtures/importmap_generator';
protected function setUp(): void
{
@@ -725,7 +724,7 @@ private function createImportMapGenerator(): ImportMapGenerator
return ImportMapEntry::createRemote($importName, $type, $path, $version, $packageModuleSpecifier, $isEntrypoint);
});
- return $this->importMapGenerator = new ImportMapGenerator(
+ return new ImportMapGenerator(
$this->assetMapper,
$this->compiledConfigReader,
$this->configReader,
diff --git a/src/Symfony/Component/AssetMapper/Tests/ImportMap/ImportMapManagerTest.php b/src/Symfony/Component/AssetMapper/Tests/ImportMap/ImportMapManagerTest.php
index 551a60492460d..51764e654f529 100644
--- a/src/Symfony/Component/AssetMapper/Tests/ImportMap/ImportMapManagerTest.php
+++ b/src/Symfony/Component/AssetMapper/Tests/ImportMap/ImportMapManagerTest.php
@@ -32,18 +32,14 @@ class ImportMapManagerTest extends TestCase
private PackageResolverInterface&MockObject $packageResolver;
private ImportMapConfigReader&MockObject $configReader;
private RemotePackageDownloader&MockObject $remotePackageDownloader;
- private ImportMapManager $importMapManager;
private Filesystem $filesystem;
- private static string $writableRoot = __DIR__.'/../Fixtures/importmaps_for_writing';
+ private static string $writableRoot = __DIR__.'/../Fixtures/importmap_manager';
protected function setUp(): void
{
$this->filesystem = new Filesystem();
- if (!file_exists(__DIR__.'/../Fixtures/importmaps_for_writing')) {
- $this->filesystem->mkdir(self::$writableRoot);
- }
- if (!file_exists(__DIR__.'/../Fixtures/importmaps_for_writing/assets')) {
+ if (!file_exists(__DIR__.'/../Fixtures/importmap_manager/assets')) {
$this->filesystem->mkdir(self::$writableRoot.'/assets');
}
}
@@ -386,7 +382,7 @@ private function createImportMapManager(): ImportMapManager
return ImportMapEntry::createRemote($importName, $type, $path, $version, $packageModuleSpecifier, $isEntrypoint);
});
- return $this->importMapManager = new ImportMapManager(
+ return new ImportMapManager(
$this->assetMapper,
$this->configReader,
$this->remotePackageDownloader,
diff --git a/src/Symfony/Component/AssetMapper/Tests/ImportMap/RemotePackageDownloaderTest.php b/src/Symfony/Component/AssetMapper/Tests/ImportMap/RemotePackageDownloaderTest.php
index e3e8cff663894..b03d0dc63430d 100644
--- a/src/Symfony/Component/AssetMapper/Tests/ImportMap/RemotePackageDownloaderTest.php
+++ b/src/Symfony/Component/AssetMapper/Tests/ImportMap/RemotePackageDownloaderTest.php
@@ -24,7 +24,7 @@
class RemotePackageDownloaderTest extends TestCase
{
private Filesystem $filesystem;
- private static string $writableRoot = __DIR__.'/../Fixtures/importmaps_for_writing';
+ private static string $writableRoot = __DIR__.'/../Fixtures/remote_package_downloader';
protected function setUp(): void
{
diff --git a/src/Symfony/Component/AssetMapper/Tests/ImportMap/RemotePackageStorageTest.php b/src/Symfony/Component/AssetMapper/Tests/ImportMap/RemotePackageStorageTest.php
index 0019f604cc8c5..9064eecc1856d 100644
--- a/src/Symfony/Component/AssetMapper/Tests/ImportMap/RemotePackageStorageTest.php
+++ b/src/Symfony/Component/AssetMapper/Tests/ImportMap/RemotePackageStorageTest.php
@@ -20,14 +20,14 @@
class RemotePackageStorageTest extends TestCase
{
private Filesystem $filesystem;
- private static string $writableRoot = __DIR__.'/../Fixtures/importmaps_for_writing';
+ private static string $writableRoot;
+ private static int $writableRootIndex = 0;
protected function setUp(): void
{
+ self::$writableRoot = sys_get_temp_dir().'/remote_package_storage'.++self::$writableRootIndex;
$this->filesystem = new Filesystem();
- if (!$this->filesystem->exists(self::$writableRoot)) {
- $this->filesystem->mkdir(self::$writableRoot);
- }
+ $this->filesystem->mkdir(self::$writableRoot);
}
protected function tearDown(): void
@@ -41,19 +41,24 @@ public function testGetStorageDir()
$this->assertSame(realpath(self::$writableRoot.'/assets/vendor'), realpath($storage->getStorageDir()));
}
- public function testSaveThrowsWhenVendorDirectoryIsNotWritable()
+ public function testSaveThrowsWhenFailing()
{
- $this->filesystem->mkdir($vendorDir = self::$writableRoot.'/assets/acme/vendor');
- $this->filesystem->chmod($vendorDir, 0555);
+ $vendorDir = self::$writableRoot.'/assets/acme/vendor';
+ $this->filesystem->mkdir($vendorDir.'/module_specifier');
+ $this->filesystem->touch($vendorDir.'/module_specifier/module_specifier.index.js');
+ $this->filesystem->chmod($vendorDir.'/module_specifier/module_specifier.index.js', 0555);
$storage = new RemotePackageStorage($vendorDir);
$entry = ImportMapEntry::createRemote('foo', ImportMapType::JS, '/does/not/matter', '1.0.0', 'module_specifier', false);
$this->expectException(\RuntimeException::class);
- $this->expectExceptionMessage('file_put_contents('.$vendorDir.'/module_specifier/module_specifier.index.js): Failed to open stream: No such file or directory');
- $storage->save($entry, 'any content');
+ $this->expectExceptionMessage('file_put_contents('.$vendorDir.'/module_specifier/module_specifier.index.js): Failed to open stream: Permission denied');
- $this->filesystem->remove($vendorDir);
+ try {
+ $storage->save($entry, 'any content');
+ } finally {
+ $this->filesystem->chmod($vendorDir.'/module_specifier/module_specifier.index.js', 0777);
+ }
}
public function testIsDownloaded()
@@ -106,7 +111,7 @@ public function testSaveExtraFile()
public function testGetDownloadedPath(string $packageModuleSpecifier, ImportMapType $importMapType, string $expectedPath)
{
$storage = new RemotePackageStorage(self::$writableRoot.'/assets/vendor');
- $this->assertSame($expectedPath, $storage->getDownloadPath($packageModuleSpecifier, $importMapType));
+ $this->assertSame(self::$writableRoot.$expectedPath, $storage->getDownloadPath($packageModuleSpecifier, $importMapType));
}
public static function getDownloadPathTests(): iterable
@@ -114,25 +119,25 @@ public static function getDownloadPathTests(): iterable
yield 'javascript bare package' => [
'packageModuleSpecifier' => 'foo',
'importMapType' => ImportMapType::JS,
- 'expectedPath' => self::$writableRoot.'/assets/vendor/foo/foo.index.js',
+ 'expectedPath' => '/assets/vendor/foo/foo.index.js',
];
yield 'javascript package with path' => [
'packageModuleSpecifier' => 'foo/bar',
'importMapType' => ImportMapType::JS,
- 'expectedPath' => self::$writableRoot.'/assets/vendor/foo/bar.js',
+ 'expectedPath' => '/assets/vendor/foo/bar.js',
];
yield 'javascript package with path and extension' => [
'packageModuleSpecifier' => 'foo/bar.js',
'importMapType' => ImportMapType::JS,
- 'expectedPath' => self::$writableRoot.'/assets/vendor/foo/bar.js',
+ 'expectedPath' => '/assets/vendor/foo/bar.js',
];
yield 'CSS package with path' => [
'packageModuleSpecifier' => 'foo/bar',
'importMapType' => ImportMapType::CSS,
- 'expectedPath' => self::$writableRoot.'/assets/vendor/foo/bar.css',
+ 'expectedPath' => '/assets/vendor/foo/bar.css',
];
}
}
diff --git a/src/Symfony/Component/AssetMapper/Tests/MapperAwareAssetPackageIntegrationTest.php b/src/Symfony/Component/AssetMapper/Tests/MapperAwareAssetPackageIntegrationTest.php
index 28818fd7a6515..821e660c6aae4 100644
--- a/src/Symfony/Component/AssetMapper/Tests/MapperAwareAssetPackageIntegrationTest.php
+++ b/src/Symfony/Component/AssetMapper/Tests/MapperAwareAssetPackageIntegrationTest.php
@@ -11,18 +11,31 @@
namespace Symfony\Component\AssetMapper\Tests;
-use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
+use PHPUnit\Framework\TestCase;
use Symfony\Component\Asset\Packages;
use Symfony\Component\AssetMapper\Tests\Fixtures\AssetMapperTestAppKernel;
+use Symfony\Component\Filesystem\Filesystem;
-class MapperAwareAssetPackageIntegrationTest extends KernelTestCase
+class MapperAwareAssetPackageIntegrationTest extends TestCase
{
- public function testDefaultAssetPackageIsDecorated()
+ private AssetMapperTestAppKernel $kernel;
+ private Filesystem $filesystem;
+
+ protected function setUp(): void
+ {
+ $this->filesystem = new Filesystem();
+ $this->kernel = new AssetMapperTestAppKernel('test', true);
+ $this->kernel->boot();
+ }
+
+ protected function tearDown(): void
{
- $kernel = new AssetMapperTestAppKernel('test', true);
- $kernel->boot();
+ $this->filesystem->remove($this->kernel->getProjectDir().'/var');
+ }
- $packages = $kernel->getContainer()->get('public.assets.packages');
+ public function testDefaultAssetPackageIsDecorated()
+ {
+ $packages = $this->kernel->getContainer()->get('public.assets.packages');
\assert($packages instanceof Packages);
$this->assertSame('/assets/file1-b3445cb7a86a0795a7af7f2004498aef.css', $packages->getUrl('file1.css'));
$this->assertSame('/non-existent.css', $packages->getUrl('non-existent.css'));
diff --git a/src/Symfony/Component/AssetMapper/Tests/Path/LocalPublicAssetsFilesystemTest.php b/src/Symfony/Component/AssetMapper/Tests/Path/LocalPublicAssetsFilesystemTest.php
index 4363ccbf577a8..5e24546e0fbe8 100644
--- a/src/Symfony/Component/AssetMapper/Tests/Path/LocalPublicAssetsFilesystemTest.php
+++ b/src/Symfony/Component/AssetMapper/Tests/Path/LocalPublicAssetsFilesystemTest.php
@@ -18,12 +18,12 @@
class LocalPublicAssetsFilesystemTest extends TestCase
{
private Filesystem $filesystem;
- private static string $writableRoot = __DIR__.'/../Fixtures/importmaps_for_writing';
+ private static string $writableRoot = __DIR__.'/../Fixtures/local_public_assets_filesystem';
protected function setUp(): void
{
$this->filesystem = new Filesystem();
- if (!file_exists(__DIR__.'/../Fixtures/importmaps_for_writing')) {
+ if (!file_exists(__DIR__.'/../Fixtures/local_public_assets_filesystem')) {
$this->filesystem->mkdir(self::$writableRoot);
}
}
diff --git a/src/Symfony/Component/Cache/Tests/Traits/RedisProxiesTest.php b/src/Symfony/Component/Cache/Tests/Traits/RedisProxiesTest.php
index 36f57f09a6605..8394b64363130 100644
--- a/src/Symfony/Component/Cache/Tests/Traits/RedisProxiesTest.php
+++ b/src/Symfony/Component/Cache/Tests/Traits/RedisProxiesTest.php
@@ -13,6 +13,7 @@
use PHPUnit\Framework\TestCase;
use Relay\Relay;
+use Symfony\Component\Cache\Traits\RelayProxy;
use Symfony\Component\VarExporter\LazyProxyTrait;
use Symfony\Component\VarExporter\ProxyHelper;
@@ -61,14 +62,30 @@ public function testRelayProxy()
{
$proxy = file_get_contents(\dirname(__DIR__, 2).'/Traits/RelayProxy.php');
$proxy = substr($proxy, 0, 4 + strpos($proxy, '[];'));
+ $expectedProxy = $proxy;
$methods = [];
+ $expectedMethods = [];
+
+ foreach ((new \ReflectionClass(RelayProxy::class))->getMethods() as $method) {
+ if ('reset' === $method->name || method_exists(LazyProxyTrait::class, $method->name) || $method->isStatic()) {
+ continue;
+ }
+
+ $return = $method->getReturnType() instanceof \ReflectionNamedType && 'void' === (string) $method->getReturnType() ? '' : 'return ';
+ $expectedMethods[$method->name] = "\n ".ProxyHelper::exportSignature($method, false, $args)."\n".<<lazyObjectState->realInstance ??= (\$this->lazyObjectState->initializer)())->{$method->name}({$args});
+ }
+
+ EOPHP;
+ }
foreach ((new \ReflectionClass(Relay::class))->getMethods() as $method) {
if ('reset' === $method->name || method_exists(LazyProxyTrait::class, $method->name) || $method->isStatic()) {
continue;
}
$return = $method->getReturnType() instanceof \ReflectionNamedType && 'void' === (string) $method->getReturnType() ? '' : 'return ';
- $methods[] = "\n ".ProxyHelper::exportSignature($method, false, $args)."\n".<<name] = "\n ".ProxyHelper::exportSignature($method, false, $args)."\n".<<lazyObjectState->realInstance ??= (\$this->lazyObjectState->initializer)())->{$method->name}({$args});
}
@@ -79,6 +96,9 @@ public function testRelayProxy()
uksort($methods, 'strnatcmp');
$proxy .= implode('', $methods)."}\n";
- $this->assertStringEqualsFile(\dirname(__DIR__, 2).'/Traits/RelayProxy.php', $proxy);
+ uksort($expectedMethods, 'strnatcmp');
+ $expectedProxy .= implode('', $expectedMethods)."}\n";
+
+ $this->assertEquals($expectedProxy, $proxy);
}
}
diff --git a/src/Symfony/Component/Cache/Tests/Traits/RedisTraitTest.php b/src/Symfony/Component/Cache/Tests/Traits/RedisTraitTest.php
index 04665608c8f7f..51d933d028e32 100644
--- a/src/Symfony/Component/Cache/Tests/Traits/RedisTraitTest.php
+++ b/src/Symfony/Component/Cache/Tests/Traits/RedisTraitTest.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\Cache\Tests\Traits;
use PHPUnit\Framework\TestCase;
+use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\Traits\RedisTrait;
/**
@@ -132,4 +133,78 @@ public function testPconnectSelectsCorrectDatabase()
ini_set('redis.pconnect.connection_limit', $prevPoolSize);
}
}
+
+ /**
+ * @dataProvider provideDbIndexDsnParameter
+ */
+ public function testDbIndexDsnParameter(string $dsn, int $expectedDb)
+ {
+ if (!getenv('REDIS_AUTHENTICATED_HOST')) {
+ self::markTestSkipped('REDIS_AUTHENTICATED_HOST env var is not defined.');
+ }
+
+ $mock = new class () {
+ use RedisTrait;
+ };
+ $connection = $mock::createConnection($dsn);
+ self::assertSame($expectedDb, $connection->getDbNum());
+ }
+
+ public static function provideDbIndexDsnParameter(): array
+ {
+ return [
+ [
+ 'redis://:p%40ssword@'.getenv('REDIS_AUTHENTICATED_HOST'),
+ 0,
+ ],
+ [
+ 'redis:?host['.getenv('REDIS_HOST').']',
+ 0,
+ ],
+ [
+ 'redis:?host['.getenv('REDIS_HOST').']&dbindex=1',
+ 1,
+ ],
+ [
+ 'redis://:p%40ssword@'.getenv('REDIS_AUTHENTICATED_HOST').'?dbindex=2',
+ 2,
+ ],
+ [
+ 'redis://:p%40ssword@'.getenv('REDIS_AUTHENTICATED_HOST').'/4',
+ 4,
+ ],
+ [
+ 'redis://:p%40ssword@'.getenv('REDIS_AUTHENTICATED_HOST').'/?dbindex=5',
+ 5,
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider provideInvalidDbIndexDsnParameter
+ */
+ public function testInvalidDbIndexDsnParameter(string $dsn)
+ {
+ if (!getenv('REDIS_AUTHENTICATED_HOST')) {
+ self::markTestSkipped('REDIS_AUTHENTICATED_HOST env var is not defined.');
+ }
+ $this->expectException(InvalidArgumentException::class);
+
+ $mock = new class () {
+ use RedisTrait;
+ };
+ $mock::createConnection($dsn);
+ }
+
+ public static function provideInvalidDbIndexDsnParameter(): array
+ {
+ return [
+ [
+ 'redis://:p%40ssword@'.getenv('REDIS_AUTHENTICATED_HOST').'/abc'
+ ],
+ [
+ 'redis://:p%40ssword@'.getenv('REDIS_AUTHENTICATED_HOST').'/3?dbindex=6'
+ ]
+ ];
+ }
}
diff --git a/src/Symfony/Component/Cache/Traits/FilesystemCommonTrait.php b/src/Symfony/Component/Cache/Traits/FilesystemCommonTrait.php
index 7fa0f2e874d63..3e8c3b1e3aa23 100644
--- a/src/Symfony/Component/Cache/Traits/FilesystemCommonTrait.php
+++ b/src/Symfony/Component/Cache/Traits/FilesystemCommonTrait.php
@@ -106,8 +106,13 @@ private function write(string $file, string $data, ?int $expiresAt = null): bool
touch($tmp, $expiresAt ?: time() + 31556952); // 1 year in seconds
}
- $success = rename($tmp, $file);
- $unlink = !$success;
+ if ('\\' === \DIRECTORY_SEPARATOR) {
+ $success = copy($tmp, $file);
+ $unlink = true;
+ } else {
+ $success = rename($tmp, $file);
+ $unlink = !$success;
+ }
return $success;
} finally {
diff --git a/src/Symfony/Component/Cache/Traits/RedisTrait.php b/src/Symfony/Component/Cache/Traits/RedisTrait.php
index d59d7ff031962..d1b7ae16c9ced 100644
--- a/src/Symfony/Component/Cache/Traits/RedisTrait.php
+++ b/src/Symfony/Component/Cache/Traits/RedisTrait.php
@@ -149,10 +149,10 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra
if (isset($params['host']) || isset($params['path'])) {
if (!isset($params['dbindex']) && isset($params['path'])) {
if (preg_match('#/(\d+)?$#', $params['path'], $m)) {
- $params['dbindex'] = $m[1] ?? '0';
+ $params['dbindex'] = $m[1] ?? $query['dbindex'] ?? '0';
$params['path'] = substr($params['path'], 0, -\strlen($m[0]));
} elseif (isset($params['host'])) {
- throw new InvalidArgumentException('Invalid Redis DSN: query parameter "dbindex" must be a number.');
+ throw new InvalidArgumentException('Invalid Redis DSN: parameter "dbindex" must be a number.');
}
}
@@ -167,6 +167,10 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra
throw new InvalidArgumentException('Invalid Redis DSN: missing host.');
}
+ if (isset($params['dbindex'], $query['dbindex']) && $params['dbindex'] !== $query['dbindex']) {
+ throw new InvalidArgumentException('Invalid Redis DSN: path and query "dbindex" parameters mismatch.');
+ }
+
$params += $query + $options + self::$defaultConnectionOptions;
if (isset($params['redis_sentinel']) && !class_exists(\Predis\Client::class) && !class_exists(\RedisSentinel::class) && !class_exists(Sentinel::class)) {
diff --git a/src/Symfony/Component/Cache/Traits/RelayProxy.php b/src/Symfony/Component/Cache/Traits/RelayProxy.php
index ac839dfda9ca0..96d7d19b46785 100644
--- a/src/Symfony/Component/Cache/Traits/RelayProxy.php
+++ b/src/Symfony/Component/Cache/Traits/RelayProxy.php
@@ -28,6 +28,7 @@ class RelayProxy extends \Relay\Relay implements ResetInterface, LazyObjectInter
use LazyProxyTrait {
resetLazyObject as reset;
}
+ use RelayProxyTrait;
private const LAZY_OBJECT_PROPERTY_SCOPES = [];
@@ -291,11 +292,6 @@ public function migrate($host, $port, $key, $dstdb, $timeout, $copy = false, $re
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->migrate(...\func_get_args());
}
- public function copy($src, $dst, $options = null): \Relay\Relay|false|int
- {
- return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->copy(...\func_get_args());
- }
-
public function echo($arg): \Relay\Relay|bool|string
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->echo(...\func_get_args());
diff --git a/src/Symfony/Component/Cache/Traits/RelayProxyTrait.php b/src/Symfony/Component/Cache/Traits/RelayProxyTrait.php
new file mode 100644
index 0000000000000..a1d252b96d2bf
--- /dev/null
+++ b/src/Symfony/Component/Cache/Traits/RelayProxyTrait.php
@@ -0,0 +1,156 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Traits;
+
+if (version_compare(phpversion('relay'), '0.8.1', '>=')) {
+ /**
+ * @internal
+ */
+ trait RelayProxyTrait
+ {
+ public function copy($src, $dst, $options = null): \Relay\Relay|bool
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->copy(...\func_get_args());
+ }
+
+ public function jsonArrAppend($key, $value_or_array, $path = null): \Relay\Relay|array|false
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonArrAppend(...\func_get_args());
+ }
+
+ public function jsonArrIndex($key, $path, $value, $start = 0, $stop = -1): \Relay\Relay|array|false
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonArrIndex(...\func_get_args());
+ }
+
+ public function jsonArrInsert($key, $path, $index, $value, ...$other_values): \Relay\Relay|array|false
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonArrInsert(...\func_get_args());
+ }
+
+ public function jsonArrLen($key, $path = null): \Relay\Relay|array|false
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonArrLen(...\func_get_args());
+ }
+
+ public function jsonArrPop($key, $path = null, $index = -1): \Relay\Relay|array|false
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonArrPop(...\func_get_args());
+ }
+
+ public function jsonArrTrim($key, $path, $start, $stop): \Relay\Relay|array|false
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonArrTrim(...\func_get_args());
+ }
+
+ public function jsonClear($key, $path = null): \Relay\Relay|false|int
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonClear(...\func_get_args());
+ }
+
+ public function jsonDebug($command, $key, $path = null): \Relay\Relay|false|int
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonDebug(...\func_get_args());
+ }
+
+ public function jsonDel($key, $path = null): \Relay\Relay|false|int
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonDel(...\func_get_args());
+ }
+
+ public function jsonForget($key, $path = null): \Relay\Relay|false|int
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonForget(...\func_get_args());
+ }
+
+ public function jsonGet($key, $options = [], ...$paths): mixed
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonGet(...\func_get_args());
+ }
+
+ public function jsonMerge($key, $path, $value): \Relay\Relay|bool
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonMerge(...\func_get_args());
+ }
+
+ public function jsonMget($key_or_array, $path): \Relay\Relay|array|false
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonMget(...\func_get_args());
+ }
+
+ public function jsonMset($key, $path, $value, ...$other_triples): \Relay\Relay|bool
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonMset(...\func_get_args());
+ }
+
+ public function jsonNumIncrBy($key, $path, $value): \Relay\Relay|array|false
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonNumIncrBy(...\func_get_args());
+ }
+
+ public function jsonNumMultBy($key, $path, $value): \Relay\Relay|array|false
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonNumMultBy(...\func_get_args());
+ }
+
+ public function jsonObjKeys($key, $path = null): \Relay\Relay|array|false
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonObjKeys(...\func_get_args());
+ }
+
+ public function jsonObjLen($key, $path = null): \Relay\Relay|array|false
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonObjLen(...\func_get_args());
+ }
+
+ public function jsonResp($key, $path = null): \Relay\Relay|array|false|int|string
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonResp(...\func_get_args());
+ }
+
+ public function jsonSet($key, $path, $value, $condition = null): \Relay\Relay|bool
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonSet(...\func_get_args());
+ }
+
+ public function jsonStrAppend($key, $value, $path = null): \Relay\Relay|array|false
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonStrAppend(...\func_get_args());
+ }
+
+ public function jsonStrLen($key, $path = null): \Relay\Relay|array|false
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonStrLen(...\func_get_args());
+ }
+
+ public function jsonToggle($key, $path): \Relay\Relay|array|false
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonToggle(...\func_get_args());
+ }
+
+ public function jsonType($key, $path = null): \Relay\Relay|array|false
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonType(...\func_get_args());
+ }
+ }
+} else {
+ /**
+ * @internal
+ */
+ trait RelayProxyTrait
+ {
+ public function copy($src, $dst, $options = null): \Relay\Relay|false|int
+ {
+ return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->copy(...\func_get_args());
+ }
+ }
+}
diff --git a/src/Symfony/Component/Console/Output/StreamOutput.php b/src/Symfony/Component/Console/Output/StreamOutput.php
index 84a7fa7342653..b46f4d2ca0a04 100644
--- a/src/Symfony/Component/Console/Output/StreamOutput.php
+++ b/src/Symfony/Component/Console/Output/StreamOutput.php
@@ -90,7 +90,7 @@ protected function doWrite(string $message, bool $newline): void
protected function hasColorSupport(): bool
{
// Follow https://no-color.org/
- if (isset($_SERVER['NO_COLOR']) || false !== getenv('NO_COLOR')) {
+ if ('' !== ($_SERVER['NO_COLOR'] ?? getenv('NO_COLOR') ?: '')) {
return false;
}
diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php
index d8e1ae8b97e5d..ac1d47245b1ef 100644
--- a/src/Symfony/Component/Console/Tests/ApplicationTest.php
+++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php
@@ -71,12 +71,10 @@ protected function tearDown(): void
if (\function_exists('pcntl_signal')) {
// We reset all signals to their default value to avoid side effects
- for ($i = 1; $i <= 15; ++$i) {
- if (9 === $i) {
- continue;
- }
- pcntl_signal($i, \SIG_DFL);
- }
+ pcntl_signal(\SIGINT, \SIG_DFL);
+ pcntl_signal(\SIGTERM, \SIG_DFL);
+ pcntl_signal(\SIGUSR1, \SIG_DFL);
+ pcntl_signal(\SIGUSR2, \SIG_DFL);
}
}
diff --git a/src/Symfony/Component/Console/Tests/ConsoleEventsTest.php b/src/Symfony/Component/Console/Tests/ConsoleEventsTest.php
index 93c228aa47eef..9c04d2706e8da 100644
--- a/src/Symfony/Component/Console/Tests/ConsoleEventsTest.php
+++ b/src/Symfony/Component/Console/Tests/ConsoleEventsTest.php
@@ -35,12 +35,10 @@ protected function tearDown(): void
if (\function_exists('pcntl_signal')) {
pcntl_async_signals(false);
// We reset all signals to their default value to avoid side effects
- for ($i = 1; $i <= 15; ++$i) {
- if (9 === $i) {
- continue;
- }
- pcntl_signal($i, \SIG_DFL);
- }
+ pcntl_signal(\SIGINT, \SIG_DFL);
+ pcntl_signal(\SIGTERM, \SIG_DFL);
+ pcntl_signal(\SIGUSR1, \SIG_DFL);
+ pcntl_signal(\SIGUSR2, \SIG_DFL);
}
}
diff --git a/src/Symfony/Component/Console/Tests/SignalRegistry/SignalRegistryTest.php b/src/Symfony/Component/Console/Tests/SignalRegistry/SignalRegistryTest.php
index 4cb4354163812..f997f7c1d8cee 100644
--- a/src/Symfony/Component/Console/Tests/SignalRegistry/SignalRegistryTest.php
+++ b/src/Symfony/Component/Console/Tests/SignalRegistry/SignalRegistryTest.php
@@ -23,12 +23,10 @@ protected function tearDown(): void
{
pcntl_async_signals(false);
// We reset all signals to their default value to avoid side effects
- for ($i = 1; $i <= 15; ++$i) {
- if (9 === $i) {
- continue;
- }
- pcntl_signal($i, \SIG_DFL);
- }
+ pcntl_signal(\SIGINT, \SIG_DFL);
+ pcntl_signal(\SIGTERM, \SIG_DFL);
+ pcntl_signal(\SIGUSR1, \SIG_DFL);
+ pcntl_signal(\SIGUSR2, \SIG_DFL);
}
public function testOneCallbackForASignalSignalIsHandled()
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/PriorityTaggedServiceTrait.php b/src/Symfony/Component/DependencyInjection/Compiler/PriorityTaggedServiceTrait.php
index 701786245d91c..42410cebefdd7 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/PriorityTaggedServiceTrait.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/PriorityTaggedServiceTrait.php
@@ -133,6 +133,10 @@ public static function getDefault(ContainerBuilder $container, string $serviceId
return null;
}
+ if ($r->isInterface()) {
+ return null;
+ }
+
if (null !== $indexAttribute) {
$service = $class !== $serviceId ? sprintf('service "%s"', $serviceId) : 'on the corresponding service';
$message = [sprintf('Either method "%s::%s()" should ', $class, $defaultMethod), sprintf(' or tag "%s" on %s is missing attribute "%s".', $tagName, $service, $indexAttribute)];
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTraitTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTraitTest.php
index 726bfddd6d40f..bc7387ab4de44 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTraitTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTraitTest.php
@@ -151,6 +151,8 @@ public function testTheIndexedTagsByDefaultIndexMethod()
$container->register('service3', IntTagClass::class)->addTag('my_custom_tag');
+ $container->register('service4', HelloInterface::class)->addTag('my_custom_tag');
+
$priorityTaggedServiceTraitImplementation = new PriorityTaggedServiceTraitImplementation();
$tag = new TaggedIteratorArgument('my_custom_tag', 'foo', 'getFooBar');
@@ -158,6 +160,7 @@ public function testTheIndexedTagsByDefaultIndexMethod()
'bar_tab_class_with_defaultmethod' => new TypedReference('service2', BarTagClass::class),
'service1' => new TypedReference('service1', FooTagClass::class),
'10' => new TypedReference('service3', IntTagClass::class),
+ 'service4' => new TypedReference('service4', HelloInterface::class),
];
$services = $priorityTaggedServiceTraitImplementation->test($tag, $container);
$this->assertSame(array_keys($expected), array_keys($services));
@@ -247,3 +250,8 @@ class HelloNamedService extends \stdClass
class HelloNamedService2
{
}
+
+interface HelloInterface
+{
+ public static function getFooBar(): string;
+}
diff --git a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php
index 72d0d5630ec9a..644126d6b2ba1 100644
--- a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php
+++ b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php
@@ -430,16 +430,16 @@ public function testHttpVarIsPartiallyOverridden()
$this->assertSame('http_value', $_SERVER['HTTP_TEST_ENV_VAR']);
}
- public function testEnvVarIsOverriden()
+ public function testEnvVarIsOverridden()
{
- putenv('TEST_ENV_VAR_OVERRIDEN=original_value');
+ putenv('TEST_ENV_VAR_OVERRIDDEN=original_value');
$dotenv = (new Dotenv())->usePutenv();
- $dotenv->populate(['TEST_ENV_VAR_OVERRIDEN' => 'new_value'], true);
+ $dotenv->populate(['TEST_ENV_VAR_OVERRIDDEN' => 'new_value'], true);
- $this->assertSame('new_value', getenv('TEST_ENV_VAR_OVERRIDEN'));
- $this->assertSame('new_value', $_ENV['TEST_ENV_VAR_OVERRIDEN']);
- $this->assertSame('new_value', $_SERVER['TEST_ENV_VAR_OVERRIDEN']);
+ $this->assertSame('new_value', getenv('TEST_ENV_VAR_OVERRIDDEN'));
+ $this->assertSame('new_value', $_ENV['TEST_ENV_VAR_OVERRIDDEN']);
+ $this->assertSame('new_value', $_SERVER['TEST_ENV_VAR_OVERRIDDEN']);
}
public function testMemorizingLoadedVarsNamesInSpecialVar()
diff --git a/src/Symfony/Component/ErrorHandler/ErrorHandler.php b/src/Symfony/Component/ErrorHandler/ErrorHandler.php
index d82ce6c7024cc..777833b95ff8b 100644
--- a/src/Symfony/Component/ErrorHandler/ErrorHandler.php
+++ b/src/Symfony/Component/ErrorHandler/ErrorHandler.php
@@ -55,7 +55,6 @@ class ErrorHandler
\E_USER_DEPRECATED => 'User Deprecated',
\E_NOTICE => 'Notice',
\E_USER_NOTICE => 'User Notice',
- \E_STRICT => 'Runtime Notice',
\E_WARNING => 'Warning',
\E_USER_WARNING => 'User Warning',
\E_COMPILE_WARNING => 'Compile Warning',
@@ -73,7 +72,6 @@ class ErrorHandler
\E_USER_DEPRECATED => [null, LogLevel::INFO],
\E_NOTICE => [null, LogLevel::WARNING],
\E_USER_NOTICE => [null, LogLevel::WARNING],
- \E_STRICT => [null, LogLevel::WARNING],
\E_WARNING => [null, LogLevel::WARNING],
\E_USER_WARNING => [null, LogLevel::WARNING],
\E_COMPILE_WARNING => [null, LogLevel::WARNING],
@@ -181,6 +179,11 @@ public static function call(callable $function, mixed ...$arguments): mixed
public function __construct(?BufferingLogger $bootstrappingLogger = null, bool $debug = false)
{
+ if (\PHP_VERSION_ID < 80400) {
+ $this->levels[\E_STRICT] = 'Runtime Notice';
+ $this->loggers[\E_STRICT] = [null, LogLevel::WARNING];
+ }
+
if ($bootstrappingLogger) {
$this->bootstrappingLogger = $bootstrappingLogger;
$this->setDefaultLogger($bootstrappingLogger);
diff --git a/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php b/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php
index 17745c8170818..032f194d2f542 100644
--- a/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php
+++ b/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php
@@ -61,7 +61,7 @@ public function render(\Throwable $exception): FlattenException
{
$headers = ['Content-Type' => 'text/html; charset='.$this->charset];
if (\is_bool($this->debug) ? $this->debug : ($this->debug)($exception)) {
- $headers['X-Debug-Exception'] = rawurlencode($exception->getMessage());
+ $headers['X-Debug-Exception'] = rawurlencode(substr($exception->getMessage(), 0, 2000));
$headers['X-Debug-Exception-File'] = rawurlencode($exception->getFile()).':'.$exception->getLine();
}
diff --git a/src/Symfony/Component/ErrorHandler/ErrorRenderer/SerializerErrorRenderer.php b/src/Symfony/Component/ErrorHandler/ErrorRenderer/SerializerErrorRenderer.php
index a42ce3f2b8138..b09a6e00c3a7b 100644
--- a/src/Symfony/Component/ErrorHandler/ErrorRenderer/SerializerErrorRenderer.php
+++ b/src/Symfony/Component/ErrorHandler/ErrorRenderer/SerializerErrorRenderer.php
@@ -47,7 +47,7 @@ public function render(\Throwable $exception): FlattenException
$headers = ['Vary' => 'Accept'];
$debug = \is_bool($this->debug) ? $this->debug : ($this->debug)($exception);
if ($debug) {
- $headers['X-Debug-Exception'] = rawurlencode($exception->getMessage());
+ $headers['X-Debug-Exception'] = rawurlencode(substr($exception->getMessage(), 0, 2000));
$headers['X-Debug-Exception-File'] = rawurlencode($exception->getFile()).':'.$exception->getLine();
}
diff --git a/src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php b/src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php
index e6d3e7d5b95a5..55a2a6b34561f 100644
--- a/src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php
+++ b/src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php
@@ -203,7 +203,6 @@ public function testDefaultLogger()
\E_USER_DEPRECATED => [null, LogLevel::INFO],
\E_NOTICE => [$logger, LogLevel::WARNING],
\E_USER_NOTICE => [$logger, LogLevel::CRITICAL],
- \E_STRICT => [null, LogLevel::WARNING],
\E_WARNING => [null, LogLevel::WARNING],
\E_USER_WARNING => [null, LogLevel::WARNING],
\E_COMPILE_WARNING => [null, LogLevel::WARNING],
@@ -215,6 +214,11 @@ public function testDefaultLogger()
\E_ERROR => [null, LogLevel::CRITICAL],
\E_CORE_ERROR => [null, LogLevel::CRITICAL],
];
+
+ if (\PHP_VERSION_ID < 80400) {
+ $loggers[\E_STRICT] = [null, LogLevel::WARNING];
+ }
+
$this->assertSame($loggers, $handler->setLoggers([]));
} finally {
restore_error_handler();
@@ -440,7 +444,6 @@ public function testBootstrappingLogger()
\E_USER_DEPRECATED => [$bootLogger, LogLevel::INFO],
\E_NOTICE => [$bootLogger, LogLevel::WARNING],
\E_USER_NOTICE => [$bootLogger, LogLevel::WARNING],
- \E_STRICT => [$bootLogger, LogLevel::WARNING],
\E_WARNING => [$bootLogger, LogLevel::WARNING],
\E_USER_WARNING => [$bootLogger, LogLevel::WARNING],
\E_COMPILE_WARNING => [$bootLogger, LogLevel::WARNING],
@@ -453,6 +456,10 @@ public function testBootstrappingLogger()
\E_CORE_ERROR => [$bootLogger, LogLevel::CRITICAL],
];
+ if (\PHP_VERSION_ID < 80400) {
+ $loggers[\E_STRICT] = [$bootLogger, LogLevel::WARNING];
+ }
+
$this->assertSame($loggers, $handler->setLoggers([]));
$handler->handleError(\E_DEPRECATED, 'Foo message', __FILE__, 123, []);
diff --git a/src/Symfony/Component/Finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php b/src/Symfony/Component/Finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php
index 3b3caa5e3f789..49144505f7883 100644
--- a/src/Symfony/Component/Finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php
+++ b/src/Symfony/Component/Finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php
@@ -27,7 +27,7 @@ protected function setUp(): void
*/
public function testRewindOnFtp()
{
- $i = new RecursiveDirectoryIterator('ftp://speedtest:speedtest@ftp.otenet.gr/', \RecursiveDirectoryIterator::SKIP_DOTS);
+ $i = new RecursiveDirectoryIterator('ftp://test.rebex.net/', \RecursiveDirectoryIterator::SKIP_DOTS);
$i->rewind();
@@ -39,11 +39,11 @@ public function testRewindOnFtp()
*/
public function testSeekOnFtp()
{
- $i = new RecursiveDirectoryIterator('ftp://speedtest:speedtest@ftp.otenet.gr/', \RecursiveDirectoryIterator::SKIP_DOTS);
+ $i = new RecursiveDirectoryIterator('ftp://test.rebex.net/', \RecursiveDirectoryIterator::SKIP_DOTS);
$contains = [
- 'ftp://speedtest:speedtest@ftp.otenet.gr'.\DIRECTORY_SEPARATOR.'test100Mb.db',
- 'ftp://speedtest:speedtest@ftp.otenet.gr'.\DIRECTORY_SEPARATOR.'test100k.db',
+ 'ftp://test.rebex.net'.\DIRECTORY_SEPARATOR.'pub',
+ 'ftp://test.rebex.net'.\DIRECTORY_SEPARATOR.'readme.txt',
];
$actual = [];
diff --git a/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataExtractorTest.php b/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataExtractorTest.php
index ec01721c704b4..b8a1fee374035 100644
--- a/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataExtractorTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataExtractorTest.php
@@ -26,6 +26,7 @@
use Symfony\Component\Form\ResolvedFormType;
use Symfony\Component\Form\ResolvedFormTypeFactory;
use Symfony\Component\Form\Tests\Fixtures\FixedDataTransformer;
+use Symfony\Component\Validator\Constraints\WordCount;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\VarDumper\Test\VarDumperTestTrait;
@@ -300,35 +301,68 @@ public function testExtractSubmittedDataStoresErrorCause()
$form->addError(new FormError('Invalid!', null, [], null, $violation));
$origin = spl_object_hash($form);
- $this->assertDumpMatchesFormat(<< array:1 [
- "norm" => "Foobar"
- ]
- "errors" => array:1 [
- 0 => array:3 [
- "message" => "Invalid!"
- "origin" => "$origin"
- "trace" => array:2 [
- 0 => Symfony\Component\Validator\ConstraintViolation {
- -message: "Foo"
- -messageTemplate: "Foo"
- -parameters: []
- -plural: null
- -root: "Root"
- -propertyPath: "property.path"
- -invalidValue: "Invalid!"
- -constraint: null
- -code: null
- -cause: Exception {%A}
+ if (class_exists(WordCount::class)) {
+ $expectedFormat = <<<"EODUMP"
+ array:3 [
+ "submitted_data" => array:1 [
+ "norm" => "Foobar"
+ ]
+ "errors" => array:1 [
+ 0 => array:3 [
+ "message" => "Invalid!"
+ "origin" => "$origin"
+ "trace" => array:2 [
+ 0 => Symfony\Component\Validator\ConstraintViolation {
+ -message: "Foo"
+ -messageTemplate: "Foo"
+ -parameters: []
+ -root: "Root"
+ -propertyPath: "property.path"
+ -invalidValue: "Invalid!"
+ -plural: null
+ -code: null
+ -constraint: null
+ -cause: Exception {%A}
+ }
+ 1 => Exception {#1}
+ ]
+ ]
+ ]
+ "synchronized" => true
+ ]
+ EODUMP;
+ } else {
+ $expectedFormat = <<<"EODUMP"
+ array:3 [
+ "submitted_data" => array:1 [
+ "norm" => "Foobar"
+ ]
+ "errors" => array:1 [
+ 0 => array:3 [
+ "message" => "Invalid!"
+ "origin" => "$origin"
+ "trace" => array:2 [
+ 0 => Symfony\Component\Validator\ConstraintViolation {
+ -message: "Foo"
+ -messageTemplate: "Foo"
+ -parameters: []
+ -plural: null
+ -root: "Root"
+ -propertyPath: "property.path"
+ -invalidValue: "Invalid!"
+ -constraint: null
+ -code: null
+ -cause: Exception {%A}
+ }
+ 1 => Exception {#1}
+ ]
+ ]
+ ]
+ "synchronized" => true
+ ]
+ EODUMP;
}
- 1 => Exception {#1}
- ]
- ]
- ]
- "synchronized" => true
-]
-EODUMP
+ $this->assertDumpMatchesFormat($expectedFormat
,
$this->dataExtractor->extractSubmittedData($form)
);
diff --git a/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php b/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php
index 20cf7ef48291b..1c3076324da02 100644
--- a/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php
+++ b/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php
@@ -115,7 +115,7 @@ public function testOverridingInternalAttributesUsingCurlOptions()
$httpClient->request('POST', 'http://localhost:8057/', [
'extra' => [
'curl' => [
- \CURLOPT_PRIVATE => 'overriden private',
+ \CURLOPT_PRIVATE => 'overridden private',
],
],
]);
diff --git a/src/Symfony/Component/HttpClient/Tests/HttplugClientTest.php b/src/Symfony/Component/HttpClient/Tests/HttplugClientTest.php
index 182d52932f724..f5f6d8ddcf9be 100644
--- a/src/Symfony/Component/HttpClient/Tests/HttplugClientTest.php
+++ b/src/Symfony/Component/HttpClient/Tests/HttplugClientTest.php
@@ -37,6 +37,9 @@ public static function tearDownAfterClass(): void
TestHttpServer::stop();
}
+ /**
+ * @requires function ob_gzhandler
+ */
public function testSendRequest()
{
$client = new HttplugClient(new NativeHttpClient());
@@ -51,6 +54,9 @@ public function testSendRequest()
$this->assertSame('HTTP/1.1', $body['SERVER_PROTOCOL']);
}
+ /**
+ * @requires function ob_gzhandler
+ */
public function testSendAsyncRequest()
{
$client = new HttplugClient(new NativeHttpClient());
diff --git a/src/Symfony/Component/HttpClient/Tests/Psr18ClientTest.php b/src/Symfony/Component/HttpClient/Tests/Psr18ClientTest.php
index d1f4deb03a006..65b7f5b3f6794 100644
--- a/src/Symfony/Component/HttpClient/Tests/Psr18ClientTest.php
+++ b/src/Symfony/Component/HttpClient/Tests/Psr18ClientTest.php
@@ -33,6 +33,9 @@ public static function tearDownAfterClass(): void
TestHttpServer::stop();
}
+ /**
+ * @requires function ob_gzhandler
+ */
public function testSendRequest()
{
$factory = new Psr17Factory();
diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php b/src/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php
index dae8a4c3f8f3e..5305848799d8a 100644
--- a/src/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php
+++ b/src/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php
@@ -169,7 +169,7 @@ public function getMetadataBag(): MetadataBag
*/
protected function generateId(): string
{
- return hash('sha256', uniqid('ss_mock_', true));
+ return bin2hex(random_bytes(16));
}
protected function loadSession(): void
diff --git a/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php
index e8a194959d879..c7d47a4d70a35 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php
@@ -344,7 +344,7 @@ public function testAcceptRangeOnUnsafeMethods()
$this->assertEquals('none', $response->headers->get('Accept-Ranges'));
}
- public function testAcceptRangeNotOverriden()
+ public function testAcceptRangeNotOverridden()
{
$request = Request::create('/', 'POST');
$response = new BinaryFileResponse(__DIR__.'/File/Fixtures/test.gif', 200, ['Content-Type' => 'application/octet-stream']);
diff --git a/src/Symfony/Component/HttpFoundation/Tests/InputBagTest.php b/src/Symfony/Component/HttpFoundation/Tests/InputBagTest.php
index 6bb4285d1b32e..01df837b20b4c 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/InputBagTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/InputBagTest.php
@@ -154,6 +154,24 @@ public function testFilterArrayWithoutArrayFlag()
$bag->filter('foo', \FILTER_VALIDATE_INT);
}
+ public function testAdd()
+ {
+ $bag = new InputBag(['foo' => 'bar']);
+ $bag->add(['baz' => 'qux']);
+
+ $this->assertSame('bar', $bag->get('foo'), '->add() does not remove existing parameters');
+ $this->assertSame('qux', $bag->get('baz'), '->add() adds new parameters');
+ }
+
+ public function testReplace()
+ {
+ $bag = new InputBag(['foo' => 'bar']);
+ $bag->replace(['baz' => 'qux']);
+
+ $this->assertNull($bag->get('foo'), '->replace() removes existing parameters');
+ $this->assertSame('qux', $bag->get('baz'), '->replace() adds new parameters');
+ }
+
public function testGetEnum()
{
$bag = new InputBag(['valid-value' => 1]);
diff --git a/src/Symfony/Component/HttpFoundation/Tests/RateLimiter/AbstractRequestRateLimiterTest.php b/src/Symfony/Component/HttpFoundation/Tests/RateLimiter/AbstractRequestRateLimiterTest.php
index 4e102777a45c6..26f2fac90801e 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/RateLimiter/AbstractRequestRateLimiterTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/RateLimiter/AbstractRequestRateLimiterTest.php
@@ -14,6 +14,7 @@
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\RateLimiter\LimiterInterface;
+use Symfony\Component\RateLimiter\Policy\NoLimiter;
use Symfony\Component\RateLimiter\RateLimit;
class AbstractRequestRateLimiterTest extends TestCase
@@ -33,6 +34,34 @@ public function testConsume(array $rateLimits, ?RateLimit $expected)
$this->assertSame($expected, $rateLimiter->consume(new Request()));
}
+ public function testConsumeWithoutLimiterAddsSpecialNoLimiter()
+ {
+ $rateLimiter = new MockAbstractRequestRateLimiter([]);
+
+ try {
+ $this->assertSame(\PHP_INT_MAX, $rateLimiter->consume(new Request())->getLimit());
+ } catch (\TypeError $error) {
+ if (str_contains($error->getMessage(), 'RateLimit::__construct(): Argument #1 ($availableTokens) must be of type int, float given')) {
+ $this->markTestSkipped('This test cannot be run on a version of the RateLimiter component that uses \INF instead of \PHP_INT_MAX in NoLimiter.');
+ }
+
+ throw $error;
+ }
+ }
+
+ public function testResetLimiters()
+ {
+ $rateLimiter = new MockAbstractRequestRateLimiter([
+ $limiter1 = $this->createMock(LimiterInterface::class),
+ $limiter2 = $this->createMock(LimiterInterface::class),
+ ]);
+
+ $limiter1->expects($this->once())->method('reset');
+ $limiter2->expects($this->once())->method('reset');
+
+ $rateLimiter->reset(new Request());
+ }
+
public static function provideRateLimits()
{
$now = new \DateTimeImmutable();
diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestMatcher/MethodRequestMatcherTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestMatcher/MethodRequestMatcherTest.php
index d4af82cd985ff..19db917fe6bf5 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/RequestMatcher/MethodRequestMatcherTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/RequestMatcher/MethodRequestMatcherTest.php
@@ -27,6 +27,13 @@ public function test(string $requestMethod, array|string $matcherMethod, bool $i
$this->assertSame($isMatch, $matcher->matches($request));
}
+ public function testAlwaysMatchesOnEmptyMethod()
+ {
+ $matcher = new MethodRequestMatcher([]);
+ $request = Request::create('https://example.com', 'POST');
+ $this->assertTrue($matcher->matches($request));
+ }
+
public static function getData()
{
return [
diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestMatcher/SchemeRequestMatcherTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestMatcher/SchemeRequestMatcherTest.php
index f8d83645f1089..6614bfcc210f9 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/RequestMatcher/SchemeRequestMatcherTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/RequestMatcher/SchemeRequestMatcherTest.php
@@ -42,6 +42,13 @@ public function test(string $requestScheme, array|string $matcherScheme, bool $i
}
}
+ public function testAlwaysMatchesOnParamsHeaders()
+ {
+ $matcher = new SchemeRequestMatcher([]);
+ $request = Request::create('sftp://example.com');
+ $this->assertTrue($matcher->matches($request));
+ }
+
public static function getData()
{
return [
diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php
index 34e48d17ced7f..8c977c1c105e4 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 = '7.0.9';
- public const VERSION_ID = 70009;
+ public const VERSION = '7.0.10';
+ public const VERSION_ID = 70010;
public const MAJOR_VERSION = 7;
public const MINOR_VERSION = 0;
- public const RELEASE_VERSION = 9;
+ public const RELEASE_VERSION = 10;
public const EXTRA_VERSION = '';
public const END_OF_MAINTENANCE = '07/2024';
@@ -521,6 +521,7 @@ protected function initializeContainer(): void
touch($oldContainerDir.'.legacy');
}
+ $buildDir = $this->container->getParameter('kernel.build_dir');
$cacheDir = $this->container->getParameter('kernel.cache_dir');
$preload = $this instanceof WarmableInterface ? (array) $this->warmUp($cacheDir, $buildDir) : [];
diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/LocaleListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/LocaleListenerTest.php
index 59872ec73c300..0ffa72fc3e0b3 100644
--- a/src/Symfony/Component/HttpKernel/Tests/EventListener/LocaleListenerTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/LocaleListenerTest.php
@@ -205,7 +205,7 @@ public function testRequestNoLocaleFromAcceptLanguageHeader()
$this->assertEquals('fr_FR', $request->getLocale());
}
- public function testRequestAttributeLocaleNotOverridenFromAcceptLanguageHeader()
+ public function testRequestAttributeLocaleNotOverriddenFromAcceptLanguageHeader()
{
$request = Request::create('/');
$request->attributes->set('_locale', 'it');
diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php
index 5837407abeb63..3064fca51f421 100644
--- a/src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php
@@ -562,7 +562,7 @@ public function testUninitializedSessionWithoutInitializedSession()
$this->assertSame('60', $response->headers->getCacheControlDirective('s-maxage'));
}
- public function testResponseHeadersMaxAgeAndExpiresNotBeOverridenIfSessionStarted()
+ public function testResponseHeadersMaxAgeAndExpiresNotBeOverriddenIfSessionStarted()
{
$session = $this->createMock(Session::class);
$session->expects($this->once())->method('getUsageIndex')->willReturn(1);
diff --git a/src/Symfony/Component/HttpKernel/Tests/KernelTest.php b/src/Symfony/Component/HttpKernel/Tests/KernelTest.php
index ff05190eb6817..905ea8e54b6be 100644
--- a/src/Symfony/Component/HttpKernel/Tests/KernelTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/KernelTest.php
@@ -452,7 +452,7 @@ public function testWarmup()
$kernel->boot();
$this->assertTrue($kernel->warmedUp);
- $this->assertSame($kernel->getBuildDir(), $kernel->warmedUpBuildDir);
+ $this->assertSame(realpath($kernel->getBuildDir()), $kernel->warmedUpBuildDir);
}
public function testServicesResetter()
diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php
index f516854226ba9..a7992e63baf5a 100644
--- a/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php
+++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php
@@ -61,6 +61,7 @@ protected function doSendApi(SentMessage $sentMessage, Email $email, Envelope $e
$endpoint = sprintf('%s/v3/%s/messages', $this->getEndpoint(), urlencode($this->domain));
$response = $this->client->request('POST', 'https://'.$endpoint, [
+ 'http_version' => '1.1',
'auth_basic' => 'api:'.$this->key,
'headers' => $headers,
'body' => $body->bodyToIterable(),
diff --git a/src/Symfony/Component/Messenger/Bridge/Redis/Tests/Transport/ConnectionTest.php b/src/Symfony/Component/Messenger/Bridge/Redis/Tests/Transport/ConnectionTest.php
index b563540893d7f..28a840e6bb4e4 100644
--- a/src/Symfony/Component/Messenger/Bridge/Redis/Tests/Transport/ConnectionTest.php
+++ b/src/Symfony/Component/Messenger/Bridge/Redis/Tests/Transport/ConnectionTest.php
@@ -413,7 +413,7 @@ public function testInvalidSentinelMasterName()
}
$master = getenv('MESSENGER_REDIS_DSN');
- $uid = uniqid('sentinel_');
+ $uid = uniqid('sentinel_', true);
$exp = explode('://', $master, 2)[1];
$this->expectException(\InvalidArgumentException::class);
diff --git a/src/Symfony/Component/Messenger/EventListener/SendFailedMessageForRetryListener.php b/src/Symfony/Component/Messenger/EventListener/SendFailedMessageForRetryListener.php
index 506206712e046..8d4e2e226205e 100644
--- a/src/Symfony/Component/Messenger/EventListener/SendFailedMessageForRetryListener.php
+++ b/src/Symfony/Component/Messenger/EventListener/SendFailedMessageForRetryListener.php
@@ -75,7 +75,7 @@ public function onMessageFailed(WorkerMessageFailedEvent $event): void
$retryEnvelope = $this->withLimitedHistory($envelope, new DelayStamp($delay), new RedeliveryStamp($retryCount));
// re-send the message for retry
- $this->getSenderForTransport($event->getReceiverName())->send($retryEnvelope);
+ $retryEnvelope = $this->getSenderForTransport($event->getReceiverName())->send($retryEnvelope);
$this->eventDispatcher?->dispatch(new WorkerMessageRetriedEvent($retryEnvelope, $event->getReceiverName()));
} else {
diff --git a/src/Symfony/Component/Messenger/Tests/EventListener/SendFailedMessageForRetryListenerTest.php b/src/Symfony/Component/Messenger/Tests/EventListener/SendFailedMessageForRetryListenerTest.php
index fccdae9bfa215..defa4cc4245df 100644
--- a/src/Symfony/Component/Messenger/Tests/EventListener/SendFailedMessageForRetryListenerTest.php
+++ b/src/Symfony/Component/Messenger/Tests/EventListener/SendFailedMessageForRetryListenerTest.php
@@ -14,13 +14,16 @@
use PHPUnit\Framework\TestCase;
use Psr\Container\ContainerInterface;
use Psr\EventDispatcher\EventDispatcherInterface;
+use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent;
+use Symfony\Component\Messenger\Event\WorkerMessageRetriedEvent;
use Symfony\Component\Messenger\EventListener\SendFailedMessageForRetryListener;
use Symfony\Component\Messenger\Exception\RecoverableMessageHandlingException;
use Symfony\Component\Messenger\Retry\RetryStrategyInterface;
use Symfony\Component\Messenger\Stamp\DelayStamp;
use Symfony\Component\Messenger\Stamp\RedeliveryStamp;
+use Symfony\Component\Messenger\Stamp\TransportMessageIdStamp;
use Symfony\Component\Messenger\Transport\Sender\SenderInterface;
class SendFailedMessageForRetryListenerTest extends TestCase
@@ -190,4 +193,47 @@ public function testEnvelopeKeepOnlyTheLast10Stamps()
$listener->onMessageFailed($event);
}
+
+ public function testRetriedEnvelopePassesToRetriedEvent()
+ {
+ $exception = new \Exception('no!');
+ $envelope = new Envelope(new \stdClass());
+
+ $sender = $this->createMock(SenderInterface::class);
+ $sender->expects($this->once())->method('send')->willReturnCallback(static function (Envelope $envelope) {
+ return $envelope->with(new TransportMessageIdStamp(123));
+ });
+
+ $eventDispatcher = $this->createMock(EventDispatcherInterface::class);
+ $eventDispatcher->expects($this->once())->method('dispatch')->willReturnCallback(
+ function (WorkerMessageRetriedEvent $retriedEvent) {
+ $envelope = $retriedEvent->getEnvelope();
+
+ $transportIdStamp = $envelope->last(TransportMessageIdStamp::class);
+ $this->assertNotNull($transportIdStamp);
+
+ return $retriedEvent;
+ });
+
+ $senderLocator = new Container();
+ $senderLocator->set('my_receiver', $sender);
+
+ $retryStrategy = $this->createMock(RetryStrategyInterface::class);
+ $retryStrategy->expects($this->once())->method('isRetryable')->willReturn(true);
+ $retryStrategy->expects($this->once())->method('getWaitingTime')->willReturn(1000);
+
+ $retryStrategyLocator = new Container();
+ $retryStrategyLocator->set('my_receiver', $retryStrategy);
+
+ $listener = new SendFailedMessageForRetryListener(
+ $senderLocator,
+ $retryStrategyLocator,
+ null,
+ $eventDispatcher
+ );
+
+ $event = new WorkerMessageFailedEvent($envelope, 'my_receiver', $exception);
+
+ $listener->onMessageFailed($event);
+ }
}
diff --git a/src/Symfony/Component/Notifier/Bridge/Iqsms/IqsmsTransport.php b/src/Symfony/Component/Notifier/Bridge/Iqsms/IqsmsTransport.php
index fbdac0d58f231..4cdb60c32fee3 100644
--- a/src/Symfony/Component/Notifier/Bridge/Iqsms/IqsmsTransport.php
+++ b/src/Symfony/Component/Notifier/Bridge/Iqsms/IqsmsTransport.php
@@ -64,7 +64,7 @@ protected function doSend(MessageInterface $message): SentMessage
'phone' => $message->getPhone(),
'text' => $message->getSubject(),
'sender' => $message->getFrom() ?: $this->from,
- 'clientId' => uniqid(),
+ 'clientId' => uniqid('', true),
],
],
'login' => $this->login,
diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php
index a66a8dbda4c19..6a326c020fd8c 100644
--- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php
+++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php
@@ -423,7 +423,7 @@ private function extractFromMutator(string $class, string $property): ?array
$type = $this->extractFromReflectionType($reflectionType, $reflectionMethod->getDeclaringClass());
if (1 === \count($type) && \in_array($prefix, $this->arrayMutatorPrefixes)) {
- $type = [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), $type[0])];
+ $type = [new Type(Type::BUILTIN_TYPE_ARRAY, $this->isNullableProperty($class, $property), null, true, new Type(Type::BUILTIN_TYPE_INT), $type[0])];
}
return $type;
diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php
index 868696209eda3..69eaf14bd1899 100644
--- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php
+++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php
@@ -14,6 +14,7 @@
use PHPUnit\Framework\TestCase;
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
use Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy;
+use Symfony\Component\PropertyInfo\Tests\Fixtures\DummyCollection;
use Symfony\Component\PropertyInfo\Tests\Fixtures\ParentDummy;
use Symfony\Component\PropertyInfo\Tests\Fixtures\Php80Dummy;
use Symfony\Component\PropertyInfo\Tests\Fixtures\PseudoTypeDummy;
@@ -134,6 +135,7 @@ public static function typesProvider()
['arrayOfMixed', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_STRING), null)], null, null],
['listOfStrings', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING))], null, null],
['self', [new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class)], null, null],
+ ['collectionAsObject', [new Type(Type::BUILTIN_TYPE_OBJECT, false, DummyCollection::class, true, [new Type(Type::BUILTIN_TYPE_INT)], [new Type(Type::BUILTIN_TYPE_STRING)])], null, null],
];
}
diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpStanExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpStanExtractorTest.php
index 73ce271e9577f..3a81133fb64ab 100644
--- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpStanExtractorTest.php
+++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpStanExtractorTest.php
@@ -17,6 +17,7 @@
use Symfony\Component\PropertyInfo\Tests\Fixtures\ConstructorDummyWithoutDocBlock;
use Symfony\Component\PropertyInfo\Tests\Fixtures\DefaultValue;
use Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy;
+use Symfony\Component\PropertyInfo\Tests\Fixtures\DummyCollection;
use Symfony\Component\PropertyInfo\Tests\Fixtures\ParentDummy;
use Symfony\Component\PropertyInfo\Tests\Fixtures\Php80Dummy;
use Symfony\Component\PropertyInfo\Tests\Fixtures\Php80PromotedDummy;
@@ -125,6 +126,7 @@ public static function typesProvider()
['self', [new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class)]],
['rootDummyItems', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_OBJECT, false, RootDummyItem::class))]],
['rootDummyItem', [new Type(Type::BUILTIN_TYPE_OBJECT, false, RootDummyItem::class)]],
+ ['collectionAsObject', [new Type(Type::BUILTIN_TYPE_OBJECT, false, DummyCollection::class, true, [new Type(Type::BUILTIN_TYPE_INT)], [new Type(Type::BUILTIN_TYPE_STRING)])]],
];
}
diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php
index 599b366db1715..88026aee80d92 100644
--- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php
+++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php
@@ -48,6 +48,7 @@ public function testGetProperties()
'bal',
'parent',
'collection',
+ 'collectionAsObject',
'nestedCollection',
'mixedCollection',
'B',
@@ -113,6 +114,7 @@ public function testGetPropertiesWithCustomPrefixes()
'bal',
'parent',
'collection',
+ 'collectionAsObject',
'nestedCollection',
'mixedCollection',
'B',
@@ -167,6 +169,7 @@ public function testGetPropertiesWithNoPrefixes()
'bal',
'parent',
'collection',
+ 'collectionAsObject',
'nestedCollection',
'mixedCollection',
'B',
@@ -518,6 +521,7 @@ public function testTypedProperties()
$this->assertEquals([new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING))], $this->extractor->getTypes(Php74Dummy::class, 'stringCollection'));
$this->assertEquals([new Type(Type::BUILTIN_TYPE_INT, true)], $this->extractor->getTypes(Php74Dummy::class, 'nullableWithDefault'));
$this->assertEquals([new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true)], $this->extractor->getTypes(Php74Dummy::class, 'collection'));
+ $this->assertEquals([new Type(Type::BUILTIN_TYPE_ARRAY, true, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class))], $this->extractor->getTypes(Php74Dummy::class, 'nullableTypedCollection'));
}
/**
diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php
index 1478c87f551b6..6c2ea073f2620 100644
--- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php
+++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php
@@ -46,6 +46,11 @@ class Dummy extends ParentDummy
#[Groups(['a', 'b'])]
public $collection;
+ /**
+ * @var DummyCollection
+ */
+ public $collectionAsObject;
+
/**
* @var string[][]
*/
diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/DummyCollection.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/DummyCollection.php
new file mode 100644
index 0000000000000..e8799d8f6be07
--- /dev/null
+++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/DummyCollection.php
@@ -0,0 +1,20 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\PropertyInfo\Tests\Fixtures;
+
+final class DummyCollection implements \IteratorAggregate
+{
+ public function getIterator(): \Traversable
+ {
+ return [];
+ }
+}
diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php
index 816b857b67b11..dc72d07756b88 100644
--- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php
+++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php
@@ -23,6 +23,9 @@ class Php74Dummy
private ?int $nullableWithDefault = 1;
public array $collection = [];
+ /** @var Dummy[]|null */
+ public ?array $nullableTypedCollection = null;
+
public function addStringCollection(string $string): void
{
}
@@ -30,4 +33,8 @@ public function addStringCollection(string $string): void
public function removeStringCollection(string $string): void
{
}
+
+ public function addNullableTypedCollection(Dummy $dummy): void
+ {
+ }
}
diff --git a/src/Symfony/Component/PropertyInfo/Util/PhpStanTypeHelper.php b/src/Symfony/Component/PropertyInfo/Util/PhpStanTypeHelper.php
index f8cc166f3be99..7d439f55660dd 100644
--- a/src/Symfony/Component/PropertyInfo/Util/PhpStanTypeHelper.php
+++ b/src/Symfony/Component/PropertyInfo/Util/PhpStanTypeHelper.php
@@ -125,7 +125,7 @@ private function extractTypes(TypeNode $node, NameScope $nameScope): array
return [$mainType];
}
- $collection = $mainType->isCollection() || \in_array($mainType->getClassName(), [\Traversable::class, \Iterator::class, \IteratorAggregate::class, \ArrayAccess::class, \Generator::class], true);
+ $collection = $mainType->isCollection() || \is_a($mainType->getClassName(), \Traversable::class, true) || \is_a($mainType->getClassName(), \ArrayAccess::class, true);
// it's safer to fall back to other extractors if the generic type is too abstract
if (!$collection && !class_exists($mainType->getClassName())) {
diff --git a/src/Symfony/Component/Routing/Router.php b/src/Symfony/Component/Routing/Router.php
index cc3d351db3f97..3aa9b4b39c2ed 100644
--- a/src/Symfony/Component/Routing/Router.php
+++ b/src/Symfony/Component/Routing/Router.php
@@ -225,6 +225,7 @@ function (ConfigCacheInterface $cache) {
}
$cache->write($dumper->dump(), $this->getRouteCollection()->getResources());
+ unset(self::$cache[$cache->getPath()]);
}
);
@@ -254,6 +255,7 @@ function (ConfigCacheInterface $cache) {
$dumper = $this->getGeneratorDumperInstance();
$cache->write($dumper->dump(), $this->getRouteCollection()->getResources());
+ unset(self::$cache[$cache->getPath()]);
}
);
diff --git a/src/Symfony/Component/Routing/Tests/Matcher/Dumper/CompiledUrlMatcherDumperTest.php b/src/Symfony/Component/Routing/Tests/Matcher/Dumper/CompiledUrlMatcherDumperTest.php
index 21016be35da02..644c908a19f6e 100644
--- a/src/Symfony/Component/Routing/Tests/Matcher/Dumper/CompiledUrlMatcherDumperTest.php
+++ b/src/Symfony/Component/Routing/Tests/Matcher/Dumper/CompiledUrlMatcherDumperTest.php
@@ -30,7 +30,7 @@ protected function setUp(): void
{
parent::setUp();
- $this->dumpPath = sys_get_temp_dir().\DIRECTORY_SEPARATOR.'php_matcher.'.uniqid('CompiledUrlMatcher').'.php';
+ $this->dumpPath = sys_get_temp_dir().\DIRECTORY_SEPARATOR.'php_matcher.'.uniqid('CompiledUrlMatcher', true).'.php';
}
protected function tearDown(): void
diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.ar.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.ar.xlf
index d90e830ff18f4..f75eb12c005eb 100644
--- a/src/Symfony/Component/Security/Core/Resources/translations/security.ar.xlf
+++ b/src/Symfony/Component/Security/Core/Resources/translations/security.ar.xlf
@@ -64,7 +64,7 @@
Too many failed login attempts, please try again later.
- عدد كبير جدا من محاولات الدخول الفاشلة، يرجى المحاولة مرة أخرى في وقت لاحق.
+ العديد من محاولات الدخول الفاشلة، يرجى المحاولة مرة أخرى في وقت لاحق.Invalid or expired login link.
@@ -72,11 +72,11 @@
Too many failed login attempts, please try again in %minutes% minute.
- عدد كبير جدا من محاولات الدخول الفاشلة، يرجى اعادة المحاولة بعد %minutes% دقيقة.
+ العديد من محاولات الدخول الفاشلة، يرجى اعادة المحاولة بعد %minutes% دقيقة.Too many failed login attempts, please try again in %minutes% minutes.
- عدد محاولات تسجيل الدخول الفاشلة كثيرة، الرجاء المحاولة مرة أخرى بعد %minutes% دقيقة.|عدد محاولات تسجيل الدخول الفاشلة كثيرة، الرجاء المحاولة مرة أخرى بعد %minutes% دقائق.
+ العديد من محاولات الدخول الفاشلة ، يرجى اعادة المحاولة بعد %minutes% دقائق.
An authentication exception occurred.
- Ocorreu uma excepção durante a autenticação.
+ Ocorreu uma exceção durante a autenticação.Authentication credentials could not be found.
@@ -12,7 +12,7 @@
Authentication request could not be processed due to a system problem.
- O pedido de autenticação não foi concluído devido a um problema no sistema.
+ A autenticação não foi concluída devido a um problema no sistema.Invalid credentials.
@@ -24,7 +24,7 @@
Not privileged to request the resource.
- Não possui privilégios para aceder a este recurso.
+ Sem privilégios para solicitar este recurso.Invalid CSRF token.
@@ -36,7 +36,7 @@
No session available, it either timed out or cookies are not enabled.
- Não existe sessão disponível, esta expirou ou os cookies estão desativados.
+ Nenhuma sessão disponível, esta expirou ou os cookies estão desativados.No token could be found.
@@ -44,7 +44,7 @@
Username could not be found.
- Nome de utilizador não encontrado.
+ Nome de usuário não encontrado.Account has expired.
@@ -60,11 +60,11 @@
Account is locked.
- A conta está trancada.
+ A conta está bloqueada.Too many failed login attempts, please try again later.
- Várias tentativas de login falhadas, por favor tente mais tarde.
+ Muitas tentativas de login sem sucesso, por favor, tente mais tarde.Invalid or expired login link.
@@ -72,11 +72,11 @@
Too many failed login attempts, please try again in %minutes% minute.
- Demasiadas tentativas de login, tente novamente num minuto.
+ Muitas tentativas de login sem sucesso, por favor, tente novamente novamente em 1 minuto.Too many failed login attempts, please try again in %minutes% minutes.
- Muitas tentativas de login sem sucesso, por favor tente novamente em %minutes% minutos.
+ Muitas tentativas de login sem sucesso, por favor, tente novamente em %minutes% minutos.