diff --git a/.github/rm-invalid-lowest-lock-files.php b/.github/rm-invalid-lowest-lock-files.php
deleted file mode 100644
index 80cf81b9340ce..0000000000000
--- a/.github/rm-invalid-lowest-lock-files.php
+++ /dev/null
@@ -1,158 +0,0 @@
- [], 'packages-dev' => []];
- $composerJsons[$composerJson['name']] = [$dir, $composerLock['packages'] + $composerLock['packages-dev'], getRelevantContent($composerJson)];
-}
-
-$referencedCommits = [];
-
-foreach ($composerJsons as list($dir, $lockedPackages)) {
- foreach ($lockedPackages as $lockedJson) {
- if (0 !== strpos($version = $lockedJson['version'], 'dev-') && '-dev' !== substr($version, -4)) {
- continue;
- }
-
- if (!isset($composerJsons[$name = $lockedJson['name']])) {
- echo "$dir/composer.lock references missing $name.\n";
- @unlink($dir.'/composer.lock');
- continue 2;
- }
-
- if (isset($composerJsons[$name][2]['repositories']) && !isset($lockedJson['repositories'])) {
- // the locked package has been patched locally but the lock references a commit,
- // which means the referencing package itself is not modified
- continue;
- }
-
- foreach (['minimum-stability', 'prefer-stable'] as $key) {
- if (array_key_exists($key, $composerJsons[$name][2])) {
- $lockedJson[$key] = $composerJsons[$name][2][$key];
- }
- }
-
- // use weak comparison to ignore ordering
- if (getRelevantContent($lockedJson) != $composerJsons[$name][2]) {
- echo "$dir/composer.lock is not in sync with $name.\n";
- @unlink($dir.'/composer.lock');
- continue 2;
- }
-
- if ($lockedJson['dist']['reference']) {
- $referencedCommits[$name][$lockedJson['dist']['reference']][] = $dir;
- }
- }
-}
-
-if (!$referencedCommits) {
- return;
-}
-
-@mkdir($_SERVER['HOME'].'/.cache/composer/repo/https---repo.packagist.org', 0777, true);
-
-$ch = null;
-$mh = curl_multi_init();
-$sh = curl_share_init();
-curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
-curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
-curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);
-$chs = [];
-
-foreach ($referencedCommits as $name => $dirsByCommit) {
- $chs[] = $ch = [curl_init(), fopen($_SERVER['HOME'].'/.cache/composer/repo/https---repo.packagist.org/provider-'.strtr($name, '/', '$').'.json', 'wb')];
- curl_setopt($ch[0], CURLOPT_URL, 'https://repo.packagist.org/p/'.$name.'.json');
- curl_setopt($ch[0], CURLOPT_FILE, $ch[1]);
- curl_setopt($ch[0], CURLOPT_SHARE, $sh);
- curl_multi_add_handle($mh, $ch[0]);
-}
-
-do {
- curl_multi_exec($mh, $active);
- curl_multi_select($mh);
-} while ($active);
-
-foreach ($chs as list($ch, $fd)) {
- curl_multi_remove_handle($mh, $ch);
- curl_close($ch);
- fclose($fd);
-}
-
-foreach ($referencedCommits as $name => $dirsByCommit) {
- $repo = file_get_contents($_SERVER['HOME'].'/.cache/composer/repo/https---repo.packagist.org/provider-'.strtr($name, '/', '$').'.json');
- $repo = json_decode($repo, true);
-
- foreach ($repo['packages'][$name] as $version) {
- unset($referencedCommits[$name][$version['source']['reference']]);
- }
-}
-
-foreach ($referencedCommits as $name => $dirsByCommit) {
- foreach ($dirsByCommit as $dirs) {
- foreach ($dirs as $dir) {
- if (file_exists($dir.'/composer.lock')) {
- echo "$dir/composer.lock references old commit for $name.\n";
- @unlink($dir.'/composer.lock');
- }
- }
- }
-}
diff --git a/.travis.yml b/.travis.yml
index ee0c4c815974d..336224a23bbbe 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -279,11 +279,7 @@ install:
[[ ! $X ]] || (exit 1)
elif [[ $deps = low ]]; then
- [[ -e ~/php-ext/composer-lowest.lock.tar ]] && tar -xf ~/php-ext/composer-lowest.lock.tar
- tar -cf ~/php-ext/composer-lowest.lock.tar --files-from /dev/null
- php .github/rm-invalid-lowest-lock-files.php $COMPONENTS
- echo "$COMPONENTS" | parallel --gnu "tfold {} 'cd {} && ([ -e composer.lock ] && ${COMPOSER_UP/update/install} || $COMPOSER_UP --prefer-lowest --prefer-stable) && $PHPUNIT_X'"
- echo "$COMPONENTS" | xargs -n1 -I{} tar --append -f ~/php-ext/composer-lowest.lock.tar {}/composer.lock
+ echo "$COMPONENTS" | parallel --gnu "tfold {} 'cd {} && $COMPOSER_UP --prefer-lowest --prefer-stable && $PHPUNIT_X'"
else
if [[ $PHP = 8.0* ]]; then
# add return types before running the test suite
diff --git a/CHANGELOG-4.4.md b/CHANGELOG-4.4.md
index 3811db5442333..3a2f916e7fc34 100644
--- a/CHANGELOG-4.4.md
+++ b/CHANGELOG-4.4.md
@@ -7,6 +7,40 @@ in 4.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/v4.4.0...v4.4.1
+* 4.4.21 (2021-03-29)
+
+ * bug #40598 [Form] error if the input string couldn't be parsed as a date (xabbuh)
+ * bug #40587 [HttpClient] fix using stream_copy_to_stream() with responses cast to php streams (nicolas-grekas)
+ * bug #40510 [Form] IntegerType: Always use en for IntegerToLocalizedStringTransformer (Warxcell)
+ * bug #40593 Uses the correct assignment action for console options depending if they are short or long (topikito)
+ * bug #40535 [HttpKernel] ConfigDataCollector to return known data without the need of a Kernel (topikito)
+ * bug #40552 [Translation] Fix update existing key with existing +int-icu domain (Alexis)
+ * bug #40537 [Security] Handle properly 'auto' option for remember me cookie security (fliespl)
+ * bug #40506 [Validator] Avoid triggering the autoloader for user-input values (Seldaek)
+ * bug #40538 [HttpClient] remove using $http_response_header (nicolas-grekas)
+ * bug #40508 [PhpUnitBridge] fix reporting deprecations from DebugClassLoader (nicolas-grekas)
+ * bug #40348 [Console] Fix line wrapping for decorated text in block output (grasmash)
+ * bug #40499 [Inflector][String] Fixed pluralize "coupon" (Nyholm)
+ * bug #40494 [PhpUnitBridge] fix compat with symfony/debug (nicolas-grekas)
+ * bug #40453 [VarDumper] Adds support for ReflectionUnionType to VarDumper (Michael Nelson, michaeldnelson)
+ * bug #40460 Correctly clear lines for multi-line progress bar messages (grasmash)
+ * bug #40450 [Console] ProgressBar clears too many lines on update (danepowell)
+ * bug #40178 [FrameworkBundle] Exclude unreadable files when executing About command (michaljusiega)
+ * bug #40472 [Bridge\Twig] Add 'form-control-range' for range input type (Oviglo)
+ * bug #39866 [Mime] Escape commas in address names (YaFou)
+ * bug #40373 Check if templating engine supports given view (fritzmg)
+ * bug #39992 [Security] Refresh original user in SwitchUserListener (AndrolGenhald)
+ * bug #40446 [TwigBridge] Fix "Serialization of 'Closure'" error when rendering an TemplatedEmail (jderusse)
+ * bug #40425 [DoctrineBridge] Fix eventListener initialization when eventSubscriber constructor dispatch an event (jderusse)
+ * bug #40313 [FrameworkBundle] Fix PropertyAccess definition when not in debug (PedroTroller)
+ * bug #40417 [Form] clear unchecked choice radio boxes even if clear missing is set to false (xabbuh)
+ * bug #40388 [ErrorHandler] Added missing type annotations to FlattenException (derrabus)
+ * bug #40407 [TwigBridge] Allow version 3 of the Twig extra packages (derrabus)
+ * bug #39685 [Mailer][Mime][TwigBridge][Validator] Allow egulias/email-validator 3.x (derrabus)
+ * bug #40398 [FrameworkBundle] : Fix method name compare in ResolveControllerNameSubscriber (glensc)
+ * bug #39733 [TwigBridge] Render email once (jderusse)
+ * bug #40386 [DependencyInjection][Security] Backport psr/container 1.1/2.0 compatibility (derrabus)
+
* 4.4.20 (2021-03-04)
* bug #40318 [Translation] deal with indented heredoc/nowdoc tokens (xabbuh)
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 09e940bebd83c..8a5518bb3390f 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -33,10 +33,10 @@ The Symfony Connect username in parenthesis allows to get more information
- Romain Neutron (romain)
- Pascal Borreli (pborreli)
- Joseph Bielawski (stloyd)
+ - Tobias Nyholm (tobias)
- Karma Dordrak (drak)
- Jules Pietri (heah)
- Lukas Kahwe Smith (lsmith)
- - Tobias Nyholm (tobias)
- Martin Hasoň (hason)
- Amrouche Hamza (simperfit)
- Jeremy Mikola (jmikola)
@@ -54,11 +54,11 @@ The Symfony Connect username in parenthesis allows to get more information
- Matthias Pigulla (mpdude)
- Diego Saint Esteben (dosten)
- Valentin Udaltsov (vudaltsov)
+ - Kevin Bond (kbond)
- Alexandre Salomé (alexandresalome)
- William Durand (couac)
- Grégoire Paris (greg0ire)
- ornicar
- - Kevin Bond (kbond)
- Dany Maillard (maidmaid)
- Francis Besset (francisbesset)
- stealth35 (stealth35)
@@ -184,6 +184,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Arman Hosseini (arman)
- Niels Keurentjes (curry684)
- Vyacheslav Pavlov
+ - Albert Casademont (acasademont)
- George Mponos (gmponos)
- Richard Shank (iampersistent)
- Thomas Rabaix (rande)
@@ -192,6 +193,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Jérôme Parmentier (lctrs)
- Ben Davies (bendavies)
- Andreas Schempp (aschempp)
+ - Jan Rosier (rosier)
- Clemens Tolboom
- Helmer Aaviksoo
- Hiromi Hishida (77web)
@@ -200,7 +202,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Dawid Nowak
- Maxime Helias (maxhelias)
- Amal Raghav (kertz)
- - Albert Casademont (acasademont)
- Jonathan Ingram (jonathaningram)
- Artur Kotyrba
- Tyson Andre
@@ -229,12 +230,12 @@ The Symfony Connect username in parenthesis allows to get more information
- DQNEO
- David Prévot
- Andre Rømcke (andrerom)
+ - Marco Pivetta (ocramius)
- Smaine Milianni (ismail1432)
- mcfedr (mcfedr)
- Christian Scheb
- Ruben Gonzalez (rubenrua)
- Benjamin Dulau (dbenjamin)
- - Jan Rosier (rosier)
- Mathieu Lemoine (lemoinem)
- Remon van de Kamp (rpkamp)
- Christian Schmidt
@@ -270,6 +271,7 @@ The Symfony Connect username in parenthesis allows to get more information
- jeff
- John Kary (johnkary)
- Tien Vo (tienvx)
+ - YaFou
- Justin Hileman (bobthecow)
- Blanchon Vincent (blanchonvincent)
- Michele Orselli (orso)
@@ -277,6 +279,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Baptiste Lafontaine (magnetik)
- Maxime Veber (nek-)
- Rui Marinho (ruimarinho)
+ - Jesse Rushlow (geeshoe)
- Eugene Wissner
- Andreas Möller (localheinz)
- Edi Modrić (emodric)
@@ -292,7 +295,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Mantis Development
- Loïc Faugeron
- dFayet
- - Marco Pivetta (ocramius)
- Antonio Pauletich (x-coder264)
- Jeroen Spee (jeroens)
- Rob Frawley 2nd (robfrawley)
@@ -317,7 +319,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Alessandro Lai (jean85)
- Adam Prager (padam87)
- Benoît Burnichon (bburnichon)
- - YaFou
- Maciej Malarz (malarzm)
- Roman Marintšenko (inori)
- Xavier Montaña Carreras (xmontana)
@@ -417,7 +418,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Aurelijus Valeiša (aurelijus)
- Jan Decavele (jandc)
- Gustavo Piltcher
- - Jesse Rushlow (geeshoe)
- Stepan Tanasiychuk (stfalcon)
- Ivan Kurnosov
- Tiago Ribeiro (fixe)
@@ -442,6 +442,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Mark Challoner (markchalloner)
- ivan
- Karoly Gossler (connorhu)
+ - Nate Wiebe (natewiebe13)
- Ahmed Raafat
- Philippe Segatori
- Gennady Telegin (gtelegin)
@@ -470,6 +471,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Harm van Tilborg (hvt)
- Malte Schlüter (maltemaltesich)
- Thomas Perez (scullwm)
+ - Michał (bambucha15)
- Felix Labrecque
- Yaroslav Kiliba
- Terje Bråten
@@ -497,11 +499,13 @@ The Symfony Connect username in parenthesis allows to get more information
- Grzegorz Zdanowski (kiler129)
- Dimitri Gritsajuk (ottaviano)
- Kirill chEbba Chebunin (chebba)
+ - Pol Dellaiera (drupol)
-
- Greg Thornton (xdissent)
- Alex Bowers
- Philipp Cordes
- Costin Bereveanu (schniper)
+ - Bozhidar Hristov (warxcell)
- Loïc Chardonnet (gnusat)
- Marek Kalnik (marekkalnik)
- Vyacheslav Salakhutdinov (megazoll)
@@ -536,6 +540,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Miha Vrhovnik
- Alessandro Desantis
- hubert lecorche (hlecorche)
+ - fritzmg
- Marc Morales Valldepérez (kuert)
- Jean-Baptiste GOMOND (mjbgo)
- Vadim Kharitonov (virtuozzz)
@@ -559,7 +564,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Christopher Davis (chrisguitarguy)
- Webnet team (webnet)
- Ben Ramsey (ramsey)
- - Nate Wiebe (natewiebe13)
- Marcin Szepczynski (czepol)
- Mohammad Emran Hasan (phpfour)
- Dmitriy Mamontov (mamontovdmitriy)
@@ -567,6 +571,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Niklas Fiekas
- Markus Bachmann (baachi)
- Kévin THERAGE (kevin_therage)
+ - Gunnstein Lye (glye)
- Erkhembayar Gantulga (erheme318)
- Greg Anderson
- Islam93
@@ -588,6 +593,7 @@ The Symfony Connect username in parenthesis allows to get more information
- DerManoMann
- vagrant
- Aurimas Niekis (gcds)
+ - Benjamin Cremer (bcremer)
- EdgarPE
- Bob van de Vijver (bobvandevijver)
- Florian Pfitzer (marmelatze)
@@ -609,6 +615,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Ariel Ferrandini (aferrandini)
- Dirk Pahl (dirkaholic)
- cedric lombardot (cedriclombardot)
+ - Dane Powell
- Arkadius Stefanski (arkadius)
- Tim Goudriaan (codedmonkey)
- Jonas Flodén (flojon)
@@ -641,7 +648,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Sam Fleming (sam_fleming)
- Alex Bakhturin
- Patrick Reimers (preimers)
- - Pol Dellaiera (drupol)
- insekticid
- Alexander Obuhovich (aik099)
- boombatower
@@ -659,7 +665,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Nathan Dench (ndenc2)
- Sebastian Bergmann
- Miroslav Sustek
- - Michał (bambucha15)
- Pablo Díez (pablodip)
- Kevin McBride
- Sergio Santoro
@@ -717,7 +722,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Jacek Jędrzejewski (jacek.jedrzejewski)
- Stefan Kruppa
- sasezaki
- - Bozhidar Hristov (warxcell)
- Dawid Pakuła (zulusx)
- Florian Rey (nervo)
- Rodrigo Borrego Bernabé (rodrigobb)
@@ -743,7 +747,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Ned Schwartz
- Ziumin
- Jeremy Benoist
- - fritzmg
- Lenar Lõhmus
- Benjamin Laugueux (yzalis)
- Zach Badgett (zachbadgett)
@@ -756,6 +759,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Geoffrey Tran (geoff)
- Pablo Lozano (arkadis)
- Jan Behrens
+ - Bernd Stellwag
- Mantas Var (mvar)
- Terje Bråten
- Sebastian Krebs
@@ -766,6 +770,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Jean-Christophe Cuvelier [Artack]
- Julien Montel (julienmgel)
- Mátyás Somfai (smatyas)
+ - Urinbayev Shakhobiddin (shokhaa)
- Bastien DURAND (deamon)
- Simon DELICATA
- Artem Henvald (artemgenvald)
@@ -813,10 +818,8 @@ The Symfony Connect username in parenthesis allows to get more information
- Hany el-Kerdany
- Wang Jingyu
- Åsmund Garfors
- - Gunnstein Lye (glye)
- Maxime Douailin
- Jean Pasdeloup (pasdeloup)
- - Benjamin Cremer (bcremer)
- Javier López (loalf)
- Reinier Kip
- Jérôme Tamarelle (jtamarelle-prismamedia)
@@ -834,6 +837,7 @@ The Symfony Connect username in parenthesis allows to get more information
- zenmate
- Michal Trojanowski
- Lescot Edouard (idetox)
+ - Andrii Popov (andrii-popov)
- David Fuhr
- Rodrigo Aguilera
- Mathias STRASSER (roukmoute)
@@ -844,6 +848,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Mardari Dorel (dorumd)
- Daisuke Ohata
- Vincent Simonin
+ - Pierrick VIGNAND (pierrick)
- Alex Bogomazov (alebo)
- maxime.steinhausser
- adev
@@ -940,7 +945,9 @@ The Symfony Connect username in parenthesis allows to get more information
- Andrew Berry
- twifty
- Indra Gunawan (guind)
+ - Roberto Nygaard
- Peter Ward
+ - Matthew Grasmick
- Davide Borsatto (davide.borsatto)
- Gert de Pagter
- Julien DIDIER (juliendidier)
@@ -1032,6 +1039,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Vincent Composieux (eko)
- Jayson Xu (superjavason)
- Gijs van Lammeren
+ - DemigodCode
- Hubert Lenoir (hubert_lenoir)
- fago
- Jan Prieser
@@ -1167,18 +1175,19 @@ The Symfony Connect username in parenthesis allows to get more information
- Dmitriy Derepko
- Stéphane Delprat
- Brian Freytag (brianfreytag)
+ - Elan Ruusamäe (glen)
- Brunet Laurent (lbrunet)
- Florent Viel (luxifer)
- Mikhail Yurasov (mym)
- LOUARDI Abdeltif (ouardisoft)
- Robert Gruendler (pulse00)
+ - Sebastian Paczkowski (sebpacz)
- Simon Terrien (sterrien)
- Benoît Merlet (trompette)
- Koen Kuipers
- datibbaw
- Thiago Cordeiro (thiagocordeiro)
- Rootie
- - Bernd Stellwag
- Alireza Mirsepassi (alirezamirsepassi)
- Daniel Alejandro Castro Arellano (lexcast)
- sensio
@@ -1258,6 +1267,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Fred Cox
- luffy1727
- Luciano Mammino (loige)
+ - LHommet Nicolas (nicolaslh)
- fabios
- Sander Coolen (scoolen)
- Amirreza Shafaat (amirrezashafaat)
@@ -1288,6 +1298,7 @@ The Symfony Connect username in parenthesis allows to get more information
- linh
- Mario Blažek (marioblazek)
- Jure (zamzung)
+ - Michael Nelson
- Ashura
- Hryhorii Hrebiniuk
- Eric Krona
@@ -1308,7 +1319,6 @@ The Symfony Connect username in parenthesis allows to get more information
- boite
- Silvio Ginter
- MGDSoft
- - Pierrick VIGNAND (pierrick)
- Vadim Tyukov (vatson)
- Arman
- Gabi Udrescu
@@ -1385,6 +1395,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Ken Marfilla (marfillaster)
- benatespina (benatespina)
- Denis Kop
+ - Cristoforo Cervino (cristoforocervino)
- Jean-Guilhem Rouel (jean-gui)
- jfcixmedia
- Dominic Tubach
@@ -1397,7 +1408,9 @@ The Symfony Connect username in parenthesis allows to get more information
- Christian
- Alexandru Patranescu
- Denis Golubovskiy (bukashk0zzz)
+ - Arkadiusz Rzadkowolski (flies)
- Sergii Smertin (nfx)
+ - Oksana Kozlova (oksanakozlova)
- Quentin Moreau (sheitak)
- Mikkel Paulson
- Michał Strzelecki
@@ -1427,6 +1440,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Atthaphon Urairat
- Benoit Garret
- Maximilian Ruta (deltachaos)
+ - Mickaël Isaert (misaert)
- Jakub Sacha
- Olaf Klischat
- orlovv
@@ -1453,6 +1467,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Benjamin Dos Santos
- Einenlum
- Jérémy Jarrié (gagnar)
+ - Martin Herndl (herndlm)
- Jochen Bayer (jocl)
- Tomas Javaisis
- Patrick Carlo-Hickman
@@ -1479,6 +1494,7 @@ The Symfony Connect username in parenthesis allows to get more information
- peter
- Jérémy Jourdin (jjk801)
- BRAMILLE Sébastien (oktapodia)
+ - Loïc Ovigne (oviglo)
- Artem Kolesnikov (tyomo4ka)
- Gustavo Adrian
- Jorrit Schippers (jorrit)
@@ -1506,6 +1522,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Eno Mullaraj (emullaraj)
- Nathan PAGE (nathix)
- Ryan Rogers
+ - Marion Hurteau
- Klaus Purer
- Dmitrii Lozhkin
- arnaud (arnooo999)
@@ -1565,6 +1582,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Andrii Serdiuk (andreyserdjuk)
- Clement Herreman (clemherreman)
- Dan Ionut Dumitriu (danionut90)
+ - Floran Brutel (notFloran) (floran)
- Vladislav Rastrusny (fractalizer)
- Alexander Kurilo (kamazee)
- Nyro (nyro)
@@ -1577,6 +1595,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Dmitri Petmanson
- heccjj
- Alexandre Melard
+ - Stefano A. (stefano93)
- Jay Klehr
- Sergey Yuferev
- Tobias Stöckler
@@ -1587,9 +1606,11 @@ The Symfony Connect username in parenthesis allows to get more information
- Mo Di (modi)
- Pablo Schläpfer
- Christian Rishøj
+ - Roromix
- Patrick Berenschot
- SuRiKmAn
- Jelte Steijaert (jelte)
+ - Maxime AILLOUD (mailloud)
- David Négrier (moufmouf)
- Quique Porta (quiqueporta)
- mohammadreza honarkhah
@@ -1604,6 +1625,7 @@ The Symfony Connect username in parenthesis allows to get more information
- ConneXNL
- Aharon Perkel
- matze
+ - Adam Wójs (awojs)
- Justin Reherman (jreherman)
- Rubén Calvo (rubencm)
- Paweł Niedzielski (steveb)
@@ -1618,6 +1640,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Artem Stepin (astepin)
- Christian Flach (cmfcmf)
- Cédric Girard (enk_)
+ - Junaid Farooq (junaidfarooq)
- Lars Ambrosius Wallenborn (larsborn)
- Oriol Mangas Abellan (oriolman)
- Sebastian Göttschkes (sgoettschkes)
@@ -1655,6 +1678,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Andrea Sprega (asprega)
- Maks Rafalko (bornfree)
- Karol Sójko (karolsojko)
+ - Viktor Bajraktar (njutn95)
- sl_toto (sl_toto)
- Walter Dal Mut (wdalmut)
- abluchet
@@ -1673,6 +1697,8 @@ The Symfony Connect username in parenthesis allows to get more information
- Cédric Lahouste (rapotor)
- Samuel Vogel (samuelvogel)
- Osayawe Ogbemudia Terry (terdia)
+ - AndrolGenhald
+ - Damien Fa
- Berat Doğan
- Guillaume LECERF
- Juanmi Rodriguez Cerón
@@ -1705,6 +1731,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Alexander Pasichnick
- Ilya Ch. (ilya0)
- Luis Ramirez (luisdeimos)
+ - Ilia Sergunin (maranqz)
- Daniel Richter (richtermeister)
- ChrisC
- JL
@@ -1713,6 +1740,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Johan de Ruijter
- Jason Desrosiers
- m.chwedziak
+ - marbul
- Andreas Frömer
- Philip Frank
- David Brooks
@@ -1720,6 +1748,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Florian Caron (shalalalala)
- Serhiy Lunak (slunak)
- Giorgio Premi
+ - tamcy
- Mikko Pesari
- Aurélien Fontaine
- ncou
@@ -1804,6 +1833,8 @@ The Symfony Connect username in parenthesis allows to get more information
- Peter Bouwdewijn
- mlively
- Wouter Diesveld
+ - Romain
+ - Matěj Humpál
- Vincent Langlet
- Amine Matmati
- caalholm
@@ -1913,6 +1944,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Biji (biji)
- Alex Teterin (errogaht)
- Gunnar Lium (gunnarlium)
+ - Marie Minasyan (marie.minassyan)
- Tiago Garcia (tiagojsag)
- Artiom
- Jakub Simon
@@ -1926,6 +1958,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Martin Eckhardt
- natechicago
- Camille Dejoye
+ - Alexis
- Sergei Gorjunov
- Jonathan Poston
- Adrian Olek (adrianolek)
@@ -2095,6 +2128,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Florent Olivaud
- Eric Hertwig
- JakeFr
+ - Oliver Klee
- Niels Robin-Aubertin
- Simon Sargeant
- efeen
@@ -2309,7 +2343,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Arjan Keeman
- Erik van Wingerden
- Valouleloup
- - Dane Powell
- Alexis MARQUIS
- Gerrit Drost
- Linnaea Von Lavia
@@ -2322,6 +2355,7 @@ The Symfony Connect username in parenthesis allows to get more information
- hainey
- Juan M Martínez
- Gilles Gauthier
+ - Benjamin Franzke
- Pavinthan
- Sylvain METAYER
- ddebree
@@ -2380,6 +2414,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Olivier Laviale (olvlvl)
- Pierre Gasté (pierre_g)
- Pablo Monterde Perez (plebs)
+ - Pierre-Olivier Vares (povares)
- Jimmy Leger (redpanda)
- Ronny López (ronnylt)
- Dmitry (staratel)
@@ -2505,6 +2540,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Paweł Tomulik
- Eric J. Duran
- Pavol Tuka
+ - stlrnz
- Alexandru Bucur
- Alexis Lefebvre
- cmfcmf
@@ -2558,6 +2594,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Jon Cave
- Sébastien HOUZE
- Abdulkadir N. A.
+ - Markus Klein
- Adam Klvač
- Bruno Nogueira Nascimento Wowk
- Matthias Dötsch
@@ -2570,7 +2607,6 @@ The Symfony Connect username in parenthesis allows to get more information
- Ondřej Führer
- Bogdan
- Sema
- - Elan Ruusamäe
- Thorsten Hallwas
- Marco Pfeiffer
- Alex Nostadt
@@ -2647,12 +2683,13 @@ The Symfony Connect username in parenthesis allows to get more information
- Alex Olmos (alexolmos)
- Antonio Mansilla (amansilla)
- Robin Kanters (anddarerobin)
- - Andrii Popov (andrii-popov)
- Juan Ases García (ases)
- Siragusa (asiragusa)
- Daniel Basten (axhm3a)
- Dude (b1rdex)
+ - Benedict Massolle (bemas)
- Gerard Berengue Llobera (bere)
+ - Ronny (big-r)
- Bernd Matzner (bmatzner)
- Bram Tweedegolf (bram_tweedegolf)
- Brandon Kelly (brandonkelly)
@@ -2722,6 +2759,7 @@ The Symfony Connect username in parenthesis allows to get more information
- Paul Andrieux (paulandrieux)
- Paweł Szczepanek (pauluz)
- Philippe Degeeter (pdegeeter)
+ - PLAZANET Pierre (pedrotroller)
- Christian López Espínola (penyaskito)
- Petr Jaroš (petajaros)
- Philipp Hoffmann (philipphoffmann)
diff --git a/composer.json b/composer.json
index 63108b1e132e9..737f767885da5 100644
--- a/composer.json
+++ b/composer.json
@@ -134,15 +134,16 @@
"predis/predis": "~1.1",
"psr/http-client": "^1.0",
"psr/simple-cache": "^1.0",
- "egulias/email-validator": "^2.1.10",
+ "egulias/email-validator": "^2.1.10|^3.1",
"symfony/phpunit-bridge": "^5.2",
"symfony/security-acl": "~2.8|~3.0",
"phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
- "twig/cssinliner-extra": "^2.12",
- "twig/inky-extra": "^2.12",
- "twig/markdown-extra": "^2.12"
+ "twig/cssinliner-extra": "^2.12|^3",
+ "twig/inky-extra": "^2.12|^3",
+ "twig/markdown-extra": "^2.12|^3"
},
"conflict": {
+ "egulias/email-validator": "~3.0.0",
"masterminds/html5": "<2.6",
"monolog/monolog": ">=2",
"phpdocumentor/reflection-docblock": "<3.0|>=3.2.0,<3.2.2",
diff --git a/src/Symfony/Bridge/Doctrine/ContainerAwareEventManager.php b/src/Symfony/Bridge/Doctrine/ContainerAwareEventManager.php
index 9b3c1595a41f0..1ee4f54ded8e1 100644
--- a/src/Symfony/Bridge/Doctrine/ContainerAwareEventManager.php
+++ b/src/Symfony/Bridge/Doctrine/ContainerAwareEventManager.php
@@ -177,6 +177,7 @@ private function initializeSubscribers()
if (!isset($this->listeners[$event])) {
$this->listeners[$event] = [];
}
+ unset($this->initialized[$event]);
$this->listeners[$event] += $listeners;
}
$this->subscribers = [];
diff --git a/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php
index 49914454569e3..845515b901155 100644
--- a/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php
+++ b/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php
@@ -234,4 +234,7 @@ abstract class UserLoaderRepository implements ObjectRepository, UserLoaderInter
abstract class PasswordUpgraderRepository implements ObjectRepository, PasswordUpgraderInterface
{
+ public function upgradePassword(UserInterface $user, string $newEncodedPassword): void
+ {
+ }
}
diff --git a/src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php b/src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php
index bf3433e154be0..f2ad907d76978 100644
--- a/src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php
+++ b/src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php
@@ -60,7 +60,7 @@ protected function configure()
->addOption('format', null, InputOption::VALUE_REQUIRED, 'The line format', ConsoleFormatter::SIMPLE_FORMAT)
->addOption('date-format', null, InputOption::VALUE_REQUIRED, 'The date format', ConsoleFormatter::SIMPLE_DATE)
->addOption('filter', null, InputOption::VALUE_REQUIRED, 'An expression to filter log. Example: "level > 200 or channel in [\'app\', \'doctrine\']"')
- ->setDescription('Starts a log server that displays logs in real time')
+ ->setDescription('Start a log server that displays logs in real time')
->setHelp(<<<'EOF'
%command.name% starts a log server to display in real time the log
messages generated by your application:
diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php
index ac1a95ef41242..fdc898a9316f5 100644
--- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php
+++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php
@@ -11,6 +11,8 @@
namespace Symfony\Bridge\PhpUnit\DeprecationErrorHandler;
+use PHPUnit\Framework\TestCase;
+use PHPUnit\Framework\TestSuite;
use PHPUnit\Util\Test;
use Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerFor;
use Symfony\Component\Debug\DebugClassLoader as LegacyDebugClassLoader;
@@ -76,43 +78,52 @@ public function __construct($message, array $trace, $file)
$this->triggeringFile = isset($trace[1 + $j]['args'][1]) ? realpath($trace[1 + $j]['args'][1]) : (new \ReflectionClass($class))->getFileName();
$this->getOriginalFilesStack();
array_splice($this->originalFilesStack, 0, $j, [$this->triggeringFile]);
+
+ if (preg_match('/(?|"([^"]++)" that is deprecated|should implement method "(?:static )?([^:]++))/', $message, $m) || preg_match('/^(?:The|Method) "([^":]++)/', $message, $m)) {
+ $this->triggeringFile = (new \ReflectionClass($m[1]))->getFileName();
+ array_unshift($this->originalFilesStack, $this->triggeringFile);
+ }
}
break;
}
}
- if (isset($line['object']) || isset($line['class'])) {
- if (!isset($line['class'], $trace[$i - 2]['function']) || 0 !== strpos($line['class'], SymfonyTestsListenerFor::class)) {
- $this->originClass = isset($line['object']) ? \get_class($line['object']) : $line['class'];
- $this->originMethod = $line['function'];
+ if (!isset($line['object']) && !isset($line['class'])) {
+ return;
+ }
- return;
- }
+ if (!isset($line['class'], $trace[$i - 2]['function']) || 0 !== strpos($line['class'], SymfonyTestsListenerFor::class)) {
+ $this->originClass = isset($line['object']) ? \get_class($line['object']) : $line['class'];
+ $this->originMethod = $line['function'];
- if ('trigger_error' !== $trace[$i - 2]['function'] || isset($trace[$i - 2]['class'])) {
- $this->originClass = \get_class($line['args'][0]);
- $this->originMethod = $line['args'][0]->getName();
+ return;
+ }
- return;
- }
+ $test = isset($line['args'][0]) ? $line['args'][0] : null;
- set_error_handler(function () {});
- $parsedMsg = unserialize($this->message);
- restore_error_handler();
- $this->message = $parsedMsg['deprecation'];
- $this->originClass = $parsedMsg['class'];
- $this->originMethod = $parsedMsg['method'];
- if (isset($parsedMsg['files_stack'])) {
- $this->originalFilesStack = $parsedMsg['files_stack'];
- }
- // If the deprecation has been triggered via
- // \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest()
- // then we need to use the serialized information to determine
- // if the error has been triggered from vendor code.
- if (isset($parsedMsg['triggering_file'])) {
- $this->triggeringFile = $parsedMsg['triggering_file'];
- }
+ if (($test instanceof TestCase || $test instanceof TestSuite) && ('trigger_error' !== $trace[$i - 2]['function'] || isset($trace[$i - 2]['class']))) {
+ $this->originClass = \get_class($test);
+ $this->originMethod = $test->getName();
+
+ return;
+ }
+
+ set_error_handler(function () {});
+ $parsedMsg = unserialize($this->message);
+ restore_error_handler();
+ $this->message = $parsedMsg['deprecation'];
+ $this->originClass = $parsedMsg['class'];
+ $this->originMethod = $parsedMsg['method'];
+ if (isset($parsedMsg['files_stack'])) {
+ $this->originalFilesStack = $parsedMsg['files_stack'];
+ }
+ // If the deprecation has been triggered via
+ // \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest()
+ // then we need to use the serialized information to determine
+ // if the error has been triggered from vendor code.
+ if (isset($parsedMsg['triggering_file'])) {
+ $this->triggeringFile = $parsedMsg['triggering_file'];
}
}
diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/debug_class_loader_deprecation.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/debug_class_loader_deprecation.phpt
new file mode 100644
index 0000000000000..a6b0133af93ed
--- /dev/null
+++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/debug_class_loader_deprecation.phpt
@@ -0,0 +1,41 @@
+--TEST--
+Test that a deprecation from the DebugClassLoader triggered by an app class extending a vendor one is considered direct.
+--FILE--
+
+--EXPECTF--
+Remaining direct deprecation notices (1)
+
+ 1x: The "App\Services\ExtendsDeprecatedFromVendor" class extends "fcy\lib\DeprecatedClass" that is deprecated.
+ 1x in DebugClassLoader::loadClass from Symfony\Component\ErrorHandler
diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_app/ExtendsDeprecatedFromVendor.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_app/ExtendsDeprecatedFromVendor.php
new file mode 100644
index 0000000000000..b4305e0d08a55
--- /dev/null
+++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_app/ExtendsDeprecatedFromVendor.php
@@ -0,0 +1,9 @@
+setDescription('Shows a list of twig functions, filters, globals and tests')
+ ->setDescription('Show a list of twig functions, filters, globals and tests')
->setHelp(<<<'EOF'
The %command.name% command outputs a list of twig functions,
filters, globals and tests.
diff --git a/src/Symfony/Bridge/Twig/Command/LintCommand.php b/src/Symfony/Bridge/Twig/Command/LintCommand.php
index 5edd15f66edb0..c65d68cdefa46 100644
--- a/src/Symfony/Bridge/Twig/Command/LintCommand.php
+++ b/src/Symfony/Bridge/Twig/Command/LintCommand.php
@@ -48,7 +48,7 @@ public function __construct(Environment $twig)
protected function configure()
{
$this
- ->setDescription('Lints a template and outputs encountered errors')
+ ->setDescription('Lint a template and outputs encountered errors')
->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt')
->addOption('show-deprecations', null, InputOption::VALUE_NONE, 'Show deprecations as errors')
->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN')
diff --git a/src/Symfony/Bridge/Twig/Mime/BodyRenderer.php b/src/Symfony/Bridge/Twig/Mime/BodyRenderer.php
index 5e75a69bb343f..166b3c195ff17 100644
--- a/src/Symfony/Bridge/Twig/Mime/BodyRenderer.php
+++ b/src/Symfony/Bridge/Twig/Mime/BodyRenderer.php
@@ -46,6 +46,14 @@ public function render(Message $message): void
}
$messageContext = $message->getContext();
+
+ $previousRenderingKey = $messageContext[__CLASS__] ?? null;
+ unset($messageContext[__CLASS__]);
+ $currentRenderingKey = $this->getFingerPrint($message);
+ if ($previousRenderingKey === $currentRenderingKey) {
+ return;
+ }
+
if (isset($messageContext['email'])) {
throw new InvalidArgumentException(sprintf('A "%s" context cannot have an "email" entry as this is a reserved variable.', \get_class($message)));
}
@@ -66,6 +74,24 @@ public function render(Message $message): void
if (!$message->getTextBody() && null !== $html = $message->getHtmlBody()) {
$message->text($this->convertHtmlToText(\is_resource($html) ? stream_get_contents($html) : $html));
}
+ $message->context($message->getContext() + [__CLASS__ => $currentRenderingKey]);
+ }
+
+ private function getFingerPrint(TemplatedEmail $message): string
+ {
+ $messageContext = $message->getContext();
+ unset($messageContext[__CLASS__]);
+
+ $payload = [$messageContext, $message->getTextTemplate(), $message->getHtmlTemplate()];
+ try {
+ $serialized = serialize($payload);
+ } catch (\Exception $e) {
+ // Serialization of 'Closure' is not allowed
+ // Happens when context contain a closure, in that case, we assume that context always change.
+ $serialized = random_bytes(8);
+ }
+
+ return md5($serialized);
}
private function convertHtmlToText(string $html): string
diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig
index 8ac32978a0925..7db2a0dadd3e3 100644
--- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig
+++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig
@@ -132,9 +132,15 @@
{% endblock %}
{% block form_widget_simple -%}
- {% if type is not defined or type != 'hidden' %}
- {%- set attr = attr|merge({class: (attr.class|default('') ~ (type|default('') == 'file' ? ' custom-file-input' : ' form-control'))|trim}) -%}
- {% endif %}
+ {%- if type is not defined or type != 'hidden' -%}
+ {%- set className = ' form-control' -%}
+ {%- if type|default('') == 'file' -%}
+ {%- set className = ' custom-file-input' -%}
+ {%- elseif type|default('') == 'range' -%}
+ {%- set className = ' form-control-range' -%}
+ {%- endif -%}
+ {%- set attr = attr|merge({class: (attr.class|default('') ~ className)|trim}) -%}
+ {%- endif -%}
{%- if type is defined and (type == 'range' or type == 'color') %}
{# Attribute "required" is not supported #}
{%- set required = false -%}
@@ -142,12 +148,12 @@
{{- parent() -}}
{%- endblock form_widget_simple %}
-{%- block widget_attributes -%}
- {%- if not valid %}
+{% block widget_attributes -%}
+ {%- if not valid -%}
{% set attr = attr|merge({class: (attr.class|default('') ~ ' is-invalid')|trim}) %}
- {% endif -%}
+ {%- endif -%}
{{ parent() }}
-{%- endblock widget_attributes -%}
+{%- endblock widget_attributes %}
{% block button_widget -%}
{%- set attr = attr|merge({class: (attr.class|default('btn-secondary') ~ ' btn')|trim}) -%}
diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4LayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4LayoutTest.php
index 2643274d47c3e..834de919edbb7 100644
--- a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4LayoutTest.php
+++ b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4LayoutTest.php
@@ -19,6 +19,7 @@
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Form\Extension\Core\Type\PercentType;
use Symfony\Component\Form\Extension\Core\Type\RadioType;
+use Symfony\Component\Form\Extension\Core\Type\RangeType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormError;
@@ -1194,6 +1195,41 @@ public function testPercentCustomSymbol()
[contains(.., "‱")]
]
]
+'
+ );
+ }
+
+ public function testRange()
+ {
+ $form = $this->factory->createNamed('name', RangeType::class, 42, ['attr' => ['min' => 5]]);
+
+ $this->assertWidgetMatchesXpath(
+ $form->createView(),
+ ['attr' => ['class' => 'my&class']],
+'/input
+ [@type="range"]
+ [@name="name"]
+ [@value="42"]
+ [@min="5"]
+ [@class="my&class form-control-range"]
+'
+ );
+ }
+
+ public function testRangeWithMinMaxValues()
+ {
+ $form = $this->factory->createNamed('name', RangeType::class, 42, ['attr' => ['min' => 5, 'max' => 57]]);
+
+ $this->assertWidgetMatchesXpath(
+ $form->createView(),
+ ['attr' => ['class' => 'my&class']],
+'/input
+ [@type="range"]
+ [@name="name"]
+ [@value="42"]
+ [@min="5"]
+ [@max="57"]
+ [@class="my&class form-control-range"]
'
);
}
diff --git a/src/Symfony/Bridge/Twig/Tests/Mime/BodyRendererTest.php b/src/Symfony/Bridge/Twig/Tests/Mime/BodyRendererTest.php
index 316d41c159989..8ff343b684b5e 100644
--- a/src/Symfony/Bridge/Twig/Tests/Mime/BodyRendererTest.php
+++ b/src/Symfony/Bridge/Twig/Tests/Mime/BodyRendererTest.php
@@ -79,6 +79,48 @@ public function testRenderWithContextReservedEmailEntry()
$this->prepareEmail('Text', '', ['email' => 'reserved!']);
}
+ public function testRenderedOnce()
+ {
+ $twig = new Environment(new ArrayLoader([
+ 'text' => 'Text',
+ ]));
+ $renderer = new BodyRenderer($twig);
+ $email = (new TemplatedEmail())
+ ->to('fabien@symfony.com')
+ ->from('helene@symfony.com')
+ ;
+ $email->textTemplate('text');
+
+ $renderer->render($email);
+ $this->assertEquals('Text', $email->getTextBody());
+
+ $email->text('reset');
+
+ $renderer->render($email);
+ $this->assertEquals('reset', $email->getTextBody());
+ }
+
+ public function testRenderedOnceUnserializableContext()
+ {
+ $twig = new Environment(new ArrayLoader([
+ 'text' => 'Text',
+ ]));
+ $renderer = new BodyRenderer($twig);
+ $email = (new TemplatedEmail())
+ ->to('fabien@symfony.com')
+ ->from('helene@symfony.com')
+ ;
+ $email->textTemplate('text');
+ $email->context([
+ 'foo' => static function () {
+ return 'bar';
+ },
+ ]);
+
+ $renderer->render($email);
+ $this->assertEquals('Text', $email->getTextBody());
+ }
+
private function prepareEmail(?string $text, ?string $html, array $context = []): TemplatedEmail
{
$twig = new Environment(new ArrayLoader([
diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json
index 6878052543bac..3fbb6b7eb4afd 100644
--- a/src/Symfony/Bridge/Twig/composer.json
+++ b/src/Symfony/Bridge/Twig/composer.json
@@ -21,7 +21,7 @@
"twig/twig": "^1.43|^2.13|^3.0.4"
},
"require-dev": {
- "egulias/email-validator": "^2.1.10",
+ "egulias/email-validator": "^2.1.10|^3",
"symfony/asset": "^3.4|^4.0|^5.0",
"symfony/dependency-injection": "^3.4|^4.0|^5.0",
"symfony/error-handler": "^4.4|^5.0",
@@ -45,9 +45,9 @@
"symfony/expression-language": "^3.4|^4.0|^5.0",
"symfony/web-link": "^4.4|^5.0",
"symfony/workflow": "^4.3|^5.0",
- "twig/cssinliner-extra": "^2.12",
- "twig/inky-extra": "^2.12",
- "twig/markdown-extra": "^2.12"
+ "twig/cssinliner-extra": "^2.12|^3",
+ "twig/inky-extra": "^2.12|^3",
+ "twig/markdown-extra": "^2.12|^3"
},
"conflict": {
"symfony/console": "<3.4",
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php
index b6e5c74a798bf..8c454cbded9b3 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php
@@ -37,7 +37,7 @@ class AboutCommand extends Command
protected function configure()
{
$this
- ->setDescription('Displays information about the current project')
+ ->setDescription('Display information about the current project')
->setHelp(<<<'EOT'
The %command.name% command displays information about the current Symfony project.
@@ -116,7 +116,9 @@ private static function formatFileSize(string $path): string
} else {
$size = 0;
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS | \RecursiveDirectoryIterator::FOLLOW_SYMLINKS)) as $file) {
- $size += $file->getSize();
+ if ($file->isReadable()) {
+ $size += $file->getSize();
+ }
}
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php
index 28ffd1ea8ba8b..f95907ddf5f1d 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php
@@ -65,10 +65,10 @@ protected function configure()
->setDefinition([
new InputArgument('target', InputArgument::OPTIONAL, 'The target directory', null),
])
- ->addOption('symlink', null, InputOption::VALUE_NONE, 'Symlinks the assets instead of copying it')
+ ->addOption('symlink', null, InputOption::VALUE_NONE, 'Symlink the assets instead of copying them')
->addOption('relative', null, InputOption::VALUE_NONE, 'Make relative symlinks')
->addOption('no-cleanup', null, InputOption::VALUE_NONE, 'Do not remove the assets of the bundles that no longer exist')
- ->setDescription('Installs bundles web assets under a public directory')
+ ->setDescription('Install bundle\'s web assets under a public directory')
->setHelp(<<<'EOT'
The %command.name% command installs bundle assets into a given
directory (e.g. the public directory).
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php
index 75836ce0b7f37..f2a9247e5f5a1 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php
@@ -57,7 +57,7 @@ protected function configure()
new InputOption('no-warmup', '', InputOption::VALUE_NONE, 'Do not warm up the cache'),
new InputOption('no-optional-warmers', '', InputOption::VALUE_NONE, 'Skip optional cache warmers (faster)'),
])
- ->setDescription('Clears the cache')
+ ->setDescription('Clear the cache')
->setHelp(<<<'EOF'
The %command.name% command clears the application cache for a given environment
and debug mode:
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/CachePoolClearCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/CachePoolClearCommand.php
index 50aacd9bbd73d..123617e58b189 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/CachePoolClearCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/CachePoolClearCommand.php
@@ -47,7 +47,7 @@ protected function configure()
->setDefinition([
new InputArgument('pools', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'A list of cache pools or cache pool clearers'),
])
- ->setDescription('Clears cache pools')
+ ->setDescription('Clear cache pools')
->setHelp(<<<'EOF'
The %command.name% command clears the given cache pools or cache pool clearers.
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/CachePoolDeleteCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/CachePoolDeleteCommand.php
index 2a7a2fe513040..922ec2dd7e94b 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/CachePoolDeleteCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/CachePoolDeleteCommand.php
@@ -46,7 +46,7 @@ protected function configure()
new InputArgument('pool', InputArgument::REQUIRED, 'The cache pool from which to delete an item'),
new InputArgument('key', InputArgument::REQUIRED, 'The cache key to delete from the pool'),
])
- ->setDescription('Deletes an item from a cache pool')
+ ->setDescription('Delete an item from a cache pool')
->setHelp(<<<'EOF'
The %command.name% deletes an item from a given cache pool.
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/CachePoolPruneCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/CachePoolPruneCommand.php
index 65f3ff6b5802e..fb9af73064cb4 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/CachePoolPruneCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/CachePoolPruneCommand.php
@@ -44,7 +44,7 @@ public function __construct(iterable $pools)
protected function configure()
{
$this
- ->setDescription('Prunes cache pools')
+ ->setDescription('Prune cache pools')
->setHelp(<<<'EOF'
The %command.name% command deletes all expired items from all pruneable pools.
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/CacheWarmupCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/CacheWarmupCommand.php
index 0a87acf264191..33a214ea01aa5 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/CacheWarmupCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/CacheWarmupCommand.php
@@ -47,7 +47,7 @@ protected function configure()
->setDefinition([
new InputOption('no-optional-warmers', '', InputOption::VALUE_NONE, 'Skip optional cache warmers (faster)'),
])
- ->setDescription('Warms up an empty cache')
+ ->setDescription('Warm up an empty cache')
->setHelp(<<<'EOF'
The %command.name% command warms up the cache.
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php
index ef4d0fb51ab16..7f0a7813a8ddd 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php
@@ -41,7 +41,7 @@ protected function configure()
new InputArgument('name', InputArgument::OPTIONAL, 'The bundle name or the extension alias'),
new InputArgument('path', InputArgument::OPTIONAL, 'The configuration option path'),
])
- ->setDescription('Dumps the current configuration for an extension')
+ ->setDescription('Dump the current configuration for an extension')
->setHelp(<<<'EOF'
The %command.name% command dumps the current configuration for an
extension/bundle.
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php
index 60445e40631ef..17690f7c99401 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php
@@ -44,7 +44,7 @@ protected function configure()
new InputArgument('path', InputArgument::OPTIONAL, 'The configuration option path'),
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (yaml or xml)', 'yaml'),
])
- ->setDescription('Dumps the default configuration for an extension')
+ ->setDescription('Dump the default configuration for an extension')
->setHelp(<<<'EOF'
The %command.name% command dumps the default configuration for an
extension/bundle.
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php
index 15890e96a7f38..668205287097c 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php
@@ -51,20 +51,20 @@ protected function configure()
$this
->setDefinition([
new InputArgument('name', InputArgument::OPTIONAL, 'A service name (foo)'),
- new InputOption('show-private', null, InputOption::VALUE_NONE, 'Used to show public *and* private services (deprecated)'),
- new InputOption('show-arguments', null, InputOption::VALUE_NONE, 'Used to show arguments in services'),
- new InputOption('show-hidden', null, InputOption::VALUE_NONE, 'Used to show hidden (internal) services'),
- new InputOption('tag', null, InputOption::VALUE_REQUIRED, 'Shows all services with a specific tag'),
- new InputOption('tags', null, InputOption::VALUE_NONE, 'Displays tagged services for an application'),
- new InputOption('parameter', null, InputOption::VALUE_REQUIRED, 'Displays a specific parameter for an application'),
- new InputOption('parameters', null, InputOption::VALUE_NONE, 'Displays parameters for an application'),
- new InputOption('types', null, InputOption::VALUE_NONE, 'Displays types (classes/interfaces) available in the container'),
- new InputOption('env-var', null, InputOption::VALUE_REQUIRED, 'Displays a specific environment variable used in the container'),
- new InputOption('env-vars', null, InputOption::VALUE_NONE, 'Displays environment variables used in the container'),
+ new InputOption('show-private', null, InputOption::VALUE_NONE, 'Show public *and* private services (deprecated)'),
+ new InputOption('show-arguments', null, InputOption::VALUE_NONE, 'Show arguments in services'),
+ new InputOption('show-hidden', null, InputOption::VALUE_NONE, 'Show hidden (internal) services'),
+ new InputOption('tag', null, InputOption::VALUE_REQUIRED, 'Show all services with a specific tag'),
+ new InputOption('tags', null, InputOption::VALUE_NONE, 'Display tagged services for an application'),
+ new InputOption('parameter', null, InputOption::VALUE_REQUIRED, 'Display a specific parameter for an application'),
+ new InputOption('parameters', null, InputOption::VALUE_NONE, 'Display parameters for an application'),
+ new InputOption('types', null, InputOption::VALUE_NONE, 'Display types (classes/interfaces) available in the container'),
+ new InputOption('env-var', null, InputOption::VALUE_REQUIRED, 'Display a specific environment variable used in the container'),
+ new InputOption('env-vars', null, InputOption::VALUE_NONE, 'Display environment variables used in the container'),
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw description'),
])
- ->setDescription('Displays current services for an application')
+ ->setDescription('Display current services for an application')
->setHelp(<<<'EOF'
The %command.name% command displays all configured public services:
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerLintCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerLintCommand.php
index 290f1da5e3af7..e89a1273c3407 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerLintCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerLintCommand.php
@@ -41,7 +41,7 @@ final class ContainerLintCommand extends Command
protected function configure()
{
$this
- ->setDescription('Ensures that arguments injected into services match type declarations')
+ ->setDescription('Ensure that arguments injected into services match type declarations')
->setHelp('This command parses service definitions and ensures that injected values match the type declarations of each services\' class.')
;
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/DebugAutowiringCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/DebugAutowiringCommand.php
index 32bd630f32516..79ac2dd8f8c98 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/DebugAutowiringCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/DebugAutowiringCommand.php
@@ -50,7 +50,7 @@ protected function configure()
new InputArgument('search', InputArgument::OPTIONAL, 'A search filter'),
new InputOption('all', null, InputOption::VALUE_NONE, 'Show also services that are not aliased'),
])
- ->setDescription('Lists classes/interfaces you can use for autowiring')
+ ->setDescription('List classes/interfaces you can use for autowiring')
->setHelp(<<<'EOF'
The %command.name% command displays the classes and interfaces that
you can use as type-hints for autowiring:
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php
index ad49cdeeaa87f..fd0a1ccb800e7 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php
@@ -50,7 +50,7 @@ protected function configure()
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw description'),
])
- ->setDescription('Displays configured listeners for an application')
+ ->setDescription('Display configured listeners for an application')
->setHelp(<<<'EOF'
The %command.name% command displays all configured listeners:
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php
index 9724e5122e2c6..22cac5256bbc2 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php
@@ -57,7 +57,7 @@ protected function configure()
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw route(s)'),
])
- ->setDescription('Displays current routes for an application')
+ ->setDescription('Display current routes for an application')
->setHelp(<<<'EOF'
The %command.name% displays the configured routes:
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/RouterMatchCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/RouterMatchCommand.php
index 454767e6a8023..8dd5b545b40c9 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/RouterMatchCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/RouterMatchCommand.php
@@ -49,11 +49,11 @@ protected function configure()
$this
->setDefinition([
new InputArgument('path_info', InputArgument::REQUIRED, 'A path info'),
- new InputOption('method', null, InputOption::VALUE_REQUIRED, 'Sets the HTTP method'),
- new InputOption('scheme', null, InputOption::VALUE_REQUIRED, 'Sets the URI scheme (usually http or https)'),
- new InputOption('host', null, InputOption::VALUE_REQUIRED, 'Sets the URI host'),
+ new InputOption('method', null, InputOption::VALUE_REQUIRED, 'Set the HTTP method'),
+ new InputOption('scheme', null, InputOption::VALUE_REQUIRED, 'Set the URI scheme (usually http or https)'),
+ new InputOption('host', null, InputOption::VALUE_REQUIRED, 'Set the URI host'),
])
- ->setDescription('Helps debug routes by simulating a path info match')
+ ->setDescription('Help debug routes by simulating a path info match')
->setHelp(<<<'EOF'
The %command.name% shows which routes match a given request and which don't and for what reason:
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/SecretsDecryptToLocalCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/SecretsDecryptToLocalCommand.php
index e4fbfd287edee..1d3a96e982c25 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/SecretsDecryptToLocalCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/SecretsDecryptToLocalCommand.php
@@ -42,8 +42,8 @@ public function __construct(AbstractVault $vault, AbstractVault $localVault = nu
protected function configure()
{
$this
- ->setDescription('Decrypts all secrets and stores them in the local vault.')
- ->addOption('force', 'f', InputOption::VALUE_NONE, 'Forces overriding of secrets that already exist in the local vault')
+ ->setDescription('Decrypt all secrets and stores them in the local vault.')
+ ->addOption('force', 'f', InputOption::VALUE_NONE, 'Force overriding of secrets that already exist in the local vault')
->setHelp(<<<'EOF'
The %command.name% command decrypts all secrets and copies them in the local vault.
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/SecretsEncryptFromLocalCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/SecretsEncryptFromLocalCommand.php
index 607140e616486..14e7c51e6df53 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/SecretsEncryptFromLocalCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/SecretsEncryptFromLocalCommand.php
@@ -41,7 +41,7 @@ public function __construct(AbstractVault $vault, AbstractVault $localVault = nu
protected function configure()
{
$this
- ->setDescription('Encrypts all local secrets to the vault.')
+ ->setDescription('Encrypt all local secrets to the vault.')
->setHelp(<<<'EOF'
The %command.name% command encrypts all locally overridden secrets to the vault.
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/SecretsGenerateKeysCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/SecretsGenerateKeysCommand.php
index f56fd0fe6c5e1..f0497815627cd 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/SecretsGenerateKeysCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/SecretsGenerateKeysCommand.php
@@ -44,9 +44,9 @@ public function __construct(AbstractVault $vault, AbstractVault $localVault = nu
protected function configure()
{
$this
- ->setDescription('Generates new encryption keys.')
- ->addOption('local', 'l', InputOption::VALUE_NONE, 'Updates the local vault.')
- ->addOption('rotate', 'r', InputOption::VALUE_NONE, 'Re-encrypts existing secrets with the newly generated keys.')
+ ->setDescription('Generate new encryption keys.')
+ ->addOption('local', 'l', InputOption::VALUE_NONE, 'Update the local vault.')
+ ->addOption('rotate', 'r', InputOption::VALUE_NONE, 'Re-encrypt existing secrets with the newly generated keys.')
->setHelp(<<<'EOF'
The %command.name% command generates a new encryption key.
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/SecretsListCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/SecretsListCommand.php
index 1210b40ee0b6a..4586677f785df 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/SecretsListCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/SecretsListCommand.php
@@ -45,7 +45,7 @@ public function __construct(AbstractVault $vault, AbstractVault $localVault = nu
protected function configure()
{
$this
- ->setDescription('Lists all secrets.')
+ ->setDescription('List all secrets.')
->addOption('reveal', 'r', InputOption::VALUE_NONE, 'Display decrypted values alongside names')
->setHelp(<<<'EOF'
The %command.name% command list all stored secrets.
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/SecretsRemoveCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/SecretsRemoveCommand.php
index b0ce9a89fedfb..f4c40a8fdec8c 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/SecretsRemoveCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/SecretsRemoveCommand.php
@@ -44,9 +44,9 @@ public function __construct(AbstractVault $vault, AbstractVault $localVault = nu
protected function configure()
{
$this
- ->setDescription('Removes a secret from the vault.')
+ ->setDescription('Remove a secret from the vault.')
->addArgument('name', InputArgument::REQUIRED, 'The name of the secret')
- ->addOption('local', 'l', InputOption::VALUE_NONE, 'Updates the local vault.')
+ ->addOption('local', 'l', InputOption::VALUE_NONE, 'Update the local vault.')
->setHelp(<<<'EOF'
The %command.name% command removes a secret from the vault.
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/SecretsSetCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/SecretsSetCommand.php
index 91e0031299c3b..ad7559d3f7ce3 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/SecretsSetCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/SecretsSetCommand.php
@@ -45,11 +45,11 @@ public function __construct(AbstractVault $vault, AbstractVault $localVault = nu
protected function configure()
{
$this
- ->setDescription('Sets a secret in the vault.')
+ ->setDescription('Set a secret in the vault.')
->addArgument('name', InputArgument::REQUIRED, 'The name of the secret')
->addArgument('file', InputArgument::OPTIONAL, 'A file where to read the secret from or "-" for reading from STDIN')
- ->addOption('local', 'l', InputOption::VALUE_NONE, 'Updates the local vault.')
- ->addOption('random', 'r', InputOption::VALUE_OPTIONAL, 'Generates a random value.', false)
+ ->addOption('local', 'l', InputOption::VALUE_NONE, 'Update the local vault.')
+ ->addOption('random', 'r', InputOption::VALUE_OPTIONAL, 'Generate a random value.', false)
->setHelp(<<<'EOF'
The %command.name% command stores a secret in the vault.
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php
index fa20154cf653e..984c72e59f795 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php
@@ -82,11 +82,11 @@ protected function configure()
new InputArgument('locale', InputArgument::REQUIRED, 'The locale'),
new InputArgument('bundle', InputArgument::OPTIONAL, 'The bundle name or directory where to load the messages'),
new InputOption('domain', null, InputOption::VALUE_OPTIONAL, 'The messages domain'),
- new InputOption('only-missing', null, InputOption::VALUE_NONE, 'Displays only missing messages'),
- new InputOption('only-unused', null, InputOption::VALUE_NONE, 'Displays only unused messages'),
+ new InputOption('only-missing', null, InputOption::VALUE_NONE, 'Display only missing messages'),
+ new InputOption('only-unused', null, InputOption::VALUE_NONE, 'Display only unused messages'),
new InputOption('all', null, InputOption::VALUE_NONE, 'Load messages from all registered bundles'),
])
- ->setDescription('Displays translation messages information')
+ ->setDescription('Display translation messages information')
->setHelp(<<<'EOF'
The %command.name% command helps finding unused or missing translation
messages and comparing them with the fallback ones by inspecting the
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php
index e922398b28cc0..1004ae7899dc6 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php
@@ -85,7 +85,7 @@ protected function configure()
new InputOption('xliff-version', null, InputOption::VALUE_OPTIONAL, 'Override the default xliff version', '1.2'),
new InputOption('sort', null, InputOption::VALUE_OPTIONAL, 'Return list of messages sorted alphabetically', 'asc'),
])
- ->setDescription('Updates the translation file')
+ ->setDescription('Update the translation file')
->setHelp(<<<'EOF'
The %command.name% command extracts translation strings from templates
of a given bundle or the default translations directory. It can display them or merge
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php
index cec930da1c0da..ecdca7cb39452 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php
@@ -40,7 +40,7 @@ protected function configure()
->setDefinition([
new InputArgument('name', InputArgument::REQUIRED, 'A workflow name'),
new InputArgument('marking', InputArgument::IS_ARRAY, 'A marking (a list of places)'),
- new InputOption('label', 'l', InputOption::VALUE_REQUIRED, 'Labels a graph'),
+ new InputOption('label', 'l', InputOption::VALUE_REQUIRED, 'Label a graph'),
new InputOption('dump-format', null, InputOption::VALUE_REQUIRED, 'The dump format [dot|puml]', 'dot'),
])
->setDescription('Dump a workflow')
diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php
index a5d00cdcec5b9..99516b5c3fac6 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php
@@ -207,7 +207,7 @@ protected function denyAccessUnlessGranted($attributes, $subject = null, string
*/
protected function renderView(string $view, array $parameters = []): string
{
- if ($this->container->has('templating')) {
+ if ($this->container->has('templating') && $this->container->get('templating')->supports($view)) {
@trigger_error('Using the "templating" service is deprecated since version 4.3 and will be removed in 5.0; use Twig instead.', \E_USER_DEPRECATED);
return $this->container->get('templating')->render($view, $parameters);
@@ -227,7 +227,7 @@ protected function renderView(string $view, array $parameters = []): string
*/
protected function render(string $view, array $parameters = [], Response $response = null): Response
{
- if ($this->container->has('templating')) {
+ if ($this->container->has('templating') && $this->container->get('templating')->supports($view)) {
@trigger_error('Using the "templating" service is deprecated since version 4.3 and will be removed in 5.0; use Twig instead.', \E_USER_DEPRECATED);
$content = $this->container->get('templating')->render($view, $parameters);
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index 9d46e259fd263..d1a3cfbdd5cdf 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -1983,7 +1983,7 @@ private function registerCacheConfiguration(array $config, ContainerBuilder $con
if (!$container->getParameter('kernel.debug')) {
$propertyAccessDefinition->setFactory([PropertyAccessor::class, 'createCache']);
- $propertyAccessDefinition->setArguments([null, 0, $version, new Reference('logger', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)]);
+ $propertyAccessDefinition->setArguments(['', 0, $version, new Reference('logger', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)]);
$propertyAccessDefinition->addTag('cache.pool', ['clearer' => 'cache.system_clearer']);
$propertyAccessDefinition->addTag('monolog.logger', ['channel' => 'cache']);
} else {
diff --git a/src/Symfony/Bundle/FrameworkBundle/EventListener/ResolveControllerNameSubscriber.php b/src/Symfony/Bundle/FrameworkBundle/EventListener/ResolveControllerNameSubscriber.php
index 5d5a416ababf7..1cd2abef4d0c8 100644
--- a/src/Symfony/Bundle/FrameworkBundle/EventListener/ResolveControllerNameSubscriber.php
+++ b/src/Symfony/Bundle/FrameworkBundle/EventListener/ResolveControllerNameSubscriber.php
@@ -48,7 +48,7 @@ public function resolveControllerName(...$args)
public function __call(string $method, array $args)
{
- if ('onKernelRequest' !== $method && 'onKernelRequest' !== strtolower($method)) {
+ if ('onKernelRequest' !== $method && 'onkernelrequest' !== strtolower($method)) {
throw new \Error(sprintf('Error: Call to undefined method "%s::%s()".', static::class, $method));
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/AboutCommand/AboutCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/AboutCommand/AboutCommandTest.php
new file mode 100644
index 0000000000000..8a1fcf93caabd
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/AboutCommand/AboutCommandTest.php
@@ -0,0 +1,90 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\FrameworkBundle\Tests\Command\AboutCommand;
+
+use Symfony\Bundle\FrameworkBundle\Command\AboutCommand;
+use Symfony\Bundle\FrameworkBundle\Console\Application;
+use Symfony\Bundle\FrameworkBundle\Tests\Command\AboutCommand\Fixture\TestAppKernel;
+use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
+use Symfony\Component\Console\Tester\CommandTester;
+use Symfony\Component\Filesystem\Exception\IOException;
+use Symfony\Component\Filesystem\Filesystem;
+
+class AboutCommandTest extends TestCase
+{
+ /** @var Filesystem */
+ private $fs;
+
+ protected function setUp(): void
+ {
+ $this->fs = new Filesystem();
+ }
+
+ public function testAboutWithReadableFiles()
+ {
+ $kernel = new TestAppKernel('test', true);
+ $this->fs->mkdir($kernel->getProjectDir());
+
+ $this->fs->dumpFile($kernel->getCacheDir().'/readable_file', 'The file content.');
+ $this->fs->chmod($kernel->getCacheDir().'/readable_file', 0777);
+
+ $tester = $this->createCommandTester($kernel);
+ $ret = $tester->execute([]);
+
+ $this->assertSame(0, $ret);
+ $this->assertStringContainsString('Cache directory', $tester->getDisplay());
+ $this->assertStringContainsString('Log directory', $tester->getDisplay());
+
+ $this->fs->chmod($kernel->getCacheDir().'/readable_file', 0777);
+
+ try {
+ $this->fs->remove($kernel->getProjectDir());
+ } catch (IOException $e) {
+ }
+ }
+
+ public function testAboutWithUnreadableFiles()
+ {
+ $kernel = new TestAppKernel('test', true);
+ $this->fs->mkdir($kernel->getProjectDir());
+
+ // skip test on Windows; PHP can't easily set file as unreadable on Windows
+ if ('\\' === \DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('This test cannot run on Windows.');
+ }
+
+ $this->fs->dumpFile($kernel->getCacheDir().'/unreadable_file', 'The file content.');
+ $this->fs->chmod($kernel->getCacheDir().'/unreadable_file', 0222);
+
+ $tester = $this->createCommandTester($kernel);
+ $ret = $tester->execute([]);
+
+ $this->assertSame(0, $ret);
+ $this->assertStringContainsString('Cache directory', $tester->getDisplay());
+ $this->assertStringContainsString('Log directory', $tester->getDisplay());
+
+ $this->fs->chmod($kernel->getCacheDir().'/unreadable_file', 0777);
+
+ try {
+ $this->fs->remove($kernel->getProjectDir());
+ } catch (IOException $e) {
+ }
+ }
+
+ private function createCommandTester(TestAppKernel $kernel): CommandTester
+ {
+ $application = new Application($kernel);
+ $application->add(new AboutCommand());
+
+ return new CommandTester($application->find('about'));
+ }
+}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/AboutCommand/Fixture/TestAppKernel.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/AboutCommand/Fixture/TestAppKernel.php
new file mode 100644
index 0000000000000..c15bf83cb1cf8
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/AboutCommand/Fixture/TestAppKernel.php
@@ -0,0 +1,40 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\FrameworkBundle\Tests\Command\AboutCommand\Fixture;
+
+use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
+use Symfony\Component\Config\Loader\LoaderInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\HttpKernel\Kernel;
+
+class TestAppKernel extends Kernel
+{
+ public function registerBundles(): iterable
+ {
+ return [
+ new FrameworkBundle(),
+ ];
+ }
+
+ public function getProjectDir(): string
+ {
+ return __DIR__.'/test';
+ }
+
+ public function registerContainerConfiguration(LoaderInterface $loader)
+ {
+ }
+
+ protected function build(ContainerBuilder $container)
+ {
+ }
+}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/ApplicationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/ApplicationTest.php
index f7c66c50d0fc9..447d2afb04125 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/ApplicationTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/ApplicationTest.php
@@ -229,7 +229,7 @@ public function testRunOnlyWarnsOnUnregistrableCommandAtTheEnd()
$tester->run(['command' => 'list']);
$this->assertSame(0, $tester->getStatusCode());
- $display = explode('Lists commands', $tester->getDisplay());
+ $display = explode('List commands', $tester->getDisplay());
$this->assertStringContainsString(trim('[WARNING] Some commands could not be registered:'), trim($display[1]));
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php
index a5392b0cc0e82..00007aee3af4a 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php
@@ -449,6 +449,7 @@ public function testRenderViewTemplating()
{
$templating = $this->createMock(EngineInterface::class);
$templating->expects($this->once())->method('render')->willReturn('bar');
+ $templating->expects($this->once())->method('supports')->willReturn(true);
$container = new Container();
$container->set('templating', $templating);
@@ -466,6 +467,7 @@ public function testRenderTemplating()
{
$templating = $this->createMock(EngineInterface::class);
$templating->expects($this->once())->method('render')->willReturn('bar');
+ $templating->expects($this->once())->method('supports')->willReturn(true);
$container = new Container();
$container->set('templating', $templating);
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
index db26edcfedebf..5e11db81026f4 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
@@ -1723,7 +1723,7 @@ protected function createContainerFromFile($file, $data = [], $resetCompilerPass
$container->getCompilerPassConfig()->setAfterRemovingPasses([]);
}
$container->getCompilerPassConfig()->setBeforeOptimizationPasses([new LoggerPass()]);
- $container->getCompilerPassConfig()->setBeforeRemovingPasses([new AddConstraintValidatorsPass(), new TranslatorPass('translator.default', 'translation.reader')]);
+ $container->getCompilerPassConfig()->setBeforeRemovingPasses([new AddConstraintValidatorsPass(), new TranslatorPass()]);
$container->getCompilerPassConfig()->setAfterRemovingPasses([new AddAnnotationsCachedReaderPass()]);
if (!$compile) {
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/CachePools/bundles.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/CachePools/bundles.php
index 15ff182c6fed5..2e46e896bca7c 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/CachePools/bundles.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/CachePools/bundles.php
@@ -14,5 +14,4 @@
return [
new FrameworkBundle(),
- new TestBundle(),
];
diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json
index f592065b28cd7..f26298324f1e4 100644
--- a/src/Symfony/Bundle/FrameworkBundle/composer.json
+++ b/src/Symfony/Bundle/FrameworkBundle/composer.json
@@ -36,7 +36,7 @@
"paragonie/sodium_compat": "^1.8",
"symfony/asset": "^3.4|^4.0|^5.0",
"symfony/browser-kit": "^4.3|^5.0",
- "symfony/console": "^4.3.4|^5.0",
+ "symfony/console": "^4.4.21|^5.0",
"symfony/css-selector": "^3.4|^4.0|^5.0",
"symfony/dom-crawler": "^4.3|^5.0",
"symfony/dotenv": "^4.3.6|^5.0",
@@ -72,7 +72,7 @@
"phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0",
"symfony/asset": "<3.4",
"symfony/browser-kit": "<4.3",
- "symfony/console": "<4.3",
+ "symfony/console": "<4.4.21",
"symfony/dotenv": "<4.3.6",
"symfony/dom-crawler": "<4.3",
"symfony/http-client": "<4.4",
diff --git a/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php b/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php
index efa9d0edcad14..b13ebbf33294c 100644
--- a/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php
+++ b/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php
@@ -52,7 +52,7 @@ public function __construct(EncoderFactoryInterface $encoderFactory, array $user
protected function configure()
{
$this
- ->setDescription('Encodes a password.')
+ ->setDescription('Encode a password.')
->addArgument('password', InputArgument::OPTIONAL, 'The plain password to encode.')
->addArgument('user-class', InputArgument::OPTIONAL, 'The User entity class path associated with the encoder used to encode the password.')
->addOption('empty-salt', null, InputOption::VALUE_NONE, 'Do not generate a salt or let the encoder generate one.')
diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php
index 70fcd16b96c44..153028165c987 100644
--- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php
+++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php
@@ -69,7 +69,12 @@ public function create(ContainerBuilder $container, $id, $config, $userProvider,
}
// remember-me options
- $rememberMeServices->replaceArgument(3, array_intersect_key($config, $this->options));
+ $mergedOptions = array_intersect_key($config, $this->options);
+ if ('auto' === $mergedOptions['secure']) {
+ $mergedOptions['secure'] = null;
+ }
+
+ $rememberMeServices->replaceArgument(3, $mergedOptions);
// attach to remember-me aware listeners
$userProviders = [];
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/RememberMeCookieTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/RememberMeCookieTest.php
new file mode 100644
index 0000000000000..6bfa1ed438732
--- /dev/null
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/RememberMeCookieTest.php
@@ -0,0 +1,33 @@
+createClient(['test_case' => 'RememberMeCookie', 'root_config' => 'config.yml']);
+
+ $client->request('POST', '/login', [
+ '_username' => 'test',
+ '_password' => 'test',
+ ], [], [
+ 'HTTPS' => (int) $https,
+ ]);
+
+ $cookies = $client->getResponse()->headers->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
+
+ $this->assertEquals($expectedSecureFlag, $cookies['']['/']['REMEMBERME']->isSecure());
+ }
+
+ public function getSessionRememberMeSecureCookieFlagAutoHttpsMap()
+ {
+ return [
+ [true, true],
+ [false, false],
+ ];
+ }
+}
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeCookie/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeCookie/bundles.php
new file mode 100644
index 0000000000000..8d4a02497947a
--- /dev/null
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeCookie/bundles.php
@@ -0,0 +1,9 @@
+ a:hover {
display: block;
text-decoration: none;
+ background-color: transparent;
color: inherit;
}
@@ -238,6 +239,7 @@ div.sf-toolbar .sf-toolbar-block a:hover {
padding: 0 10px;
}
.sf-toolbar-block-request .sf-toolbar-info-piece a {
+ background-color: transparent;
text-decoration: none;
}
.sf-toolbar-block-request .sf-toolbar-info-piece a:hover {
diff --git a/src/Symfony/Bundle/WebServerBundle/Command/ServerLogCommand.php b/src/Symfony/Bundle/WebServerBundle/Command/ServerLogCommand.php
index 10d06ddf5a952..b21368a4f99df 100644
--- a/src/Symfony/Bundle/WebServerBundle/Command/ServerLogCommand.php
+++ b/src/Symfony/Bundle/WebServerBundle/Command/ServerLogCommand.php
@@ -62,7 +62,7 @@ protected function configure()
->addOption('format', null, InputOption::VALUE_REQUIRED, 'The line format', ConsoleFormatter::SIMPLE_FORMAT)
->addOption('date-format', null, InputOption::VALUE_REQUIRED, 'The date format', ConsoleFormatter::SIMPLE_DATE)
->addOption('filter', null, InputOption::VALUE_REQUIRED, 'An expression to filter log. Example: "level > 200 or channel in [\'app\', \'doctrine\']"')
- ->setDescription('Starts a log server that displays logs in real time')
+ ->setDescription('Start a log server that displays logs in real time')
->setHelp(<<<'EOF'
%command.name% starts a log server to display in real time the log
messages generated by your application:
diff --git a/src/Symfony/Bundle/WebServerBundle/Command/ServerRunCommand.php b/src/Symfony/Bundle/WebServerBundle/Command/ServerRunCommand.php
index 041c38ac0d30c..cd135385c822e 100644
--- a/src/Symfony/Bundle/WebServerBundle/Command/ServerRunCommand.php
+++ b/src/Symfony/Bundle/WebServerBundle/Command/ServerRunCommand.php
@@ -57,7 +57,7 @@ protected function configure()
new InputOption('docroot', 'd', InputOption::VALUE_REQUIRED, 'Document root, usually where your front controllers are stored'),
new InputOption('router', 'r', InputOption::VALUE_REQUIRED, 'Path to custom router script'),
])
- ->setDescription('Runs a local web server')
+ ->setDescription('Run a local web server')
->setHelp(<<<'EOF'
%command.name% runs a local web server: By default, the server
listens on 127.0.0.1> address and the port number is automatically selected
diff --git a/src/Symfony/Bundle/WebServerBundle/Command/ServerStartCommand.php b/src/Symfony/Bundle/WebServerBundle/Command/ServerStartCommand.php
index ef21baa961310..673b7b3179a34 100644
--- a/src/Symfony/Bundle/WebServerBundle/Command/ServerStartCommand.php
+++ b/src/Symfony/Bundle/WebServerBundle/Command/ServerStartCommand.php
@@ -58,7 +58,7 @@ protected function configure()
new InputOption('router', 'r', InputOption::VALUE_REQUIRED, 'Path to custom router script'),
new InputOption('pidfile', null, InputOption::VALUE_REQUIRED, 'PID file'),
])
- ->setDescription('Starts a local web server in the background')
+ ->setDescription('Start a local web server in the background')
->setHelp(<<<'EOF'
%command.name% runs a local web server: By default, the server
listens on 127.0.0.1> address and the port number is automatically selected
diff --git a/src/Symfony/Bundle/WebServerBundle/Command/ServerStatusCommand.php b/src/Symfony/Bundle/WebServerBundle/Command/ServerStatusCommand.php
index 19659d6ff01a2..9cf9501a9b9e2 100644
--- a/src/Symfony/Bundle/WebServerBundle/Command/ServerStatusCommand.php
+++ b/src/Symfony/Bundle/WebServerBundle/Command/ServerStatusCommand.php
@@ -51,7 +51,7 @@ protected function configure()
new InputOption('pidfile', null, InputOption::VALUE_REQUIRED, 'PID file'),
new InputOption('filter', null, InputOption::VALUE_REQUIRED, 'The value to display (one of port, host, or address)'),
])
- ->setDescription('Outputs the status of the local web server')
+ ->setDescription('Output the status of the local web server')
->setHelp(<<<'EOF'
%command.name% shows the details of the given local web
server, such as the address and port where it is listening to:
diff --git a/src/Symfony/Bundle/WebServerBundle/Command/ServerStopCommand.php b/src/Symfony/Bundle/WebServerBundle/Command/ServerStopCommand.php
index 50b53dde20811..81c1fdf06d11e 100644
--- a/src/Symfony/Bundle/WebServerBundle/Command/ServerStopCommand.php
+++ b/src/Symfony/Bundle/WebServerBundle/Command/ServerStopCommand.php
@@ -48,7 +48,7 @@ protected function configure()
->setDefinition([
new InputOption('pidfile', null, InputOption::VALUE_REQUIRED, 'PID file'),
])
- ->setDescription('Stops the local web server that was started with the server:start command')
+ ->setDescription('Stop the local web server that was started with the server:start command')
->setHelp(<<<'EOF'
%command.name% stops the local web server:
diff --git a/src/Symfony/Component/Cache/Tests/DataCollector/CacheDataCollectorTest.php b/src/Symfony/Component/Cache/Tests/DataCollector/CacheDataCollectorTest.php
index f704bbfe0e49f..6aa94c2c63383 100644
--- a/src/Symfony/Component/Cache/Tests/DataCollector/CacheDataCollectorTest.php
+++ b/src/Symfony/Component/Cache/Tests/DataCollector/CacheDataCollectorTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Cache\Tests\Marshaller;
+namespace Symfony\Component\Cache\Tests\DataCollector;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Cache\Adapter\TraceableAdapter;
diff --git a/src/Symfony/Component/Console/Command/Command.php b/src/Symfony/Component/Console/Command/Command.php
index 71ad4a49e9e3e..d4ab2eb8df3da 100644
--- a/src/Symfony/Component/Console/Command/Command.php
+++ b/src/Symfony/Component/Console/Command/Command.php
@@ -394,11 +394,11 @@ public function addArgument($name, $mode = null, $description = '', $default = n
/**
* Adds an option.
*
- * @param string $name The option name
- * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
- * @param int|null $mode The option mode: One of the InputOption::VALUE_* constants
- * @param string $description A description text
- * @param string|string[]|int|bool|null $default The default value (must be null for InputOption::VALUE_NONE)
+ * @param string $name The option name
+ * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
+ * @param int|null $mode The option mode: One of the InputOption::VALUE_* constants
+ * @param string $description A description text
+ * @param string|string[]|bool|null $default The default value (must be null for InputOption::VALUE_NONE)
*
* @throws InvalidArgumentException If option mode is invalid or incompatible
*
diff --git a/src/Symfony/Component/Console/Command/HelpCommand.php b/src/Symfony/Component/Console/Command/HelpCommand.php
index b32be4c95cce4..cece7829993e7 100644
--- a/src/Symfony/Component/Console/Command/HelpCommand.php
+++ b/src/Symfony/Component/Console/Command/HelpCommand.php
@@ -40,7 +40,7 @@ protected function configure()
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help'),
])
- ->setDescription('Displays help for a command')
+ ->setDescription('Display help for a command')
->setHelp(<<<'EOF'
The %command.name% command displays help for a given command:
diff --git a/src/Symfony/Component/Console/Command/ListCommand.php b/src/Symfony/Component/Console/Command/ListCommand.php
index 8af952652872a..44324a5e7ff9c 100644
--- a/src/Symfony/Component/Console/Command/ListCommand.php
+++ b/src/Symfony/Component/Console/Command/ListCommand.php
@@ -33,7 +33,7 @@ protected function configure()
$this
->setName('list')
->setDefinition($this->createDefinition())
- ->setDescription('Lists commands')
+ ->setDescription('List commands')
->setHelp(<<<'EOF'
The %command.name% command lists all commands:
diff --git a/src/Symfony/Component/Console/Helper/ProgressBar.php b/src/Symfony/Component/Console/Helper/ProgressBar.php
index 4690cffbdc92c..5049c7dae0636 100644
--- a/src/Symfony/Component/Console/Helper/ProgressBar.php
+++ b/src/Symfony/Component/Console/Helper/ProgressBar.php
@@ -441,8 +441,15 @@ private function overwrite(string $message): void
if ($this->overwrite) {
if (null !== $this->previousMessage) {
if ($this->output instanceof ConsoleSectionOutput) {
- $lines = floor(Helper::strlen($message) / $this->terminal->getWidth()) + $this->formatLineCount + 1;
- $this->output->clear($lines);
+ $messageLines = explode("\n", $message);
+ $lineCount = \count($messageLines);
+ foreach ($messageLines as $messageLine) {
+ $messageLineLength = Helper::strlenWithoutDecoration($this->output->getFormatter(), $messageLine);
+ if ($messageLineLength > $this->terminal->getWidth()) {
+ $lineCount += floor($messageLineLength / $this->terminal->getWidth());
+ }
+ }
+ $this->output->clear($lineCount);
} else {
// Erase previous lines
if ($this->formatLineCount > 0) {
diff --git a/src/Symfony/Component/Console/Helper/QuestionHelper.php b/src/Symfony/Component/Console/Helper/QuestionHelper.php
index d211fcfd1e6ec..6dde580cf6214 100644
--- a/src/Symfony/Component/Console/Helper/QuestionHelper.php
+++ b/src/Symfony/Component/Console/Helper/QuestionHelper.php
@@ -309,7 +309,7 @@ private function autocomplete(OutputInterface $output, Question $question, $inpu
$remainingCharacters = substr($ret, \strlen(trim($this->mostRecentlyEnteredValue($fullChoice))));
$output->write($remainingCharacters);
$fullChoice .= $remainingCharacters;
- $i = self::strlen($fullChoice);
+ $i = (false === $encoding = mb_detect_encoding($fullChoice, null, true)) ? \strlen($fullChoice) : mb_strlen($fullChoice, $encoding);
$matches = array_filter(
$autocomplete($ret),
diff --git a/src/Symfony/Component/Console/Input/ArrayInput.php b/src/Symfony/Component/Console/Input/ArrayInput.php
index 25d2b750b4aae..bf9a8a455a4c5 100644
--- a/src/Symfony/Component/Console/Input/ArrayInput.php
+++ b/src/Symfony/Component/Console/Input/ArrayInput.php
@@ -108,12 +108,13 @@ public function __toString()
$params = [];
foreach ($this->parameters as $param => $val) {
if ($param && \is_string($param) && '-' === $param[0]) {
+ $glue = ('-' === $param[1]) ? '=' : ' ';
if (\is_array($val)) {
foreach ($val as $v) {
- $params[] = $param.('' != $v ? '='.$this->escapeToken($v) : '');
+ $params[] = $param.('' != $v ? $glue.$this->escapeToken($v) : '');
}
} else {
- $params[] = $param.('' != $val ? '='.$this->escapeToken($val) : '');
+ $params[] = $param.('' != $val ? $glue.$this->escapeToken($val) : '');
}
} else {
$params[] = \is_array($val) ? implode(' ', array_map([$this, 'escapeToken'], $val)) : $this->escapeToken($val);
diff --git a/src/Symfony/Component/Console/Input/InputOption.php b/src/Symfony/Component/Console/Input/InputOption.php
index 66f857a6c0d3b..a8e956db55b19 100644
--- a/src/Symfony/Component/Console/Input/InputOption.php
+++ b/src/Symfony/Component/Console/Input/InputOption.php
@@ -33,11 +33,11 @@ class InputOption
private $description;
/**
- * @param string $name The option name
- * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
- * @param int|null $mode The option mode: One of the VALUE_* constants
- * @param string $description A description text
- * @param string|string[]|int|bool|null $default The default value (must be null for self::VALUE_NONE)
+ * @param string $name The option name
+ * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
+ * @param int|null $mode The option mode: One of the VALUE_* constants
+ * @param string $description A description text
+ * @param string|string[]|bool|null $default The default value (must be null for self::VALUE_NONE)
*
* @throws InvalidArgumentException If option mode is invalid or incompatible
*/
@@ -149,7 +149,7 @@ public function isArray()
/**
* Sets the default value.
*
- * @param string|string[]|int|bool|null $default The default value
+ * @param string|string[]|bool|null $default The default value
*
* @throws LogicException When incorrect default value is given
*/
@@ -173,7 +173,7 @@ public function setDefault($default = null)
/**
* Returns the default value.
*
- * @return string|string[]|int|bool|null The default value
+ * @return string|string[]|bool|null The default value
*/
public function getDefault()
{
diff --git a/src/Symfony/Component/Console/Style/SymfonyStyle.php b/src/Symfony/Component/Console/Style/SymfonyStyle.php
index 2056f04c99ad5..ecdf9b1a3b376 100644
--- a/src/Symfony/Component/Console/Style/SymfonyStyle.php
+++ b/src/Symfony/Component/Console/Style/SymfonyStyle.php
@@ -471,7 +471,12 @@ private function createBlock(iterable $messages, string $type = null, string $st
$message = OutputFormatter::escape($message);
}
- $lines = array_merge($lines, explode(\PHP_EOL, wordwrap($message, $this->lineLength - $prefixLength - $indentLength, \PHP_EOL, true)));
+ $decorationLength = Helper::strlen($message) - Helper::strlenWithoutDecoration($this->getFormatter(), $message);
+ $messageLineLength = min($this->lineLength - $prefixLength - $indentLength + $decorationLength, $this->lineLength);
+ $messageLines = explode(\PHP_EOL, wordwrap($message, $messageLineLength, \PHP_EOL, true));
+ foreach ($messageLines as $messageLine) {
+ $lines[] = $messageLine;
+ }
if (\count($messages) > 1 && $key < \count($messages) - 1) {
$lines[] = '';
@@ -491,7 +496,7 @@ private function createBlock(iterable $messages, string $type = null, string $st
}
$line = $prefix.$line;
- $line .= str_repeat(' ', $this->lineLength - Helper::strlenWithoutDecoration($this->getFormatter(), $line));
+ $line .= str_repeat(' ', max($this->lineLength - Helper::strlenWithoutDecoration($this->getFormatter(), $line), 0));
if ($style) {
$line = sprintf('<%s>%s>', $style, $line);
diff --git a/src/Symfony/Component/Console/Tests/Command/ListCommandTest.php b/src/Symfony/Component/Console/Tests/Command/ListCommandTest.php
index 3908ca5bb21f2..7269b39fe999d 100644
--- a/src/Symfony/Component/Console/Tests/Command/ListCommandTest.php
+++ b/src/Symfony/Component/Console/Tests/Command/ListCommandTest.php
@@ -23,7 +23,7 @@ public function testExecuteListsCommands()
$commandTester = new CommandTester($command = $application->get('list'));
$commandTester->execute(['command' => $command->getName()], ['decorated' => false]);
- $this->assertMatchesRegularExpression('/help\s{2,}Displays help for a command/', $commandTester->getDisplay(), '->execute() returns a list of available commands');
+ $this->assertMatchesRegularExpression('/help\s{2,}Display help for a command/', $commandTester->getDisplay(), '->execute() returns a list of available commands');
}
public function testExecuteListsCommandsWithXmlOption()
@@ -40,8 +40,8 @@ public function testExecuteListsCommandsWithRawOption()
$commandTester = new CommandTester($command = $application->get('list'));
$commandTester->execute(['command' => $command->getName(), '--raw' => true]);
$output = <<<'EOF'
-help Displays help for a command
-list Lists commands
+help Display help for a command
+list List commands
EOF;
@@ -86,8 +86,8 @@ public function testExecuteListsCommandsOrder()
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands:
- help Displays help for a command
- list Lists commands
+ help Display help for a command
+ list List commands
0foo
0foo:bar 0foo:bar command
EOF;
@@ -103,8 +103,8 @@ public function testExecuteListsCommandsOrderRaw()
$commandTester = new CommandTester($command = $application->get('list'));
$commandTester->execute(['command' => $command->getName(), '--raw' => true]);
$output = <<<'EOF'
-help Displays help for a command
-list Lists commands
+help Display help for a command
+list List commands
0foo:bar 0foo:bar command
EOF;
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/output/output_13.txt b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/output/output_13.txt
index 0f3704b7482ea..ea8e4351eafa5 100644
--- a/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/output/output_13.txt
+++ b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/output/output_13.txt
@@ -1,7 +1,7 @@
-[39;49m // [39;49mLorem ipsum dolor sit [33mamet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et [39m
-[39;49m // [39;49m[33mdolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea [39m
-[39;49m // [39;49m[33mcommodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla [39m
-[39;49m // [39;49m[33mpariatur.[39m Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim
-[39;49m // [39;49mid est laborum
+[39;49m // [39;49mLorem ipsum dolor sit [33mamet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore [39m
+[39;49m // [39;49m[33mmagna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo [39m
+[39;49m // [39;49m[33mconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla [39m
+[39;49m // [39;49m[33mpariatur.[39m Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
+[39;49m // [39;49mest laborum
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/application_1.json b/src/Symfony/Component/Console/Tests/Fixtures/application_1.json
index 29faa8262dceb..230b072b06353 100644
--- a/src/Symfony/Component/Console/Tests/Fixtures/application_1.json
+++ b/src/Symfony/Component/Console/Tests/Fixtures/application_1.json
@@ -6,7 +6,7 @@
"usage": [
"help [--format FORMAT] [--raw] [--] []"
],
- "description": "Displays help for a command",
+ "description": "Display help for a command",
"help": "The help<\/info> command displays help for a given command:\n\n php app\/console help list<\/info>\n\nYou can also output the help in other formats by using the --format<\/comment> option:\n\n php app\/console help --format=xml list<\/info>\n\nTo display the list of available commands, please use the list<\/info> command.",
"definition": {
"arguments": {
@@ -109,7 +109,7 @@
"usage": [
"list [--raw] [--format FORMAT] [--] []"
],
- "description": "Lists commands",
+ "description": "List commands",
"help": "The list<\/info> command lists all commands:\n\n php app\/console list<\/info>\n\nYou can also display the commands for a specific namespace:\n\n php app\/console list test<\/info>\n\nYou can also output the information in other formats by using the --format<\/comment> option:\n\n php app\/console list --format=xml<\/info>\n\nIt's also possible to get raw list of commands (useful for embedding command runner):\n\n php app\/console list --raw<\/info>",
"definition": {
"arguments": {
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/application_1.md b/src/Symfony/Component/Console/Tests/Fixtures/application_1.md
index b46c975a79082..63822d037f137 100644
--- a/src/Symfony/Component/Console/Tests/Fixtures/application_1.md
+++ b/src/Symfony/Component/Console/Tests/Fixtures/application_1.md
@@ -7,7 +7,7 @@ Console Tool
`help`
------
-Displays help for a command
+Display help for a command
### Usage
@@ -119,7 +119,7 @@ Do not ask any interactive question
`list`
------
-Lists commands
+List commands
### Usage
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/application_1.txt b/src/Symfony/Component/Console/Tests/Fixtures/application_1.txt
index 8a7b47e0c4b00..ab345e65c62ca 100644
--- a/src/Symfony/Component/Console/Tests/Fixtures/application_1.txt
+++ b/src/Symfony/Component/Console/Tests/Fixtures/application_1.txt
@@ -13,5 +13,5 @@ Console Tool
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands:
- help Displays help for a command
- list Lists commands
+ help Display help for a command
+ list List commands
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/application_1.xml b/src/Symfony/Component/Console/Tests/Fixtures/application_1.xml
index a0bd076c5a9f3..f47bfb23b702f 100644
--- a/src/Symfony/Component/Console/Tests/Fixtures/application_1.xml
+++ b/src/Symfony/Component/Console/Tests/Fixtures/application_1.xml
@@ -5,7 +5,7 @@
help [--format FORMAT] [--raw] [--] [<command_name>]
- Displays help for a command
+ Display help for a commandThe <info>help</info> command displays help for a given command:
<info>php app/console help list</info>
@@ -60,7 +60,7 @@
list [--raw] [--format FORMAT] [--] [<namespace>]
- Lists commands
+ List commandsThe <info>list</info> command lists all commands:
<info>php app/console list</info>
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/application_2.json b/src/Symfony/Component/Console/Tests/Fixtures/application_2.json
index 4777a60b52a3e..f47267ab4e8d0 100644
--- a/src/Symfony/Component/Console/Tests/Fixtures/application_2.json
+++ b/src/Symfony/Component/Console/Tests/Fixtures/application_2.json
@@ -10,7 +10,7 @@
"usage": [
"help [--format FORMAT] [--raw] [--] []"
],
- "description": "Displays help for a command",
+ "description": "Display help for a command",
"help": "The help<\/info> command displays help for a given command:\n\n php app\/console help list<\/info>\n\nYou can also output the help in other formats by using the --format<\/comment> option:\n\n php app\/console help --format=xml list<\/info>\n\nTo display the list of available commands, please use the list<\/info> command.",
"definition": {
"arguments": {
@@ -113,7 +113,7 @@
"usage": [
"list [--raw] [--format FORMAT] [--] []"
],
- "description": "Lists commands",
+ "description": "List commands",
"help": "The list<\/info> command lists all commands:\n\n php app\/console list<\/info>\n\nYou can also display the commands for a specific namespace:\n\n php app\/console list test<\/info>\n\nYou can also output the information in other formats by using the --format<\/comment> option:\n\n php app\/console list --format=xml<\/info>\n\nIt's also possible to get raw list of commands (useful for embedding command runner):\n\n php app\/console list --raw<\/info>",
"definition": {
"arguments": {
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/application_2.md b/src/Symfony/Component/Console/Tests/Fixtures/application_2.md
index 5b4896c0825c7..77c1dc523cddd 100644
--- a/src/Symfony/Component/Console/Tests/Fixtures/application_2.md
+++ b/src/Symfony/Component/Console/Tests/Fixtures/application_2.md
@@ -20,7 +20,7 @@ My Symfony application v1.0
`help`
------
-Displays help for a command
+Display help for a command
### Usage
@@ -132,7 +132,7 @@ Do not ask any interactive question
`list`
------
-Lists commands
+List commands
### Usage
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/application_2.txt b/src/Symfony/Component/Console/Tests/Fixtures/application_2.txt
index d624f19466221..3d605c838ce76 100644
--- a/src/Symfony/Component/Console/Tests/Fixtures/application_2.txt
+++ b/src/Symfony/Component/Console/Tests/Fixtures/application_2.txt
@@ -13,8 +13,8 @@ My Symfony application v1.0-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands:
- help Displays help for a command
- list Lists commands
+ help Display help for a command
+ list List commands
descriptordescriptor:command1 [alias1|alias2] command 1 description
descriptor:command2 command 2 description
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/application_2.xml b/src/Symfony/Component/Console/Tests/Fixtures/application_2.xml
index 5f0f98bd9f15d..27e5f482417bd 100644
--- a/src/Symfony/Component/Console/Tests/Fixtures/application_2.xml
+++ b/src/Symfony/Component/Console/Tests/Fixtures/application_2.xml
@@ -5,7 +5,7 @@
help [--format FORMAT] [--raw] [--] [<command_name>]
- Displays help for a command
+ Display help for a commandThe <info>help</info> command displays help for a given command:
<info>php app/console help list</info>
@@ -60,7 +60,7 @@
list [--raw] [--format FORMAT] [--] [<namespace>]
- Lists commands
+ List commandsThe <info>list</info> command lists all commands:
<info>php app/console list</info>
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/application_mbstring.md b/src/Symfony/Component/Console/Tests/Fixtures/application_mbstring.md
index f34e5585cf399..e3f43aff5ca2f 100644
--- a/src/Symfony/Component/Console/Tests/Fixtures/application_mbstring.md
+++ b/src/Symfony/Component/Console/Tests/Fixtures/application_mbstring.md
@@ -11,7 +11,7 @@ MbString åpplicätion
`help`
------
-Displays help for a command
+Display help for a command
### Usage
@@ -123,7 +123,7 @@ Do not ask any interactive question
`list`
------
-Lists commands
+List commands
### Usage
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/application_mbstring.txt b/src/Symfony/Component/Console/Tests/Fixtures/application_mbstring.txt
index b409d18816758..8091bedd30ca4 100644
--- a/src/Symfony/Component/Console/Tests/Fixtures/application_mbstring.txt
+++ b/src/Symfony/Component/Console/Tests/Fixtures/application_mbstring.txt
@@ -13,7 +13,7 @@ MbString åpplicätion
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands:
- help Displays help for a command
- list Lists commands
+ help Display help for a command
+ list List commands
descriptordescriptor:åèä command åèä description
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/application_run1.txt b/src/Symfony/Component/Console/Tests/Fixtures/application_run1.txt
index 0dc2730983f4b..c95d282f29def 100644
--- a/src/Symfony/Component/Console/Tests/Fixtures/application_run1.txt
+++ b/src/Symfony/Component/Console/Tests/Fixtures/application_run1.txt
@@ -13,5 +13,5 @@ Options:
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands:
- help Displays help for a command
- list Lists commands
+ help Display help for a command
+ list List commands
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/application_run2.txt b/src/Symfony/Component/Console/Tests/Fixtures/application_run2.txt
index 90050b0544982..d6e45b6521055 100644
--- a/src/Symfony/Component/Console/Tests/Fixtures/application_run2.txt
+++ b/src/Symfony/Component/Console/Tests/Fixtures/application_run2.txt
@@ -1,5 +1,5 @@
Description:
- Lists commands
+ List commands
Usage:
list [options] [--] []
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/application_run3.txt b/src/Symfony/Component/Console/Tests/Fixtures/application_run3.txt
index 90050b0544982..d6e45b6521055 100644
--- a/src/Symfony/Component/Console/Tests/Fixtures/application_run3.txt
+++ b/src/Symfony/Component/Console/Tests/Fixtures/application_run3.txt
@@ -1,5 +1,5 @@
Description:
- Lists commands
+ List commands
Usage:
list [options] [--] []
diff --git a/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php b/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php
index d927f4dfccb54..2d32e1c3d512a 100644
--- a/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php
+++ b/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php
@@ -343,6 +343,31 @@ public function testOverwriteWithSectionOutput()
);
}
+ public function testOverwriteWithAnsiSectionOutput()
+ {
+ // output has 43 visible characters plus 2 invisible ANSI characters
+ putenv('COLUMNS=43');
+ $sections = [];
+ $stream = $this->getOutputStream(true);
+ $output = new ConsoleSectionOutput($stream->getStream(), $sections, $stream->getVerbosity(), $stream->isDecorated(), new OutputFormatter());
+
+ $bar = new ProgressBar($output, 50, 0);
+ $bar->setFormat(" \033[44;37m%current%/%max%\033[0m [%bar%] %percent:3s%%");
+ $bar->start();
+ $bar->display();
+ $bar->advance();
+ $bar->advance();
+
+ rewind($output->getStream());
+ $this->assertSame(
+ " \033[44;37m 0/50\033[0m [>---------------------------] 0%".\PHP_EOL.
+ "\x1b[1A\x1b[0J"." \033[44;37m 1/50\033[0m [>---------------------------] 2%".\PHP_EOL.
+ "\x1b[1A\x1b[0J"." \033[44;37m 2/50\033[0m [=>--------------------------] 4%".\PHP_EOL,
+ stream_get_contents($output->getStream())
+ );
+ putenv('COLUMNS=120');
+ }
+
public function testOverwriteMultipleProgressBarsWithSectionOutputs()
{
$sections = [];
@@ -372,6 +397,34 @@ public function testOverwriteMultipleProgressBarsWithSectionOutputs()
);
}
+ public function testOverwriteWithSectionOutputWithNewlinesInMessage()
+ {
+ $sections = [];
+ $stream = $this->getOutputStream(true);
+ $output = new ConsoleSectionOutput($stream->getStream(), $sections, $stream->getVerbosity(), $stream->isDecorated(), new OutputFormatter());
+
+ ProgressBar::setFormatDefinition('test', '%current%/%max% [%bar%] %percent:3s%% %message% Fruitcake marzipan toffee. Cupcake gummi bears tart dessert ice cream chupa chups cupcake chocolate bar sesame snaps. Croissant halvah cookie jujubes powder macaroon. Fruitcake bear claw bonbon jelly beans oat cake pie muffin Fruitcake marzipan toffee.');
+
+ $bar = new ProgressBar($output, 50, 0);
+ $bar->setFormat('test');
+ $bar->start();
+ $bar->display();
+ $bar->setMessage("Twas brillig, and the slithy toves. Did gyre and gimble in the wabe: All mimsy were the borogoves, And the mome raths outgrabe.\nBeware the Jabberwock, my son! The jaws that bite, the claws that catch! Beware the Jubjub bird, and shun The frumious Bandersnatch!");
+ $bar->advance();
+ $bar->setMessage("He took his vorpal sword in hand; Long time the manxome foe he sought— So rested he by the Tumtum tree And stood awhile in thought.\nAnd, as in uffish thought he stood, The Jabberwock, with eyes of flame, Came whiffling through the tulgey wood, And burbled as it came!");
+ $bar->advance();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ ' 0/50 [>] 0% %message% Fruitcake marzipan toffee. Cupcake gummi bears tart dessert ice cream chupa chups cupcake chocolate bar sesame snaps. Croissant halvah cookie jujubes powder macaroon. Fruitcake bear claw bonbon jelly beans oat cake pie muffin Fruitcake marzipan toffee.'.\PHP_EOL.
+ "\x1b[6A\x1b[0J 1/50 [>] 2% Twas brillig, and the slithy toves. Did gyre and gimble in the wabe: All mimsy were the borogoves, And the mome raths outgrabe.
+Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Beware the Jubjub bird, and shun The frumious Bandersnatch! Fruitcake marzipan toffee. Cupcake gummi bears tart dessert ice cream chupa chups cupcake chocolate bar sesame snaps. Croissant halvah cookie jujubes powder macaroon. Fruitcake bear claw bonbon jelly beans oat cake pie muffin Fruitcake marzipan toffee.".\PHP_EOL.
+ "\x1b[6A\x1b[0J 2/50 [>] 4% He took his vorpal sword in hand; Long time the manxome foe he sought— So rested he by the Tumtum tree And stood awhile in thought.
+And, as in uffish thought he stood, The Jabberwock, with eyes of flame, Came whiffling through the tulgey wood, And burbled as it came! Fruitcake marzipan toffee. Cupcake gummi bears tart dessert ice cream chupa chups cupcake chocolate bar sesame snaps. Croissant halvah cookie jujubes powder macaroon. Fruitcake bear claw bonbon jelly beans oat cake pie muffin Fruitcake marzipan toffee.".\PHP_EOL,
+ stream_get_contents($output->getStream())
+ );
+ }
+
public function testMultipleSectionsWithCustomFormat()
{
$sections = [];
diff --git a/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php b/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php
index f3eedb3a2d57f..5777c44b7269a 100644
--- a/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php
+++ b/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php
@@ -162,10 +162,10 @@ public function provideInvalidInput()
public function testToString()
{
$input = new ArrayInput(['-f' => null, '-b' => 'bar', '--foo' => 'b a z', '--lala' => null, 'test' => 'Foo', 'test2' => "A\nB'C"]);
- $this->assertEquals('-f -b=bar --foo='.escapeshellarg('b a z').' --lala Foo '.escapeshellarg("A\nB'C"), (string) $input);
+ $this->assertEquals('-f -b bar --foo='.escapeshellarg('b a z').' --lala Foo '.escapeshellarg("A\nB'C"), (string) $input);
$input = new ArrayInput(['-b' => ['bval_1', 'bval_2'], '--f' => ['fval_1', 'fval_2']]);
- $this->assertSame('-b=bval_1 -b=bval_2 --f=fval_1 --f=fval_2', (string) $input);
+ $this->assertSame('-b bval_1 -b bval_2 --f=fval_1 --f=fval_2', (string) $input);
$input = new ArrayInput(['array_arg' => ['val_1', 'val_2']]);
$this->assertSame('val_1 val_2', (string) $input);
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
index a53df4e933237..0fbcbbf0d0df0 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
@@ -146,7 +146,7 @@ private function autowireCalls(\ReflectionClass $reflectionClass, bool $isRoot):
$this->decoratedClass = null;
$this->getPreviousValue = null;
- if ($isRoot && ($definition = $this->container->getDefinition($this->currentId)) && $this->container->has($this->decoratedId = $definition->innerServiceId)) {
+ if ($isRoot && ($definition = $this->container->getDefinition($this->currentId)) && null !== ($this->decoratedId = $definition->innerServiceId) && $this->container->has($this->decoratedId)) {
$this->decoratedClass = $this->container->findDefinition($this->decoratedId)->getClass();
}
diff --git a/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php b/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php
index 0dcd72673e1e2..18e9b5ac1b7f4 100644
--- a/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php
+++ b/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php
@@ -26,17 +26,40 @@
*/
class FlattenException extends LegacyFlattenException
{
+ /** @var string */
private $message;
+
+ /** @var int|string */
private $code;
+
+ /** @var self|null */
private $previous;
+
+ /** @var array */
private $trace;
+
+ /** @var string */
private $traceAsString;
+
+ /** @var string */
private $class;
+
+ /** @var int */
private $statusCode;
+
+ /** @var string */
private $statusText;
+
+ /** @var array */
private $headers;
+
+ /** @var string */
private $file;
+
+ /** @var int */
private $line;
+
+ /** @var string|null */
private $asString;
public static function create(\Exception $exception, $statusCode = null, array $headers = []): self
@@ -104,6 +127,8 @@ public function getStatusCode(): int
}
/**
+ * @param int $code
+ *
* @return $this
*/
public function setStatusCode($code): self
@@ -134,6 +159,8 @@ public function getClass(): string
}
/**
+ * @param string $class
+ *
* @return $this
*/
public function setClass($class): self
@@ -149,6 +176,8 @@ public function getFile(): string
}
/**
+ * @param string $file
+ *
* @return $this
*/
public function setFile($file): self
@@ -164,6 +193,8 @@ public function getLine(): int
}
/**
+ * @param int $line
+ *
* @return $this
*/
public function setLine($line): self
@@ -191,6 +222,8 @@ public function getMessage(): string
}
/**
+ * @param string $message
+ *
* @return $this
*/
public function setMessage($message): self
@@ -215,6 +248,8 @@ public function getCode()
}
/**
+ * @param int|string $code
+ *
* @return $this
*/
public function setCode($code): self
@@ -282,6 +317,10 @@ public function setTraceFromThrowable(\Throwable $throwable): self
}
/**
+ * @param array $trace
+ * @param string|null $file
+ * @param int|null $line
+ *
* @return $this
*/
public function setTrace($trace, $file, $line): self
diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php
index c5f1674c4e37e..77f780127e050 100644
--- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php
+++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php
@@ -1731,7 +1731,7 @@ public function testDumpKeepsExistingPermissionsWhenOverwritingAnExistingFile()
file_put_contents($filename, 'FOO BAR');
chmod($filename, 0745);
- $this->filesystem->dumpFile($filename, 'bar', null);
+ $this->filesystem->dumpFile($filename, 'bar');
$this->assertFilePermissions(745, $filename);
}
@@ -1752,7 +1752,7 @@ public function testCopyShouldKeepExecutionPermission()
}
/**
- * Normalize the given path (transform each blackslash into a real directory separator).
+ * Normalize the given path (transform each forward slash into a real directory separator).
*/
private function normalize(string $path): string
{
diff --git a/src/Symfony/Component/Form/Command/DebugCommand.php b/src/Symfony/Component/Form/Command/DebugCommand.php
index 4150feaf8ce85..3ee7609725105 100644
--- a/src/Symfony/Component/Form/Command/DebugCommand.php
+++ b/src/Symfony/Component/Form/Command/DebugCommand.php
@@ -64,7 +64,7 @@ protected function configure()
new InputOption('show-deprecated', null, InputOption::VALUE_NONE, 'Display deprecated options in form types'),
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt or json)', 'txt'),
])
- ->setDescription('Displays form type information')
+ ->setDescription('Display form type information')
->setHelp(<<<'EOF'
The %command.name% command displays information about form types.
diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php
index 8d73404b5d1b0..a5ef4f6f067bc 100644
--- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php
+++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php
@@ -130,6 +130,10 @@ public function reverseTransform($value)
} elseif ($timestamp > 253402214400) {
// This timestamp represents UTC midnight of 9999-12-31 to prevent 5+ digit years
throw new TransformationFailedException('Years beyond 9999 are not supported.');
+ } elseif (false === $timestamp) {
+ // the value couldn't be parsed but the Intl extension didn't report an error code, this
+ // could be the case when the Intl polyfill is used which always returns 0 as the error code
+ throw new TransformationFailedException(sprintf('"%s" could not be parsed as a date.', $value));
}
try {
diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformer.php
index 76e3eea8ede9a..7e0eeea2a50b0 100644
--- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformer.php
+++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformer.php
@@ -24,19 +24,21 @@ class IntegerToLocalizedStringTransformer extends NumberToLocalizedStringTransfo
/**
* Constructs a transformer.
*
- * @param bool $grouping Whether thousands should be grouped
- * @param int $roundingMode One of the ROUND_ constants in this class
+ * @param bool $grouping Whether thousands should be grouped
+ * @param int $roundingMode One of the ROUND_ constants in this class
+ * @param string|null $locale locale used for transforming
*/
- public function __construct($grouping = false, $roundingMode = self::ROUND_DOWN)
+ public function __construct($grouping = false, $roundingMode = self::ROUND_DOWN, $locale = null)
{
- if (\is_int($grouping) || \is_bool($roundingMode) || 2 < \func_num_args()) {
+ if (\is_int($grouping) || \is_bool($roundingMode) || \is_int($locale)) {
@trigger_error(sprintf('Passing a precision as the first value to %s::__construct() is deprecated since Symfony 4.2 and support for it will be dropped in 5.0.', __CLASS__), \E_USER_DEPRECATED);
$grouping = $roundingMode;
- $roundingMode = 2 < \func_num_args() ? func_get_arg(2) : self::ROUND_DOWN;
+ $roundingMode = null !== $locale ? $locale : self::ROUND_DOWN;
+ $locale = null;
}
- parent::__construct(0, $grouping, $roundingMode);
+ parent::__construct(0, $grouping, $roundingMode, $locale);
}
/**
diff --git a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php
index bd2985b313137..e4355084fe1e0 100644
--- a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php
+++ b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php
@@ -141,6 +141,8 @@ public function buildForm(FormBuilderInterface $builder, array $options)
$knownValues[$child->getName()] = $value;
unset($unknownValues[$value]);
continue;
+ } else {
+ $knownValues[$child->getName()] = null;
}
}
} else {
diff --git a/src/Symfony/Component/Form/Extension/Core/Type/IntegerType.php b/src/Symfony/Component/Form/Extension/Core/Type/IntegerType.php
index 540cdb6f79db3..2fa7c9c642316 100644
--- a/src/Symfony/Component/Form/Extension/Core/Type/IntegerType.php
+++ b/src/Symfony/Component/Form/Extension/Core/Type/IntegerType.php
@@ -25,7 +25,7 @@ class IntegerType extends AbstractType
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
- $builder->addViewTransformer(new IntegerToLocalizedStringTransformer($options['grouping'], $options['rounding_mode']));
+ $builder->addViewTransformer(new IntegerToLocalizedStringTransformer($options['grouping'], $options['rounding_mode'], !$options['grouping'] ? 'en' : null));
}
/**
diff --git a/src/Symfony/Component/Form/Resources/translations/validators.nn.xlf b/src/Symfony/Component/Form/Resources/translations/validators.nn.xlf
index 2f5da23444d0b..9fac1bf34e34f 100644
--- a/src/Symfony/Component/Form/Resources/translations/validators.nn.xlf
+++ b/src/Symfony/Component/Form/Resources/translations/validators.nn.xlf
@@ -4,7 +4,7 @@
This form should not contain extra fields.
- Feltgruppa må ikkje innehalde ekstra felt.
+ Feltgruppa kan ikkje innehalde ekstra felt.The uploaded file was too large. Please try to upload a smaller file.
@@ -14,6 +14,126 @@
The CSRF token is invalid.CSRF-nøkkelen er ikkje gyldig.
+
+ This value is not a valid HTML5 color.
+ Verdien er ikkje ein gyldig HTML5-farge.
+
+
+ Please enter a valid birthdate.
+ Gje opp ein gyldig fødselsdato.
+
+
+ The selected choice is invalid.
+ Valget du gjorde er ikkje gyldig.
+
+
+ The collection is invalid.
+ Samlinga er ikkje gyldig.
+
+
+ Please select a valid color.
+ Gje opp ein gyldig farge.
+
+
+ Please select a valid country.
+ Gje opp eit gyldig land.
+
+
+ Please select a valid currency.
+ Gje opp ein gyldig valuta.
+
+
+ Please choose a valid date interval.
+ Gje opp eit gyldig datointervall.
+
+
+ Please enter a valid date and time.
+ Gje opp ein gyldig dato og tid.
+
+
+ Please enter a valid date.
+ Gje opp ein gyldig dato.
+
+
+ Please select a valid file.
+ Velg ei gyldig fil.
+
+
+ The hidden field is invalid.
+ Det skjulte feltet er ikkje gyldig.
+
+
+ Please enter an integer.
+ Gje opp eit heiltal.
+
+
+ Please select a valid language.
+ Gje opp eit gyldig språk.
+
+
+ Please select a valid locale.
+ Gje opp eit gyldig locale.
+
+
+ Please enter a valid money amount.
+ Gje opp ein gyldig sum pengar.
+
+
+ Please enter a number.
+ Gje opp eit nummer.
+
+
+ The password is invalid.
+ Passordet er ikkje gyldig.
+
+
+ Please enter a percentage value.
+ Gje opp ein prosentverdi.
+
+
+ The values do not match.
+ Verdiane er ikkje eins.
+
+
+ Please enter a valid time.
+ Gje opp ei gyldig tid.
+
+
+ Please select a valid timezone.
+ Gje opp ei gyldig tidssone.
+
+
+ Please enter a valid URL.
+ Gje opp ein gyldig URL.
+
+
+ Please enter a valid search term.
+ Gje opp gyldige søkjeord.
+
+
+ Please provide a valid phone number.
+ Gje opp eit gyldig telefonnummer.
+
+
+ The checkbox has an invalid value.
+ Sjekkboksen har ein ugyldig verdi.
+
+
+ Please enter a valid email address.
+ Gje opp ei gyldig e-postadresse.
+
+
+ Please select a valid option.
+ Velg eit gyldig vilkår.
+
+
+ Please select a valid range.
+ Velg eit gyldig spenn.
+
+
+ Please enter a valid week.
+ Gje opp ei gyldig veke.
+
diff --git a/src/Symfony/Component/Form/Resources/translations/validators.uz.xlf b/src/Symfony/Component/Form/Resources/translations/validators.uz.xlf
new file mode 100644
index 0000000000000..58591d69e9539
--- /dev/null
+++ b/src/Symfony/Component/Form/Resources/translations/validators.uz.xlf
@@ -0,0 +1,139 @@
+
+
+
+
+
+ This form should not contain extra fields.
+ Ushbu fo'rmada qo'shimcha maydonlar bo'lmasligi kerak.
+
+
+ The uploaded file was too large. Please try to upload a smaller file.
+ Yuklab olingan fayl juda katta. Iltimos, kichikroq faylni yuklashga harakat qiling.
+
+
+ The CSRF token is invalid. Please try to resubmit the form.
+ CSRF qiymati yaroqsiz. Fo'rmani qayta yuborishga harakat qiling.
+
+
+ This value is not a valid HTML5 color.
+ Qiymat noto'g'ri, HTML5 rangi emas.
+
+
+ Please enter a valid birthdate.
+ Iltimos, tug'ilgan kuningizni to'g'ri kiriting.
+
+
+ The selected choice is invalid.
+ Tanlangan parametr noto'g'ri.
+
+
+ The collection is invalid.
+ Kolleksiya noto'g'ri
+
+
+ Please select a valid color.
+ Iltimos, to'g'ri rang tanlang.
+
+
+ Please select a valid country.
+ Iltimos, to'g'ri mamlakatni tanlang.
+
+
+ Please select a valid currency.
+ Iltimos, to'g'ri valyutani tanlang.
+
+
+ Please choose a valid date interval.
+ Iltimos, to'g'ri sana oralig'ini tanlang.
+
+
+ Please enter a valid date and time.
+ Iltimos, to'g'ri sana va vaqtni kiriting.
+
+
+ Please enter a valid date.
+ Iltimos, to'g'ri sanani kiriting.
+
+
+ Please select a valid file.
+ Iltimos, to'g'ri faylni tanlang.
+
+
+ The hidden field is invalid.
+ Yashirin maydon qiymati yaroqsiz.
+
+
+ Please enter an integer.
+ Iltimos, butun son kiriting.
+
+
+ Please select a valid language.
+ Iltimos, to'g'ri tilni tanlang.
+
+
+ Please select a valid locale.
+ Iltimos, to'g'ri localni tanlang.
+
+
+ Please enter a valid money amount.
+ Iltimos, tegishli miqdordagi pulni kiriting.
+
+
+ Please enter a number.
+ Iltimos, raqam kiriting.
+
+
+ The password is invalid.
+ Parol noto'g'ri.
+
+
+ Please enter a percentage value.
+ Iltimos, foyizli qiymat kiriting.
+
+
+ The values do not match.
+ Qiymatlar mos kelmaydi.
+
+
+ Please enter a valid time.
+ Iltimos, to'g'ri vaqtni tanlang.
+
+
+ Please select a valid timezone.
+ Iltimos, to'g'ri vaqt zonasini tanlang.
+
+
+ Please enter a valid URL.
+ Iltimos, to'g'ri URL kiriting.
+
+
+ Please enter a valid search term.
+ Iltimos, to'g'ri qidiruv so'zini kiriting.
+
+
+ Please provide a valid phone number.
+ Iltimos, to'g'ri telefon raqamini kiriting.
+
+
+ The checkbox has an invalid value.
+ Belgilash katagida yaroqsiz qiymat mavjud.
+
+
+ Please enter a valid email address.
+ Iltimos, to'g'ri email kiriting.
+
+
+ Please select a valid option.
+ Iltimos, yaroqli variantni tanlang.
+
+
+ Please select a valid range.
+ Iltimos, yaroqli oraliqni tanlang.
+
+
+ Please enter a valid week.
+ Iltimos, haqiqiy haftani kiriting.
+
+
+
+
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php
index 691081aeb9ef5..c96ec62eed9bf 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php
@@ -1287,6 +1287,20 @@ public function testSubmitSingleExpandedObjectChoices()
$this->assertNull($form[4]->getViewData());
}
+ public function testSubmitSingleExpandedClearMissingFalse()
+ {
+ $form = $this->factory->create(self::TESTED_TYPE, 'foo', [
+ 'choices' => [
+ 'foo label' => 'foo',
+ 'bar label' => 'bar',
+ ],
+ 'expanded' => true,
+ ]);
+ $form->submit('bar', false);
+
+ $this->assertSame('bar', $form->getData());
+ }
+
public function testSubmitMultipleExpanded()
{
$form = $this->factory->create(static::TESTED_TYPE, null, [
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php
index a88eb70c5fe7a..15cf308d990dd 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php
@@ -17,13 +17,48 @@ class IntegerTypeTest extends BaseTypeTest
{
public const TESTED_TYPE = 'Symfony\Component\Form\Extension\Core\Type\IntegerType';
+ private $previousLocale;
+
protected function setUp(): void
{
IntlTestHelper::requireIntl($this, false);
-
+ $this->previousLocale = \Locale::getDefault();
parent::setUp();
}
+ protected function tearDown(): void
+ {
+ \Locale::setDefault($this->previousLocale);
+ }
+
+ /**
+ * @requires extension intl
+ */
+ public function testArabicLocale()
+ {
+ \Locale::setDefault('ar');
+
+ $form = $this->factory->create(static::TESTED_TYPE);
+ $form->submit('123456');
+
+ $this->assertSame(123456, $form->getData());
+ $this->assertSame('123456', $form->getViewData());
+ }
+
+ /**
+ * @requires extension intl
+ */
+ public function testArabicLocaleNonHtml5()
+ {
+ \Locale::setDefault('ar');
+
+ $form = $this->factory->create(static::TESTED_TYPE, null, ['grouping' => true]);
+ $form->submit('123456');
+
+ $this->assertSame(123456, $form->getData());
+ $this->assertSame('١٢٣٬٤٥٦', $form->getViewData());
+ }
+
public function testSubmitRejectsFloats()
{
$form = $this->factory->create(static::TESTED_TYPE);
diff --git a/src/Symfony/Component/HttpClient/Response/NativeResponse.php b/src/Symfony/Component/HttpClient/Response/NativeResponse.php
index a3566aea326e4..e87402f0ad8dc 100644
--- a/src/Symfony/Component/HttpClient/Response/NativeResponse.php
+++ b/src/Symfony/Component/HttpClient/Response/NativeResponse.php
@@ -137,7 +137,7 @@ private function open(): void
// Send request and follow redirects when needed
$this->handle = $h = fopen($url, 'r', false, $this->context);
- self::addResponseHeaders($http_response_header, $this->info, $this->headers, $this->info['debug']);
+ self::addResponseHeaders(stream_get_meta_data($h)['wrapper_data'], $this->info, $this->headers, $this->info['debug']);
$url = ($this->resolveRedirect)($this->multi, $this->headers['location'][0] ?? null, $this->context);
if (null === $url) {
diff --git a/src/Symfony/Component/HttpClient/Response/StreamWrapper.php b/src/Symfony/Component/HttpClient/Response/StreamWrapper.php
index 961681e4c445a..83f1562e84e35 100644
--- a/src/Symfony/Component/HttpClient/Response/StreamWrapper.php
+++ b/src/Symfony/Component/HttpClient/Response/StreamWrapper.php
@@ -281,7 +281,7 @@ public function stream_stat(): array
'uid' => 0,
'gid' => 0,
'rdev' => 0,
- 'size' => (int) ($headers['content-length'][0] ?? 0),
+ 'size' => (int) ($headers['content-length'][0] ?? -1),
'atime' => 0,
'mtime' => strtotime($headers['last-modified'][0] ?? '') ?: 0,
'ctime' => 0,
diff --git a/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php b/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php
index d429934b8bdfa..a3782df49e5ed 100644
--- a/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php
+++ b/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php
@@ -63,6 +63,19 @@ public function testToStream()
$this->assertTrue(feof($stream));
}
+ public function testStreamCopyToStream()
+ {
+ $client = $this->getHttpClient(__FUNCTION__);
+ $response = $client->request('GET', 'http://localhost:8057');
+ $h = fopen('php://temp', 'w+');
+ stream_copy_to_stream($response->toStream(), $h);
+
+ $this->assertTrue(rewind($h));
+ $this->assertSame("{\n \"SER", fread($h, 10));
+ $this->assertSame('VER_PROTOCOL', fread($h, 12));
+ $this->assertFalse(feof($h));
+ }
+
public function testToStream404()
{
$client = $this->getHttpClient(__FUNCTION__);
diff --git a/src/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php
index d4b298c594a14..c32c71b7477b4 100644
--- a/src/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php
+++ b/src/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php
@@ -59,12 +59,19 @@ public function setKernel(KernelInterface $kernel = null)
*/
public function collect(Request $request, Response $response/*, \Throwable $exception = null*/)
{
+ $eom = \DateTime::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_MAINTENANCE);
+ $eol = \DateTime::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_LIFE);
+
$this->data = [
'app_name' => $this->name,
'app_version' => $this->version,
'token' => $response->headers->get('X-Debug-Token'),
'symfony_version' => Kernel::VERSION,
- 'symfony_state' => 'unknown',
+ 'symfony_minor_version' => sprintf('%s.%s', Kernel::MAJOR_VERSION, Kernel::MINOR_VERSION),
+ 'symfony_lts' => 4 === Kernel::MINOR_VERSION,
+ 'symfony_state' => $this->determineSymfonyState(),
+ 'symfony_eom' => $eom->format('F Y'),
+ 'symfony_eol' => $eol->format('F Y'),
'env' => isset($this->kernel) ? $this->kernel->getEnvironment() : 'n/a',
'debug' => isset($this->kernel) ? $this->kernel->isDebug() : 'n/a',
'php_version' => \PHP_VERSION,
@@ -82,14 +89,6 @@ public function collect(Request $request, Response $response/*, \Throwable $exce
foreach ($this->kernel->getBundles() as $name => $bundle) {
$this->data['bundles'][$name] = new ClassStub(\get_class($bundle));
}
-
- $this->data['symfony_state'] = $this->determineSymfonyState();
- $this->data['symfony_minor_version'] = sprintf('%s.%s', Kernel::MAJOR_VERSION, Kernel::MINOR_VERSION);
- $this->data['symfony_lts'] = 4 === Kernel::MINOR_VERSION;
- $eom = \DateTime::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_MAINTENANCE);
- $eol = \DateTime::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_LIFE);
- $this->data['symfony_eom'] = $eom->format('F Y');
- $this->data['symfony_eol'] = $eol->format('F Y');
}
if (preg_match('~^(\d+(?:\.\d+)*)(.+)?$~', $this->data['php_version'], $matches) && isset($matches[2])) {
diff --git a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php
index ae751c4f2e011..a3cf2147cb576 100644
--- a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php
+++ b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php
@@ -183,6 +183,11 @@ public function __wakeup()
$charset = array_pop($this->data);
$fileLinkFormat = array_pop($this->data);
$this->dataCount = \count($this->data);
+ foreach ($this->data as $dump) {
+ if (!\is_string($dump['name']) || !\is_string($dump['file']) || !\is_int($dump['line'])) {
+ throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
+ }
+ }
self::__construct($this->stopwatch, \is_string($fileLinkFormat) || $fileLinkFormat instanceof FileLinkFormatter ? $fileLinkFormat : null, \is_string($charset) ? $charset : null);
}
@@ -257,7 +262,7 @@ public function __destruct()
}
}
- private function doDump(DataDumperInterface $dumper, $data, string $name, string $file, int $line)
+ private function doDump(DataDumperInterface $dumper, Data $data, string $name, string $file, int $line)
{
if ($dumper instanceof CliDumper) {
$contextDumper = function ($name, $file, $line, $fmt) {
diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php
index 18ac83f6a8f45..f0ec789e82073 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 $freshCache = [];
- public const VERSION = '4.4.20';
- public const VERSION_ID = 40420;
+ public const VERSION = '4.4.21';
+ public const VERSION_ID = 40421;
public const MAJOR_VERSION = 4;
public const MINOR_VERSION = 4;
- public const RELEASE_VERSION = 20;
+ public const RELEASE_VERSION = 21;
public const EXTRA_VERSION = '';
public const END_OF_MAINTENANCE = '11/2022';
@@ -533,7 +533,7 @@ protected function initializeContainer()
if (!flock($lock, $wouldBlock ? \LOCK_SH : \LOCK_EX)) {
fclose($lock);
$lock = null;
- } elseif (!\is_object($this->container = include $cachePath)) {
+ } elseif (!is_file($cachePath) || !\is_object($this->container = include $cachePath)) {
$this->container = null;
} elseif (!$oldContainer || \get_class($this->container) !== $oldContainer->name) {
flock($lock, \LOCK_UN);
diff --git a/src/Symfony/Component/HttpKernel/Tests/DataCollector/ConfigDataCollectorTest.php b/src/Symfony/Component/HttpKernel/Tests/DataCollector/ConfigDataCollectorTest.php
index df6af954f3a7b..86bd394f56087 100644
--- a/src/Symfony/Component/HttpKernel/Tests/DataCollector/ConfigDataCollectorTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/DataCollector/ConfigDataCollectorTest.php
@@ -41,6 +41,13 @@ public function testCollect()
$this->assertSame(\extension_loaded('xdebug'), $c->hasXDebug());
$this->assertSame(\extension_loaded('Zend OPcache') && filter_var(ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN), $c->hasZendOpcache());
$this->assertSame(\extension_loaded('apcu') && filter_var(ini_get('apc.enabled'), \FILTER_VALIDATE_BOOLEAN), $c->hasApcu());
+ $this->assertSame(sprintf('%s.%s', Kernel::MAJOR_VERSION, Kernel::MINOR_VERSION), $c->getSymfonyMinorVersion());
+ $this->assertContains($c->getSymfonyState(), ['eol', 'eom', 'dev', 'stable']);
+
+ $eom = \DateTime::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_MAINTENANCE)->format('F Y');
+ $eol = \DateTime::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_LIFE)->format('F Y');
+ $this->assertSame($eom, $c->getSymfonyEom());
+ $this->assertSame($eol, $c->getSymfonyEol());
}
/**
@@ -58,6 +65,34 @@ public function testLegacy()
$this->assertSame('name', $c->getApplicationName());
$this->assertNull($c->getApplicationVersion());
}
+
+ public function testCollectWithoutKernel()
+ {
+ $c = new ConfigDataCollector();
+ $c->collect(new Request(), new Response());
+
+ $this->assertSame('n/a', $c->getEnv());
+ $this->assertSame('n/a', $c->isDebug());
+ $this->assertSame('config', $c->getName());
+ $this->assertMatchesRegularExpression('~^'.preg_quote($c->getPhpVersion(), '~').'~', \PHP_VERSION);
+ $this->assertMatchesRegularExpression('~'.preg_quote((string) $c->getPhpVersionExtra(), '~').'$~', \PHP_VERSION);
+ $this->assertSame(\PHP_INT_SIZE * 8, $c->getPhpArchitecture());
+ $this->assertSame(class_exists(\Locale::class, false) && \Locale::getDefault() ? \Locale::getDefault() : 'n/a', $c->getPhpIntlLocale());
+ $this->assertSame(date_default_timezone_get(), $c->getPhpTimezone());
+ $this->assertSame(Kernel::VERSION, $c->getSymfonyVersion());
+ $this->assertSame(4 === Kernel::MINOR_VERSION, $c->isSymfonyLts());
+ $this->assertNull($c->getToken());
+ $this->assertSame(\extension_loaded('xdebug'), $c->hasXDebug());
+ $this->assertSame(\extension_loaded('Zend OPcache') && filter_var(ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN), $c->hasZendOpcache());
+ $this->assertSame(\extension_loaded('apcu') && filter_var(ini_get('apc.enabled'), \FILTER_VALIDATE_BOOLEAN), $c->hasApcu());
+ $this->assertSame(sprintf('%s.%s', Kernel::MAJOR_VERSION, Kernel::MINOR_VERSION), $c->getSymfonyMinorVersion());
+ $this->assertContains($c->getSymfonyState(), ['eol', 'eom', 'dev', 'stable']);
+
+ $eom = \DateTime::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_MAINTENANCE)->format('F Y');
+ $eol = \DateTime::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_LIFE)->format('F Y');
+ $this->assertSame($eom, $c->getSymfonyEom());
+ $this->assertSame($eol, $c->getSymfonyEol());
+ }
}
class KernelForTest extends Kernel
diff --git a/src/Symfony/Component/Inflector/Inflector.php b/src/Symfony/Component/Inflector/Inflector.php
index 8d2323cc4bd15..461c5f6090572 100644
--- a/src/Symfony/Component/Inflector/Inflector.php
+++ b/src/Symfony/Component/Inflector/Inflector.php
@@ -231,6 +231,9 @@ final class Inflector
// bacteria (bacterium), criteria (criterion), phenomena (phenomenon)
['noi', 3, true, true, 'ions'],
+ // coupon (coupons)
+ ['nop', 3, true, true, 'pons'],
+
// seasons (season), treasons (treason), poisons (poison), lessons (lesson)
['nos', 3, true, true, 'sons'],
diff --git a/src/Symfony/Component/Inflector/Tests/InflectorTest.php b/src/Symfony/Component/Inflector/Tests/InflectorTest.php
index a3c22ac0f5106..62b3790fd3e33 100644
--- a/src/Symfony/Component/Inflector/Tests/InflectorTest.php
+++ b/src/Symfony/Component/Inflector/Tests/InflectorTest.php
@@ -201,6 +201,7 @@ public function pluralizeProvider()
['crisis', 'crises'],
['criteria', 'criterion'],
['cup', 'cups'],
+ ['coupon', 'coupons'],
['data', 'data'],
['day', 'days'],
['disco', 'discos'],
diff --git a/src/Symfony/Component/Lock/Tests/Store/StoreFactoryTest.php b/src/Symfony/Component/Lock/Tests/Store/StoreFactoryTest.php
index 06bdd57b6cd83..31abcdf5894c4 100644
--- a/src/Symfony/Component/Lock/Tests/Store/StoreFactoryTest.php
+++ b/src/Symfony/Component/Lock/Tests/Store/StoreFactoryTest.php
@@ -40,7 +40,7 @@ public function testCreateStore($connection, string $expectedStoreClass)
public function validConnections()
{
if (class_exists(\Redis::class)) {
- yield [$this->createMock(\Redis::class), RedisStore::class];
+ yield [new \Redis(), RedisStore::class];
}
if (class_exists(RedisProxy::class)) {
yield [$this->createMock(RedisProxy::class), RedisStore::class];
diff --git a/src/Symfony/Component/Mailer/Bridge/Amazon/Tests/Transport/SesApiTransportTest.php b/src/Symfony/Component/Mailer/Bridge/Amazon/Tests/Transport/SesApiTransportTest.php
index 254a1ff84eb09..d795457560c1e 100644
--- a/src/Symfony/Component/Mailer/Bridge/Amazon/Tests/Transport/SesApiTransportTest.php
+++ b/src/Symfony/Component/Mailer/Bridge/Amazon/Tests/Transport/SesApiTransportTest.php
@@ -62,8 +62,8 @@ public function testSend()
parse_str($options['body'], $content);
$this->assertSame('Hello!', $content['Message_Subject_Data']);
- $this->assertSame('Saif Eddin ', $content['Destination_ToAddresses_member'][0]);
- $this->assertSame('Fabien ', $content['Source']);
+ $this->assertSame('"Saif Eddin" ', $content['Destination_ToAddresses_member'][0]);
+ $this->assertSame('"Fabien" ', $content['Source']);
$this->assertSame('Hello There!', $content['Message_Body_Text_Data']);
$xml = '
diff --git a/src/Symfony/Component/Mailer/Bridge/Amazon/composer.json b/src/Symfony/Component/Mailer/Bridge/Amazon/composer.json
index 5108ba33a92f1..3f66c4172ab71 100644
--- a/src/Symfony/Component/Mailer/Bridge/Amazon/composer.json
+++ b/src/Symfony/Component/Mailer/Bridge/Amazon/composer.json
@@ -17,7 +17,7 @@
],
"require": {
"php": ">=7.1.3",
- "symfony/mailer": "^4.4|^5.0"
+ "symfony/mailer": "^4.4.21|^5.2.6"
},
"require-dev": {
"symfony/http-client": "^4.3|^5.0"
diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/Tests/Transport/MailgunApiTransportTest.php b/src/Symfony/Component/Mailer/Bridge/Mailgun/Tests/Transport/MailgunApiTransportTest.php
index b4d235671ccda..2e4c53b83fc98 100644
--- a/src/Symfony/Component/Mailer/Bridge/Mailgun/Tests/Transport/MailgunApiTransportTest.php
+++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/Tests/Transport/MailgunApiTransportTest.php
@@ -82,8 +82,8 @@ public function testSend()
}
$this->assertStringContainsString('Hello!', $content);
- $this->assertStringContainsString('Saif Eddin ', $content);
- $this->assertStringContainsString('Fabien ', $content);
+ $this->assertStringContainsString('"Saif Eddin" ', $content);
+ $this->assertStringContainsString('"Fabien" ', $content);
$this->assertStringContainsString('Hello There!', $content);
return new MockResponse(json_encode(['id' => 'foobar']), [
diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/composer.json b/src/Symfony/Component/Mailer/Bridge/Mailgun/composer.json
index ac4051d7782f1..606d00281682f 100644
--- a/src/Symfony/Component/Mailer/Bridge/Mailgun/composer.json
+++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/composer.json
@@ -17,7 +17,7 @@
],
"require": {
"php": ">=7.1.3",
- "symfony/mailer": "^4.4|^5.0"
+ "symfony/mailer": "^4.4.21|^5.2.6"
},
"require-dev": {
"symfony/http-client": "^4.3|^5.0"
diff --git a/src/Symfony/Component/Mailer/Bridge/Postmark/Tests/Transport/PostmarkApiTransportTest.php b/src/Symfony/Component/Mailer/Bridge/Postmark/Tests/Transport/PostmarkApiTransportTest.php
index 356880bc20e63..a7c7259ce3426 100644
--- a/src/Symfony/Component/Mailer/Bridge/Postmark/Tests/Transport/PostmarkApiTransportTest.php
+++ b/src/Symfony/Component/Mailer/Bridge/Postmark/Tests/Transport/PostmarkApiTransportTest.php
@@ -74,8 +74,8 @@ public function testSend()
$this->assertStringContainsStringIgnoringCase('X-Postmark-Server-Token: KEY', $options['headers'][1] ?? $options['request_headers'][1]);
$body = json_decode($options['body'], true);
- $this->assertSame('Fabien ', $body['From']);
- $this->assertSame('Saif Eddin ', $body['To']);
+ $this->assertSame('"Fabien" ', $body['From']);
+ $this->assertSame('"Saif Eddin" ', $body['To']);
$this->assertSame('Hello!', $body['Subject']);
$this->assertSame('Hello There!', $body['TextBody']);
diff --git a/src/Symfony/Component/Mailer/Bridge/Postmark/composer.json b/src/Symfony/Component/Mailer/Bridge/Postmark/composer.json
index 2efbe5c3381ae..e70d4df085295 100644
--- a/src/Symfony/Component/Mailer/Bridge/Postmark/composer.json
+++ b/src/Symfony/Component/Mailer/Bridge/Postmark/composer.json
@@ -17,7 +17,7 @@
],
"require": {
"php": ">=7.1.3",
- "symfony/mailer": "^4.4|^5.0"
+ "symfony/mailer": "^4.4.21|^5.2.6"
},
"require-dev": {
"symfony/http-client": "^4.3|^5.0"
diff --git a/src/Symfony/Component/Mailer/composer.json b/src/Symfony/Component/Mailer/composer.json
index 88bf72e353c79..f8c416649d68f 100644
--- a/src/Symfony/Component/Mailer/composer.json
+++ b/src/Symfony/Component/Mailer/composer.json
@@ -17,10 +17,10 @@
],
"require": {
"php": ">=7.1.3",
- "egulias/email-validator": "^2.1.10",
+ "egulias/email-validator": "^2.1.10|^3",
"psr/log": "~1.0",
"symfony/event-dispatcher": "^4.3",
- "symfony/mime": "^4.4|^5.0",
+ "symfony/mime": "^4.4.21|^5.2.6",
"symfony/service-contracts": "^1.1|^2"
},
"require-dev": {
diff --git a/src/Symfony/Component/Messenger/Command/ConsumeMessagesCommand.php b/src/Symfony/Component/Messenger/Command/ConsumeMessagesCommand.php
index da432fa4c934f..d3151b49a47c0 100644
--- a/src/Symfony/Component/Messenger/Command/ConsumeMessagesCommand.php
+++ b/src/Symfony/Component/Messenger/Command/ConsumeMessagesCommand.php
@@ -79,7 +79,7 @@ protected function configure(): void
new InputOption('sleep', null, InputOption::VALUE_REQUIRED, 'Seconds to sleep before asking for new messages after no messages were found', 1),
new InputOption('bus', 'b', InputOption::VALUE_REQUIRED, 'Name of the bus to which received messages should be dispatched (if not passed, bus is determined automatically)'),
])
- ->setDescription('Consumes messages')
+ ->setDescription('Consume messages')
->setHelp(<<<'EOF'
The %command.name% command consumes messages and dispatches them to the message bus.
diff --git a/src/Symfony/Component/Messenger/Command/DebugCommand.php b/src/Symfony/Component/Messenger/Command/DebugCommand.php
index 6e9fc617755ab..999bb557a4cd1 100644
--- a/src/Symfony/Component/Messenger/Command/DebugCommand.php
+++ b/src/Symfony/Component/Messenger/Command/DebugCommand.php
@@ -43,7 +43,7 @@ protected function configure()
{
$this
->addArgument('bus', InputArgument::OPTIONAL, sprintf('The bus id (one of "%s")', implode('", "', array_keys($this->mapping))))
- ->setDescription('Lists messages you can dispatch using the message buses')
+ ->setDescription('List messages you can dispatch using the message buses')
->setHelp(<<<'EOF'
The %command.name% command displays all messages that can be
dispatched using the message buses:
diff --git a/src/Symfony/Component/Messenger/Command/FailedMessagesRetryCommand.php b/src/Symfony/Component/Messenger/Command/FailedMessagesRetryCommand.php
index 696e77f7f1949..415b719dc5f8c 100644
--- a/src/Symfony/Component/Messenger/Command/FailedMessagesRetryCommand.php
+++ b/src/Symfony/Component/Messenger/Command/FailedMessagesRetryCommand.php
@@ -59,7 +59,7 @@ protected function configure(): void
new InputArgument('id', InputArgument::IS_ARRAY, 'Specific message id(s) to retry'),
new InputOption('force', null, InputOption::VALUE_NONE, 'Force action without confirmation'),
])
- ->setDescription('Retries one or more messages from the failure transport.')
+ ->setDescription('Retry one or more messages from the failure transport.')
->setHelp(<<<'EOF'
The %command.name% retries message in the failure transport.
diff --git a/src/Symfony/Component/Messenger/Command/FailedMessagesShowCommand.php b/src/Symfony/Component/Messenger/Command/FailedMessagesShowCommand.php
index bcb6911632152..349f27293ab1c 100644
--- a/src/Symfony/Component/Messenger/Command/FailedMessagesShowCommand.php
+++ b/src/Symfony/Component/Messenger/Command/FailedMessagesShowCommand.php
@@ -37,7 +37,7 @@ protected function configure(): void
new InputArgument('id', InputArgument::OPTIONAL, 'Specific message id to show'),
new InputOption('max', null, InputOption::VALUE_REQUIRED, 'Maximum number of messages to list', 50),
])
- ->setDescription('Shows one or more messages from the failure transport.')
+ ->setDescription('Show one or more messages from the failure transport.')
->setHelp(<<<'EOF'
The %command.name% shows message that are pending in the failure transport.
diff --git a/src/Symfony/Component/Messenger/Command/SetupTransportsCommand.php b/src/Symfony/Component/Messenger/Command/SetupTransportsCommand.php
index 84395892fdf9b..4157a911f4902 100644
--- a/src/Symfony/Component/Messenger/Command/SetupTransportsCommand.php
+++ b/src/Symfony/Component/Messenger/Command/SetupTransportsCommand.php
@@ -41,7 +41,7 @@ protected function configure()
{
$this
->addArgument('transport', InputArgument::OPTIONAL, 'Name of the transport to setup', null)
- ->setDescription('Prepares the required infrastructure for the transport')
+ ->setDescription('Prepare the required infrastructure for the transport')
->setHelp(<<%command.name% command setups the transports:
diff --git a/src/Symfony/Component/Messenger/Command/StopWorkersCommand.php b/src/Symfony/Component/Messenger/Command/StopWorkersCommand.php
index 7df9b9d2014f0..646ea5e87e151 100644
--- a/src/Symfony/Component/Messenger/Command/StopWorkersCommand.php
+++ b/src/Symfony/Component/Messenger/Command/StopWorkersCommand.php
@@ -42,7 +42,7 @@ protected function configure(): void
{
$this
->setDefinition([])
- ->setDescription('Stops workers after their current message')
+ ->setDescription('Stop workers after their current message')
->setHelp(<<<'EOF'
The %command.name% command sends a signal to stop any messenger:consume processes that are running.
diff --git a/src/Symfony/Component/Mime/Address.php b/src/Symfony/Component/Mime/Address.php
index 53f682c9c2bb7..61d35e39e9cfe 100644
--- a/src/Symfony/Component/Mime/Address.php
+++ b/src/Symfony/Component/Mime/Address.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\Mime;
use Egulias\EmailValidator\EmailValidator;
+use Egulias\EmailValidator\Validation\MessageIDValidation;
use Egulias\EmailValidator\Validation\RFCValidation;
use Symfony\Component\Mime\Encoder\IdnAddressEncoder;
use Symfony\Component\Mime\Exception\InvalidArgumentException;
@@ -51,7 +52,7 @@ public function __construct(string $address, string $name = '')
$this->address = trim($address);
$this->name = trim(str_replace(["\n", "\r"], '', $name));
- if (!self::$validator->isValid($this->address, new RFCValidation())) {
+ if (!self::$validator->isValid($this->address, class_exists(MessageIDValidation::class) ? new MessageIDValidation() : new RFCValidation())) {
throw new RfcComplianceException(sprintf('Email "%s" does not comply with addr-spec of RFC 2822.', $address));
}
}
@@ -77,7 +78,16 @@ public function getEncodedAddress(): string
public function toString(): string
{
- return ($n = $this->getName()) ? $n.' <'.$this->getEncodedAddress().'>' : $this->getEncodedAddress();
+ return ($n = $this->getEncodedName()) ? $n.' <'.$this->getEncodedAddress().'>' : $this->getEncodedAddress();
+ }
+
+ public function getEncodedName(): string
+ {
+ if ('' === $this->getName()) {
+ return '';
+ }
+
+ return sprintf('"%s"', preg_replace('/"/u', '\"', $this->getName()));
}
/**
diff --git a/src/Symfony/Component/Mime/Tests/AddressTest.php b/src/Symfony/Component/Mime/Tests/AddressTest.php
index 50d5780d82b34..476bb9c91acf4 100644
--- a/src/Symfony/Component/Mime/Tests/AddressTest.php
+++ b/src/Symfony/Component/Mime/Tests/AddressTest.php
@@ -27,7 +27,7 @@ public function testConstructor()
$a = new Address('fabien@symfonï.com', 'Fabien');
$this->assertEquals('Fabien', $a->getName());
$this->assertEquals('fabien@symfonï.com', $a->getAddress());
- $this->assertEquals('Fabien ', $a->toString());
+ $this->assertEquals('"Fabien" ', $a->toString());
$this->assertEquals('fabien@xn--symfon-nwa.com', $a->getEncodedAddress());
}
@@ -153,4 +153,10 @@ public function fromStringProvider()
],
];
}
+
+ public function testEncodeNameIfNameContainsCommas()
+ {
+ $address = new Address('fabien@symfony.com', 'Fabien, "Potencier');
+ $this->assertSame('"Fabien, \"Potencier" ', $address->toString());
+ }
}
diff --git a/src/Symfony/Component/Mime/composer.json b/src/Symfony/Component/Mime/composer.json
index 166dfea10fe0c..aaced87ff49c7 100644
--- a/src/Symfony/Component/Mime/composer.json
+++ b/src/Symfony/Component/Mime/composer.json
@@ -21,10 +21,11 @@
"symfony/polyfill-mbstring": "^1.0"
},
"require-dev": {
- "egulias/email-validator": "^2.1.10",
+ "egulias/email-validator": "^2.1.10|^3.1",
"symfony/dependency-injection": "^3.4|^4.1|^5.0"
},
"conflict": {
+ "egulias/email-validator": "~3.0.0",
"symfony/mailer": "<4.4"
},
"autoload": {
diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.nn.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.nn.xlf
index 27b55e5675cac..89ca44fa88f26 100644
--- a/src/Symfony/Component/Security/Core/Resources/translations/security.nn.xlf
+++ b/src/Symfony/Component/Security/Core/Resources/translations/security.nn.xlf
@@ -36,7 +36,7 @@
No session available, it either timed out or cookies are not enabled.
- Ingen sesjon tilgjengeleg. Sesjonen er anten ikkje lenger gyldig, eller informasjonskapslar er ikke skrudd på i nettlesaren.
+ Ingen sesjon tilgjengeleg. Sesjonen er anten ikkje lenger gyldig, eller informasjonskapslar er ikkje skrudd på i nettlesaren.No token could be found.
@@ -56,12 +56,20 @@
Account is disabled.
- Brukarkontoen er deaktivert.
+ Brukarkontoen er sperra.Account is locked.Brukarkontoen er sperra.
+
+ Too many failed login attempts, please try again later.
+ For mange innloggingsforsøk har feila, prøv igjen seinare.
+
+
+ Invalid or expired login link.
+ Innloggingslenka er ugyldig eller utgjengen.
+