diff --git a/CHANGELOG-5.4.md b/CHANGELOG-5.4.md
index e9bc07dc724c4..74a11a2fd933e 100644
--- a/CHANGELOG-5.4.md
+++ b/CHANGELOG-5.4.md
@@ -7,6 +7,38 @@ in 5.4 minor versions.
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v5.4.0...v5.4.1
+* 5.4.26 (2023-07-29)
+
+ * bug #50933 [Serializer] Fix deserializing nested arrays of objects with mixed keys (HypeMC)
+ * bug #51078 [FrameworkBundle][Workflow] Throw exception is workflow.xxx.transitions is not an array (lyrixx)
+ * bug #51114 [Serializer] Fix denormalizing abstract part headers in MimeMessageNormalizer (fancyweb)
+ * bug #50788 [Validator] Fix regression with class metadatada on parent classes (rmikalkenas)
+ * bug #51017 [VarExporter] Fix exporting classes with __serialize() but not __unserialize() (fancyweb)
+ * bug #51031 Fix deprecations on PHP 8.3 (nicolas-grekas)
+ * bug #51000 [WebProfilerBundle] Fix error in case of 'Content-Type' set null in dev environment with no debug (alexbuyanow)
+ * bug #50994 [ErrorHandler][Runtime] Don't mess with ini_set('assert.warning') (nicolas-grekas)
+ * bug #50968 [PropertyAccess] Fix access to undefined "file" key when checking stack frames (nicolas-grekas)
+ * bug #50552 [Security] Allow custom scheme to be used as redirection URIs (Spomky)
+ * bug #50945 [DebugBundle][FrameworkBundle] Fix using the framework without the Console component (HypeMC)
+ * bug #50913 [HttpKernel][WebProfilerBundle] Fix search feature (Cyril HERRERA)
+ * bug #50937 [Form] fetch all known ChoiceType values at once (xabbuh)
+ * bug #50944 [FrameworkBundle] Add missing monolog channel tag to the `messenger:failed:retry` command (HypeMC)
+ * bug #49070 [RateLimiter] fix incorrect retryAfter of FixedWindow (RobertMe)
+ * bug #50960 [VarDumper] Fix dumping `ArrayObject` with `DumpDataCollector` (lyrixx, HypeMC)
+ * bug #50943 [Intl] Taking into account bibliographic + overlong (oleg-andreyev)
+ * bug #50954 [PhpUnitBridge] Kill the last concurrent process when it stales for more than 60s (nicolas-grekas)
+ * bug #50475 [FrameworkBundle] Prevent `cache:clear` to lose files on subsequent runs (Okhoshi)
+ * bug #47252 [PhpUnitBridge] Use triggering class to generate baseline for deprecation messages from DebugClassLoader (leongersen)
+ * bug #50582 [Security/Http] Fix false-string handling in `RememberMeAuthenticator` (ossinkine)
+ * bug #50595 [DependencyInjection] Don't ignore attributes on the actual decorator (HypeMC)
+ * bug #50804 [Serializer] Fix Normalizer not utilizing converted name for index variadic param (DidierLmn)
+ * bug #50813 [DoctrineBridge] Load refreshed user proxy (MatTheCat)
+ * bug #50905 [DepdencyInjection] Fix costly logic when checking errored definitions (nicolas-grekas)
+ * bug #50884 [Finder] Fix initial directory is opened twice (mvorisek)
+ * bug #50881 [Messenger] Fix passing options set via tags to handler descriptors (nicolas-grekas)
+ * bug #50837 [DependencyInjection] Fix autocasting null env values to empty string (fancyweb)
+ * bug #50810 [String] Fix Inflector for 'status' (evertharmeling)
+
* 5.4.25 (2023-06-26)
* bug #50763 [DependencyInjection] Skip errored definitions deep-referenced as runtime exceptions (nicolas-grekas)
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 52c9fcc29c0d4..19baafa1bdafb 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -23,8 +23,8 @@ The Symfony Connect username in parenthesis allows to get more information
- Victor Berchet (victor)
- Javier Eguiluz (javier.eguiluz)
- Yonel Ceruto (yonelceruto)
- - Tobias Nyholm (tobias)
- Ryan Weaver (weaverryan)
+ - Tobias Nyholm (tobias)
- Oskar Stark (oskarstark)
- Johannes S (johannes)
- Jakub Zalas (jakubzalas)
@@ -32,33 +32,33 @@ The Symfony Connect username in parenthesis allows to get more information
- Hugo Hamon (hhamon)
- Hamza Amrouche (simperfit)
- Samuel ROZE (sroze)
- - Pascal Borreli (pborreli)
- Jules Pietri (heah)
+ - Pascal Borreli (pborreli)
- Romain Neutron
- Joseph Bielawski (stloyd)
+ - Alexandre Daubois (alexandre-daubois)
- Drak (drak)
- Abdellatif Ait boudad (aitboudad)
+ - Jérôme Tamarelle (gromnan)
- Jan Schädlich (jschaedl)
- Lukas Kahwe Smith (lsmith)
- Kevin Bond (kbond)
- - Jérôme Tamarelle (gromnan)
- Martin Hasoň (hason)
- - Alexandre Daubois (alexandre-daubois)
- Jeremy Mikola (jmikola)
- Jean-François Simon (jfsimon)
- Benjamin Eberlei (beberlei)
- Igor Wiedler
- HypeMC (hypemc)
- - Valentin Udaltsov (vudaltsov)
- Antoine Lamirault (alamirault)
+ - Valentin Udaltsov (vudaltsov)
- Vasilij Duško (staff)
- Matthias Pigulla (mpdude)
- - Gabriel Ostrolucký (gadelat)
- Laurent VOULLEMIER (lvo)
+ - Gabriel Ostrolucký (gadelat)
- Antoine Makdessi (amakdessi)
+ - Mathieu Lechat (mat_the_cat)
- Pierre du Plessis (pierredup)
- Grégoire Paris (greg0ire)
- - Mathieu Lechat (mat_the_cat)
- Jonathan Wage (jwage)
- Titouan Galopin (tgalopin)
- David Maicher (dmaicher)
@@ -116,12 +116,13 @@ The Symfony Connect username in parenthesis allows to get more information
- Henrik Westphal (snc)
- Dariusz Górecki (canni)
- Maxime Helias (maxhelias)
+ - Gary PEGEOT (gary-p)
- Ener-Getick
- Tugdual Saunier (tucksaun)
+ - Rokas Mikalkėnas (rokasm)
- Sebastiaan Stok (sstok)
- Jérôme Vasseur (jvasseur)
- Ion Bazan (ionbazan)
- - Rokas Mikalkėnas (rokasm)
- Yanick Witschi (toflar)
- Lee McDermott
- Brandon Turner
@@ -145,16 +146,17 @@ The Symfony Connect username in parenthesis allows to get more information
- Peter Kokot (maastermedia)
- jeremyFreeAgent (jeremyfreeagent)
- Ahmed TAILOULOUTE (ahmedtai)
+ - Joel Wurtz (brouznouf)
- Tim Nagel (merk)
+ - Allison Guilhem (a_guilhem)
- Andreas Braun
- Teoh Han Hui (teohhanhui)
- YaFou
- - Gary PEGEOT (gary-p)
- Chris Wilkinson (thewilkybarkid)
- Brice BERNARD (brikou)
- Roman Martinuk (a2a4)
- - Joel Wurtz (brouznouf)
- Gregor Harlan (gharlan)
+ - Christopher Hertel (chertel)
- Baptiste Clavié (talus)
- Adrien Brault (adrienbrault)
- Michal Piotrowski
@@ -168,7 +170,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Hugo Alliaume (kocal)
- Christian Scheb
- Guillaume (guill)
- - Christopher Hertel (chertel)
- Jacob Dreesen (jdreesen)
- Olivier Dolbeau (odolbeau)
- Florian Voutzinos (florianv)
@@ -180,13 +181,13 @@ The Symfony Connect username in parenthesis allows to get more information
- Jérôme Parmentier (lctrs)
- HeahDude
- Richard van Laak (rvanlaak)
+ - Nicolas Philippe (nikophil)
- Paráda József (paradajozsef)
- Hubert Lenoir (hubert_lenoir)
- Alessandro Lai (jean85)
- Alexander Schwenn (xelaris)
- Fabien Pennequin (fabienpennequin)
- Gordon Franke (gimler)
- - Nicolas Philippe (nikophil)
- François-Xavier de Guillebon (de-gui_f)
- Andreas Schempp (aschempp)
- Gabriel Caruso
@@ -195,11 +196,13 @@ The Symfony Connect username in parenthesis allows to get more information
- Jan Rosier (rosier)
- Andreas Möller (localheinz)
- Daniel Wehner (dawehner)
+ - Gocha Ossinkine (ossinkine)
- Chi-teck
- Hugo Monteiro (monteiro)
- Baptiste Leduc (korbeil)
- Marco Pivetta (ocramius)
- Robert Schönthal (digitalkaoz)
+ - Michael Voříšek
- Alexis Lefebvre
- Võ Xuân Tiến (tienvx)
- fd6130 (fdtvui)
@@ -212,13 +215,13 @@ The Symfony Connect username in parenthesis allows to get more information
- Alessandro Chitolina (alekitto)
- Valentine Boineau (valentineboineau)
- Jeroen Noten (jeroennoten)
- - Gocha Ossinkine (ossinkine)
- OGAWA Katsuhiro (fivestar)
- Dāvis Zālītis (k0d3r1s)
- Jhonny Lidfors (jhonne)
- Martin Hujer (martinhujer)
- Wouter J
- Guilliam Xavier
+ - David Prévot
- Sergey (upyx)
- Antonio Pauletich (x-coder264)
- Timo Bakx (timobakx)
@@ -236,12 +239,12 @@ The Symfony Connect username in parenthesis allows to get more information
- Albert Casademont (acasademont)
- Arnaud Kleinpeter (nanocom)
- Guilherme Blanco (guilhermeblanco)
- - Michael Voříšek
- SpacePossum
- Pablo Godel (pgodel)
- Denis Brumann (dbrumann)
- Romaric Drigon (romaricdrigon)
- Andréia Bohner (andreia)
+ - Bastien Jaillot (bastnic)
- Jannik Zschiesche
- Rafael Dohms (rdohms)
- George Mponos (gmponos)
@@ -249,11 +252,11 @@ The Symfony Connect username in parenthesis allows to get more information
- Aleksandar Jakovljevic (ajakov)
- jwdeitch
- Jurica Vlahoviček (vjurica)
- - David Prévot
- Vincent Touzet (vincenttouzet)
- Fabien Bourigault (fbourigault)
- soyuka
- Jérémy Derussé
+ - Sébastien Alfaiate (seb33300)
- Florent Mata (fmata)
- mcfedr (mcfedr)
- Maciej Malarz (malarzm)
@@ -262,7 +265,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Sokolov Evgeniy (ewgraf)
- Stadly
- Justin Hileman (bobthecow)
- - Bastien Jaillot (bastnic)
- Tom Van Looy (tvlooy)
- Niels Keurentjes (curry684)
- Vyacheslav Pavlov
@@ -274,6 +276,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Rouven Weßling (realityking)
- BoShurik
- Zmey
+ - Maximilian Beckers (maxbeckers)
- Clemens Tolboom
- Oleg Voronkovich
- Alan Poulain (alanpoulain)
@@ -301,14 +304,12 @@ The Symfony Connect username in parenthesis allows to get more information
- dFayet
- Karoly Gossler (connorhu)
- Vincent AUBERT (vincent)
- - Allison Guilhem (a_guilhem)
- Sebastien Morel (plopix)
- Yoann RENARD (yrenard)
+ - Oleg Andreyev (oleg.andreyev)
- Thomas Lallement (raziel057)
- Timothée Barray (tyx)
- - Sébastien Alfaiate (seb33300)
- James Halsall (jaitsu)
- - Maximilian Beckers (maxbeckers)
- Mikael Pajunen
- Marcin Sikoń (marphi)
- Warnar Boekkooi (boekkooi)
@@ -343,7 +344,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Thibaut Cheymol (tcheymol)
- Julien Pauli
- Islam Israfilov (islam93)
- - Oleg Andreyev (oleg.andreyev)
- Daniel Gorgan
- Hendrik Luup (hluup)
- Bob van de Vijver (bobvandevijver)
@@ -375,9 +375,11 @@ The Symfony Connect username in parenthesis allows to get more information
- Vladyslav Loboda
- Pierre Minnieur (pminnieur)
- Kyle
+ - Frank A. Fiebig (fafiebig)
- Dominique Bongiraud
- Hidde Wieringa (hiddewie)
- Dane Powell
+ - Loïc Frémont (loic425)
- Christopher Davis (chrisguitarguy)
- Lukáš Holeczy (holicz)
- Michael Lee (zerustech)
@@ -422,7 +424,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Antonio Jose Cerezo (ajcerezo)
- Marcin Szepczynski (czepol)
- Lescot Edouard (idetox)
- - Loïc Frémont (loic425)
- Rob Frawley 2nd (robfrawley)
- Mohammad Emran Hasan (phpfour)
- Dmitriy Mamontov (mamontovdmitriy)
@@ -463,6 +464,7 @@ The Symfony Connect username in parenthesis allows to get more information
- M. Vondano
- Xavier Perez
- Arjen Brouwer (arjenjb)
+ - Vladimir Tsykun (vtsykun)
- Tavo Nieves J (tavoniievez)
- Arjen van der Meijden
- Patrick McDougle (patrick-mcdougle)
@@ -493,6 +495,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Yannick Ihmels (ihmels)
- Andrii Dembitskyi
- Chekote
+ - Evert Harmeling (evertharmeling)
- bhavin (bhavin4u)
- Pavel Popov (metaer)
- Thomas Adam
@@ -506,10 +509,12 @@ The Symfony Connect username in parenthesis allows to get more information
- Bob den Otter (bopp)
- Johan Vlaar (johjohan)
- Thomas Schulz (king2500)
+ - Anderson Müller
- Benjamin Morel
- Bernd Stellwag
- Philippe SEGATORI (tigitz)
- Frank de Jonge
+ - Florent Morselli (spomky_)
- Chris Tanaskoski
- julien57
- Renan (renanbr)
@@ -538,10 +543,10 @@ The Symfony Connect username in parenthesis allows to get more information
- Pascal Luna (skalpa)
- Wouter Van Hecke
- Michael Holm (hollo)
- - Vladimir Tsykun (vtsykun)
- Yassine Guedidi (yguedidi)
- Giso Stallenberg (gisostallenberg)
- Blanchon Vincent (blanchonvincent)
+ - Quentin Devos
- William Arslett (warslett)
- Jérémy REYNAUD (babeuloula)
- Christian Schmidt
@@ -583,7 +588,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Emmanuel BORGES (eborges78)
- siganushka (siganushka)
- Aurelijus Valeiša (aurelijus)
- - Evert Harmeling (evertharmeling)
- Jan Decavele (jandc)
- Gustavo Piltcher
- Joachim Løvgaard (loevgaard)
@@ -598,13 +602,11 @@ The Symfony Connect username in parenthesis allows to get more information
- Pavel Batanov (scaytrase)
- Francesc Rosàs (frosas)
- Bongiraud Dominique
- - Anderson Müller
- janschoenherr
- Marko Kaznovac (kaznovac)
- Emanuele Gaspari (inmarelibero)
- Dariusz Rumiński
- Terje Bråten
- - Florent Morselli (spomky_)
- Gennadi Janzen
- James Hemery
- Egor Taranov
@@ -685,7 +687,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Thomas Perez (scullwm)
- Thomas P
- Kristijan Kanalaš (kristijan_kanalas_infostud)
- - Quentin Devos
- Felix Labrecque
- mondrake (mondrake)
- Yaroslav Kiliba
@@ -889,6 +890,7 @@ The Symfony Connect username in parenthesis allows to get more information
- AKeeman (akeeman)
- Martijn Cuppens
- Restless-ET
+ - Robert Meijers
- Vlad Gregurco (vgregurco)
- Boris Vujicic (boris.vujicic)
- Chris Sedlmayr (catchamonkey)
@@ -914,6 +916,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Adam Harvey
- ilyes kooli (skafandri)
- Anton Bakai
+ - Nicolas Dousson
- Sam Fleming (sam_fleming)
- Alex Bakhturin
- Brayden Williams (redstar504)
@@ -997,6 +1000,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Krzysztof Piasecki (krzysztek)
- Lenard Palko
- Nils Adermann (naderman)
+ - Roland Franssen :)
- Gábor Fási
- Nate (frickenate)
- Sander De la Marche (sanderdlm)
@@ -1054,6 +1058,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Sorin Pop (sorinpop)
- Piotr Stankowski
- Stewart Malik
+ - Pierre-Emmanuel Tanguy (petanguy)
- Stefan Graupner (efrane)
- Gemorroj (gemorroj)
- Adrien Chinour
@@ -1158,7 +1163,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Javier López (loalf)
- tamar peled
- Reinier Kip
- - Robert Meijers
- Geoffrey Brier (geoffrey-brier)
- Sofien Naas
- Christophe Meneses (c77men)
@@ -1297,7 +1301,6 @@ The Symfony Connect username in parenthesis allows to get more information
- dbrekelmans
- Piet Steinhart
- mousezheng
- - Nicolas Dousson
- Rémy LESCALLIER
- Simon Schick (simonsimcity)
- Victor Macko (victor_m)
@@ -1397,6 +1400,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Osayawe Ogbemudia Terry (terdia)
- Toni Peric (tperic)
- yclian
+ - radar3301
- Aleksey Prilipko
- Andrew Berry
- Wybren Koelmans (wybren_koelmans)
@@ -1795,7 +1799,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Jeremy Benoist
- Ben Johnson
- Jan Kramer
- - Roland Franssen :)
- mweimerskirch
- robmro27
- Vallel Blanco
@@ -2181,6 +2184,7 @@ The Symfony Connect username in parenthesis allows to get more information
- jfcixmedia
- Dominic Tubach
- Martijn Evers
+ - Léon Gersen
- Dustin Wilson
- Benjamin Paap (benjaminpaap)
- Christian
@@ -2248,6 +2252,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Gordienko Vladislav
- Ener-Getick
- Moza Bogdan (bogdan_moza)
+ - johan Vlaar
- Viacheslav Sychov
- Nicolas Sauveur (baishu)
- Helmut Hummel (helhum)
@@ -2275,7 +2280,6 @@ The Symfony Connect username in parenthesis allows to get more information
- rchoquet
- v.shevelev
- gitlost
- - radar3301
- Taras Girnyk
- Sergio
- Mehrdad
@@ -2387,6 +2391,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Christian Flach (cmfcmf)
- Lars Ambrosius Wallenborn (larsborn)
- Oriol Mangas Abellan (oriolman)
+ - Raphaël Geffroy (raphael-geffroy)
- Sebastian Göttschkes (sgoettschkes)
- Tatsuya Tsuruoka
- Ross Tuck
@@ -2451,6 +2456,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Jules Lamur
- Renato Mendes Figueiredo
- Raphaël Droz
+ - Asis Pattisahusiwa
- Eric Stern
- ShiraNai7
- Antal Áron (antalaron)
@@ -2500,6 +2506,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Phillip Look (plook)
- Max Summe
- Ema Panz
+ - DidierLmn
- Chihiro Adachi (chihiro-adachi)
- Thomas Trautner (thomastr)
- mfettig
@@ -2581,6 +2588,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Charly Terrier (charlypoppins)
- Emre Akinci (emre)
- psampaz (psampaz)
+ - Stan Jansen (stanjan)
- Maxwell Vandervelde
- kaywalker
- Sebastian Ionescu
@@ -2591,6 +2599,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Simon Neidhold
- Valentin VALCIU
- Jeremiah VALERIE
+ - Franck Ranaivo-Harisoa
- Cas van Dongen
- Patrik Patie Gmitter
- Yannick Snobbert
@@ -2631,6 +2640,7 @@ The Symfony Connect username in parenthesis allows to get more information
- moldcraft
- Antoine Bellion (abellion)
- Ramon Kleiss (akathos)
+ - Alexey Buyanow (alexbuyanow)
- Antonio Peric-Mazar (antonioperic)
- César Suárez (csuarez)
- Bjorn Twachtmann (dotbjorn)
@@ -2724,6 +2734,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Jeremy Benoist
- sdrewergutland
- Michal Gebauer
+ - René Landgrebe
- Phil Davis
- Gleb Sidora
- David Stone
@@ -2889,6 +2900,7 @@ The Symfony Connect username in parenthesis allows to get more information
- taiiiraaa
- gedrox
- Alan Bondarchuk
+ - Cyril HERRERA
- dropfen
- Andrey Chernykh
- Edvinas Klovas
@@ -3076,6 +3088,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Olivier Laviale (olvlvl)
- Pablo Monterde Perez (plebs)
- Jimmy Leger (redpanda)
+ - Sébastien JEAN (sebastien76)
- Mokhtar Tlili (sf-djuba)
- Marcin Szepczynski (szepczynski)
- Simone Di Maulo (toretto460)
@@ -3197,6 +3210,7 @@ The Symfony Connect username in parenthesis allows to get more information
- n-aleha
- Anatol Belski
- Alexis BOYER
+ - Shyim
- Kaipi Yann
- wiseguy1394
- adam-mospan
@@ -3446,6 +3460,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Bogdan Rancichi (devck)
- Daniel Kolvik (dkvk)
- Marc Lemay (flug)
+ - Courcier Marvin (helyakin)
- Henne Van Och (hennevo)
- Jeroen De Dauw (jeroendedauw)
- Maxime COLIN (maximecolin)
diff --git a/README.md b/README.md
index 2a43c34952b2f..d02bbd835b32b 100644
--- a/README.md
+++ b/README.md
@@ -38,7 +38,7 @@ Community
---------
* [Join the Symfony Community][11] and meet other members at the [Symfony events][12].
-* [Get Symfony support][13] on Stack Overflow, Slack, IRC, etc.
+* [Get Symfony support][13] on GitHub Discussions, Slack, etc.
* Follow us on [GitHub][14], [Twitter][15] and [Facebook][16].
* Read our [Code of Conduct][24] and meet the [CARE Team][25].
diff --git a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php
index b9bdf26e0d1ca..a1043d8213f33 100644
--- a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php
+++ b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php
@@ -15,6 +15,7 @@
use Doctrine\Persistence\Mapping\ClassMetadata;
use Doctrine\Persistence\ObjectManager;
use Doctrine\Persistence\ObjectRepository;
+use Doctrine\Persistence\Proxy;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
@@ -117,6 +118,10 @@ public function refreshUser(UserInterface $user)
}
}
+ if ($refreshedUser instanceof Proxy && !$refreshedUser->__isInitialized()) {
+ $refreshedUser->__load();
+ }
+
return $refreshedUser;
}
diff --git a/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php
index 7a09cb8802f72..eb7b00d561173 100644
--- a/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php
+++ b/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php
@@ -16,6 +16,7 @@
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\Persistence\ObjectManager;
use Doctrine\Persistence\ObjectRepository;
+use Doctrine\Persistence\Proxy;
use PHPUnit\Framework\TestCase;
use Symfony\Bridge\Doctrine\Security\User\EntityUserProvider;
use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface;
@@ -197,6 +198,27 @@ public function testPasswordUpgrades()
$provider->upgradePassword($user, 'foobar');
}
+ public function testRefreshedUserProxyIsLoaded()
+ {
+ $em = DoctrineTestHelper::createTestEntityManager();
+ $this->createSchema($em);
+
+ $user = new User(1, 1, 'user1');
+
+ $em->persist($user);
+ $em->flush();
+ $em->clear();
+
+ // store a proxy in the identity map
+ $em->getReference(User::class, ['id1' => 1, 'id2' => 1]);
+
+ $provider = new EntityUserProvider($this->getManager($em), User::class);
+ $refreshedUser = $provider->refreshUser($user);
+
+ $this->assertInstanceOf(Proxy::class, $refreshedUser);
+ $this->assertTrue($refreshedUser->__isInitialized());
+ }
+
private function getManager($em, $name = null)
{
$manager = $this->createMock(ManagerRegistry::class);
diff --git a/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php b/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php
index 7ea316f41a2d0..fe199c2043ff0 100644
--- a/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php
+++ b/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php
@@ -108,7 +108,7 @@ public function loadClassMetadata(ClassMetadata $metadata): bool
if (isset($mapping['originalClass']) && !str_contains($mapping['declaredField'], '.')) {
$metadata->addPropertyConstraint($mapping['declaredField'], new Valid());
$loaded = true;
- } elseif (property_exists($className, $mapping['fieldName'])) {
+ } elseif (property_exists($className, $mapping['fieldName']) && (!$doctrineMetadata->isMappedSuperclass || $metadata->getReflectionClass()->getProperty($mapping['fieldName'])->isPrivate())) {
$metadata->addPropertyConstraint($mapping['fieldName'], new Length(['max' => $mapping['length']]));
$loaded = true;
}
diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Configuration.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Configuration.php
index 6e9f0e485a693..e749c74aa6133 100644
--- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Configuration.php
+++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Configuration.php
@@ -200,7 +200,9 @@ public function isBaselineDeprecation(Deprecation $deprecation)
return false;
}
- if ($deprecation->originatesFromAnObject()) {
+ if ($deprecation->originatesFromDebugClassLoader()) {
+ $location = $deprecation->triggeringClass();
+ } elseif ($deprecation->originatesFromAnObject()) {
$location = $deprecation->originatingClass().'::'.$deprecation->originatingMethod();
} else {
$location = 'procedural code';
diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php
index 5a5a0f61c4e64..95737f8b5a9cc 100644
--- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php
+++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php
@@ -41,6 +41,7 @@ class Deprecation
private $originClass;
private $originMethod;
private $triggeringFile;
+ private $triggeringClass;
/** @var string[] Absolute paths to vendor directories */
private static $vendors;
@@ -61,6 +62,10 @@ class Deprecation
*/
public function __construct($message, array $trace, $file, $languageDeprecation = false)
{
+ if (isset($trace[2]['class']) && \in_array($trace[2]['class'], [DebugClassLoader::class, LegacyDebugClassLoader::class], true)) {
+ $this->triggeringClass = $trace[2]['args'][0];
+ }
+
if (isset($trace[2]['function']) && 'trigger_deprecation' === $trace[2]['function']) {
$file = $trace[2]['file'];
array_splice($trace, 1, 1);
@@ -158,6 +163,26 @@ private function lineShouldBeSkipped(array $line)
return 'ReflectionMethod' === $class || 0 === strpos($class, 'PHPUnit\\');
}
+ /**
+ * @return bool
+ */
+ public function originatesFromDebugClassLoader()
+ {
+ return isset($this->triggeringClass);
+ }
+
+ /**
+ * @return string
+ */
+ public function triggeringClass()
+ {
+ if (null === $this->triggeringClass) {
+ throw new \LogicException('Check with originatesFromDebugClassLoader() before calling this method.');
+ }
+
+ return $this->triggeringClass;
+ }
+
/**
* @return bool
*/
diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/ConfigurationTest.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/ConfigurationTest.php
index 9170605a5aa9a..6116fbe9f0260 100644
--- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/ConfigurationTest.php
+++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/ConfigurationTest.php
@@ -15,6 +15,7 @@
use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\Configuration;
use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\Deprecation;
use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\DeprecationGroup;
+use Symfony\Component\ErrorHandler\DebugClassLoader;
class ConfigurationTest extends TestCase
{
@@ -356,7 +357,7 @@ public function testBaselineGenerationEmptyFile()
$this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Test message 1', $trace, '')));
$configuration->writeBaseline();
$this->assertEquals($filename, $configuration->getBaselineFile());
- $expected_baseline = [
+ $expected = [
[
'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest',
'message' => 'Test message 1',
@@ -368,7 +369,7 @@ public function testBaselineGenerationEmptyFile()
'count' => 1,
],
];
- $this->assertEquals(json_encode($expected_baseline, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename));
+ $this->assertEquals(json_encode($expected, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename));
}
public function testBaselineGenerationNoFile()
@@ -383,7 +384,7 @@ public function testBaselineGenerationNoFile()
$this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Test message 1', $trace, '')));
$configuration->writeBaseline();
$this->assertEquals($filename, $configuration->getBaselineFile());
- $expected_baseline = [
+ $expected = [
[
'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest',
'message' => 'Test message 1',
@@ -395,7 +396,7 @@ public function testBaselineGenerationNoFile()
'count' => 2,
],
];
- $this->assertEquals(json_encode($expected_baseline, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename));
+ $this->assertEquals(json_encode($expected, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename));
}
public function testExistingBaseline()
@@ -447,7 +448,7 @@ public function testExistingBaselineAndGeneration()
$this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Test message 3', $trace, '')));
$configuration->writeBaseline();
$this->assertEquals($filename, $configuration->getBaselineFile());
- $expected_baseline = [
+ $expected = [
[
'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest',
'message' => 'Test message 2',
@@ -459,7 +460,44 @@ public function testExistingBaselineAndGeneration()
'count' => 1,
],
];
- $this->assertEquals(json_encode($expected_baseline, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename));
+ $this->assertEquals(json_encode($expected, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename));
+ }
+
+ public function testBaselineGenerationWithDeprecationTriggeredByDebugClassLoader()
+ {
+ $filename = $this->createFile();
+ $configuration = Configuration::fromUrlEncodedString('generateBaseline=true&baselineFile='.urlencode($filename));
+
+ $trace = debug_backtrace();
+ $this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Regular deprecation', $trace, '')));
+
+ $trace[2] = [
+ 'class' => DebugClassLoader::class,
+ 'function' => 'testBaselineGenerationWithDeprecationTriggeredByDebugClassLoader',
+ 'args' => [self::class]
+ ];
+
+ $deprecation = new Deprecation('Deprecation by debug class loader', $trace, '');
+
+ $this->assertTrue($deprecation->originatesFromDebugClassLoader());
+
+ $this->assertTrue($configuration->isBaselineDeprecation($deprecation));
+
+ $configuration->writeBaseline();
+ $this->assertEquals($filename, $configuration->getBaselineFile());
+ $expected = [
+ [
+ 'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest',
+ 'message' => 'Regular deprecation',
+ 'count' => 1,
+ ],
+ [
+ 'location' => self::class,
+ 'message' => 'Deprecation by debug class loader',
+ 'count' => 1,
+ ],
+ ];
+ $this->assertEquals(json_encode($expected, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename));
}
public function testBaselineArgumentException()
diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php
index 5a1ba44ef0010..bc251877d7cdf 100644
--- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php
+++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php
@@ -398,6 +398,9 @@ class_exists(\SymfonyExcludeListSimplePhpunit::class, false) && PHPUnit\Util\Bla
}
}
+ $lastOutput = null;
+ $lastOutputTime = null;
+
while ($runningProcs) {
usleep(300000);
$terminatedProcs = [];
@@ -410,6 +413,26 @@ class_exists(\SymfonyExcludeListSimplePhpunit::class, false) && PHPUnit\Util\Bla
}
}
+ if (!$terminatedProcs && 1 === count($runningProcs)) {
+ $component = key($runningProcs);
+
+ $output = file_get_contents("$component/phpunit.stdout");
+ $output .= file_get_contents("$component/phpunit.stderr");
+
+ if ($lastOutput !== $output) {
+ $lastOutput = $output;
+ $lastOutputTime = microtime(true);
+ } elseif (microtime(true) - $lastOutputTime > 60) {
+ echo "\033[41mTimeout\033[0m $component\n\n";
+
+ if ('\\' === \DIRECTORY_SEPARATOR) {
+ exec(sprintf('taskkill /F /T /PID %d 2>&1', $procStatus['pid']), $output, $exitCode);
+ } else {
+ proc_terminate(current($runningProcs));
+ }
+ }
+ }
+
foreach ($terminatedProcs as $component => $procStatus) {
foreach (['out', 'err'] as $file) {
$file = "$component/phpunit.std$file";
diff --git a/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php b/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php
index ab45b83fecd72..cf98191233057 100644
--- a/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php
+++ b/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php
@@ -47,9 +47,9 @@ public function testCompile()
{
$form = new NameExpression('form', 0);
$resources = new ArrayExpression([
- new ConstantExpression(0, 0),
- new ConstantExpression('tpl1', 0),
new ConstantExpression(1, 0),
+ new ConstantExpression('tpl1', 0),
+ new ConstantExpression(0, 0),
new ConstantExpression('tpl2', 0),
], 0);
@@ -62,7 +62,7 @@ public function testCompile()
$this->assertEquals(
sprintf(
- '$this->env->getRuntime("Symfony\\\\Component\\\\Form\\\\FormRenderer")->setTheme(%s, [0 => "tpl1", 1 => "tpl2"], true);',
+ '$this->env->getRuntime("Symfony\\\\Component\\\\Form\\\\FormRenderer")->setTheme(%s, [1 => "tpl1", 0 => "tpl2"], true);',
$this->getVariableGetter('form')
),
trim($compiler->compile($node)->getSource())
@@ -72,7 +72,7 @@ public function testCompile()
$this->assertEquals(
sprintf(
- '$this->env->getRuntime("Symfony\\\\Component\\\\Form\\\\FormRenderer")->setTheme(%s, [0 => "tpl1", 1 => "tpl2"], false);',
+ '$this->env->getRuntime("Symfony\\\\Component\\\\Form\\\\FormRenderer")->setTheme(%s, [1 => "tpl1", 0 => "tpl2"], false);',
$this->getVariableGetter('form')
),
trim($compiler->compile($node)->getSource())
diff --git a/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php b/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php
index bce977e9b1197..4b709eb508928 100644
--- a/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php
+++ b/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php
@@ -14,6 +14,7 @@
use Symfony\Bridge\Monolog\Command\ServerLogCommand;
use Symfony\Bundle\DebugBundle\Command\ServerDumpPlaceholderCommand;
use Symfony\Component\Config\FileLocator;
+use Symfony\Component\Console\Command\Command;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
@@ -92,7 +93,7 @@ public function load(array $configs, ContainerBuilder $container)
;
}
- if (!class_exists(ServerLogCommand::class)) {
+ if (!class_exists(Command::class) || !class_exists(ServerLogCommand::class)) {
$container->removeDefinition('monolog.command.server_log');
}
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php
index 053810757a0d8..4d2d8422335bf 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php
@@ -137,7 +137,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
if ($output->isVerbose()) {
$io->comment('Warming up optional cache...');
}
- $this->warmupOptionals($realCacheDir);
+ $this->warmupOptionals($realCacheDir, $realBuildDir);
}
} else {
$fs->mkdir($warmupDir);
@@ -152,7 +152,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
if ($output->isVerbose()) {
$io->comment('Warming up optional cache...');
}
- $this->warmupOptionals($realCacheDir);
+ $this->warmupOptionals($useBuildDir ? $realCacheDir : $warmupDir, $warmupDir);
}
}
@@ -247,15 +247,15 @@ private function warmup(string $warmupDir, string $realBuildDir): void
}
}
- private function warmupOptionals(string $realCacheDir): void
+ private function warmupOptionals(string $cacheDir, string $warmupDir): void
{
$kernel = $this->getApplication()->getKernel();
$warmer = $kernel->getContainer()->get('cache_warmer');
// non optional warmers already ran during container compilation
$warmer->enableOnlyOptionalWarmers();
- $preload = (array) $warmer->warmUp($realCacheDir);
+ $preload = (array) $warmer->warmUp($cacheDir);
- if ($preload && file_exists($preloadFile = $realCacheDir.'/'.$kernel->getContainer()->getParameter('kernel.container_class').'.preload.php')) {
+ if ($preload && file_exists($preloadFile = $warmupDir.'/'.$kernel->getContainer()->getParameter('kernel.container_class').'.preload.php')) {
Preloader::append($preloadFile, $preload);
}
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
index e9b95db35a0c2..156c16b27ae8f 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
@@ -446,6 +446,10 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode)
->beforeNormalization()
->always()
->then(function ($places) {
+ if (!\is_array($places)) {
+ throw new InvalidConfigurationException('The "places" option must be an array in workflow configuration.');
+ }
+
// It's an indexed array of shape ['place1', 'place2']
if (isset($places[0]) && \is_string($places[0])) {
return array_map(function (string $place) {
@@ -491,6 +495,10 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode)
->beforeNormalization()
->always()
->then(function ($transitions) {
+ if (!\is_array($transitions)) {
+ throw new InvalidConfigurationException('The "transitions" option must be an array in workflow configuration.');
+ }
+
// It's an indexed array, we let the validation occur
if (isset($transitions[0]) && \is_array($transitions[0])) {
return $transitions;
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index 82b798b18e698..206bda1039a44 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -2154,12 +2154,14 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder
->replaceArgument(0, $transportRetryReferences);
if (\count($failureTransports) > 0) {
- $container->getDefinition('console.command.messenger_failed_messages_retry')
- ->replaceArgument(0, $config['failure_transport']);
- $container->getDefinition('console.command.messenger_failed_messages_show')
- ->replaceArgument(0, $config['failure_transport']);
- $container->getDefinition('console.command.messenger_failed_messages_remove')
- ->replaceArgument(0, $config['failure_transport']);
+ if ($this->hasConsole()) {
+ $container->getDefinition('console.command.messenger_failed_messages_retry')
+ ->replaceArgument(0, $config['failure_transport']);
+ $container->getDefinition('console.command.messenger_failed_messages_show')
+ ->replaceArgument(0, $config['failure_transport']);
+ $container->getDefinition('console.command.messenger_failed_messages_remove')
+ ->replaceArgument(0, $config['failure_transport']);
+ }
$failureTransportsByTransportNameServiceLocator = ServiceLocatorTagPass::register($container, $failureTransportReferencesByTransportName);
$container->getDefinition('messenger.failure.send_failed_message_to_failure_transport_listener')
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/console.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/console.php
index 610a83addec42..d8588ae6de881 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/console.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/console.php
@@ -181,9 +181,10 @@
abstract_arg('Receivers'),
service('messenger.routable_message_bus'),
service('event_dispatcher'),
- service('logger'),
+ service('logger')->nullOnInvalid(),
])
->tag('console.command')
+ ->tag('monolog.logger', ['channel' => 'messenger'])
->set('console.command.messenger_failed_messages_show', FailedMessagesShowCommand::class)
->args([
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
index 4366cab50d64b..3a1a9a6d70a65 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
@@ -398,8 +398,6 @@
-
-
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows.xml
index ba373aad2863c..6f29bad9f4588 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows.xml
@@ -10,7 +10,6 @@
draft
-
Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTestCase
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/PhpFrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/PhpFrameworkExtensionTest.php
index 871b62e8811da..77332f5a6b95c 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/PhpFrameworkExtensionTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/PhpFrameworkExtensionTest.php
@@ -11,6 +11,7 @@
namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection;
+use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\LogicException;
@@ -56,6 +57,36 @@ public function testAssetPackageCannotHavePathAndUrl()
});
}
+ public function testWorkflowValidationPlacesIsArray()
+ {
+ $this->expectException(InvalidConfigurationException::class);
+ $this->expectExceptionMessage('The "places" option must be an array in workflow configuration.');
+ $this->createContainerFromClosure(function ($container) {
+ $container->loadFromExtension('framework', [
+ 'workflows' => [
+ 'article' => [
+ 'places' => null,
+ ],
+ ],
+ ]);
+ });
+ }
+
+ public function testWorkflowValidationTransitonsIsArray()
+ {
+ $this->expectException(InvalidConfigurationException::class);
+ $this->expectExceptionMessage('The "transitions" option must be an array in workflow configuration.');
+ $this->createContainerFromClosure(function ($container) {
+ $container->loadFromExtension('framework', [
+ 'workflows' => [
+ 'article' => [
+ 'transitions' => null,
+ ],
+ ],
+ ]);
+ });
+ }
+
public function testWorkflowValidationStateMachine()
{
$this->expectException(InvalidDefinitionException::class);
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php
index b092b8a18d0e6..9e12116ac2aaa 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php
@@ -434,7 +434,7 @@ private function getRoleHierarchy()
final class DummyVoter implements VoterInterface
{
- public function vote(TokenInterface $token, $subject, array $attributes)
+ public function vote(TokenInterface $token, $subject, array $attributes): int
{
}
}
diff --git a/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php b/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php
index b2e7db2696661..e703cf98c79f4 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php
+++ b/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php
@@ -121,7 +121,7 @@ public function onKernelResponse(ResponseEvent $event)
if (self::DISABLED === $this->mode
|| !$response->headers->has('X-Debug-Token')
|| $response->isRedirection()
- || ($response->headers->has('Content-Type') && !str_contains($response->headers->get('Content-Type'), 'html'))
+ || ($response->headers->has('Content-Type') && !str_contains($response->headers->get('Content-Type') ?? '', 'html'))
|| 'html' !== $request->getRequestFormat()
|| false !== stripos($response->headers->get('Content-Disposition', ''), 'attachment;')
) {
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/EventListener/WebDebugToolbarListenerTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/EventListener/WebDebugToolbarListenerTest.php
index 450802a38efef..c4972c97c9e3b 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Tests/EventListener/WebDebugToolbarListenerTest.php
+++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/EventListener/WebDebugToolbarListenerTest.php
@@ -344,6 +344,20 @@ public function testCspIsKeptEnabledIfDumperWasNotUsed()
$this->assertEquals("\nWDT\n", $response->getContent());
}
+ public function testNullContentTypeWithNoDebugEnv()
+ {
+ $response = new Response('');
+ $response->headers->set('Content-Type', null);
+ $response->headers->set('X-Debug-Token', 'xxxxxxxx');
+
+ $event = new ResponseEvent($this->createMock(Kernel::class), new Request(), HttpKernelInterface::MAIN_REQUEST, $response);
+
+ $listener = new WebDebugToolbarListener($this->getTwigMock(), false, WebDebugToolbarListener::ENABLED, null);
+ $listener->onKernelResponse($event);
+
+ $this->expectNotToPerformAssertions();
+ }
+
protected function getTwigMock($render = 'WDT')
{
$templating = $this->createMock(Environment::class);
diff --git a/src/Symfony/Component/Config/Tests/ConfigCacheTest.php b/src/Symfony/Component/Config/Tests/ConfigCacheTest.php
index d7099fb970ca0..41d7fed92862a 100644
--- a/src/Symfony/Component/Config/Tests/ConfigCacheTest.php
+++ b/src/Symfony/Component/Config/Tests/ConfigCacheTest.php
@@ -72,7 +72,7 @@ public function testFreshResourceInDebug()
{
$p = (new \ReflectionClass(SelfCheckingResourceChecker::class))->getProperty('cache');
$p->setAccessible(true);
- $p->setValue(SelfCheckingResourceChecker::class, []);
+ $p->setValue(null, []);
$freshResource = new ResourceStub();
$freshResource->setFresh(true);
@@ -87,7 +87,7 @@ public function testStaleResourceInDebug()
{
$p = (new \ReflectionClass(SelfCheckingResourceChecker::class))->getProperty('cache');
$p->setAccessible(true);
- $p->setValue(SelfCheckingResourceChecker::class, []);
+ $p->setValue(null, []);
$staleResource = new ResourceStub();
$staleResource->setFresh(false);
diff --git a/src/Symfony/Component/Console/Tests/TerminalTest.php b/src/Symfony/Component/Console/Tests/TerminalTest.php
index 34d32b08ebecb..08b0df7cdabd6 100644
--- a/src/Symfony/Component/Console/Tests/TerminalTest.php
+++ b/src/Symfony/Component/Console/Tests/TerminalTest.php
@@ -41,7 +41,7 @@ private function resetStatics()
foreach (['height', 'width', 'stty'] as $name) {
$property = new \ReflectionProperty(Terminal::class, $name);
$property->setAccessible(true);
- $property->setValue(null);
+ $property->setValue(null, null);
}
}
diff --git a/src/Symfony/Component/CssSelector/Tests/XPath/Fixtures/ids.html b/src/Symfony/Component/CssSelector/Tests/XPath/Fixtures/ids.html
index 5799fad25ecfb..1147bf3f157dc 100644
--- a/src/Symfony/Component/CssSelector/Tests/XPath/Fixtures/ids.html
+++ b/src/Symfony/Component/CssSelector/Tests/XPath/Fixtures/ids.html
@@ -45,4 +45,8 @@
-