Merge branch '4.4' into 5.0
* 4.4: (30 commits) [Security] Check UserInterface::getPassword is not null before calling needsRehash gracefully handle missing event dispatchers Fix TokenStorage::reset not called in stateless firewall [DotEnv] Remove `usePutEnv` property default value [HttpFoundation] get currently session.gc_maxlifetime if ttl doesnt exists Set up typo fix [DependencyInjection] Handle env var placeholders in CheckTypeDeclarationsPass [Cache] fix memory leak when using PhpArrayAdapter [Validator] Allow underscore character "_" in URL username and password [TwigBridge] Update bootstrap_4_layout.html.twig [FrameworkBundle][SodiumVault] Create secrets directory only when needed fix parsing negative octal numbers [SecurityBundle] Passwords are not encoded when algorithm set to \"true\" [DependencyInjection] Resolve expressions in CheckTypeDeclarationsPass [SecurityBundle] Properly escape regex in AddSessionDomainConstraintPass do not validate passwords when the hash is null [DI] fix resolving bindings for named TypedReference [Config] never try loading failed classes twice with ClassExistenceResource [Mailer] Fix SMTP Authentication when using STARTTLS [DI] Fix making the container path-independent when the app is in /app ...
This commit is contained in:
commit
1d1e29c8cd
@ -7,6 +7,46 @@ in 4.3 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.3.0...v4.3.1
|
||||
|
||||
* 4.3.9 (2019-12-01)
|
||||
|
||||
* bug #34649 more robust initialization from request (dbu)
|
||||
* bug #34671 [Security] Fix clearing remember-me cookie after deauthentication (chalasr)
|
||||
* bug #34711 Fix the translation commands when a template contains a syntax error (fabpot)
|
||||
* bug #34560 [Config][ReflectionClassResource] Handle parameters with undefined constant as their default values (fancyweb)
|
||||
* bug #34695 [Config] don't break on virtual stack frames in ClassExistenceResource (nicolas-grekas)
|
||||
* bug #34716 [DependencyInjection] fix dumping number-like string parameters (xabbuh)
|
||||
* bug #34558 [Console] Fix autocomplete multibyte input support (fancyweb)
|
||||
* bug #34130 [Console] Fix commands description with numeric namespaces (fancyweb)
|
||||
* bug #34677 [EventDispatcher] Better error reporting when arguments to dispatch() are swapped (rimas-kudelis)
|
||||
* bug #33573 [TwigBridge] Add row_attr to all form themes (fancyweb)
|
||||
* bug #34019 [Serializer] CsvEncoder::NO_HEADERS_KEY ignored when used in constructor (Dario Savella)
|
||||
* bug #34083 [Form] Keep preferred_choices order for choice groups (vilius-g)
|
||||
* bug #34091 [Debug] work around failing chdir() on Darwin (mary2501)
|
||||
* bug #34305 [PhpUnitBridge] Read configuration CLI directive (ro0NL)
|
||||
* bug #34490 [Serializer] Fix MetadataAwareNameConverter usage with string group (antograssiot)
|
||||
* bug #34632 [Console] Fix trying to access array offset on value of type int (Tavafi)
|
||||
* bug #34669 [HttpClient] turn exception into log when the request has no content-type (nicolas-grekas)
|
||||
* bug #34636 [VarDumper] notice on potential undefined index (sylvainmetayer)
|
||||
* bug #34668 [Cache] Make sure we get the correct number of values from redis::mget() (thePanz)
|
||||
* bug #34569 [Workflow] Apply the same logic of precedence between the apply() and the buildTransitionBlockerList() method (lyrixx)
|
||||
* bug #34533 [Monolog Bridge] Fixed accessing static property as non static. (Sander-Toonen)
|
||||
* bug #34546 [Serializer] Add DateTimeZoneNormalizer into Dependency Injection (jewome62)
|
||||
* bug #34547 [Messenger] Error when specified default bus is not among the configured (vudaltsov)
|
||||
* bug #34551 [Security] SwitchUser is broken when the User Provider always returns a valid user (tucksaun)
|
||||
* bug #34385 Avoid empty "If-Modified-Since" header in validation request (mpdude)
|
||||
* bug #34458 [Validator] ConstraintValidatorTestCase: add missing return value to mocked validate method calls (ogizanagi)
|
||||
* bug #34451 [DependencyInjection] Fix dumping multiple deprecated aliases (shyim)
|
||||
* bug #34448 [Form] allow button names to start with uppercase letter (xabbuh)
|
||||
* bug #34419 [Cache] Disable igbinary on PHP >= 7.4 (nicolas-grekas)
|
||||
* bug #34366 [HttpFoundation] Allow redirecting to URLs that contain a semicolon (JayBizzle)
|
||||
* bug #34397 [FrameworkBundle] Remove project dir from Translator cache vary scanned directories (fancyweb)
|
||||
* bug #34408 [Cache] catch exceptions when using PDO directly (xabbuh)
|
||||
* bug #34410 [HttpFoundation] Fix MySQL column type definition. (jbroutier)
|
||||
* bug #34398 [Config] fix id-generation for GlobResource (nicolas-grekas)
|
||||
* bug #34396 [Finder] Allow ssh2 stream wrapper for sftp (damienalexandre)
|
||||
* bug #34383 [DI] Use reproducible entropy to generate env placeholders (nicolas-grekas)
|
||||
* bug #34381 [WebProfilerBundle] Require symfony/twig-bundle (fancyweb)
|
||||
|
||||
* 4.3.8 (2019-11-13)
|
||||
|
||||
* bug #34344 [Console] Constant STDOUT might be undefined (nicolas-grekas)
|
||||
|
@ -19,8 +19,8 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Jakub Zalas (jakubzalas)
|
||||
- Javier Eguiluz (javier.eguiluz)
|
||||
- Roland Franssen (ro0)
|
||||
- Johannes S (johannes)
|
||||
- Grégoire Pineau (lyrixx)
|
||||
- Johannes S (johannes)
|
||||
- Kris Wallsmith (kriswallsmith)
|
||||
- Yonel Ceruto (yonelceruto)
|
||||
- Hugo Hamon (hhamon)
|
||||
@ -36,13 +36,13 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Martin Hasoň (hason)
|
||||
- Hamza Amrouche (simperfit)
|
||||
- Jeremy Mikola (jmikola)
|
||||
- Jean-François Simon (jfsimon)
|
||||
- Jules Pietri (heah)
|
||||
- Jean-François Simon (jfsimon)
|
||||
- Benjamin Eberlei (beberlei)
|
||||
- Igor Wiedler (igorw)
|
||||
- Jérémy DERUSSÉ (jderusse)
|
||||
- Eriksen Costa (eriksencosta)
|
||||
- Thomas Calvet (fancyweb)
|
||||
- Eriksen Costa (eriksencosta)
|
||||
- Guilhem Niot (energetick)
|
||||
- Sarah Khalil (saro0h)
|
||||
- Tobias Nyholm (tobias)
|
||||
@ -57,15 +57,15 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Francis Besset (francisbesset)
|
||||
- stealth35 (stealth35)
|
||||
- Alexander Mols (asm89)
|
||||
- Konstantin Myakshin (koc)
|
||||
- Matthias Pigulla (mpdude)
|
||||
- Konstantin Myakshin (koc)
|
||||
- Bulat Shakirzyanov (avalanche123)
|
||||
- Valentin Udaltsov (vudaltsov)
|
||||
- Grégoire Paris (greg0ire)
|
||||
- Saša Stamenković (umpirsky)
|
||||
- Peter Rehm (rpet)
|
||||
- Kevin Bond (kbond)
|
||||
- Henrik Bjørnskov (henrikbjorn)
|
||||
- Valentin Udaltsov (vudaltsov)
|
||||
- Miha Vrhovnik
|
||||
- Diego Saint Esteben (dii3g0)
|
||||
- Gábor Egyed (1ed)
|
||||
@ -91,11 +91,11 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Henrik Westphal (snc)
|
||||
- Dariusz Górecki (canni)
|
||||
- David Buchmann (dbu)
|
||||
- Graham Campbell (graham)
|
||||
- Dariusz Ruminski
|
||||
- Lee McDermott
|
||||
- Brandon Turner
|
||||
- Luis Cordova (cordoval)
|
||||
- Graham Campbell (graham)
|
||||
- Daniel Holmes (dholmes)
|
||||
- Toni Uebernickel (havvg)
|
||||
- Bart van den Burg (burgov)
|
||||
@ -109,20 +109,21 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Maxime STEINHAUSSER
|
||||
- Michal Piotrowski (eventhorizon)
|
||||
- Tim Nagel (merk)
|
||||
- Baptiste Clavié (talus)
|
||||
- Chris Wilkinson (thewilkybarkid)
|
||||
- Brice BERNARD (brikou)
|
||||
- Baptiste Clavié (talus)
|
||||
- marc.weistroff
|
||||
- Tomáš Votruba (tomas_votruba)
|
||||
- Peter Kokot (maastermedia)
|
||||
- Jérôme Vasseur (jvasseur)
|
||||
- lenar
|
||||
- Alexander Schwenn (xelaris)
|
||||
- Włodzimierz Gajda (gajdaw)
|
||||
- Sebastiaan Stok (sstok)
|
||||
- Adrien Brault (adrienbrault)
|
||||
- Peter Kokot (maastermedia)
|
||||
- Jacob Dreesen (jdreesen)
|
||||
- Florian Voutzinos (florianv)
|
||||
- Teoh Han Hui (teohhanhui)
|
||||
- Colin Frei
|
||||
- Oskar Stark (oskarstark)
|
||||
- Javier Spagnoletti (phansys)
|
||||
@ -131,13 +132,12 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Daniel Wehner (dawehner)
|
||||
- excelwebzone
|
||||
- Gordon Franke (gimler)
|
||||
- Teoh Han Hui (teohhanhui)
|
||||
- Tugdual Saunier (tucksaun)
|
||||
- Fabien Pennequin (fabienpennequin)
|
||||
- Théo FIDRY (theofidry)
|
||||
- Eric GELOEN (gelo)
|
||||
- Joel Wurtz (brouznouf)
|
||||
- Lars Strojny (lstrojny)
|
||||
- Tugdual Saunier (tucksaun)
|
||||
- Jannik Zschiesche (apfelbox)
|
||||
- Robert Schönthal (digitalkaoz)
|
||||
- Gregor Harlan (gharlan)
|
||||
@ -209,6 +209,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Mario A. Alvarez Garcia (nomack84)
|
||||
- Dennis Benkert (denderello)
|
||||
- DQNEO
|
||||
- Andre Rømcke (andrerom)
|
||||
- mcfedr (mcfedr)
|
||||
- Ben Davies (bendavies)
|
||||
- Gary PEGEOT (gary-p)
|
||||
@ -233,7 +234,6 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Pierre Minnieur (pminnieur)
|
||||
- fivestar
|
||||
- Dominique Bongiraud
|
||||
- Andre Rømcke (andrerom)
|
||||
- Jeremy Livingston (jeremylivingston)
|
||||
- Michael Lee (zerustech)
|
||||
- Matthieu Auger (matthieuauger)
|
||||
@ -249,6 +249,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Michele Orselli (orso)
|
||||
- Sven Paulus (subsven)
|
||||
- Maxime Veber (nek-)
|
||||
- Anthony GRASSIOT (antograssiot)
|
||||
- Rui Marinho (ruimarinho)
|
||||
- Eugene Wissner
|
||||
- Pascal Montoya
|
||||
@ -257,8 +258,10 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Tristan Darricau (nicofuma)
|
||||
- Victor Bocharsky (bocharsky_bw)
|
||||
- Marcel Beerta (mazen)
|
||||
- Maxime Helias (maxhelias)
|
||||
- Pavel Batanov (scaytrase)
|
||||
- Mantis Development
|
||||
- David Prévot
|
||||
- Loïc Faugeron
|
||||
- Hidde Wieringa (hiddewie)
|
||||
- dFayet
|
||||
@ -285,7 +288,6 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Xavier Montaña Carreras (xmontana)
|
||||
- Rémon van de Kamp (rpkamp)
|
||||
- Mickaël Andrieu (mickaelandrieu)
|
||||
- Anthony GRASSIOT (antograssiot)
|
||||
- Xavier Perez
|
||||
- Arjen Brouwer (arjenjb)
|
||||
- Katsuhiro OGAWA
|
||||
@ -311,13 +313,12 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Smaine Milianni (ismail1432)
|
||||
- Chekote
|
||||
- François Pluchino (francoispluchino)
|
||||
- Christopher Hertel (chertel)
|
||||
- Antoine Makdessi (amakdessi)
|
||||
- Thomas Adam
|
||||
- Jhonny Lidfors (jhonne)
|
||||
- Diego Agulló (aeoris)
|
||||
- jdhoek
|
||||
- Maxime Helias (maxhelias)
|
||||
- David Prévot
|
||||
- Bob den Otter (bopp)
|
||||
- Thomas Schulz (king2500)
|
||||
- Frank de Jonge (frenkynet)
|
||||
@ -342,6 +343,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Arjen van der Meijden
|
||||
- Mathieu Lechat
|
||||
- Marc Weistroff (futurecat)
|
||||
- Damien Alexandre (damienalexandre)
|
||||
- Simon Mönch (sm)
|
||||
- Christian Schmidt
|
||||
- Patrick Landolt (scube)
|
||||
@ -349,6 +351,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- David Badura (davidbadura)
|
||||
- Chad Sikorra (chadsikorra)
|
||||
- Chris Smith (cs278)
|
||||
- Thomas Bisignani (toma)
|
||||
- Florian Klein (docteurklein)
|
||||
- Manuel Kiessling (manuelkiessling)
|
||||
- Atsuhiro KUBO (iteman)
|
||||
@ -407,18 +410,17 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Tomasz Kowalczyk (thunderer)
|
||||
- Artur Eshenbrener
|
||||
- Timo Bakx (timobakx)
|
||||
- Damien Alexandre (damienalexandre)
|
||||
- Thomas Perez (scullwm)
|
||||
- Saif Eddin Gmati (azjezz)
|
||||
- Felix Labrecque
|
||||
- Yaroslav Kiliba
|
||||
- Terje Bråten
|
||||
- Tien Vo (tienvx)
|
||||
- Robbert Klarenbeek (robbertkl)
|
||||
- Eric Masoero (eric-masoero)
|
||||
- JhonnyL
|
||||
- hossein zolfi (ocean)
|
||||
- Clément Gautier (clementgautier)
|
||||
- Thomas Bisignani (toma)
|
||||
- Dāvis Zālītis (k0d3r1s)
|
||||
- Sanpi
|
||||
- Eduardo Gulias (egulias)
|
||||
@ -429,6 +431,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Grzegorz (Greg) Zdanowski (kiler129)
|
||||
- Iker Ibarguren (ikerib)
|
||||
- Kirill chEbba Chebunin (chebba)
|
||||
- Rokas Mikalkėnas (rokasm)
|
||||
- Greg Thornton (xdissent)
|
||||
- Martin Hujer (martinhujer)
|
||||
- Alex Bowers
|
||||
@ -443,7 +446,6 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Michele Locati
|
||||
- Pavel Volokitin (pvolok)
|
||||
- Valentine Boineau (valentineboineau)
|
||||
- Christopher Hertel (chertel)
|
||||
- Arthur de Moulins (4rthem)
|
||||
- Matthias Althaus (althaus)
|
||||
- Nicolas Dewez (nicolas_dewez)
|
||||
@ -476,6 +478,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Oscar Cubo Medina (ocubom)
|
||||
- Karel Souffriau
|
||||
- Christophe L. (christophelau)
|
||||
- Sander Toonen (xatoo)
|
||||
- Anthon Pang (robocoder)
|
||||
- Michael Käfer (michael_kaefer)
|
||||
- Sébastien Santoro (dereckson)
|
||||
@ -502,6 +505,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Olivier Dolbeau (odolbeau)
|
||||
- Jan Rosier (rosier)
|
||||
- Alessandro Lai (jean85)
|
||||
- Desjardins Jérôme (jewome62)
|
||||
- Arturs Vonda
|
||||
- Josip Kruslin
|
||||
- Matthew Smeets
|
||||
@ -529,7 +533,6 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Gonzalo Vilaseca (gonzalovilaseca)
|
||||
- Tarmo Leppänen (tarlepp)
|
||||
- Marcin Sikoń (marphi)
|
||||
- Tien Vo (tienvx)
|
||||
- Denis Brumann (dbrumann)
|
||||
- Dominik Zogg (dominik.zogg)
|
||||
- Marek Pietrzak
|
||||
@ -540,6 +543,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Gintautas Miselis
|
||||
- Rob Bast
|
||||
- Roberto Espinoza (respinoza)
|
||||
- Emanuele Panzeri (thepanz)
|
||||
- Soufian EZ-ZANTAR (soezz)
|
||||
- Zander Baldwin
|
||||
- Gocha Ossinkine (ossinkine)
|
||||
@ -603,7 +607,6 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Adam Szaraniec (mimol)
|
||||
- Dariusz Ruminski
|
||||
- Erik Trapman (eriktrapman)
|
||||
- Rokas Mikalkėnas (rokasm)
|
||||
- De Cock Xavier (xdecock)
|
||||
- Almog Baku (almogbaku)
|
||||
- Karoly Gossler (connorhu)
|
||||
@ -648,11 +651,11 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Jeremy Benoist
|
||||
- fritzmg
|
||||
- Lenar Lõhmus
|
||||
- Sander Toonen (xatoo)
|
||||
- Benjamin Laugueux (yzalis)
|
||||
- Zach Badgett (zachbadgett)
|
||||
- Aurélien Fredouelle
|
||||
- Pavel Campr (pcampr)
|
||||
- Andrii Dembitskyi
|
||||
- Johnny Robeson (johnny)
|
||||
- Marko Kaznovac (kaznovac)
|
||||
- Disquedur
|
||||
@ -694,7 +697,6 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Sinan Eldem
|
||||
- Alexandre Dupuy (satchette)
|
||||
- Malte Blättermann
|
||||
- Desjardins Jérôme (jewome62)
|
||||
- Simeon Kolev (simeon_kolev9)
|
||||
- Joost van Driel (j92)
|
||||
- Jonas Elfering
|
||||
@ -762,11 +764,12 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Giso Stallenberg (gisostallenberg)
|
||||
- Michael Devery (mickadoo)
|
||||
- Antoine Corcy
|
||||
- Ahmed Ashraf (ahmedash95)
|
||||
- Sascha Grossenbacher
|
||||
- Emanuele Panzeri (thepanz)
|
||||
- Szijarto Tamas
|
||||
- Robin Lehrmann (robinlehrmann)
|
||||
- Catalin Dan
|
||||
- Soner Sayakci
|
||||
- Jaroslav Kuba
|
||||
- Kristijan Kanalas
|
||||
- Stephan Vock
|
||||
@ -825,11 +828,13 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Markus Fasselt (digilist)
|
||||
- Julien DIDIER (juliendidier)
|
||||
- Dominik Ritter (dritter)
|
||||
- Dimitri Gritsajuk (ottaviano)
|
||||
- Sebastian Grodzicki (sgrodzicki)
|
||||
- Jeroen van den Enden (stoefke)
|
||||
- Pascal Helfenstein
|
||||
- Baldur Rensch (brensch)
|
||||
- Pierre Rineau
|
||||
- Vilius Grigaliūnas
|
||||
- Vladyslav Petrovych
|
||||
- Alex Xandra Albert Sim
|
||||
- Carson Full
|
||||
@ -946,6 +951,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Patrick Allaert
|
||||
- Gustavo Falco (gfalco)
|
||||
- Matt Robinson (inanimatt)
|
||||
- Kristof Van Cauwenbergh (kristofvc)
|
||||
- Aleksey Podskrebyshev
|
||||
- Calin Mihai Pristavu
|
||||
- David Marín Carreño (davefx)
|
||||
@ -984,6 +990,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Thomas Landauer
|
||||
- 243083df
|
||||
- Thibault Duplessis
|
||||
- Rimas Kudelis
|
||||
- Marc Abramowitz
|
||||
- Martijn Evers
|
||||
- Tony Tran
|
||||
@ -996,12 +1003,12 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Johnson Page (jwpage)
|
||||
- Ruben Gonzalez (rubenruateltek)
|
||||
- Michael Roterman (wtfzdotnet)
|
||||
- Andrii Dembitskyi
|
||||
- Arno Geurts
|
||||
- Adán Lobato (adanlobato)
|
||||
- Ian Jenkins (jenkoian)
|
||||
- Marcos Gómez Vilches (markitosgv)
|
||||
- Matthew Davis (mdavis1982)
|
||||
- Markus S. (staabm)
|
||||
- Maks
|
||||
- Antoine LA
|
||||
- den
|
||||
@ -1187,7 +1194,6 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Sergii Smertin (nfx)
|
||||
- Mikkel Paulson
|
||||
- Michał Strzelecki
|
||||
- Soner Sayakci
|
||||
- hugofonseca (fonsecas72)
|
||||
- Marc Duboc (icemad)
|
||||
- Matthias Krauser (mkrauser)
|
||||
@ -1241,6 +1247,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Jeremy Bush
|
||||
- wizhippo
|
||||
- Thomason, James
|
||||
- Dario Savella
|
||||
- Gordienko Vladislav
|
||||
- marie
|
||||
- Viacheslav Sychov
|
||||
@ -1291,6 +1298,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Oxan van Leeuwen
|
||||
- pkowalczyk
|
||||
- Soner Sayakci
|
||||
- Koen Reiniers (koenre)
|
||||
- Max Voloshin (maxvoloshin)
|
||||
- Nicolas Fabre (nfabre)
|
||||
- Raul Rodriguez (raul782)
|
||||
@ -1306,6 +1314,8 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Felicitus
|
||||
- Krzysztof Przybyszewski
|
||||
- alexpozzi
|
||||
- Vladimir
|
||||
- Jorge Vahldick (jvahldick)
|
||||
- Frederic Godfrin
|
||||
- Paul Matthews
|
||||
- Jakub Kisielewski
|
||||
@ -1752,7 +1762,6 @@ Symfony is the result of the work of many people who made the code better
|
||||
- downace
|
||||
- Aarón Nieves Fernández
|
||||
- Mike Meier
|
||||
- Vilius Grigaliūnas
|
||||
- Kirill Saksin
|
||||
- Koalabaerchen
|
||||
- michalmarcinkowski
|
||||
@ -1765,6 +1774,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- efeen
|
||||
- Nicolas Pion
|
||||
- Muhammed Akbulut
|
||||
- Roy-Orbison
|
||||
- Aaron Somi
|
||||
- Michał Dąbrowski (defrag)
|
||||
- Konstantin Grachev (grachevko)
|
||||
@ -1802,12 +1812,14 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Alexander Li (aweelex)
|
||||
- Bram Van der Sype (brammm)
|
||||
- Guile (guile)
|
||||
- Mark Beech (jaybizzle)
|
||||
- Julien Moulin (lizjulien)
|
||||
- Raito Akehanareru (raito)
|
||||
- Mauro Foti (skler)
|
||||
- Yannick Warnier (ywarnier)
|
||||
- Kevin Decherf
|
||||
- Jason Woods
|
||||
- Maria Grazia Patteri
|
||||
- klemens
|
||||
- dened
|
||||
- Dmitry Korotovsky
|
||||
@ -1823,6 +1835,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Sören Bernstein
|
||||
- devel
|
||||
- taiiiraaa
|
||||
- Ali Tavafi
|
||||
- Trevor Suarez
|
||||
- gedrox
|
||||
- Bohan Yang
|
||||
@ -1959,6 +1972,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Juan M Martínez
|
||||
- Gilles Gauthier
|
||||
- Pavinthan
|
||||
- Sylvain METAYER
|
||||
- ddebree
|
||||
- Kuba Werłos
|
||||
- Gyula Szucs
|
||||
@ -2015,6 +2029,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Marcin Szepczynski (szepczynski)
|
||||
- Cyrille Jouineau (tuxosaurus)
|
||||
- Vladimir Chernyshev (volch)
|
||||
- Wim Godden (wimg)
|
||||
- Yorkie Chadwick (yorkie76)
|
||||
- GuillaumeVerdon
|
||||
- Philipp Keck
|
||||
@ -2026,6 +2041,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Taylan Kasap
|
||||
- Michael Orlitzky
|
||||
- Nicolas A. Bérard-Nault
|
||||
- Quentin Favrie
|
||||
- Saem Ghani
|
||||
- Stefan Oderbolz
|
||||
- Curtis
|
||||
@ -2051,12 +2067,10 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Jeffrey Moelands (jeffreymoelands)
|
||||
- Hugo Alliaume (kocal)
|
||||
- Simon CONSTANS (kosssi)
|
||||
- Kristof Van Cauwenbergh (kristofvc)
|
||||
- Dennis Langen (nijusan)
|
||||
- Paulius Jarmalavičius (pjarmalavicius)
|
||||
- Ramon Henrique Ornelas (ramonornela)
|
||||
- Ricardo de Vries (ricknox)
|
||||
- Markus S. (staabm)
|
||||
- Thomas Dutrion (theocrite)
|
||||
- Till Klampaeckel (till)
|
||||
- Tobias Weinert (tweini)
|
||||
@ -2074,6 +2088,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Cas
|
||||
- Dusan Kasan
|
||||
- Michael Steininger
|
||||
- Nardberjean
|
||||
- Karolis
|
||||
- Myke79
|
||||
- Brian Debuire
|
||||
@ -2145,7 +2160,6 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Daniel STANCU
|
||||
- Ryan Rud
|
||||
- Ondrej Slinták
|
||||
- Rimas Kudelis
|
||||
- vlechemin
|
||||
- Brian Corrigan
|
||||
- Ladislav Tánczos
|
||||
@ -2263,6 +2277,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Sebastian Landwehr (dword123)
|
||||
- Adel ELHAIBA (eadel)
|
||||
- Damián Nohales (eagleoneraptor)
|
||||
- Jordane VASPARD (elementaire)
|
||||
- Elliot Anderson (elliot)
|
||||
- Fabien D. (fabd)
|
||||
- Carsten Eilers (fnc)
|
||||
@ -2277,6 +2292,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Peter Orosz (ill_logical)
|
||||
- Imangazaliev Muhammad (imangazaliev)
|
||||
- j0k (j0k)
|
||||
- Jeremie Broutier (jbroutier)
|
||||
- joris de wit (jdewit)
|
||||
- Jérémy CROMBEZ (jeremy)
|
||||
- Jose Manuel Gonzalez (jgonzalez)
|
||||
@ -2293,6 +2309,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- samuel laulhau (lalop)
|
||||
- Laurent Bachelier (laurentb)
|
||||
- Luís Cobucci (lcobucci)
|
||||
- Jérémy (libertjeremy)
|
||||
- Mehdi Achour (machour)
|
||||
- Matthieu Mota (matthieumota)
|
||||
- Matthieu Moquet (mattketmo)
|
||||
@ -2300,12 +2317,12 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Michal Čihař (mcihar)
|
||||
- Matt Drollette (mdrollette)
|
||||
- Adam Monsen (meonkeys)
|
||||
- Hugo Monteiro (monteiro)
|
||||
- Ala Eddine Khefifi (nayzo)
|
||||
- emilienbouard (neime)
|
||||
- Nicholas Byfleet (nickbyfleet)
|
||||
- Marco Petersen (ocrampete16)
|
||||
- ollie harridge (ollietb)
|
||||
- Dimitri Gritsajuk (ottaviano)
|
||||
- Paul Andrieux (paulandrieux)
|
||||
- Paulo Ribeiro (paulo)
|
||||
- Paweł Szczepanek (pauluz)
|
||||
@ -2333,6 +2350,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Julien Sanchez (sumbobyboys)
|
||||
- Guillermo Gisinger (t3chn0r)
|
||||
- Markus Tacker (tacker)
|
||||
- Thiago Cordeiro (thiagocordeiro)
|
||||
- Tom Newby (tomnewbyau)
|
||||
- Andrew Clark (tqt_andrew_clark)
|
||||
- David Lumaye (tux1124)
|
||||
@ -2341,6 +2359,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Moritz Kraft (userfriendly)
|
||||
- Víctor Mateo (victormateo)
|
||||
- Vincent (vincent1870)
|
||||
- Vincent MOULENE (vints24)
|
||||
- David Herrmann (vworldat)
|
||||
- Eugene Babushkin (warl)
|
||||
- Wouter Sioen (wouter_sioen)
|
||||
@ -2365,6 +2384,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- damaya
|
||||
- Kevin Weber
|
||||
- Ben Scott
|
||||
- Alexandru Năstase
|
||||
- Dionysis Arvanitis
|
||||
- Sergey Fedotov
|
||||
- Konstantin Scheumann
|
||||
@ -2378,6 +2398,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Zander Baldwin
|
||||
- Philipp Scheit
|
||||
- max
|
||||
- Alexander Bauer (abauer)
|
||||
- Ahmad Mayahi (ahmadmayahi)
|
||||
- Mohamed Karnichi (amiral)
|
||||
- Andrew Carter (andrewcarteruk)
|
||||
|
21
link
21
link
@ -23,11 +23,14 @@ use Symfony\Component\Filesystem\Filesystem;
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
|
||||
$copy = false !== $k = array_search('--copy', $argv, true);
|
||||
$copy && array_splice($argv, $k, 1);
|
||||
$pathToProject = $argv[1] ?? getcwd();
|
||||
|
||||
if (!is_dir("$pathToProject/vendor/symfony")) {
|
||||
echo 'Link dependencies to components to a local clone of the main symfony/symfony GitHub repository.'.PHP_EOL.PHP_EOL;
|
||||
echo "Usage: $argv[0] /path/to/the/project".PHP_EOL.PHP_EOL;
|
||||
echo 'Link (or copy) dependencies to components to a local clone of the main symfony/symfony GitHub repository.'.PHP_EOL.PHP_EOL;
|
||||
echo "Usage: $argv[0] /path/to/the/project".PHP_EOL;
|
||||
echo ' Use `--copy` to copy dependencies instead of symlink'.PHP_EOL.PHP_EOL;
|
||||
echo "The directory \"$pathToProject\" does not exist or the dependencies are not installed, did you forget to run \"composer install\" in your project?".PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
@ -50,7 +53,7 @@ foreach ($directories as $dir) {
|
||||
|
||||
foreach (glob("$pathToProject/vendor/symfony/*", GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
|
||||
$package = 'symfony/'.basename($dir);
|
||||
if (is_link($dir)) {
|
||||
if (!$copy && is_link($dir)) {
|
||||
echo "\"$package\" is already a symlink, skipping.".PHP_EOL;
|
||||
continue;
|
||||
}
|
||||
@ -59,11 +62,17 @@ foreach (glob("$pathToProject/vendor/symfony/*", GLOB_ONLYDIR | GLOB_NOSORT) as
|
||||
continue;
|
||||
}
|
||||
|
||||
$sfDir = '\\' === DIRECTORY_SEPARATOR ? $sfPackages[$package] : $filesystem->makePathRelative($sfPackages[$package], dirname(realpath($dir)));
|
||||
$sfDir = ('\\' === DIRECTORY_SEPARATOR || $copy) ? $sfPackages[$package] : $filesystem->makePathRelative($sfPackages[$package], dirname(realpath($dir)));
|
||||
|
||||
$filesystem->remove($dir);
|
||||
$filesystem->symlink($sfDir, $dir);
|
||||
echo "\"$package\" has been linked to \"$sfPackages[$package]\".".PHP_EOL;
|
||||
|
||||
if ($copy) {
|
||||
$filesystem->mirror($sfDir, $dir);
|
||||
echo "\"$package\" has been copied from \"$sfPackages[$package]\".".PHP_EOL;
|
||||
} else {
|
||||
$filesystem->symlink($sfDir, $dir);
|
||||
echo "\"$package\" has been linked to \"$sfPackages[$package]\".".PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (glob("$pathToProject/var/cache/*", GLOB_NOSORT) as $cacheDir) {
|
||||
|
@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Tests\Handler;
|
||||
|
||||
use Monolog\Formatter\JsonFormatter;
|
||||
use Monolog\Logger;
|
||||
use Monolog\Processor\ProcessIdProcessor;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Bridge\Monolog\Formatter\VarDumperFormatter;
|
||||
use Symfony\Bridge\Monolog\Handler\ServerLogHandler;
|
||||
use Symfony\Component\VarDumper\Cloner\Data;
|
||||
|
||||
/**
|
||||
* Tests the ServerLogHandler.
|
||||
*/
|
||||
class ServerLogHandlerTest extends TestCase
|
||||
{
|
||||
public function testFormatter()
|
||||
{
|
||||
$handler = new ServerLogHandler('tcp://127.0.0.1:9999');
|
||||
$this->assertInstanceOf(VarDumperFormatter::class, $handler->getFormatter());
|
||||
|
||||
$formatter = new JsonFormatter();
|
||||
$handler->setFormatter($formatter);
|
||||
$this->assertSame($formatter, $handler->getFormatter());
|
||||
}
|
||||
|
||||
public function testIsHandling()
|
||||
{
|
||||
$handler = new ServerLogHandler('tcp://127.0.0.1:9999', Logger::INFO);
|
||||
$this->assertFalse($handler->isHandling(['level' => Logger::DEBUG]), '->isHandling returns false when no output is set');
|
||||
}
|
||||
|
||||
public function testGetFormatter()
|
||||
{
|
||||
$handler = new ServerLogHandler('tcp://127.0.0.1:9999');
|
||||
$this->assertInstanceOf(VarDumperFormatter::class, $handler->getFormatter(),
|
||||
'-getFormatter returns VarDumperFormatter by default'
|
||||
);
|
||||
}
|
||||
|
||||
public function testWritingAndFormatting()
|
||||
{
|
||||
$host = 'tcp://127.0.0.1:9999';
|
||||
$handler = new ServerLogHandler($host, Logger::INFO, false);
|
||||
$handler->pushProcessor(new ProcessIdProcessor());
|
||||
|
||||
$infoRecord = [
|
||||
'message' => 'My info message',
|
||||
'context' => [],
|
||||
'level' => Logger::INFO,
|
||||
'level_name' => Logger::getLevelName(Logger::INFO),
|
||||
'channel' => 'app',
|
||||
'datetime' => new \DateTime('2013-05-29 16:21:54'),
|
||||
'extra' => [],
|
||||
];
|
||||
|
||||
$socket = stream_socket_server($host, $errno, $errstr);
|
||||
$this->assertIsResource($socket, sprintf('Server start failed on "%s": %s %s.', $host, $errstr, $errno));
|
||||
|
||||
$this->assertTrue($handler->handle($infoRecord), 'The handler finished handling the log as bubble is false.');
|
||||
|
||||
$sockets = [(int) $socket => $socket];
|
||||
$write = [];
|
||||
|
||||
for ($i = 0; $i < 10; ++$i) {
|
||||
$read = $sockets;
|
||||
stream_select($read, $write, $write, null);
|
||||
|
||||
foreach ($read as $stream) {
|
||||
if ($socket === $stream) {
|
||||
$stream = stream_socket_accept($socket);
|
||||
$sockets[(int) $stream] = $stream;
|
||||
} elseif (feof($stream)) {
|
||||
unset($sockets[(int) $stream]);
|
||||
fclose($stream);
|
||||
} else {
|
||||
$message = fgets($stream);
|
||||
fclose($stream);
|
||||
|
||||
$record = unserialize(base64_decode($message));
|
||||
$this->assertIsArray($record);
|
||||
|
||||
$this->assertArrayHasKey('message', $record);
|
||||
$this->assertEquals('My info message', $record['message']);
|
||||
|
||||
$this->assertArrayHasKey('extra', $record);
|
||||
$this->assertInstanceOf(Data::class, $record['extra']);
|
||||
$extra = $record['extra']->getValue(true);
|
||||
$this->assertIsArray($extra);
|
||||
$this->assertArrayHasKey('process_id', $extra);
|
||||
$this->assertSame(getmypid(), $extra['process_id']);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
usleep(100000);
|
||||
}
|
||||
$this->fail('Fail to read message from server');
|
||||
}
|
||||
}
|
@ -242,7 +242,7 @@
|
||||
{% block checkbox_radio_label -%}
|
||||
{#- Do not display the label if widget is not defined in order to prevent double label rendering -#}
|
||||
{%- if widget is defined -%}
|
||||
{% set is_parent_custom = parent_label_class is defined and ('checkbox-custom' in parent_label_class or 'radio-custom' in parent_label_class) %}
|
||||
{% set is_parent_custom = parent_label_class is defined and ('checkbox-custom' in parent_label_class or 'radio-custom' in parent_label_class or 'switch-custom' in parent_label_class) %}
|
||||
{% set is_custom = label_attr.class is defined and ('checkbox-custom' in label_attr.class or 'radio-custom' in label_attr.class or 'switch-custom' in label_attr.class) %}
|
||||
{%- if is_parent_custom or is_custom -%}
|
||||
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' custom-control-label')|trim}) -%}
|
||||
|
@ -21,6 +21,7 @@ use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
|
||||
@ -228,6 +229,8 @@ EOF
|
||||
$container->compile();
|
||||
} else {
|
||||
(new XmlFileLoader($container = new ContainerBuilder(), new FileLocator()))->load($kernel->getContainer()->getParameter('debug.container.dump'));
|
||||
$locatorPass = new ServiceLocatorTagPass();
|
||||
$locatorPass->process($container);
|
||||
}
|
||||
|
||||
return $this->containerBuilder = $container;
|
||||
|
@ -25,6 +25,7 @@ class SodiumVault extends AbstractVault implements EnvVarLoaderInterface
|
||||
private $encryptionKey;
|
||||
private $decryptionKey;
|
||||
private $pathPrefix;
|
||||
private $secretsDir;
|
||||
|
||||
/**
|
||||
* @param string|object|null $decryptionKey A string or a stringable object that defines the private key to use to decrypt the vault
|
||||
@ -36,12 +37,9 @@ class SodiumVault extends AbstractVault implements EnvVarLoaderInterface
|
||||
throw new \TypeError(sprintf('Decryption key should be a string or an object that implements the __toString() method, %s given.', \gettype($decryptionKey)));
|
||||
}
|
||||
|
||||
if (!is_dir($secretsDir) && !@mkdir($secretsDir, 0777, true) && !is_dir($secretsDir)) {
|
||||
throw new \RuntimeException(sprintf('Unable to create the secrets directory (%s)', $secretsDir));
|
||||
}
|
||||
|
||||
$this->pathPrefix = rtrim(strtr($secretsDir, '/', \DIRECTORY_SEPARATOR), \DIRECTORY_SEPARATOR).\DIRECTORY_SEPARATOR.basename($secretsDir).'.';
|
||||
$this->decryptionKey = $decryptionKey;
|
||||
$this->secretsDir = $secretsDir;
|
||||
}
|
||||
|
||||
public function generateKeys(bool $override = false): bool
|
||||
@ -203,9 +201,20 @@ class SodiumVault extends AbstractVault implements EnvVarLoaderInterface
|
||||
$data = str_replace('%', '\x', rawurlencode($data));
|
||||
$data = sprintf("<?php // %s on %s\n\nreturn \"%s\";\n", $name, date('r'), $data);
|
||||
|
||||
$this->createSecretsDir();
|
||||
|
||||
if (false === file_put_contents($this->pathPrefix.$file.'.php', $data, LOCK_EX)) {
|
||||
$e = error_get_last();
|
||||
throw new \ErrorException($e['message'] ?? 'Failed to write secrets data.', 0, $e['type'] ?? E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
private function createSecretsDir(): void
|
||||
{
|
||||
if ($this->secretsDir && !is_dir($this->secretsDir) && !@mkdir($this->secretsDir, 0777, true) && !is_dir($this->secretsDir)) {
|
||||
throw new \RuntimeException(sprintf('Unable to create the secrets directory (%s)', $this->secretsDir));
|
||||
}
|
||||
|
||||
$this->secretsDir = null;
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ class AddSessionDomainConstraintPass implements CompilerPassInterface
|
||||
}
|
||||
|
||||
$sessionOptions = $container->getParameter('session.storage.options');
|
||||
$domainRegexp = empty($sessionOptions['cookie_domain']) ? '%s' : sprintf('(?:%%s|(?:.+\.)?%s)', preg_quote(trim($sessionOptions['cookie_domain'], '.')));
|
||||
$domainRegexp = empty($sessionOptions['cookie_domain']) ? '%%s' : sprintf('(?:%%%%s|(?:.+\.)?%s)', preg_quote(trim($sessionOptions['cookie_domain'], '.')));
|
||||
|
||||
if ('auto' === ($sessionOptions['cookie_secure'] ?? null)) {
|
||||
$secureDomainRegexp = sprintf('{^https://%s$}i', $domainRegexp);
|
||||
|
@ -43,6 +43,7 @@ class RegisterTokenUsageTrackingPass implements CompilerPassInterface
|
||||
|
||||
if (!$container->has('session')) {
|
||||
$container->setAlias('security.token_storage', 'security.untracked_token_storage')->setPublic(true);
|
||||
$container->getDefinition('security.untracked_token_storage')->addTag('kernel.reset', ['method' => 'reset']);
|
||||
} elseif ($container->hasDefinition('security.context_listener')) {
|
||||
$container->getDefinition('security.context_listener')
|
||||
->setArgument(6, [new Reference('security.token_storage'), 'enableUsageTracking']);
|
||||
|
@ -362,7 +362,13 @@ class MainConfiguration implements ConfigurationInterface
|
||||
->performNoDeepMerging()
|
||||
->beforeNormalization()->ifString()->then(function ($v) { return ['algorithm' => $v]; })->end()
|
||||
->children()
|
||||
->scalarNode('algorithm')->cannotBeEmpty()->end()
|
||||
->scalarNode('algorithm')
|
||||
->cannotBeEmpty()
|
||||
->validate()
|
||||
->ifTrue(function ($v) { return !\is_string($v); })
|
||||
->thenInvalid('You must provide a string value.')
|
||||
->end()
|
||||
->end()
|
||||
->arrayNode('migrate_from')
|
||||
->prototype('scalar')->end()
|
||||
->beforeNormalization()->castToArray()->end()
|
||||
|
@ -39,6 +39,8 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
|
||||
private $values;
|
||||
private $createCacheItem;
|
||||
|
||||
private static $valuesCache = [];
|
||||
|
||||
/**
|
||||
* @param string $file The PHP file were values are cached
|
||||
* @param AdapterInterface $fallbackPool A pool to fallback on when an item is not hit
|
||||
@ -65,22 +67,17 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
|
||||
* This adapter takes advantage of how PHP stores arrays in its latest versions.
|
||||
*
|
||||
* @param string $file The PHP file were values are cached
|
||||
* @param CacheItemPoolInterface $fallbackPool Fallback when opcache is disabled
|
||||
* @param CacheItemPoolInterface $fallbackPool A pool to fallback on when an item is not hit
|
||||
*
|
||||
* @return CacheItemPoolInterface
|
||||
*/
|
||||
public static function create(string $file, CacheItemPoolInterface $fallbackPool)
|
||||
{
|
||||
// Shared memory is available in PHP 7.0+ with OPCache enabled
|
||||
if (filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN)) {
|
||||
if (!$fallbackPool instanceof AdapterInterface) {
|
||||
$fallbackPool = new ProxyAdapter($fallbackPool);
|
||||
}
|
||||
|
||||
return new static($file, $fallbackPool);
|
||||
if (!$fallbackPool instanceof AdapterInterface) {
|
||||
$fallbackPool = new ProxyAdapter($fallbackPool);
|
||||
}
|
||||
|
||||
return $fallbackPool;
|
||||
return new static($file, $fallbackPool);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -281,6 +278,7 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
|
||||
$this->keys = $this->values = [];
|
||||
|
||||
$cleared = @unlink($this->file) || !file_exists($this->file);
|
||||
unset(self::$valuesCache[$this->file]);
|
||||
|
||||
if ($this->pool instanceof AdapterInterface) {
|
||||
return $this->pool->clear($prefix) && $cleared;
|
||||
@ -375,6 +373,7 @@ EOF;
|
||||
unset($serialized, $value, $dump);
|
||||
|
||||
@rename($tmpFile, $this->file);
|
||||
unset(self::$valuesCache[$this->file]);
|
||||
|
||||
$this->initialize();
|
||||
}
|
||||
@ -384,12 +383,15 @@ EOF;
|
||||
*/
|
||||
private function initialize()
|
||||
{
|
||||
if (!file_exists($this->file)) {
|
||||
if (isset(self::$valuesCache[$this->file])) {
|
||||
$values = self::$valuesCache[$this->file];
|
||||
} elseif (!file_exists($this->file)) {
|
||||
$this->keys = $this->values = [];
|
||||
|
||||
return;
|
||||
} else {
|
||||
$values = self::$valuesCache[$this->file] = (include $this->file) ?: [[], []];
|
||||
}
|
||||
$values = (include $this->file) ?: [[], []];
|
||||
|
||||
if (2 !== \count($values) || !isset($values[0], $values[1])) {
|
||||
$this->keys = $this->values = [];
|
||||
|
@ -66,6 +66,8 @@ class PhpArrayAdapterTest extends AdapterTestCase
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
$this->createCachePool()->clear();
|
||||
|
||||
if (file_exists(sys_get_temp_dir().'/symfony-cache')) {
|
||||
FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache');
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ class PhpArrayAdapterWithFallbackTest extends AdapterTestCase
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
$this->createCachePool()->clear();
|
||||
|
||||
if (file_exists(sys_get_temp_dir().'/symfony-cache')) {
|
||||
FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache');
|
||||
}
|
||||
|
@ -37,7 +37,9 @@ class ClassExistenceResource implements SelfCheckingResourceInterface
|
||||
public function __construct(string $resource, bool $exists = null)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
$this->exists = $exists;
|
||||
if (null !== $exists) {
|
||||
$this->exists = [(bool) $exists, null];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,9 +67,13 @@ class ClassExistenceResource implements SelfCheckingResourceInterface
|
||||
{
|
||||
$loaded = class_exists($this->resource, false) || interface_exists($this->resource, false) || trait_exists($this->resource, false);
|
||||
|
||||
if (null !== $exists = &self::$existsCache[(int) (0 >= $timestamp)][$this->resource]) {
|
||||
$exists = $exists || $loaded;
|
||||
} elseif (!$exists = $loaded) {
|
||||
if (null !== $exists = &self::$existsCache[$this->resource]) {
|
||||
if ($loaded) {
|
||||
$exists = [true, null];
|
||||
} elseif (0 >= $timestamp && !$exists[0] && null !== $exists[1]) {
|
||||
throw new \ReflectionException($exists[1]);
|
||||
}
|
||||
} elseif ([false, null] === $exists = [$loaded, null]) {
|
||||
if (!self::$autoloadLevel++) {
|
||||
spl_autoload_register(__CLASS__.'::throwOnRequiredClass');
|
||||
}
|
||||
@ -75,16 +81,19 @@ class ClassExistenceResource implements SelfCheckingResourceInterface
|
||||
self::$autoloadedClass = ltrim($this->resource, '\\');
|
||||
|
||||
try {
|
||||
$exists = class_exists($this->resource) || interface_exists($this->resource, false) || trait_exists($this->resource, false);
|
||||
$exists[0] = class_exists($this->resource) || interface_exists($this->resource, false) || trait_exists($this->resource, false);
|
||||
} catch (\Exception $e) {
|
||||
$exists[1] = $e->getMessage();
|
||||
|
||||
try {
|
||||
self::throwOnRequiredClass($this->resource, $e);
|
||||
} catch (\ReflectionException $e) {
|
||||
if (0 >= $timestamp) {
|
||||
unset(self::$existsCache[1][$this->resource]);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$exists[1] = $e->getMessage();
|
||||
} finally {
|
||||
self::$autoloadedClass = $autoloadedClass;
|
||||
if (!--self::$autoloadLevel) {
|
||||
@ -97,7 +106,7 @@ class ClassExistenceResource implements SelfCheckingResourceInterface
|
||||
$this->exists = $exists;
|
||||
}
|
||||
|
||||
return $this->exists xor !$exists;
|
||||
return $this->exists[0] xor !$exists[0];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -112,6 +121,16 @@ class ClassExistenceResource implements SelfCheckingResourceInterface
|
||||
return ['resource', 'exists'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __wakeup()
|
||||
{
|
||||
if (\is_bool($this->exists)) {
|
||||
$this->exists = [$this->exists, null];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws a reflection exception when the passed class does not exist but is required.
|
||||
*
|
||||
@ -147,7 +166,17 @@ class ClassExistenceResource implements SelfCheckingResourceInterface
|
||||
throw $previous;
|
||||
}
|
||||
|
||||
$e = new \ReflectionException(sprintf('Class "%s" not found while loading "%s".', $class, self::$autoloadedClass), 0, $previous);
|
||||
$message = sprintf('Class "%s" not found.', $class);
|
||||
|
||||
if (self::$autoloadedClass !== $class) {
|
||||
$message = substr_replace($message, sprintf(' while loading "%s"', self::$autoloadedClass), -1, 0);
|
||||
}
|
||||
|
||||
if (null !== $previous) {
|
||||
$message = $previous->getMessage();
|
||||
}
|
||||
|
||||
$e = new \ReflectionException($message, 0, $previous);
|
||||
|
||||
if (null !== $previous) {
|
||||
throw $e;
|
||||
|
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Config\Tests\Fixtures;
|
||||
|
||||
class FileNameMismatchOnPurpose
|
||||
{
|
||||
}
|
||||
|
||||
throw new \RuntimeException('Mismatch between file name and class name.');
|
@ -13,6 +13,7 @@ namespace Symfony\Component\Config\Tests\Resource;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Config\Resource\ClassExistenceResource;
|
||||
use Symfony\Component\Config\Tests\Fixtures\BadFileName;
|
||||
use Symfony\Component\Config\Tests\Fixtures\BadParent;
|
||||
use Symfony\Component\Config\Tests\Fixtures\Resource\ConditionalClass;
|
||||
|
||||
@ -90,6 +91,24 @@ EOF
|
||||
$res->isFresh(0);
|
||||
}
|
||||
|
||||
public function testBadFileName()
|
||||
{
|
||||
$this->expectException('ReflectionException');
|
||||
$this->expectExceptionMessage('Mismatch between file name and class name.');
|
||||
|
||||
$res = new ClassExistenceResource(BadFileName::class, false);
|
||||
$res->isFresh(0);
|
||||
}
|
||||
|
||||
public function testBadFileNameBis()
|
||||
{
|
||||
$this->expectException('ReflectionException');
|
||||
$this->expectExceptionMessage('Mismatch between file name and class name.');
|
||||
|
||||
$res = new ClassExistenceResource(BadFileName::class, false);
|
||||
$res->isFresh(0);
|
||||
}
|
||||
|
||||
public function testConditionalClass()
|
||||
{
|
||||
$res = new ClassExistenceResource(ConditionalClass::class, false);
|
||||
|
@ -14,12 +14,16 @@ namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\Container;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\EnvNotFoundException;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidParameterTypeException;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\ExpressionLanguage;
|
||||
use Symfony\Component\DependencyInjection\Parameter;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\ServiceLocator;
|
||||
use Symfony\Component\ExpressionLanguage\Expression;
|
||||
|
||||
/**
|
||||
* Checks whether injected parameters are compatible with type declarations.
|
||||
@ -39,6 +43,8 @@ final class CheckTypeDeclarationsPass extends AbstractRecursivePass
|
||||
|
||||
private $autoload;
|
||||
|
||||
private $expressionLanguage;
|
||||
|
||||
/**
|
||||
* @param bool $autoload Whether services who's class in not loaded should be checked or not.
|
||||
* Defaults to false to save loading code during compilation.
|
||||
@ -100,19 +106,21 @@ final class CheckTypeDeclarationsPass extends AbstractRecursivePass
|
||||
$reflectionParameters = $reflectionFunction->getParameters();
|
||||
$checksCount = min($reflectionFunction->getNumberOfParameters(), \count($values));
|
||||
|
||||
$envPlaceholderUniquePrefix = $this->container->getParameterBag() instanceof EnvPlaceholderParameterBag ? $this->container->getParameterBag()->getEnvPlaceholderUniquePrefix() : null;
|
||||
|
||||
for ($i = 0; $i < $checksCount; ++$i) {
|
||||
if (!$reflectionParameters[$i]->hasType() || $reflectionParameters[$i]->isVariadic()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->checkType($checkedDefinition, $values[$i], $reflectionParameters[$i]);
|
||||
$this->checkType($checkedDefinition, $values[$i], $reflectionParameters[$i], $envPlaceholderUniquePrefix);
|
||||
}
|
||||
|
||||
if ($reflectionFunction->isVariadic() && ($lastParameter = end($reflectionParameters))->hasType()) {
|
||||
$variadicParameters = \array_slice($values, $lastParameter->getPosition());
|
||||
|
||||
foreach ($variadicParameters as $variadicParameter) {
|
||||
$this->checkType($checkedDefinition, $variadicParameter, $lastParameter);
|
||||
$this->checkType($checkedDefinition, $variadicParameter, $lastParameter, $envPlaceholderUniquePrefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -120,7 +128,7 @@ final class CheckTypeDeclarationsPass extends AbstractRecursivePass
|
||||
/**
|
||||
* @throws InvalidParameterTypeException When a parameter is not compatible with the declared type
|
||||
*/
|
||||
private function checkType(Definition $checkedDefinition, $value, \ReflectionParameter $parameter): void
|
||||
private function checkType(Definition $checkedDefinition, $value, \ReflectionParameter $parameter, ?string $envPlaceholderUniquePrefix): void
|
||||
{
|
||||
$type = $parameter->getType()->getName();
|
||||
|
||||
@ -172,8 +180,24 @@ final class CheckTypeDeclarationsPass extends AbstractRecursivePass
|
||||
|
||||
if ($value instanceof Parameter) {
|
||||
$value = $this->container->getParameter($value);
|
||||
} elseif (\is_string($value) && '%' === ($value[0] ?? '') && preg_match('/^%([^%]+)%$/', $value, $match)) {
|
||||
$value = $this->container->getParameter($match[1]);
|
||||
} elseif ($value instanceof Expression) {
|
||||
$value = $this->getExpressionLanguage()->evaluate($value, ['container' => $this->container]);
|
||||
} elseif (\is_string($value)) {
|
||||
if ('%' === ($value[0] ?? '') && preg_match('/^%([^%]+)%$/', $value, $match)) {
|
||||
// Only array parameters are not inlined when dumped.
|
||||
$value = [];
|
||||
} elseif ($envPlaceholderUniquePrefix && false !== strpos($value, 'env_')) {
|
||||
// If the value is an env placeholder that is either mixed with a string or with another env placeholder, then its resolved value will always be a string, so we don't need to resolve it.
|
||||
// We don't need to change the value because it is already a string.
|
||||
if ('' === preg_replace('/'.$envPlaceholderUniquePrefix.'_\w+_[a-f0-9]{32}/U', '', $value, -1, $c) && 1 === $c) {
|
||||
try {
|
||||
$value = $this->container->resolveEnvPlaceholders($value, true);
|
||||
} catch (EnvNotFoundException | RuntimeException $e) {
|
||||
// If an env placeholder cannot be resolved, we skip the validation.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null === $value && $parameter->allowsNull()) {
|
||||
@ -202,4 +226,13 @@ final class CheckTypeDeclarationsPass extends AbstractRecursivePass
|
||||
throw new InvalidParameterTypeException($this->currentId, \is_object($value) ? \get_class($value) : \gettype($value), $parameter);
|
||||
}
|
||||
}
|
||||
|
||||
private function getExpressionLanguage(): ExpressionLanguage
|
||||
{
|
||||
if (null === $this->expressionLanguage) {
|
||||
$this->expressionLanguage = new ExpressionLanguage(null, $this->container->getExpressionLanguageProviders());
|
||||
}
|
||||
|
||||
return $this->expressionLanguage;
|
||||
}
|
||||
}
|
||||
|
@ -96,6 +96,11 @@ class ResolveBindingsPass extends AbstractRecursivePass
|
||||
if ($value instanceof TypedReference && $value->getType() === (string) $value) {
|
||||
// Already checked
|
||||
$bindings = $this->container->getDefinition($this->currentId)->getBindings();
|
||||
$name = $value->getName();
|
||||
|
||||
if (isset($name, $bindings[$name = $value.' $'.$name])) {
|
||||
return $this->getBindingValue($bindings[$name]);
|
||||
}
|
||||
|
||||
if (isset($bindings[$value->getType()])) {
|
||||
return $this->getBindingValue($bindings[$value->getType()]);
|
||||
|
@ -203,14 +203,14 @@ class PhpDumper extends Dumper
|
||||
if (!empty($options['file']) && is_dir($dir = \dirname($options['file']))) {
|
||||
// Build a regexp where the first root dirs are mandatory,
|
||||
// but every other sub-dir is optional up to the full path in $dir
|
||||
// Mandate at least 2 root dirs and not more that 5 optional dirs.
|
||||
// Mandate at least 1 root dir and not more than 5 optional dirs.
|
||||
|
||||
$dir = explode(\DIRECTORY_SEPARATOR, realpath($dir));
|
||||
$i = \count($dir);
|
||||
|
||||
if (3 <= $i) {
|
||||
if (2 + (int) ('\\' === \DIRECTORY_SEPARATOR) <= $i) {
|
||||
$regex = '';
|
||||
$lastOptionalDir = $i > 8 ? $i - 5 : 3;
|
||||
$lastOptionalDir = $i > 8 ? $i - 5 : (2 + (int) ('\\' === \DIRECTORY_SEPARATOR));
|
||||
$this->targetDirMaxMatches = $i - $lastOptionalDir;
|
||||
|
||||
while (--$i >= $lastOptionalDir) {
|
||||
|
@ -14,8 +14,10 @@ namespace Symfony\Component\DependencyInjection\Tests\Compiler;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CheckTypeDeclarationsPass;
|
||||
use Symfony\Component\DependencyInjection\Compiler\ResolveParameterPlaceHoldersPass;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\Bar;
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\BarMethodCall;
|
||||
@ -23,6 +25,7 @@ use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPa
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\BarOptionalArgumentNotNull;
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\Foo;
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\FooObject;
|
||||
use Symfony\Component\ExpressionLanguage\Expression;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
@ -569,4 +572,101 @@ class CheckTypeDeclarationsPassTest extends TestCase
|
||||
|
||||
$this->assertInstanceOf(\stdClass::class, $container->get('bar')->foo);
|
||||
}
|
||||
|
||||
public function testProcessResolveArrayParameters()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->setParameter('ccc', ['foobar']);
|
||||
|
||||
$container
|
||||
->register('foobar', BarMethodCall::class)
|
||||
->addMethodCall('setArray', ['%ccc%']);
|
||||
|
||||
(new CheckTypeDeclarationsPass(true))->process($container);
|
||||
|
||||
$this->addToAssertionCount(1);
|
||||
}
|
||||
|
||||
public function testProcessResolveExpressions()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->setParameter('ccc', ['array']);
|
||||
|
||||
$container
|
||||
->register('foobar', BarMethodCall::class)
|
||||
->addMethodCall('setArray', [new Expression("parameter('ccc')")]);
|
||||
|
||||
(new CheckTypeDeclarationsPass(true))->process($container);
|
||||
|
||||
$this->addToAssertionCount(1);
|
||||
}
|
||||
|
||||
public function testProcessHandleMixedEnvPlaceholder()
|
||||
{
|
||||
$this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Invalid definition for service "foobar": argument 1 of "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\BarMethodCall::setArray" accepts "array", "string" passed.');
|
||||
|
||||
$container = new ContainerBuilder(new EnvPlaceholderParameterBag([
|
||||
'ccc' => '%env(FOO)%',
|
||||
]));
|
||||
|
||||
$container
|
||||
->register('foobar', BarMethodCall::class)
|
||||
->addMethodCall('setArray', ['foo%ccc%']);
|
||||
|
||||
(new CheckTypeDeclarationsPass(true))->process($container);
|
||||
}
|
||||
|
||||
public function testProcessHandleMultipleEnvPlaceholder()
|
||||
{
|
||||
$this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Invalid definition for service "foobar": argument 1 of "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\BarMethodCall::setArray" accepts "array", "string" passed.');
|
||||
|
||||
$container = new ContainerBuilder(new EnvPlaceholderParameterBag([
|
||||
'ccc' => '%env(FOO)%',
|
||||
'fcy' => '%env(int:BAR)%',
|
||||
]));
|
||||
|
||||
$container
|
||||
->register('foobar', BarMethodCall::class)
|
||||
->addMethodCall('setArray', ['%ccc%%fcy%']);
|
||||
|
||||
(new CheckTypeDeclarationsPass(true))->process($container);
|
||||
}
|
||||
|
||||
public function testProcessHandleExistingEnvPlaceholder()
|
||||
{
|
||||
putenv('ARRAY={"foo":"bar"}');
|
||||
|
||||
$container = new ContainerBuilder(new EnvPlaceholderParameterBag([
|
||||
'ccc' => '%env(json:ARRAY)%',
|
||||
]));
|
||||
|
||||
$container
|
||||
->register('foobar', BarMethodCall::class)
|
||||
->addMethodCall('setArray', ['%ccc%']);
|
||||
|
||||
(new ResolveParameterPlaceHoldersPass())->process($container);
|
||||
(new CheckTypeDeclarationsPass(true))->process($container);
|
||||
|
||||
$this->addToAssertionCount(1);
|
||||
|
||||
putenv('ARRAY=');
|
||||
}
|
||||
|
||||
public function testProcessHandleNotFoundEnvPlaceholder()
|
||||
{
|
||||
$container = new ContainerBuilder(new EnvPlaceholderParameterBag([
|
||||
'ccc' => '%env(json:ARRAY)%',
|
||||
]));
|
||||
|
||||
$container
|
||||
->register('foobar', BarMethodCall::class)
|
||||
->addMethodCall('setArray', ['%ccc%']);
|
||||
|
||||
(new ResolveParameterPlaceHoldersPass())->process($container);
|
||||
(new CheckTypeDeclarationsPass(true))->process($container);
|
||||
|
||||
$this->addToAssertionCount(1);
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,10 @@ class ResolveBindingsPassTest extends TestCase
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$bindings = [CaseSensitiveClass::class => new BoundArgument(new Reference('foo'))];
|
||||
$bindings = [
|
||||
CaseSensitiveClass::class => new BoundArgument(new Reference('foo')),
|
||||
CaseSensitiveClass::class.' $c' => new BoundArgument(new Reference('bar')),
|
||||
];
|
||||
|
||||
// Explicit service id
|
||||
$definition1 = $container->register('def1', NamedArgumentsDummy::class);
|
||||
@ -95,11 +98,16 @@ class ResolveBindingsPassTest extends TestCase
|
||||
$definition2->addArgument(new TypedReference(CaseSensitiveClass::class, CaseSensitiveClass::class));
|
||||
$definition2->setBindings($bindings);
|
||||
|
||||
$definition3 = $container->register('def3', NamedArgumentsDummy::class);
|
||||
$definition3->addArgument(new TypedReference(CaseSensitiveClass::class, CaseSensitiveClass::class, ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE, 'c'));
|
||||
$definition3->setBindings($bindings);
|
||||
|
||||
$pass = new ResolveBindingsPass();
|
||||
$pass->process($container);
|
||||
|
||||
$this->assertEquals([$typedRef], $container->getDefinition('def1')->getArguments());
|
||||
$this->assertEquals([new Reference('foo')], $container->getDefinition('def2')->getArguments());
|
||||
$this->assertEquals([new Reference('bar')], $container->getDefinition('def3')->getArguments());
|
||||
}
|
||||
|
||||
public function testScalarSetter()
|
||||
|
@ -35,7 +35,7 @@ final class Dotenv
|
||||
private $data;
|
||||
private $end;
|
||||
private $values;
|
||||
private $usePutenv = true;
|
||||
private $usePutenv;
|
||||
|
||||
/**
|
||||
* @var bool If `putenv()` should be used to define environment variables or not.
|
||||
|
@ -63,7 +63,7 @@ class RedisSessionHandler extends AbstractSessionHandler
|
||||
|
||||
$this->redis = $redis;
|
||||
$this->prefix = $options['prefix'] ?? 'sf_s';
|
||||
$this->ttl = $options['ttl'] ?? (int) ini_get('session.gc_maxlifetime');
|
||||
$this->ttl = $options['ttl'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -79,7 +79,7 @@ class RedisSessionHandler extends AbstractSessionHandler
|
||||
*/
|
||||
protected function doWrite(string $sessionId, string $data): bool
|
||||
{
|
||||
$result = $this->redis->setEx($this->prefix.$sessionId, $this->ttl, $data);
|
||||
$result = $this->redis->setEx($this->prefix.$sessionId, (int) ($this->ttl ?? ini_get('session.gc_maxlifetime')), $data);
|
||||
|
||||
return $result && !$result instanceof ErrorInterface;
|
||||
}
|
||||
@ -115,6 +115,6 @@ class RedisSessionHandler extends AbstractSessionHandler
|
||||
*/
|
||||
public function updateTimestamp($sessionId, $data)
|
||||
{
|
||||
return (bool) $this->redis->expire($this->prefix.$sessionId, $this->ttl);
|
||||
return (bool) $this->redis->expire($this->prefix.$sessionId, (int) ($this->ttl ?? ini_get('session.gc_maxlifetime')));
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +115,7 @@ class EsmtpTransport extends SmtpTransport
|
||||
|
||||
try {
|
||||
$response = $this->executeCommand(sprintf("EHLO %s\r\n", $this->getLocalDomain()), [250]);
|
||||
$capabilities = $this->getCapabilities($response);
|
||||
} catch (TransportExceptionInterface $e) {
|
||||
parent::doHeloCommand();
|
||||
|
||||
|
@ -59,7 +59,7 @@ EOF
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
|
||||
$transportNames = $this->transportNames;
|
||||
// do we want to setup only one transport?
|
||||
// do we want to set up only one transport?
|
||||
if ($transport = $input->getArgument('transport')) {
|
||||
if (!$this->transportLocator->has($transport)) {
|
||||
throw new \RuntimeException(sprintf('The "%s" transport does not exist.', $transport));
|
||||
@ -71,7 +71,7 @@ EOF
|
||||
$transport = $this->transportLocator->get($transportName);
|
||||
if ($transport instanceof SetupableTransportInterface) {
|
||||
$transport->setup();
|
||||
$io->success(sprintf('The "%s" transport was setup successfully.', $transportName));
|
||||
$io->success(sprintf('The "%s" transport was set up successfully.', $transportName));
|
||||
} else {
|
||||
$io->note(sprintf('The "%s" transport does not support setup.', $transportName));
|
||||
}
|
||||
|
@ -35,7 +35,13 @@ class SendMessageMiddleware implements MiddlewareInterface
|
||||
public function __construct(SendersLocatorInterface $sendersLocator, EventDispatcherInterface $eventDispatcher = null)
|
||||
{
|
||||
$this->sendersLocator = $sendersLocator;
|
||||
$this->eventDispatcher = LegacyEventDispatcherProxy::decorate($eventDispatcher);
|
||||
|
||||
if (null !== $eventDispatcher && class_exists(LegacyEventDispatcherProxy::class)) {
|
||||
$this->eventDispatcher = LegacyEventDispatcherProxy::decorate($eventDispatcher);
|
||||
} else {
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
}
|
||||
|
||||
$this->logger = new NullLogger();
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ class SetupTransportsCommandTest extends TestCase
|
||||
$tester->execute([]);
|
||||
$display = $tester->getDisplay();
|
||||
|
||||
$this->assertStringContainsString('The "amqp" transport was setup successfully.', $display);
|
||||
$this->assertStringContainsString('The "amqp" transport was set up successfully.', $display);
|
||||
$this->assertStringContainsString('The "other_transport" transport does not support setup.', $display);
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ class SetupTransportsCommandTest extends TestCase
|
||||
$tester->execute(['transport' => 'amqp']);
|
||||
$display = $tester->getDisplay();
|
||||
|
||||
$this->assertStringContainsString('The "amqp" transport was setup successfully.', $display);
|
||||
$this->assertStringContainsString('The "amqp" transport was set up successfully.', $display);
|
||||
}
|
||||
|
||||
public function testReceiverNameArgumentNotFound()
|
||||
|
@ -322,7 +322,7 @@ class Connection
|
||||
}
|
||||
} catch (\AMQPQueueException $e) {
|
||||
if (404 === $e->getCode() && $this->shouldSetup()) {
|
||||
// If we get a 404 for the queue, it means we need to setup the exchange & queue.
|
||||
// If we get a 404 for the queue, it means we need to set up the exchange & queue.
|
||||
$this->setupExchangeAndQueues();
|
||||
|
||||
return $this->get();
|
||||
|
@ -47,8 +47,13 @@ class Worker
|
||||
{
|
||||
$this->receivers = $receivers;
|
||||
$this->bus = $bus;
|
||||
$this->eventDispatcher = LegacyEventDispatcherProxy::decorate($eventDispatcher);
|
||||
$this->logger = $logger;
|
||||
|
||||
if (null !== $eventDispatcher && class_exists(LegacyEventDispatcherProxy::class)) {
|
||||
$this->eventDispatcher = LegacyEventDispatcherProxy::decorate($eventDispatcher);
|
||||
} else {
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,6 +55,10 @@ class DaoAuthenticationProvider extends UserAuthenticationProvider
|
||||
throw new BadCredentialsException('The presented password cannot be empty.');
|
||||
}
|
||||
|
||||
if (null === $user->getPassword()) {
|
||||
throw new BadCredentialsException('The presented password is invalid.');
|
||||
}
|
||||
|
||||
$encoder = $this->encoderFactory->getEncoder($user);
|
||||
|
||||
if (!$encoder->isPasswordValid($user->getPassword(), $presentedPassword, $user->getSalt())) {
|
||||
|
@ -42,6 +42,10 @@ class UserPasswordEncoder implements UserPasswordEncoderInterface
|
||||
*/
|
||||
public function isPasswordValid(UserInterface $user, string $raw)
|
||||
{
|
||||
if (null === $user->getPassword()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$encoder = $this->encoderFactory->getEncoder($user);
|
||||
|
||||
return $encoder->isPasswordValid($user->getPassword(), $raw, $user->getSalt());
|
||||
@ -52,6 +56,10 @@ class UserPasswordEncoder implements UserPasswordEncoderInterface
|
||||
*/
|
||||
public function needsRehash(UserInterface $user): bool
|
||||
{
|
||||
if (null === $user->getPassword()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$encoder = $this->encoderFactory->getEncoder($user);
|
||||
|
||||
return $encoder->needsRehash($user->getPassword());
|
||||
|
@ -147,7 +147,11 @@ class DaoAuthenticationProviderTest extends TestCase
|
||||
->willReturn('0')
|
||||
;
|
||||
|
||||
$method->invoke($provider, new TestUser(), $token);
|
||||
$method->invoke(
|
||||
$provider,
|
||||
new User('username', 'password'),
|
||||
$token
|
||||
);
|
||||
}
|
||||
|
||||
public function testCheckAuthenticationWhenCredentialsAreNotValid()
|
||||
@ -169,7 +173,7 @@ class DaoAuthenticationProviderTest extends TestCase
|
||||
->willReturn('foo')
|
||||
;
|
||||
|
||||
$method->invoke($provider, new TestUser(), $token);
|
||||
$method->invoke($provider, new User('username', 'password'), $token);
|
||||
}
|
||||
|
||||
public function testCheckAuthenticationDoesNotReauthenticateWhenPasswordHasChanged()
|
||||
@ -241,7 +245,7 @@ class DaoAuthenticationProviderTest extends TestCase
|
||||
->willReturn('foo')
|
||||
;
|
||||
|
||||
$method->invoke($provider, new TestUser(), $token);
|
||||
$method->invoke($provider, new User('username', 'password'), $token);
|
||||
}
|
||||
|
||||
public function testPasswordUpgrades()
|
||||
|
@ -53,7 +53,7 @@ class UserPasswordValidator extends ConstraintValidator
|
||||
|
||||
$encoder = $this->encoderFactory->getEncoder($user);
|
||||
|
||||
if (!$encoder->isPasswordValid($user->getPassword(), $password, $user->getSalt())) {
|
||||
if (null === $user->getPassword() || !$encoder->isPasswordValid($user->getPassword(), $password, $user->getSalt())) {
|
||||
$this->context->addViolation($constraint->message);
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,13 @@ class ContextListener extends AbstractListener
|
||||
$this->userProviders = $userProviders;
|
||||
$this->sessionKey = '_security_'.$contextKey;
|
||||
$this->logger = $logger;
|
||||
$this->dispatcher = LegacyEventDispatcherProxy::decorate($dispatcher);
|
||||
|
||||
if (null !== $dispatcher && class_exists(LegacyEventDispatcherProxy::class)) {
|
||||
$this->dispatcher = LegacyEventDispatcherProxy::decorate($dispatcher);
|
||||
} else {
|
||||
$this->dispatcher = $dispatcher;
|
||||
}
|
||||
|
||||
$this->trustResolver = $trustResolver ?: new AuthenticationTrustResolver(AnonymousToken::class, RememberMeToken::class);
|
||||
$this->sessionTrackerEnabler = $sessionTrackerEnabler;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ class UrlValidator extends ConstraintValidator
|
||||
{
|
||||
const PATTERN = '~^
|
||||
(%s):// # protocol
|
||||
(([\.\pL\pN-]+:)?([\.\pL\pN-]+)@)? # basic auth
|
||||
(([\_\.\pL\pN-]+:)?([\_\.\pL\pN-]+)@)? # basic auth
|
||||
(
|
||||
([\pL\pN\pS\-\_\.])+(\.?([\pL\pN]|xn\-\-[\pL\pN-]+)+\.?) # a domain name
|
||||
| # or
|
||||
|
@ -148,9 +148,11 @@ class UrlValidatorTest extends ConstraintValidatorTestCase
|
||||
['http://☎.com/'],
|
||||
['http://username:password@symfony.com'],
|
||||
['http://user.name:password@symfony.com'],
|
||||
['http://user_name:pass_word@symfony.com'],
|
||||
['http://username:pass.word@symfony.com'],
|
||||
['http://user.name:pass.word@symfony.com'],
|
||||
['http://user-name@symfony.com'],
|
||||
['http://user_name@symfony.com'],
|
||||
['http://symfony.com?'],
|
||||
['http://symfony.com?query=1'],
|
||||
['http://symfony.com/?query=1'],
|
||||
|
@ -617,11 +617,11 @@ class Inline
|
||||
// Optimize for returning strings.
|
||||
// no break
|
||||
case '+' === $scalar[0] || '-' === $scalar[0] || '.' === $scalar[0] || is_numeric($scalar[0]):
|
||||
if (Parser::preg_match('{^[+-]?[0-9][0-9_]*$}', $scalar)) {
|
||||
$scalar = str_replace('_', '', (string) $scalar);
|
||||
}
|
||||
|
||||
switch (true) {
|
||||
case Parser::preg_match('{^[+-]?[0-9][0-9_]*$}', $scalar):
|
||||
$scalar = str_replace('_', '', (string) $scalar);
|
||||
// omitting the break / return as integers are handled in the next case
|
||||
// no break
|
||||
case ctype_digit($scalar):
|
||||
$raw = $scalar;
|
||||
$cast = (int) $scalar;
|
||||
@ -631,7 +631,7 @@ class Inline
|
||||
$raw = $scalar;
|
||||
$cast = (int) $scalar;
|
||||
|
||||
return '0' == $scalar[1] ? octdec($scalar) : (((string) $raw === (string) $cast) ? $cast : $raw);
|
||||
return '0' == $scalar[1] ? -octdec(substr($scalar, 1)) : (($raw === (string) $cast) ? $cast : $raw);
|
||||
case is_numeric($scalar):
|
||||
case Parser::preg_match(self::getHexRegex(), $scalar):
|
||||
$scalar = str_replace('_', '', $scalar);
|
||||
|
@ -720,4 +720,20 @@ class InlineTest extends TestCase
|
||||
$this->expectExceptionMessage("Unexpected end of line, expected one of \",}\n\" at line 1 (near \"{abc: 'def'\").");
|
||||
Inline::parse("{abc: 'def'");
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getTestsForOctalNumbers
|
||||
*/
|
||||
public function testParseOctalNumbers($expected, $yaml)
|
||||
{
|
||||
self::assertSame($expected, Inline::parse($yaml));
|
||||
}
|
||||
|
||||
public function getTestsForOctalNumbers()
|
||||
{
|
||||
return [
|
||||
'positive octal number' => [28, '034'],
|
||||
'negative octal number' => [-28, '-034'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user