From 82ea45fce18e40f2bc066f4dfb3b0a65ae25c7d8 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 28 Oct 2020 06:38:23 +0100 Subject: [PATCH 001/136] Update CHANGELOG for 3.4.46 --- CHANGELOG-3.4.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CHANGELOG-3.4.md b/CHANGELOG-3.4.md index 8766558fe6e3c..95a2107528b52 100644 --- a/CHANGELOG-3.4.md +++ b/CHANGELOG-3.4.md @@ -7,6 +7,21 @@ in 3.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/v3.4.0...v3.4.1 +* 3.4.46 (2020-10-28) + + * bug #38669 [Serializer] fix decoding float XML attributes starting with 0 (Marcin Kruk) + * bug #38595 [TwigBridge] do not translate null placeholders or titles (xabbuh) + * bug #38652 [Filesystem] Check if failed unlink was caused by permission denied (Nyholm) + * bug #38604 [DoctrineBridge] indexBy does not refer to attributes, but to column names (xabbuh) + * bug #38606 [WebProfilerBundle] Hide debug toolbar in print view (jt2k) + * bug #38582 [DI] Fix Reflection file name with eval()\'d code (maxime-aknin) + * bug #38516 [HttpFoundation] Fix Range Requests (BattleRattle) + * bug #38510 [PropertyInfo] Support for the mixed type (derrabus) + * bug #38444 [PhpUnitBridge] fix running parallel tests with phpunit 9 (nicolas-grekas) + * bug #38442 [VarDumper] fix truncating big arrays (nicolas-grekas) + * bug #38380 [Form] propagate validation groups to subforms (johanderuijter, xabbuh) + * bug #38360 [BrowserKit] Cookie expiration at current timestamp (iquito) + * 3.4.45 (2020-09-27) * bug #38228 [Yaml Parser] Fix edge cases when parsing multiple documents (digilist) From f2de5e53216e5c26b500e1eb92a51108c2038e0f Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 28 Oct 2020 06:38:46 +0100 Subject: [PATCH 002/136] Update CONTRIBUTORS for 3.4.46 --- CONTRIBUTORS.md | 114 +++++++++++++++++++++++++++++++----------------- 1 file changed, 74 insertions(+), 40 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index f3217f25a966c..5d3ae522834d7 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -22,18 +22,18 @@ Symfony is the result of the work of many people who made the code better - Jakub Zalas (jakubzalas) - Johannes S (johannes) - Kris Wallsmith (kriswallsmith) + - Alexander M. Turek (derrabus) - Wouter de Jong (wouterj) - Yonel Ceruto (yonelceruto) - - Alexander M. Turek (derrabus) - - Hugo Hamon (hhamon) - Thomas Calvet (fancyweb) + - Hugo Hamon (hhamon) - Abdellatif Ait boudad (aitboudad) - Samuel ROZE (sroze) - Romain Neutron (romain) - Pascal Borreli (pborreli) + - Jérémy DERUSSÉ (jderusse) - Joseph Bielawski (stloyd) - Karma Dordrak (drak) - - Jérémy DERUSSÉ (jderusse) - Jules Pietri (heah) - Lukas Kahwe Smith (lsmith) - Martin Hasoň (hason) @@ -42,12 +42,13 @@ Symfony is the result of the work of many people who made the code better - Jean-François Simon (jfsimon) - Benjamin Eberlei (beberlei) - Igor Wiedler (igorw) - - Eriksen Costa (eriksencosta) - Tobias Nyholm (tobias) + - Eriksen Costa (eriksencosta) - Guilhem Niot (energetick) - Sarah Khalil (saro0h) - Jonathan Wage (jwage) - Lynn van der Berg (kjarli) + - Jan Schädlich (jschaedl) - Matthias Pigulla (mpdude) - Diego Saint Esteben (dosten) - Pierre du Plessis (pierredup) @@ -55,28 +56,27 @@ Symfony is the result of the work of many people who made the code better - William Durand (couac) - Valentin Udaltsov (vudaltsov) - ornicar - - Jan Schädlich (jschaedl) - Dany Maillard (maidmaid) - Francis Besset (francisbesset) - stealth35 ‏ (stealth35) - Alexander Mols (asm89) + - Kevin Bond (kbond) - Konstantin Myakshin (koc) - Grégoire Paris (greg0ire) - Bulat Shakirzyanov (avalanche123) - - Kevin Bond (kbond) - Saša Stamenković (umpirsky) - Peter Rehm (rpet) - Gabriel Ostrolucký (gadelat) + - Titouan Galopin (tgalopin) - David Maicher (dmaicher) - Gábor Egyed (1ed) - Henrik Bjørnskov (henrikbjorn) - Miha Vrhovnik - - Titouan Galopin (tgalopin) - Diego Saint Esteben (dii3g0) - Konstantin Kudryashov (everzet) + - Mathieu Piot (mpiot) - Vladimir Reznichenko (kalessil) - Bilal Amarni (bamarni) - - Mathieu Piot (mpiot) - Florin Patan (florinpatan) - Jáchym Toušek (enumag) - Andrej Hudec (pulzarraider) @@ -86,13 +86,13 @@ Symfony is the result of the work of many people who made the code better - Charles Sarrazin (csarrazi) - Christian Raue - Douglas Greenshields (shieldo) + - Laurent VOULLEMIER (lvo) - Arnout Boks (aboks) + - Graham Campbell (graham) - Jérôme Tamarelle (gromnan) - - Laurent VOULLEMIER (lvo) - Deni - Henrik Westphal (snc) - Dariusz Górecki (canni) - - Graham Campbell (graham) - David Buchmann (dbu) - Dariusz Ruminski - Fran Moreno (franmomu) @@ -100,11 +100,11 @@ Symfony is the result of the work of many people who made the code better - Brandon Turner - Luis Cordova (cordoval) - Daniel Holmes (dholmes) + - Alex Pott - Toni Uebernickel (havvg) - Bart van den Burg (burgov) - Jordan Alliot (jalliot) - John Wards (johnwards) - - Alex Pott - Antoine Hérault (herzult) - Paráda József (paradajozsef) - Arnaud Le Blanc (arnaud-lb) @@ -119,18 +119,19 @@ Symfony is the result of the work of many people who made the code better - marc.weistroff - Tomáš Votruba (tomas_votruba) - Peter Kokot (maastermedia) + - Lars Strojny (lstrojny) - lenar - Alexander Schwenn (xelaris) - Włodzimierz Gajda (gajdaw) + - Alexander Schranz (alexander-schranz) + - Oskar Stark (oskarstark) - Adrien Brault (adrienbrault) - - Lars Strojny (lstrojny) - Massimiliano Arione (garak) - Jacob Dreesen (jdreesen) - Florian Voutzinos (florianv) - Teoh Han Hui (teohhanhui) - Przemysław Bogusz (przemyslaw-bogusz) - Colin Frei - - Oskar Stark (oskarstark) - Javier Spagnoletti (phansys) - Joshua Thijssen - Daniel Wehner (dawehner) @@ -138,7 +139,6 @@ Symfony is the result of the work of many people who made the code better - excelwebzone - Gordon Franke (gimler) - Joel Wurtz (brouznouf) - - Alexander Schranz (alexander-schranz) - Fabien Pennequin (fabienpennequin) - Julien Falque (julienfalque) - Théo FIDRY (theofidry) @@ -175,6 +175,7 @@ Symfony is the result of the work of many people who made the code better - Rafael Dohms (rdohms) - jwdeitch - Ahmed TAILOULOUTE (ahmedtai) + - Andreas Braun - Mikael Pajunen - Arman Hosseini (arman) - Niels Keurentjes (curry684) @@ -209,6 +210,7 @@ Symfony is the result of the work of many people who made the code better - Marek Štípek (maryo) - Filippo Tessarotto (slamdunk) - Daniel Espendiller + - Maxime Helias (maxhelias) - Possum - Dorian Villet (gnutix) - Michaël Perrin (michael.perrin) @@ -228,9 +230,9 @@ Symfony is the result of the work of many people who made the code better - Ruben Gonzalez (rubenrua) - Benjamin Dulau (dbenjamin) - Jan Rosier (rosier) - - Andreas Braun - Mathieu Lemoine (lemoinem) - Rémon van de Kamp (rpkamp) + - HypeMC - Christian Schmidt - Andreas Hucks (meandmymonkey) - Tom Van Looy (tvlooy) @@ -246,7 +248,6 @@ Symfony is the result of the work of many people who made the code better - Nikolay Labinskiy (e-moe) - Martin Schuhfuß (usefulthink) - apetitpa - - Maxime Helias (maxhelias) - Matthieu Bontemps (mbontemps) - apetitpa - Pierre Minnieur (pminnieur) @@ -255,6 +256,7 @@ Symfony is the result of the work of many people who made the code better - Dominique Bongiraud - Hidde Wieringa (hiddewie) - Jeremy Livingston (jeremylivingston) + - Olivier Dolbeau (odolbeau) - Michael Lee (zerustech) - Dmitrii Poddubnyi (karser) - Matthieu Auger (matthieuauger) @@ -288,7 +290,6 @@ Symfony is the result of the work of many people who made the code better - Marco Pivetta (ocramius) - Antonio Pauletich (x-coder264) - Jeroen Spee (jeroens) - - Olivier Dolbeau (odolbeau) - Rob Frawley 2nd (robfrawley) - julien pauli (jpauli) - Lorenz Schori @@ -304,6 +305,7 @@ Symfony is the result of the work of many people who made the code better - Elnur Abdurrakhimov (elnur) - Manuel Reinhard (sprain) - Danny Berger (dpb587) + - zairig imad (zairigimad) - Antonio J. García Lagar (ajgarlag) - Adam Prager (padam87) - Benoît Burnichon (bburnichon) @@ -338,11 +340,13 @@ Symfony is the result of the work of many people who made the code better - Jhonny Lidfors (jhonne) - Diego Agulló (aeoris) - jdhoek + - Michael Käfer (michael_kaefer) - Bob den Otter (bopp) - Thomas Schulz (king2500) - Frank de Jonge (frenkynet) - Nikita Konstantinov - Wodor Wodorski + - Timo Bakx (timobakx) - Joe Bennett (kralos) - Thomas Lallement (raziel057) - soyuka @@ -370,8 +374,8 @@ Symfony is the result of the work of many people who made the code better - Simon Mönch (sm) - Christian Schmidt - Patrick Landolt (scube) - - HypeMC - MatTheCat + - Bohan Yang (brentybh) - Vilius Grigaliūnas - David Badura (davidbadura) - Chad Sikorra (chadsikorra) @@ -379,6 +383,7 @@ Symfony is the result of the work of many people who made the code better - Chris Smith (cs278) - Thomas Bisignani (toma) - Florian Klein (docteurklein) + - Timothée Barray (tyx) - Benjamin Leveque (benji07) - Manuel Kiessling (manuelkiessling) - Alexey Kopytko (sanmai) @@ -412,7 +417,6 @@ Symfony is the result of the work of many people who made the code better - Romain Pierre (romain-pierre) - Julien Galenski (ruian) - Thomas Landauer (thomas-landauer) - - Michael Käfer (michael_kaefer) - Bongiraud Dominique - janschoenherr - Emanuele Gaspari (inmarelibero) @@ -423,6 +427,8 @@ Symfony is the result of the work of many people who made the code better - Sebastien Morel (plopix) - Ricard Clau (ricardclau) - Mark Challoner (markchalloner) + - ivan + - Karoly Gossler (connorhu) - Ahmed Raafat - Philippe Segatori - Gennady Telegin (gtelegin) @@ -432,6 +438,7 @@ Symfony is the result of the work of many people who made the code better - Matthew Lewinski (lewinski) - Magnus Nordlander (magnusnordlander) - Thomas Royer (cydonia7) + - Nicolas Philippe (nikophil) - Nicolas LEFEVRE (nicoweb) - alquerci - Oleg Andreyev @@ -441,12 +448,13 @@ Symfony is the result of the work of many people who made the code better - Vitaliy Zakharov (zakharovvi) - Tobias Sjösten (tobiassjosten) - Gyula Sallai (salla) + - Romaric Drigon (romaricdrigon) - Inal DJAFAR (inalgnu) - Christian Gärtner (dagardner) - Dmytro Borysovskyi (dmytr0) - Tomasz Kowalczyk (thunderer) + - Sylvain Fabre (sylfabre) - Artur Eshenbrener - - Timo Bakx (timobakx) - Harm van Tilborg (hvt) - Thomas Perez (scullwm) - Felix Labrecque @@ -498,7 +506,6 @@ Symfony is the result of the work of many people who made the code better - Endre Fejes - Tobias Naumann (tna) - Daniel Beyer - - Timothée Barray (tyx) - Shein Alexey - Romain Gautier (mykiwi) - Joe Lencioni @@ -540,9 +547,12 @@ Symfony is the result of the work of many people who made the code better - Jeanmonod David (jeanmonod) - Christopher Davis (chrisguitarguy) - Webnet team (webnet) + - Ben Ramsey (ramsey) + - Nate Wiebe (natewiebe13) - Marcin Szepczynski (czepol) - Mohammad Emran Hasan (phpfour) - Farhad Safarov + - Dmitriy Mamontov (mamontovdmitriy) - Jan Schumann - Niklas Fiekas - Markus Bachmann (baachi) @@ -554,6 +564,7 @@ Symfony is the result of the work of many people who made the code better - Mihai Stancu - Ivan Nikolaev (destillat) - Gildas Quéméner (gquemener) + - Baptiste Leduc (korbeil) - Laurent Masforné (heisenberg) - Claude Khedhiri (ck-developer) - Desjardins Jérôme (jewome62) @@ -563,22 +574,25 @@ Symfony is the result of the work of many people who made the code better - Toni Rudolf (toooni) - Asmir Mustafic (goetas) - DerManoMann - - Nicolas Philippe (nikophil) - vagrant - Aurimas Niekis (gcds) - EdgarPE + - Bob van de Vijver (bobvandevijver) - Florian Pfitzer (marmelatze) - Asier Illarramendi (doup) - - Sylvain Fabre (sylfabre) - Martijn Cuppens - Vlad Gregurco (vgregurco) - Boris Vujicic (boris.vujicic) - Artem Lopata - Judicaël RUFFIEUX (axanagor) - Chris Sedlmayr (catchamonkey) + - Indra Gunawan (indragunawan) - Kamil Kokot (pamil) - Seb Koelen - Christoph Mewes (xrstf) + - Andrew M-Y (andr) + - Krasimir Bosilkov (kbosilkov) + - Marcin Michalski (marcinmichalski) - Vitaliy Tverdokhlib (vitaliytv) - Ariel Ferrandini (aferrandini) - Dirk Pahl (dirkaholic) @@ -590,10 +604,11 @@ Symfony is the result of the work of many people who made the code better - Tobias Weichart - Tarmo Leppänen (tarlepp) - Marcin Sikoń (marphi) - - Bohan Yang (brentybh) + - M. Vondano - Dominik Zogg (dominik.zogg) - Marek Pietrzak - Luc Vieillescazes (iamluc) + - Lukáš Holeczy (holicz) - franek (franek) - Raulnet - Marco Petersen (ocrampete16) @@ -659,6 +674,7 @@ Symfony is the result of the work of many people who made the code better - Leevi Graham (leevigraham) - Anthony Ferrara - Ioan Negulescu + - Greg ORIOL - Jakub Škvára (jskvara) - Andrew Udvare (audvare) - alexpods @@ -668,7 +684,6 @@ Symfony is the result of the work of many people who made the code better - Erik Trapman (eriktrapman) - De Cock Xavier (xdecock) - Almog Baku (almogbaku) - - Karoly Gossler (connorhu) - Scott Arciszewski - Xavier HAUSHERR - Norbert Orzechowicz (norzechowicz) @@ -735,22 +750,18 @@ Symfony is the result of the work of many people who made the code better - Julien Montel (julienmgel) - Mátyás Somfai (smatyas) - Bastien DURAND (deamon) - - Ben Ramsey (ramsey) - Simon DELICATA - Artem Henvald (artemgenvald) - Dmitry Simushev - alcaeus - Thomas Talbot (ioni) - - Nate Wiebe (natewiebe13) - Fred Cox - vitaliytv - - ivan - Philippe Segatori - Dalibor Karlović (dkarlovi) - Andrey Sevastianov - Sebastian Blum - Alexis Lefebvre - - Dmitriy Mamontov (mamontovdmitriy) - aubx - Julien Turby - Marvin Butkereit @@ -761,7 +772,6 @@ Symfony is the result of the work of many people who made the code better - Max Rath (drak3) - marie - Stéphane Escandell (sescandell) - - Baptiste Leduc (korbeil) - Konstantin S. M. Möllers (ksmmoellers) - James Johnston - Noémi Salaün (noemi-salaun) @@ -779,7 +789,6 @@ Symfony is the result of the work of many people who made the code better - Christophe Villeger (seragan) - Matthias Krauser (mkrauser) - Julien Fredon - - Bob van de Vijver (bobvandevijver) - Xavier Leune (xleune) - Stefan Gehrig (sgehrig) - Hany el-Kerdany @@ -795,7 +804,6 @@ Symfony is the result of the work of many people who made the code better - Geoffrey Brier (geoffrey-brier) - Alexandre Parent - Vladimir Tsykun - - Romaric Drigon (romaricdrigon) - Dustin Dobervich (dustin10) - dantleech - Philipp Kolesnikov @@ -804,7 +812,9 @@ Symfony is the result of the work of many people who made the code better - Carlos Pereira De Amorim (epitre) - zenmate - Michal Trojanowski + - Lescot Edouard (idetox) - David Fuhr + - Rodrigo Aguilera - Mathias STRASSER (roukmoute) - Max Grigorian (maxakawizard) - Rostyslav Kinash @@ -822,13 +832,13 @@ Symfony is the result of the work of many people who made the code better - Xavier Briand (xavierbriand) - Ke WANG (yktd26) - Ivo Bathke (ivoba) + - David Molineus - Strate - Anton A. Sumin - Israel J. Carberry - Miquel Rodríguez Telep (mrtorrent) - Sergey Kolodyazhnyy (skolodyazhnyy) - umpirski - - M. Vondano - Quentin de Longraye (quentinus95) - Chris Heng (gigablah) - Shaun Simmons (simshaun) @@ -909,6 +919,7 @@ Symfony is the result of the work of many people who made the code better - Davide Borsatto (davide.borsatto) - Julien DIDIER (juliendidier) - Dominik Ritter (dritter) + - Andreas Leathley (iquito) - Sebastian Grodzicki (sgrodzicki) - Mohamed Gamal - Jeroen van den Enden (stoefke) @@ -922,6 +933,7 @@ Symfony is the result of the work of many people who made the code better - Carson Full - Sergey Yastrebov - Trent Steel (trsteel88) + - Steve Grunwell - Yuen-Chi Lian - Tarjei Huse (tarjei) - Besnik Br @@ -949,10 +961,10 @@ Symfony is the result of the work of many people who made the code better - Casper Valdemar Poulsen - Josiah (josiah) - Guillaume Verstraete (versgui) - - Greg ORIOL - Joschi Kuphal - John Bohn (jbohn) - Marc Morera (mmoreram) + - Jason Tan - BENOIT POLASZEK (bpolaszek) - Julien Pauli - Mathieu Rochette (mathroc) @@ -1026,7 +1038,6 @@ Symfony is the result of the work of many people who made the code better - Sergey Zolotov (enleur) - Maksim Kotlyar (makasim) - Neil Ferreira - - Indra Gunawan (indragunawan) - Julie Hourcade (juliehde) - Dmitry Parnas (parnas) - Paul LE CORRE @@ -1034,6 +1045,7 @@ Symfony is the result of the work of many people who made the code better - Daniel Gorgan - Tony Malzhacker - Mathieu MARCHOIS + - Tavo Nieves J - Cyril Quintin (cyqui) - Gerard van Helden (drm) - flack (flack) @@ -1098,6 +1110,7 @@ Symfony is the result of the work of many people who made the code better - Johnson Page (jwpage) - Ruben Gonzalez (rubenruateltek) - Michael Roterman (wtfzdotnet) + - Dieter - Arno Geurts - Adán Lobato (adanlobato) - Ian Jenkins (jenkoian) @@ -1133,6 +1146,7 @@ Symfony is the result of the work of many people who made the code better - Erik Saunier (snickers) - Thiago Cordeiro (thiagocordeiro) - Rootie + - Bernd Stellwag - Alireza Mirsepassi (alirezamirsepassi) - Daniel Alejandro Castro Arellano (lexcast) - sensio @@ -1157,6 +1171,7 @@ Symfony is the result of the work of many people who made the code better - Christian Jul Jensen - Alexandre GESLIN (alexandregeslin) - The Whole Life to Learn + - Pierre Tondereau - Alex Vo (votanlean) - Mikkel Paulson - ergiegonzaga @@ -1204,6 +1219,7 @@ Symfony is the result of the work of many people who made the code better - Luciano Mammino (loige) - fabios - Sander Coolen (scoolen) + - Laurent Clouet - Nicolas Le Goff (nlegoff) - Ben Oman - Chris de Kok @@ -1213,21 +1229,22 @@ Symfony is the result of the work of many people who made the code better - Guillaume (guill) - Igor Timoshenko (igor.timoshenko) - Manuele Menozzi - - zairig imad (zairigimad) - Anton Babenko (antonbabenko) - Irmantas Šiupšinskas (irmantas) - Benoit Mallo - - Lescot Edouard (idetox) - Danilo Silva - Giuseppe Campanelli + - Valentin - pizzaminded - Arnaud PETITPAS (apetitpa) - Ken Stanley - Zachary Tong (polyfractal) - linh + - Guilherme Augusto Henschel - Mario Blažek (marioblazek) - Ashura - Hryhorii Hrebiniuk + - Eric Krona - johnstevenson - hamza - dantleech @@ -1238,6 +1255,7 @@ Symfony is the result of the work of many people who made the code better - Stanislav Kocanda - DerManoMann - Damien Fayet (rainst0rm) + - Ippei SUmida (ippey_s) - MatTheCat - Guillaume Royer - Artem (digi) @@ -1247,6 +1265,7 @@ Symfony is the result of the work of many people who made the code better - Pierrick VIGNAND (pierrick) - Vadim Tyukov (vatson) - Arman + - Adamo Crespi (aerendir) - David Wolter (davewww) - Sortex - chispita @@ -1322,12 +1341,15 @@ Symfony is the result of the work of many people who made the code better - Nikita Konstantinov - Martijn Evers - Philipp Fritsche + - tarlepp + - Luca Saba (lucasaba) - Benjamin Paap (benjaminpaap) - Claus Due (namelesscoder) - Christian - Alexandru Patranescu - Denis Golubovskiy (bukashk0zzz) - Sergii Smertin (nfx) + - Quentin Moreau (sheitak) - Mikkel Paulson - Michał Strzelecki - hugofonseca (fonsecas72) @@ -1420,13 +1442,13 @@ Symfony is the result of the work of many people who made the code better - Arun Philip - Rémi Leclerc - Jan Vernarsky + - Jonas Hünig - Amine Yakoubi - Eduardo García Sanz (coma) - Sergio (deverad) - Makdessi Alex - James Gilliland - fduch (fduch) - - David Molineus - Stuart Fyfe - David de Boer (ddeboer) - Eno Mullaraj (emullaraj) @@ -1532,6 +1554,7 @@ Symfony is the result of the work of many people who made the code better - pthompson - Malaney J. Hill - Alexandre Pavy + - Adiel Cristo (arcristo) - Christian Flach (cmfcmf) - Cédric Girard (enk_) - Lars Ambrosius Wallenborn (larsborn) @@ -1547,6 +1570,7 @@ Symfony is the result of the work of many people who made the code better - Javier Espinosa - Anton Kroshilin - Dawid Sajdak + - Norman Soetbeer - Ludek Stepan - Aaron Stephens (astephens) - Craig Menning (cmenning) @@ -1557,7 +1581,6 @@ Symfony is the result of the work of many people who made the code better - Marc J. Schmidt (marcjs) - František Maša - Sebastian Schwarz - - Jason Tan - Marco Jantke - Saem Ghani - Clément LEFEBVRE @@ -1622,6 +1645,7 @@ Symfony is the result of the work of many people who made the code better - JL - Ilya Biryukov - Kim Laï Trinh + - Johan de Ruijter - Jason Desrosiers - m.chwedziak - Andreas Frömer @@ -1694,6 +1718,7 @@ Symfony is the result of the work of many people who made the code better - Mara Blaga - Rick Prent - skalpa + - Kai - Martin Eckhardt - Bartłomiej Zając - Pieter Jordaan @@ -1702,6 +1727,7 @@ Symfony is the result of the work of many people who made the code better - Michael Dowling (mtdowling) - Karlos Presumido (oneko) - Tony Vermeiren (tony) + - Jos Elstgeest - Thomas Counsell - BilgeXA - r1pp3rj4ck @@ -1746,6 +1772,7 @@ Symfony is the result of the work of many people who made the code better - Pablo Ogando Ferreira - Thomas Ploch - Simon Neidhold + - Ben Hakim - Valentin VALCIU - Jeremiah VALERIE - Julien Menth @@ -1773,6 +1800,7 @@ Symfony is the result of the work of many people who made the code better - Flavian (2much) - Gautier Deuette - mike + - Gilbertsoft - tadas - Kirk Madera - Keith Maika @@ -1792,6 +1820,7 @@ Symfony is the result of the work of many people who made the code better - Zdeněk Drahoš - Dan Harper - moldcraft + - Marcin Kruk - Antoine Bellion (abellion) - Ramon Kleiss (akathos) - Antonio Peric-Mazar (antonioperic) @@ -1853,6 +1882,7 @@ Symfony is the result of the work of many people who made the code better - Wing - Thomas Bibb - kick-the-bucket + - Joni Halme - Matt Farmer - catch - siganushka @@ -2216,6 +2246,7 @@ Symfony is the result of the work of many people who made the code better - Gyula Szucs - Tomas Liubinas - Alex + - Thomas P - Jan Hort - Klaas Naaijkens - Daniel González Cerviño @@ -2275,6 +2306,7 @@ Symfony is the result of the work of many people who made the code better - Vladimir Chernyshev (volch) - Wim Godden (wimg) - Yorkie Chadwick (yorkie76) + - Maxime Aknin (3m1x4m) - GuillaumeVerdon - Philipp Keck - Angel Fernando Quiroz Campos @@ -2383,7 +2415,6 @@ Symfony is the result of the work of many people who made the code better - Jack Wright - MrNicodemuz - Anonymous User - - Dieter - Paweł Tomulik - Eric J. Duran - Alexandru Bucur @@ -2546,6 +2577,7 @@ Symfony is the result of the work of many people who made the code better - Damián Nohales (eagleoneraptor) - Jordane VASPARD (elementaire) - Elliot Anderson (elliot) + - Erwan Nader (ernadoo) - Fabien D. (fabd) - Carsten Eilers (fnc) - Sorin Gitlan (forapathy) @@ -2619,6 +2651,7 @@ Symfony is the result of the work of many people who made the code better - Volker (skydiablo) - Success Go (successgo) - Julien Sanchez (sumbobyboys) + - Stephan Vierkant (svierkant) - Guillermo Gisinger (t3chn0r) - Markus Tacker (tacker) - Tom Newby (tomnewbyau) @@ -2645,6 +2678,7 @@ Symfony is the result of the work of many people who made the code better - simpson - Antoine Leblanc - drublic + - Andre Johnson - MaPePeR - Andreas Streichardt - Alexandre Segura From e700242adf32f65318f2c5fafff4acde5eaffbd8 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 28 Oct 2020 06:40:17 +0100 Subject: [PATCH 003/136] Update VERSION for 3.4.46 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 4c2040e3495fb..95eb438d49cee 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -67,12 +67,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private $requestStackSize = 0; private $resetServices = false; - const VERSION = '3.4.46-DEV'; + const VERSION = '3.4.46'; const VERSION_ID = 30446; const MAJOR_VERSION = 3; const MINOR_VERSION = 4; const RELEASE_VERSION = 46; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2020'; const END_OF_LIFE = '11/2021'; From 4eb10eaa2ce831880ed5f433ac418cadf64f5128 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 28 Oct 2020 06:49:13 +0100 Subject: [PATCH 004/136] Bump Symfony version to 3.4.47 --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 95eb438d49cee..815359e13201b 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -67,12 +67,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private $requestStackSize = 0; private $resetServices = false; - const VERSION = '3.4.46'; - const VERSION_ID = 30446; + const VERSION = '3.4.47-DEV'; + const VERSION_ID = 30447; const MAJOR_VERSION = 3; const MINOR_VERSION = 4; - const RELEASE_VERSION = 46; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 47; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '11/2020'; const END_OF_LIFE = '11/2021'; From 9a171c5dbb56016aa5af4aa79d360cbe8fd5c89f Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 28 Oct 2020 06:50:47 +0100 Subject: [PATCH 005/136] Update CHANGELOG for 4.4.16 --- CHANGELOG-4.4.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/CHANGELOG-4.4.md b/CHANGELOG-4.4.md index 9b3ef80dc1c16..eb669f2baca7b 100644 --- a/CHANGELOG-4.4.md +++ b/CHANGELOG-4.4.md @@ -7,6 +7,35 @@ 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.16 (2020-10-28) + + * bug #38713 [DI] Fix Preloader exception when preloading a class with an unknown parent/interface (rgeraads) + * bug #38647 [HttpClient] relax auth bearer format requirements (xabbuh) + * bug #38699 [DependencyInjection] Preload classes with union types correctly (derrabus) + * bug #38669 [Serializer] fix decoding float XML attributes starting with 0 (Marcin Kruk) + * bug #38680 [PhpUnitBridge] Support new expect methods in test case polyfill (alcaeus) + * bug #38681 [PHPUnitBridge] Support PHPUnit 8 and PHPUnit 9 in constraint compatibility trait (alcaeus) + * bug #38679 [PhpUnitBridge] Add missing exporter function for PHPUnit 7 (alcaeus) + * bug #38595 [TwigBridge] do not translate null placeholders or titles (xabbuh) + * bug #38635 [Cache] Use correct expiry in ChainAdapter (Nyholm) + * bug #38652 [Filesystem] Check if failed unlink was caused by permission denied (Nyholm) + * bug #38645 [PropertyAccess] forward the caught exception (xabbuh) + * bug #38604 [DoctrineBridge] indexBy does not refer to attributes, but to column names (xabbuh) + * bug #38606 [WebProfilerBundle] Hide debug toolbar in print view (jt2k) + * bug #38582 [DI] Fix Reflection file name with eval()\'d code (maxime-aknin) + * bug #38516 [HttpFoundation] Fix Range Requests (BattleRattle) + * bug #38553 [Lock] Reset Key lifetime time before we acquire it (Nyholm) + * bug #38551 Remove content-type check on toArray methods (jderusse) + * bug #38544 [DI] fix dumping env vars (nicolas-grekas) + * bug #38530 [HttpClient] fix reading the body after a ClientException (nicolas-grekas) + * bug #38510 [PropertyInfo] Support for the mixed type (derrabus) + * bug #38493 [HttpClient] Fix CurlHttpClient memory leak (HypeMC) + * bug #38456 [Cache] skip igbinary < 3.1.6 (nicolas-grekas) + * bug #38392 [Ldap] Bypass the use of `ldap_control_paged_result` on PHP >= 7.3 (lucasaba) + * bug #38444 [PhpUnitBridge] fix running parallel tests with phpunit 9 (nicolas-grekas) + * bug #38442 [VarDumper] fix truncating big arrays (nicolas-grekas) + * bug #38433 [Mime] Fix serialization of RawMessage (gilbertsoft) + * 4.4.15 (2020-10-04) * bug #36291 [Lock] Fix StoreFactory to accept same DSN syntax as AbstractAdapter (Jontsa) From 1864a9c5285f7dbc42414cab71965d0e1da7ac94 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 28 Oct 2020 06:50:56 +0100 Subject: [PATCH 006/136] Update VERSION for 4.4.16 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index d5bf69ea73192..c21108b0407ad 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -76,12 +76,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private static $freshCache = []; - const VERSION = '4.4.16-DEV'; + const VERSION = '4.4.16'; const VERSION_ID = 40416; const MAJOR_VERSION = 4; const MINOR_VERSION = 4; const RELEASE_VERSION = 16; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2022'; const END_OF_LIFE = '11/2023'; From 8b0146cb63bb2914d458c5c77e3e9d0b3b931b1a Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 28 Oct 2020 06:54:40 +0100 Subject: [PATCH 007/136] Bump Symfony version to 4.4.17 --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index c21108b0407ad..079d375abafbd 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -76,12 +76,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private static $freshCache = []; - const VERSION = '4.4.16'; - const VERSION_ID = 40416; + const VERSION = '4.4.17-DEV'; + const VERSION_ID = 40417; const MAJOR_VERSION = 4; const MINOR_VERSION = 4; - const RELEASE_VERSION = 16; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 17; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '11/2022'; const END_OF_LIFE = '11/2023'; From b1cb5b300891891b5d7c51d236dadee8cdfb2a83 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 28 Oct 2020 07:07:48 +0100 Subject: [PATCH 008/136] Bump Symfony version to 5.1.9 --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 59689807370d0..8410143b86582 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -73,12 +73,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private static $freshCache = []; - const VERSION = '5.1.8'; - const VERSION_ID = 50108; + const VERSION = '5.1.9-DEV'; + const VERSION_ID = 50109; const MAJOR_VERSION = 5; const MINOR_VERSION = 1; - const RELEASE_VERSION = 8; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 9; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '01/2021'; const END_OF_LIFE = '01/2021'; From b440637960c820c25e52cba866da65cf6ee8edbc Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 28 Oct 2020 07:18:26 +0100 Subject: [PATCH 009/136] Remove 3.4 from the Github PR template --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index df9db03fa8bca..c113ccbf96f1b 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,6 +1,6 @@ | Q | A | ------------- | --- -| Branch? | 5.x for features / 3.4, 4.4 or 5.1 for bug fixes +| Branch? | 5.x for features / 4.4 or 5.1 for bug fixes | Bug fix? | yes/no | New feature? | yes/no | Deprecations? | yes/no From 1a83a469c36c7b4c96189fd1923e2e7d8982a45f Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Mon, 26 Oct 2020 01:24:11 +0100 Subject: [PATCH 010/136] Enable Redis tests on nightly. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b21d6ba81ae00..562305e6191c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -162,11 +162,11 @@ before_install: tfold ext.mongodb tpecl mongodb-1.6.16 mongodb.so $INI tfold ext.zookeeper tpecl zookeeper-0.7.2 zookeeper.so $INI tfold ext.amqp tpecl amqp-1.10.2 amqp.so $INI - tfold ext.redis tpecl redis-5.2.2 redis.so $INI "no" fi tfold ext.apcu tpecl apcu-5.1.19 apcu.so $INI tfold ext.igbinary tpecl igbinary-3.1.6 igbinary.so $INI + tfold ext.redis tpecl redis-5.2.3 redis.so $INI "no" done - | From bcb27b4426dedd35072f5c7e26bdf09d39412917 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 28 Oct 2020 08:18:22 +0100 Subject: [PATCH 011/136] [Cache] Add missing use statement --- src/Symfony/Component/Cache/Traits/AbstractAdapterTrait.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/Cache/Traits/AbstractAdapterTrait.php b/src/Symfony/Component/Cache/Traits/AbstractAdapterTrait.php index cae96ef25ad90..7e0669a086fa3 100644 --- a/src/Symfony/Component/Cache/Traits/AbstractAdapterTrait.php +++ b/src/Symfony/Component/Cache/Traits/AbstractAdapterTrait.php @@ -13,6 +13,7 @@ use Psr\Cache\CacheItemInterface; use Symfony\Component\Cache\CacheItem; +use Symfony\Component\Cache\Exception\InvalidArgumentException; /** * @author Nicolas Grekas From 29e3964da62351d0fbecac46a952985b455d309f Mon Sep 17 00:00:00 2001 From: Nyholm Date: Wed, 28 Oct 2020 11:52:59 +0100 Subject: [PATCH 012/136] Remove translation keys that does not exists in English --- .../Security/Core/Resources/translations/security.fi.xlf | 4 ---- .../Security/Core/Resources/translations/security.sq.xlf | 4 ---- .../Security/Core/Resources/translations/security.zh_TW.xlf | 4 ---- 3 files changed, 12 deletions(-) diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.fi.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.fi.xlf index d5358a6c1700c..7b8d232cdd9a9 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.fi.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.fi.xlf @@ -30,10 +30,6 @@ Invalid CSRF token. Virheellinen CSRF tunnus. - - Digest nonce has expired. - Digest nonce on vanhentunut. - No authentication provider found to support the authentication token. Autentikointi tunnukselle ei löydetty tuettua autentikointi tarjoajaa. diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.sq.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.sq.xlf index 4f4bc6d4cbc61..03e13708af4b9 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.sq.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.sq.xlf @@ -30,10 +30,6 @@ Invalid CSRF token. Identifikues i pavlefshëm CSRF. - - Digest nonce has expired. - Numeri një perdorimësh i verifikimit Digest ka skaduar. - No authentication provider found to support the authentication token. Asnjë ofrues i vërtetimit nuk u gjet që të mbështesë simbolin e vërtetimit. diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.zh_TW.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.zh_TW.xlf index 7085206440528..86310473180b1 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.zh_TW.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.zh_TW.xlf @@ -30,10 +30,6 @@ Invalid CSRF token. 無效的 CSRF token 。 - - Digest nonce has expired. - 摘要隨機串(digest nonce)已過期。 - No authentication provider found to support the authentication token. 沒有找到支持此 token 的身份驗證服務提供方。 From 7608142ced6672927621bdd5b56c601fa9899c89 Mon Sep 17 00:00:00 2001 From: zumba Date: Wed, 28 Oct 2020 16:05:29 +0200 Subject: [PATCH 013/136] Add FI Form validation translations --- .../Resources/translations/validators.fi.xlf | 126 +++++++++++++++++- 1 file changed, 123 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Form/Resources/translations/validators.fi.xlf b/src/Symfony/Component/Form/Resources/translations/validators.fi.xlf index 4eb393aee90b1..7ad87b5468261 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.fi.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.fi.xlf @@ -3,8 +3,8 @@ - This field group should not contain extra fields. - Tämä kenttäryhmä ei voi sisältää ylimääräisiä kenttiä. + This form should not contain extra fields. + Tämä lomake ei voi sisältää ylimääräisiä kenttiä. The uploaded file was too large. Please try to upload a smaller file. @@ -12,7 +12,127 @@ The CSRF token is invalid. Please try to resubmit the form. - CSRF tarkiste on virheellinen. Ole hyvä ja yritä lähettää lomake uudestaan. + CSRF-tarkiste on virheellinen. Ole hyvä ja yritä lähettää lomake uudestaan. + + + This value is not a valid HTML5 color. + Tämä arvo ei ole kelvollinen HTML5-väri. + + + Please enter a valid birthdate. + Syötä kelvollinen syntymäaika. + + + The selected choice is invalid. + Valittu vaihtoehto ei kelpaa. + + + The collection is invalid. + Ryhmä ei kelpaa. + + + Please select a valid color. + Valitse kelvollinen väri. + + + Please select a valid country. + Valitse kelvollinen maa. + + + Please select a valid currency. + Valitse kelvollinen valuutta. + + + Please choose a valid date interval. + Valitse kelvollinen aikaväli. + + + Please enter a valid date and time. + Syötä kelvolliset päivä ja aika. + + + Please enter a valid date. + Syötä kelvollinen päivä. + + + Please select a valid file. + Valitse kelvollinen tiedosto. + + + The hidden field is invalid. + Piilotettu kenttä ei ole kelvollinen. + + + Please enter an integer. + Syötä kokonaisluku. + + + Please select a valid language. + Valitse kelvollinen kieli. + + + Please select a valid locale. + Valitse kelvollinen kielikoodi. + + + Please enter a valid money amount. + Syötä kelvollinen rahasumma. + + + Please enter a number. + Syötä numero. + + + The password is invalid. + Salasana ei kelpaa. + + + Please enter a percentage value. + Syötä prosenttiluku. + + + The values do not match. + Arvot eivät vastaa toisiaan. + + + Please enter a valid time. + Syötä kelvollinen kellonaika. + + + Please select a valid timezone. + Valitse kelvollinen aikavyöhyke. + + + Please enter a valid URL. + Syötä kelvollinen URL. + + + Please enter a valid search term. + Syötä kelvollinen hakusana. + + + Please provide a valid phone number. + Anna kelvollinen puhelinnumero. + + + The checkbox has an invalid value. + Valintaruudun arvo ei kelpaa. + + + Please enter a valid email address. + Syötä kelvollinen sähköpostiosoite. + + + Please select a valid option. + Valitse kelvollinen vaihtoehto. + + + Please select a valid range. + Valitse kelvollinen väli. + + + Please enter a valid week. + Syötä kelvollinen viikko. From 0f13737cc16512734951b549522639cbbadeca90 Mon Sep 17 00:00:00 2001 From: zumba Date: Wed, 28 Oct 2020 14:17:39 +0200 Subject: [PATCH 014/136] Add new FI Validator translations --- .../Resources/translations/validators.fi.xlf | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.fi.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.fi.xlf index d35bff2c6e8e7..423775903d6c4 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.fi.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.fi.xlf @@ -336,7 +336,7 @@ This collection should contain only unique elements. - Tämä ryhmä tulisi sisältää vain yksilöllisiä arvoja. + Tämän ryhmän tulisi sisältää vain yksilöllisiä arvoja. This value should be positive. @@ -366,6 +366,26 @@ This value should be between {{ min }} and {{ max }}. Arvon tulisi olla välillä {{ min }} - {{ max }}. + + This value is not a valid hostname. + Arvo ei ole kelvollinen laitenimi (hostname). + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Ryhmässä olevien elementtien määrän pitää olla monikerta luvulle {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Tämän arvon tulee läpäistä vähintään yksi seuraavista tarkistuksista: + + + Each element of this collection should satisfy its own set of constraints. + Ryhmän jokaisen elementin tulee läpäistä omat tarkistuksensa. + + + This value is not a valid International Securities Identification Number (ISIN). + Tämä arvo ei ole kelvollinen ISIN-koodi (International Securities Identification Number). + From c4461b760ac89bc75dc04c0ed0cd7b474da6d198 Mon Sep 17 00:00:00 2001 From: Marco Petersen Date: Tue, 27 Oct 2020 21:11:21 +0100 Subject: [PATCH 015/136] Add missing translations for Tagalog (tl) --- .../Resources/translations/validators.tl.xlf | 20 +++++++++++++++++++ .../Resources/translations/security.tl.xlf | 16 +++++++++++---- .../Resources/translations/validators.tl.xlf | 18 ++++++++++++----- 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/Form/Resources/translations/validators.tl.xlf b/src/Symfony/Component/Form/Resources/translations/validators.tl.xlf index 950c4110d880a..272e331298a2f 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.tl.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.tl.xlf @@ -114,6 +114,26 @@ Please provide a valid phone number. Pakilagay ang balidong numero ng telepono. + + The checkbox has an invalid value. + Ang checkbox ay mayroon hindi balidong halaga. + + + Please enter a valid email address. + Pakilagay ang balidong email address. + + + Please select a valid option. + Pakipiliin ang balidong pagpipilian. + + + Please select a valid range. + Pakipilian ang balidong layo. + + + Please enter a valid week. + Pakilagay ang balidong linggo. + diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.tl.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.tl.xlf index c74b10aea83ab..013f22f826e28 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.tl.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.tl.xlf @@ -52,19 +52,27 @@ Account has expired. - Ang akawnt ay nag-expire na. + Ang account ay nag-expire na. Credentials have expired. - .ng mga kinakailangang dokumento ay nag expire na. + Ang mga kinakailangang dokumento ay nag expire na. Account is disabled. - Ang akawnt ay hindi pinagana. + Ang account ay hindi pinagana. Account is locked. - ng akawnt ay nakasara. + Ang account ay nakasara. + + + Too many failed login attempts, please try again later. + Madaming bagsak na pagtatangka, pakisubukan ulit mamaya. + + + Invalid or expired login link. + Inbalido o nagexpire na ang link para makapaglogin. diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.tl.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.tl.xlf index 34754b1e9bb8d..e930e59014191 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.tl.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.tl.xlf @@ -68,7 +68,7 @@ The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. - Ang uri ng file ng mime ay hindi balido ({{ type }}).Ang mga pinapayagang uri ng mime ay ang {{ types }}. + Ang uri ng file ng mime ay hindi balido ({{ type }}). Ang mga pinapayagang uri ng mime ay ang {{ types }}. This value should be {{ limit }} or less. @@ -76,7 +76,7 @@ This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. - Ang halaga nito ay masyadong mahaba.Ito ay dapat na {{ limit }} karakter o maliit pa.|Ang halaga nito ay masyadong mahaba. Ito ay dapat na {{ limit }} mga karakter o maliit pa. + Ang halaga nito ay masyadong mahaba. Ito ay dapat na {{ limit }} karakter o maliit pa.|Ang halaga nito ay masyadong mahaba. Ito ay dapat na {{ limit }} mga karakter o maliit pa. This value should be {{ limit }} or more. @@ -268,7 +268,7 @@ This value should be less than or equal to {{ compared_value }}. - Ang halagang ito ay dapat mas mmaliit o magkapareha sa {{ compared_value }}. + Ang halagang ito ay dapat mas maliit o magkapareha sa {{ compared_value }}. This value should not be equal to {{ compared_value }}. @@ -284,7 +284,7 @@ The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. - ng ratio ng imahe ay masyadong maliit ({{ ratio }}). Ang pinamaliit na ratio ay {{ min_ratio }}. + Ang ratio ng imahe ay masyadong maliit ({{ ratio }}). Ang pinakamaliit na ratio ay {{ min_ratio }}. The image is square ({{ width }}x{{ height }}px). Square images are not allowed. @@ -296,7 +296,7 @@ The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. - Ang orientasyon ng imahe ay nakaportrait ({{ width }}x{{ height }}px). PAng mga imaheng nakaportrait ang orientasyon ay hindi pwede. + Ang orientasyon ng imahe ay nakaportrait ({{ width }}x{{ height }}px). Ang mga imaheng nakaportrait ang orientasyon ay hindi pwede. An empty file is not allowed. @@ -374,6 +374,14 @@ The number of elements in this collection should be a multiple of {{ compared_value }}. Ang bilang ng mga elemento sa koleksyon na ito ay dapat multiple ng {{ compared_value }}. + + This value should satisfy at least one of the following constraints: + Ang halagang ito ay dapat masunod ang kahit na isang sumusunod na batayan. + + + Each element of this collection should satisfy its own set of constraints. + Ang bawat elemento sa koleksyon na ito ay dapat masunod ang nararapat na batayan. + This value is not a valid International Securities Identification Number (ISIN). Ang halagang ito ay hindi wastong International Securities Identification Number (ISIN). From ef24b10b04bfdc86cbbc88f1eda0605b6590a843 Mon Sep 17 00:00:00 2001 From: Marco Lipparini Date: Wed, 28 Oct 2020 16:15:44 +0100 Subject: [PATCH 016/136] [FrameworkBundle] Fixing TranslationUpdateCommand failure when using "--no-backup" --- src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md | 2 +- .../FrameworkBundle/Command/TranslationUpdateCommand.php | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index 9815c8fd12616..1b5fc917beb54 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -3,7 +3,7 @@ CHANGELOG 5.1.0 ----- - + * Removed `--no-backup` option from `translation:update` command (broken since `5.0.0`) * Added link to source for controllers registered as named services * Added link to source on controller on `router:match`/`debug:router` (when `framework.ide` is configured) * Added the `framework.router.default_uri` configuration option to configure the default `RequestContext` diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php index 57a9a19157fa3..f43e236b7a402 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php @@ -79,7 +79,6 @@ protected function configure() new InputOption('output-format', null, InputOption::VALUE_OPTIONAL, 'Override the default output format', 'xlf'), new InputOption('dump-messages', null, InputOption::VALUE_NONE, 'Should the messages be dumped in the console'), new InputOption('force', null, InputOption::VALUE_NONE, 'Should the update be done'), - new InputOption('no-backup', null, InputOption::VALUE_NONE, 'Should backup be disabled'), new InputOption('clean', null, InputOption::VALUE_NONE, 'Should clean not found messages'), new InputOption('domain', null, InputOption::VALUE_OPTIONAL, 'Specify the domain to update'), new InputOption('xliff-version', null, InputOption::VALUE_OPTIONAL, 'Override the default xliff version', '1.2'), @@ -283,10 +282,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $resultMessage = sprintf('%d message%s successfully extracted', $extractedMessagesCount, $extractedMessagesCount > 1 ? 's were' : ' was'); } - if (true === $input->getOption('no-backup')) { - $this->writer->disableBackup(); - } - // save the files if (true === $input->getOption('force')) { $io->comment('Writing files...'); From 4f3951655843c024d7a5d34fd340a72fc4c0a9ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cteerasak=E2=80=9D?= Date: Wed, 28 Oct 2020 21:48:46 +0700 Subject: [PATCH 017/136] Added Thai missing translations --- .../Resources/translations/validators.th.xlf | 139 ++++++++++++++++++ .../Resources/translations/security.th.xlf | 8 + .../Resources/translations/validators.th.xlf | 20 +++ 3 files changed, 167 insertions(+) create mode 100644 src/Symfony/Component/Form/Resources/translations/validators.th.xlf diff --git a/src/Symfony/Component/Form/Resources/translations/validators.th.xlf b/src/Symfony/Component/Form/Resources/translations/validators.th.xlf new file mode 100644 index 0000000000000..060dc9ec48094 --- /dev/null +++ b/src/Symfony/Component/Form/Resources/translations/validators.th.xlf @@ -0,0 +1,139 @@ + + + + + + This form should not contain extra fields. + ฟอร์มนี้ไม่ควรมี extra fields + + + The uploaded file was too large. Please try to upload a smaller file. + ไฟล์ที่อัพโหลดมีขนาดใหญ่เกินไป กรุณาลองอัพโหลดใหม่อีกครั้งด้วยไฟล์ที่มีขนาดเล็กลง + + + The CSRF token is invalid. Please try to resubmit the form. + CSRF token ไม่ถูกต้อง กรุณาลองส่งแบบฟอร์มใหม่ + + + This value is not a valid HTML5 color. + ค่านี้ไม่ใช่ค่าที่ถูกต้องของค่าสี HTML5 + + + Please enter a valid birthdate. + กรุณากรอกวันเดือนปีเกิดที่ถูกต้อง + + + The selected choice is invalid. + ตัวเลือกที่เลิอกไม่ถูกต้อง + + + The collection is invalid. + คอเล็กชั่นไม่ถูกต้อง + + + Please select a valid color. + กรุณาเลือกค่าสีที่ถูกต้อง + + + Please select a valid country. + กรุณาเลือกประเทศที่ถูกต้อง + + + Please select a valid currency. + กรุุณาเลิอกค่าสกุลเงินที่ถูกต้อง + + + Please choose a valid date interval. + กรุณณากรอกช่วงวันที่ที่ถูกต้อง + + + Please enter a valid date and time. + กรุณณากรอกค่าเวลาและวันที่ที่ถูกต้อง + + + Please enter a valid date. + กรุณณากรอกค่าวันที่ที่ถูกต้อง + + + Please select a valid file. + กรุณาเลือกไฟล์ที่ถูกต้อง + + + The hidden field is invalid. + ค่า Hidden field ไม่ถูกต้อง + + + Please enter an integer. + กรุณากรอกตัวเลขจำนวนเต็ม + + + Please select a valid language. + กรุณาเลือกภาษาที่ถูกต้อง + + + Please select a valid locale. + กรุณาเลือกท้องถิ่นที่ถูกต้อง + + + Please enter a valid money amount. + กรุณากรอกจำนวนเงินที่ถูกต้อง + + + Please enter a number. + กรุณากรอกตัวเลข + + + The password is invalid. + รหัสผ่านไม่ถูกต้อง + + + Please enter a percentage value. + กรุณากรอกค่าเปอร์เซ็นต์ + + + The values do not match. + ค่าทั้งสองไม่ตรงกัน + + + Please enter a valid time. + กรุณากรอกค่าเวลาที่ถูกต้อง + + + Please select a valid timezone. + กรุณาเลือกค่าเขตเวลาที่ถูกต้อง + + + Please enter a valid URL. + กรุณากรอก URL ที่ถูกต้อง + + + Please enter a valid search term. + กรุณากรอกคำค้นหาที่ถูกต้อง + + + Please provide a valid phone number. + กรุณากรอกเบอร์โทรศัพท์ที่ถูกต้อง + + + The checkbox has an invalid value. + Checkbox มีค่าที่ไม่ถูกต้อง + + + Please enter a valid email address. + กรุณากรอกที่อยู่อีเมล์ที่ถูกต้อง + + + Please select a valid option. + กรุณาเลือกตัวเลือกที่ถูกต้อง + + + Please select a valid range. + กรุณาเลือกค่าช่วงที่ถูกต้อง + + + Please enter a valid week. + กรุณากรอกค่าสัปดาห์ที่ถูกต้อง + + + + diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.th.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.th.xlf index 84ae66769c611..2b2f1e068ba76 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.th.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.th.xlf @@ -62,6 +62,14 @@ Account is locked. บัญชีถูกล็อกแล้ว + + Too many failed login attempts, please try again later. + มีความพยายามเข้าสู่ระบบล้มเหลวมากเกินไป กรุณาลองใหม่ภายหลัง + + + Invalid or expired login link. + ลิงค์เข้าสู่ระบบไม่ถูกต้องหรือหมดอายุไปแล้ว + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.th.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.th.xlf index 31aa00cfac011..31453ff15736d 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.th.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.th.xlf @@ -366,6 +366,26 @@ This value should be between {{ min }} and {{ max }}. ค่านี้ควรอยู่ระหว่าง {{ min }} ถึง {{ max }} + + This value is not a valid hostname. + ค่าโฮสต์เนมไม่ถูกต้อง + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + จำนวนของสมาชิกในคอเล็กชั่นควรเป็นพหุคูณของ {{ compared_value }} + + + This value should satisfy at least one of the following constraints: + ค่านี้ควรเป็นไปตามข้อจำกัดอย่างน้อยหนึ่งข้อจากข้อจำกัดเหล่านี้: + + + Each element of this collection should satisfy its own set of constraints. + สมากชิกแต่ละตัวในคอเล็กชั่นควรเป็นไปตามเซ็ตข้อจำกัดของคอเล็กชั่น + + + This value is not a valid International Securities Identification Number (ISIN). + ค่า​รหัสหลักทรัพย์สากล (ISIN) ไม่ถูกต้อง + From ed80bcc82c18959825bc575b75166fb04ab8f965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Wed, 28 Oct 2020 18:57:35 +0100 Subject: [PATCH 018/136] Remove dependency on doctrine/reflection That package is being phased out, and there are good chances that the classes involved at runtime are completely different from the classes involved in the test changed in that commit. That test was the only piece of code I could find still referencing the Doctrine\Common\Reflection namespace. --- composer.json | 1 - .../Constraints/UniqueEntityValidatorTest.php | 11 +---------- src/Symfony/Bridge/Doctrine/composer.json | 3 +-- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/composer.json b/composer.json index 4ae6826ce77ef..55f83ce8e724e 100644 --- a/composer.json +++ b/composer.json @@ -107,7 +107,6 @@ "doctrine/data-fixtures": "^1.1", "doctrine/dbal": "~2.4|^3.0", "doctrine/orm": "~2.4,>=2.4.5", - "doctrine/reflection": "~1.0", "doctrine/doctrine-bundle": "^1.5|^2.0", "guzzlehttp/promises": "^1.3.1", "masterminds/html5": "^2.6", diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php index e9e905c89c3a4..0b7cfb071bcfe 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php @@ -114,17 +114,8 @@ protected function createEntityManagerMock($repositoryMock) ->method('hasField') ->willReturn(true) ; - $reflParser = $this->getMockBuilder('Doctrine\Common\Reflection\StaticReflectionParser') - ->disableOriginalConstructor() - ->getMock() - ; - $refl = $this->getMockBuilder('Doctrine\Common\Reflection\StaticReflectionProperty') - ->setConstructorArgs([$reflParser, 'property-name']) - ->setMethods(['getValue']) - ->getMock() - ; + $refl = $this->createStub(\ReflectionProperty::class); $refl - ->expects($this->any()) ->method('getValue') ->willReturn(true) ; diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json index b792582d59502..2d8a44f7138b9 100644 --- a/src/Symfony/Bridge/Doctrine/composer.json +++ b/src/Symfony/Bridge/Doctrine/composer.json @@ -44,8 +44,7 @@ "doctrine/collections": "~1.0", "doctrine/data-fixtures": "^1.1", "doctrine/dbal": "~2.4|^3.0", - "doctrine/orm": "^2.6.3", - "doctrine/reflection": "~1.0" + "doctrine/orm": "^2.6.3" }, "conflict": { "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", From 52380eed38acd3c6d1a8ca9fd918ac95fdf1fee8 Mon Sep 17 00:00:00 2001 From: Miro Michalicka Date: Mon, 26 Oct 2020 13:44:49 +0100 Subject: [PATCH 019/136] [Form] Add missing slovak translations --- .../Resources/translations/validators.sk.xlf | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/src/Symfony/Component/Form/Resources/translations/validators.sk.xlf b/src/Symfony/Component/Form/Resources/translations/validators.sk.xlf index 638d0cc4a0b3e..06b2bbdbead5f 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.sk.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.sk.xlf @@ -14,6 +14,126 @@ The CSRF token is invalid. Please try to resubmit the form. CSRF token je neplatný. Prosím skúste znovu odoslať formulár. + + This value is not a valid HTML5 color. + Táto hodnota nie je platná HTML5 farba. + + + Please enter a valid birthdate. + Prosím zadajte platný dátum narodenia. + + + The selected choice is invalid. + Vybraná možnosť je neplatná. + + + The collection is invalid. + Kolekcia je neplatná. + + + Please select a valid color. + Prosím vyberte platnú farbu. + + + Please select a valid country. + Prosím vyberte platnú krajinu. + + + Please select a valid currency. + Prosím vyberte platnú menu. + + + Please choose a valid date interval. + Prosím vyberte platný rozsah dát. + + + Please enter a valid date and time. + Prosím zadajte platný dátum a čas. + + + Please enter a valid date. + Prosím zadajte platný dátum. + + + Please select a valid file. + Prosím vyberte platný súbor. + + + The hidden field is invalid. + Skryté pole je neplatné. + + + Please enter an integer. + Prosím zadajte celé číslo. + + + Please select a valid language. + Prosím vyberte platný jazyk. + + + Please select a valid locale. + Prosím vyberte platné miestne nastavenia. + + + Please enter a valid money amount. + Prosím zadajte platnú čiastku. + + + Please enter a number. + Prosím zadajte číslo. + + + The password is invalid. + Heslo je neprávne. + + + Please enter a percentage value. + Prosím zadajte percentuálnu hodnotu. + + + The values do not match. + Hodnoty nie sú zhodné. + + + Please enter a valid time. + Prosím zadajte platný čas. + + + Please select a valid timezone. + Prosím vyberte platné časové pásmo. + + + Please enter a valid URL. + Prosím zadajte platnú URL. + + + Please enter a valid search term. + Prosím zadajte platný vyhľadávací výraz. + + + Please provide a valid phone number. + Prosím zadajte platné telefónne číslo. + + + The checkbox has an invalid value. + Zaškrtávacie políčko má neplatnú hodnotu. + + + Please enter a valid email address. + Prosím zadajte platnú emailovú adresu. + + + Please select a valid option. + Prosím vyberte platnú možnosť. + + + Please select a valid range. + Prosím vyberte platný rozsah. + + + Please enter a valid week. + Prosím zadajte platný týždeň. + From f0605b8137a1979116c833ddb9d3a736ba2719e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Wed, 28 Oct 2020 19:29:55 +0100 Subject: [PATCH 020/136] Use createMock() rather than createStub() The CI is not using a recent enough version of PHPUnit for that --- .../Tests/Validator/Constraints/UniqueEntityValidatorTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php index 0b7cfb071bcfe..98377acdeaf4b 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php @@ -114,7 +114,7 @@ protected function createEntityManagerMock($repositoryMock) ->method('hasField') ->willReturn(true) ; - $refl = $this->createStub(\ReflectionProperty::class); + $refl = $this->createMock(\ReflectionProperty::class); $refl ->method('getValue') ->willReturn(true) From 447d9c22f6eb7e90799660e1a855a57c8084caa4 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Wed, 28 Oct 2020 09:39:57 +0100 Subject: [PATCH 021/136] Simplify phpunit script. --- phpunit | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/phpunit b/phpunit index 71915eecb2b34..03bf63b0aae99 100755 --- a/phpunit +++ b/phpunit @@ -8,17 +8,12 @@ if (!file_exists(__DIR__.'/vendor/symfony/phpunit-bridge/bin/simple-phpunit')) { exit(1); } if (!getenv('SYMFONY_PHPUNIT_VERSION')) { - if (\PHP_VERSION_ID >= 70200) { - if (false === getenv('SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT') && false !== strpos(@file_get_contents(__DIR__.'/src/Symfony/Component/HttpKernel/Kernel.php'), 'const MAJOR_VERSION = 3;')) { - putenv('SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT=1'); - } - if (\PHP_VERSION_ID < 70300) { - putenv('SYMFONY_PHPUNIT_VERSION=8.5'); - } else { - putenv('SYMFONY_PHPUNIT_VERSION=9.4'); - } - } elseif (\PHP_VERSION_ID >= 70000) { - putenv('SYMFONY_PHPUNIT_VERSION=6.5'); + if (\PHP_VERSION_ID < 70200) { + putenv('SYMFONY_PHPUNIT_VERSION=7.5'); + } elseif (\PHP_VERSION_ID < 70300) { + putenv('SYMFONY_PHPUNIT_VERSION=8.5'); + } else { + putenv('SYMFONY_PHPUNIT_VERSION=9.4'); } } if (!getenv('SYMFONY_PATCH_TYPE_DECLARATIONS')) { From 659decf594cd0447c7e67614b0b7b3cd6450ef37 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Wed, 28 Oct 2020 08:52:32 +0100 Subject: [PATCH 022/136] Use short array deconstruction syntax. --- .php_cs.dist | 1 + .../DataCollector/DoctrineDataCollector.php | 4 ++-- ...gisterEventListenersAndSubscribersPass.php | 4 ++-- .../Doctrine/Form/DoctrineOrmTypeGuesser.php | 2 +- .../Bridge/Monolog/Tests/LoggerTest.php | 2 +- .../Tests/Processor/WebProcessorTest.php | 6 +++--- .../Bridge/Twig/Command/DebugCommand.php | 4 ++-- .../Bridge/Twig/Extension/CodeExtension.php | 2 +- src/Symfony/Bridge/Twig/Node/TransNode.php | 2 +- .../Controller/ControllerNameParser.php | 2 +- .../FrameworkExtension.php | 2 +- .../Templating/Helper/CodeHelper.php | 2 +- .../Controller/SessionController.php | 2 +- .../Translation/Translator.php | 2 +- .../DependencyInjection/SecurityExtension.php | 6 +++--- .../CompleteConfigurationTest.php | 2 +- .../Security/Factory/AbstractFactoryTest.php | 8 ++++---- .../GuardAuthenticationFactoryTest.php | 8 ++++---- .../Profiler/TemplateManager.php | 2 +- .../Command/ServerStatusCommand.php | 2 +- src/Symfony/Component/BrowserKit/Cookie.php | 2 +- .../Tests/Adapter/PhpArrayAdapterTest.php | 2 +- .../Tests/Simple/PhpArrayCacheWrapper.php | 4 ++-- .../Component/Cache/Traits/MemcachedTrait.php | 2 +- .../Component/Cache/Traits/PhpArrayTrait.php | 2 +- .../Component/Cache/Traits/RedisTrait.php | 2 +- .../Component/Config/Definition/ArrayNode.php | 2 +- .../Definition/Dumper/XmlReferenceDumper.php | 2 +- .../Component/Console/Helper/Table.php | 8 ++++---- .../Component/CssSelector/Parser/Parser.php | 6 +++--- .../XPath/Extension/FunctionExtension.php | 2 +- .../Component/Debug/DebugClassLoader.php | 8 ++++---- .../Argument/BoundArgument.php | 4 ++-- .../Compiler/AbstractRecursivePass.php | 2 +- .../Compiler/AutowirePass.php | 4 ++-- .../Compiler/AutowireRequiredMethodsPass.php | 2 +- .../Compiler/DecoratorServicePass.php | 4 ++-- .../Compiler/ResolveBindingsPass.php | 12 +++++------ .../Compiler/ResolveNamedArgumentsPass.php | 4 ++-- .../DependencyInjection/ContainerBuilder.php | 2 +- .../DependencyInjection/Dumper/PhpDumper.php | 12 +++++------ .../DependencyInjection/Dumper/XmlDumper.php | 2 +- .../DependencyInjection/Dumper/YamlDumper.php | 2 +- .../Loader/XmlFileLoader.php | 2 +- .../ResolveParameterPlaceHoldersPassTest.php | 2 +- .../ErrorHandler/DebugClassLoader.php | 14 ++++++------- .../Debug/TraceableEventDispatcher.php | 4 ++-- .../Component/ExpressionLanguage/Lexer.php | 4 ++-- .../Component/Filesystem/Filesystem.php | 6 +++--- .../Form/Extension/Core/Type/FileType.php | 2 +- src/Symfony/Component/Form/FormBuilder.php | 2 +- .../HttpFoundation/BinaryFileResponse.php | 4 ++-- .../Component/HttpFoundation/IpUtils.php | 4 ++-- .../Component/HttpFoundation/ServerBag.php | 2 +- .../Controller/ControllerResolver.php | 4 ++-- .../DataCollector/DumpDataCollector.php | 2 +- ...RegisterControllerArgumentLocatorsPass.php | 6 +++--- ...oveEmptyControllerArgumentLocatorsPass.php | 4 ++-- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- .../Profiler/FileProfilerStorage.php | 2 +- ...ontrollerArgumentValueResolverPassTest.php | 4 ++-- .../HttpKernel/Tests/HttpCache/StoreTest.php | 4 ++-- .../Tests/HttpCache/TestHttpKernel.php | 4 ++-- .../Component/Lock/Store/MemcachedStore.php | 4 ++-- .../Lock/Tests/Store/SemaphoreStoreTest.php | 2 +- src/Symfony/Component/Mailer/Transport.php | 4 ++-- .../Mailer/Transport/Smtp/SmtpTransport.php | 2 +- src/Symfony/Component/Mime/Email.php | 2 +- src/Symfony/Component/Mime/Part/DataPart.php | 2 +- .../Process/Tests/ErrorProcessInitiator.php | 2 +- .../PropertyAccess/PropertyAccessor.php | 4 ++-- .../Extractor/PhpDocExtractor.php | 10 +++++----- .../Extractor/ReflectionExtractor.php | 8 ++++---- .../PropertyInfo/Util/PhpDocTypeHelper.php | 4 ++-- .../Generator/CompiledUrlGenerator.php | 2 +- .../Routing/Loader/XmlFileLoader.php | 4 ++-- .../Routing/Matcher/CompiledUrlMatcher.php | 2 +- .../Dumper/CompiledUrlMatcherDumper.php | 14 ++++++------- .../Dumper/CompiledUrlMatcherTrait.php | 4 ++-- .../Matcher/Dumper/StaticPrefixCollection.php | 8 ++++---- .../Dumper/StaticPrefixCollectionTest.php | 2 +- .../TraceableAccessDecisionManagerTest.php | 2 +- .../Csrf/Tests/CsrfTokenManagerTest.php | 12 +++++------ .../Http/Firewall/ChannelListener.php | 2 +- .../Http/Logout/LogoutUrlGenerator.php | 4 ++-- ...PersistentTokenBasedRememberMeServices.php | 4 ++-- .../TokenBasedRememberMeServices.php | 2 +- .../Tests/Firewall/LogoutListenerTest.php | 20 +++++++++---------- .../Tests/Firewall/RememberMeListenerTest.php | 18 ++++++++--------- .../Security/Http/Tests/FirewallMapTest.php | 6 +++--- .../Serializer/Encoder/CsvEncoder.php | 4 ++-- .../TranslatorPathsPass.php | 2 +- .../Translation/Loader/MoFileLoader.php | 2 +- .../Validator/Constraints/FileValidator.php | 4 ++-- .../NotCompromisedPasswordValidator.php | 2 +- .../AddValidatorInitializersPass.php | 2 +- .../Mapping/Loader/AbstractLoader.php | 2 +- .../Test/ConstraintValidatorTestCase.php | 2 +- .../AbstractComparisonValidatorTestCase.php | 2 +- .../Tests/Constraints/FileValidatorTest.php | 2 +- .../Component/VarDumper/Caster/ArgsStub.php | 2 +- .../VarDumper/Cloner/AbstractCloner.php | 2 +- .../Component/VarDumper/Server/DumpServer.php | 2 +- .../VarExporter/Tests/VarExporterTest.php | 6 +++--- .../Component/VarExporter/VarExporter.php | 2 +- src/Symfony/Component/Workflow/Registry.php | 4 ++-- 106 files changed, 215 insertions(+), 214 deletions(-) diff --git a/.php_cs.dist b/.php_cs.dist index 1c4726d679316..78ba3c0266ed3 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -15,6 +15,7 @@ return PhpCsFixer\Config::create() 'protected_to_private' => false, 'native_constant_invocation' => true, 'combine_nested_dirname' => true, + 'list_syntax' => ['syntax' => 'short'], ]) ->setRiskyAllowed(true) ->setFinder( diff --git a/src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php b/src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php index 31ba75891e1ea..d259e4123976a 100644 --- a/src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php +++ b/src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php @@ -195,7 +195,7 @@ private function sanitizeQuery(string $connectionName, array $query): array } } - list($query['params'][$j], $explainable, $runnable) = $this->sanitizeParam($param, $e); + [$query['params'][$j], $explainable, $runnable] = $this->sanitizeParam($param, $e); if (!$explainable) { $query['explainable'] = false; } @@ -231,7 +231,7 @@ private function sanitizeParam($var, ?\Throwable $error): array $a = []; $explainable = $runnable = true; foreach ($var as $k => $v) { - list($value, $e, $r) = $this->sanitizeParam($v, null); + [$value, $e, $r] = $this->sanitizeParam($v, null); $explainable = $explainable && $e; $runnable = $runnable && $r; $a[$k] = $value; diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php index c1bbde27aa9c6..d2c8343ddb3c1 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php @@ -65,7 +65,7 @@ private function addTaggedSubscribers(ContainerBuilder $container) $taggedSubscribers = $this->findAndSortTags($subscriberTag, $container); foreach ($taggedSubscribers as $taggedSubscriber) { - list($id, $tag) = $taggedSubscriber; + [$id, $tag] = $taggedSubscriber; $connections = isset($tag['connection']) ? [$tag['connection']] : array_keys($this->connections); foreach ($connections as $con) { if (!isset($this->connections[$con])) { @@ -84,7 +84,7 @@ private function addTaggedListeners(ContainerBuilder $container) $listenerRefs = []; foreach ($taggedListeners as $taggedListener) { - list($id, $tag) = $taggedListener; + [$id, $tag] = $taggedListener; if (!isset($tag['event'])) { throw new InvalidArgumentException(sprintf('Doctrine event listener "%s" must specify the "event" attribute.', $id)); } diff --git a/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php b/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php index ca4f832c4de12..944c305ab70a7 100644 --- a/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php +++ b/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php @@ -49,7 +49,7 @@ public function guessType($class, $property) return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TextType', [], Guess::LOW_CONFIDENCE); } - list($metadata, $name) = $ret; + [$metadata, $name] = $ret; if ($metadata->hasAssociation($property)) { $multiple = $metadata->isCollectionValuedAssociation($property); diff --git a/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php b/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php index 2b2c7a3763a72..c6f34799fc7dc 100644 --- a/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php @@ -75,7 +75,7 @@ public function testGetLogsWithDebugProcessor2() $logger->info('test'); $this->assertCount(1, $logger->getLogs()); - list($record) = $logger->getLogs(); + [$record] = $logger->getLogs(); $this->assertEquals('test', $record['message']); $this->assertEquals(Logger::INFO, $record['priority']); diff --git a/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php b/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php index 321bd7a8eed32..24aed730954e4 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php @@ -22,7 +22,7 @@ class WebProcessorTest extends TestCase { public function testUsesRequestServerData() { - list($event, $server) = $this->createRequestEvent(); + [$event, $server] = $this->createRequestEvent(); $processor = new WebProcessor(); $processor->onKernelRequest($event); @@ -39,7 +39,7 @@ public function testUsesRequestServerData() public function testUseRequestClientIp() { Request::setTrustedProxies(['192.168.0.1'], Request::HEADER_X_FORWARDED_ALL); - list($event, $server) = $this->createRequestEvent(['X_FORWARDED_FOR' => '192.168.0.2']); + [$event, $server] = $this->createRequestEvent(['X_FORWARDED_FOR' => '192.168.0.2']); $processor = new WebProcessor(); $processor->onKernelRequest($event); @@ -61,7 +61,7 @@ public function testCanBeConstructedWithExtraFields() $this->markTestSkipped('WebProcessor of the installed Monolog version does not support $extraFields parameter'); } - list($event, $server) = $this->createRequestEvent(); + [$event, $server] = $this->createRequestEvent(); $processor = new WebProcessor(['url', 'referrer']); $processor->onKernelRequest($event); diff --git a/src/Symfony/Bridge/Twig/Command/DebugCommand.php b/src/Symfony/Bridge/Twig/Command/DebugCommand.php index a66e77c363422..d3a68aca5841f 100644 --- a/src/Symfony/Bridge/Twig/Command/DebugCommand.php +++ b/src/Symfony/Bridge/Twig/Command/DebugCommand.php @@ -161,7 +161,7 @@ private function displayPathsText(SymfonyStyle $io, string $name) $shortnames[] = str_replace('\\', '/', $file->getRelativePathname()); } - list($namespace, $shortname) = $this->parseTemplateName($name); + [$namespace, $shortname] = $this->parseTemplateName($name); $alternatives = $this->findAlternatives($shortname, $shortnames); if (FilesystemLoader::MAIN_NAMESPACE !== $namespace) { $alternatives = array_map(function ($shortname) use ($namespace) { @@ -482,7 +482,7 @@ private function error(SymfonyStyle $io, string $message, array $alternatives = private function findTemplateFiles(string $name): array { - list($namespace, $shortname) = $this->parseTemplateName($name); + [$namespace, $shortname] = $this->parseTemplateName($name); $files = []; foreach ($this->getFilesystemLoaders() as $loader) { diff --git a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php index 389fc65cc5509..7f60b542bff40 100644 --- a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php @@ -72,7 +72,7 @@ public function abbrClass($class) public function abbrMethod($method) { if (false !== strpos($method, '::')) { - list($class, $method) = explode('::', $method, 2); + [$class, $method] = explode('::', $method, 2); $result = sprintf('%s::%s()', $this->abbrClass($class), $method); } elseif ('Closure' === $method) { $result = sprintf('%1$s', $method); diff --git a/src/Symfony/Bridge/Twig/Node/TransNode.php b/src/Symfony/Bridge/Twig/Node/TransNode.php index 0a754fa859858..54247a59e3078 100644 --- a/src/Symfony/Bridge/Twig/Node/TransNode.php +++ b/src/Symfony/Bridge/Twig/Node/TransNode.php @@ -60,7 +60,7 @@ public function compile(Compiler $compiler) $defaults = $this->getNode('vars'); $vars = null; } - list($msg, $defaults) = $this->compileString($this->getNode('body'), $defaults, (bool) $vars); + [$msg, $defaults] = $this->compileString($this->getNode('body'), $defaults, (bool) $vars); $compiler ->write('echo $this->env->getExtension(\'Symfony\Bridge\Twig\Extension\TranslationExtension\')->trans(') diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php index 6ac0dc01da906..30668f8585536 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php @@ -58,7 +58,7 @@ public function parse($controller) } $originalController = $controller; - list($bundleName, $controller, $action) = $parts; + [$bundleName, $controller, $action] = $parts; $controller = str_replace('/', '\\', $controller); try { diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 0968852cca393..5f0f6f5140487 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -589,7 +589,7 @@ private function registerProfilerConfiguration(array $config, ContainerBuilder $ $container->setParameter('profiler_listener.only_master_requests', $config['only_master_requests']); // Choose storage class based on the DSN - list($class) = explode(':', $config['dsn'], 2); + [$class] = explode(':', $config['dsn'], 2); if ('file' !== $class) { throw new \LogicException(sprintf('Driver "%s" is not supported for the profiler.', $class)); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php b/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php index fc96806ded010..d62126765d5ed 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php @@ -64,7 +64,7 @@ public function abbrClass($class) public function abbrMethod($method) { if (false !== strpos($method, '::')) { - list($class, $method) = explode('::', $method, 2); + [$class, $method] = explode('::', $method, 2); $result = sprintf('%s::%s()', $this->abbrClass($class), $method); } elseif ('Closure' === $method) { $result = sprintf('%1$s', $method); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SessionController.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SessionController.php index 0d9464d7dfab4..168cd2d45a52a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SessionController.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/SessionController.php @@ -71,7 +71,7 @@ public function showFlashAction(Request $request) $session = $request->getSession(); if ($session->getFlashBag()->has('notice')) { - list($output) = $session->getFlashBag()->get('notice'); + [$output] = $session->getFlashBag()->get('notice'); } else { $output = 'No flash was set.'; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php index ec6a5febaaa74..e11e515aba1d6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php @@ -144,7 +144,7 @@ protected function initialize() $this->addResourceFiles(); } foreach ($this->resources as $key => $params) { - list($format, $resource, $locale, $domain) = $params; + [$format, $resource, $locale, $domain] = $params; parent::addResource($format, $resource, $locale, $domain); } $this->resources = []; diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index 8260fb6ce85e4..eec8f4675b5cc 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -239,7 +239,7 @@ private function createFirewalls(array $config, ContainerBuilder $container) $configId = 'security.firewall.map.config.'.$name; - list($matcher, $listeners, $exceptionListener, $logoutListener) = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds, $configId); + [$matcher, $listeners, $exceptionListener, $logoutListener] = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds, $configId); $contextId = 'security.firewall.map.context.'.$name; $context = new ChildDefinition($firewall['stateless'] || empty($firewall['anonymous']['lazy']) ? 'security.firewall.context' : 'security.firewall.lazy_context'); @@ -397,7 +397,7 @@ private function createFirewall(ContainerBuilder $container, string $id, array $ $configuredEntryPoint = isset($firewall['entry_point']) ? $firewall['entry_point'] : null; // Authentication listeners - list($authListeners, $defaultEntryPoint) = $this->createAuthenticationListeners($container, $id, $firewall, $authenticationProviders, $defaultProvider, $providerIds, $configuredEntryPoint, $contextListenerId); + [$authListeners, $defaultEntryPoint] = $this->createAuthenticationListeners($container, $id, $firewall, $authenticationProviders, $defaultProvider, $providerIds, $configuredEntryPoint, $contextListenerId); $config->replaceArgument(7, $configuredEntryPoint ?: $defaultEntryPoint); @@ -479,7 +479,7 @@ private function createAuthenticationListeners(ContainerBuilder $container, stri throw new InvalidConfigurationException(sprintf('Not configuring explicitly the provider for the "%s" listener on "%s" firewall is ambiguous as there is more than one registered provider.', $key, $id)); } - list($provider, $listenerId, $defaultEntryPoint) = $factory->create($container, $id, $firewall[$key], $userProvider, $defaultEntryPoint); + [$provider, $listenerId, $defaultEntryPoint] = $factory->create($container, $id, $firewall[$key], $userProvider, $defaultEntryPoint); $listeners[] = new Reference($listenerId); $authenticationProviders[] = $provider; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php index 68920c865e48a..6eca98ae70190 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php @@ -236,7 +236,7 @@ public function testAccess() } $matcherIds = []; - foreach ($rules as list($matcherId, $attributes, $channel)) { + foreach ($rules as [$matcherId, $attributes, $channel]) { $requestMatcher = $container->getDefinition($matcherId); $this->assertArrayNotHasKey($matcherId, $matcherIds); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php index 01e03b0312bd9..3360863159a90 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php @@ -19,7 +19,7 @@ class AbstractFactoryTest extends TestCase { public function testCreate() { - list($container, $authProviderId, $listenerId, $entryPointId) = $this->callFactory('foo', [ + [$container, $authProviderId, $listenerId, $entryPointId] = $this->callFactory('foo', [ 'use_forward' => true, 'failure_path' => '/foo', 'success_handler' => 'custom_success_handler', @@ -61,7 +61,7 @@ public function testDefaultFailureHandler($serviceId, $defaultHandlerInjection) $options['failure_handler'] = $serviceId; } - list($container) = $this->callFactory('foo', $options, 'user_provider', 'entry_point'); + [$container] = $this->callFactory('foo', $options, 'user_provider', 'entry_point'); $definition = $container->getDefinition('abstract_listener.foo'); $arguments = $definition->getArguments(); @@ -99,7 +99,7 @@ public function testDefaultSuccessHandler($serviceId, $defaultHandlerInjection) $options['success_handler'] = $serviceId; } - list($container) = $this->callFactory('foo', $options, 'user_provider', 'entry_point'); + [$container] = $this->callFactory('foo', $options, 'user_provider', 'entry_point'); $definition = $container->getDefinition('abstract_listener.foo'); $arguments = $definition->getArguments(); @@ -150,7 +150,7 @@ protected function callFactory($id, $config, $userProviderId, $defaultEntryPoint $container->register('custom_success_handler'); $container->register('custom_failure_handler'); - list($authProviderId, $listenerId, $entryPointId) = $factory->create($container, $id, $config, $userProviderId, $defaultEntryPointId); + [$authProviderId, $listenerId, $entryPointId] = $factory->create($container, $id, $config, $userProviderId, $defaultEntryPointId); return [$container, $authProviderId, $listenerId, $entryPointId]; } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/GuardAuthenticationFactoryTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/GuardAuthenticationFactoryTest.php index fd812c13ae04c..c1f3669c11255 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/GuardAuthenticationFactoryTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/GuardAuthenticationFactoryTest.php @@ -103,7 +103,7 @@ public function testBasicCreate() 'authenticators' => ['authenticator123'], 'entry_point' => null, ]; - list($container, $entryPointId) = $this->executeCreate($config, null); + [$container, $entryPointId] = $this->executeCreate($config, null); $this->assertEquals('authenticator123', $entryPointId); $providerDefinition = $container->getDefinition('security.authentication.provider.guard.my_firewall'); @@ -126,7 +126,7 @@ public function testExistingDefaultEntryPointUsed() 'authenticators' => ['authenticator123'], 'entry_point' => null, ]; - list(, $entryPointId) = $this->executeCreate($config, 'some_default_entry_point'); + [, $entryPointId] = $this->executeCreate($config, 'some_default_entry_point'); $this->assertEquals('some_default_entry_point', $entryPointId); } @@ -159,7 +159,7 @@ public function testCreateWithEntryPoint() 'authenticators' => ['authenticator123', 'authenticatorABC'], 'entry_point' => 'authenticatorABC', ]; - list(, $entryPointId) = $this->executeCreate($config, null); + [, $entryPointId] = $this->executeCreate($config, null); $this->assertEquals('authenticatorABC', $entryPointId); } @@ -172,7 +172,7 @@ private function executeCreate(array $config, $defaultEntryPointId) $userProviderId = 'my_user_provider'; $factory = new GuardAuthenticationFactory(); - list(, , $entryPointId) = $factory->create($container, $id, $config, $userProviderId, $defaultEntryPointId); + [, , $entryPointId] = $factory->create($container, $id, $config, $userProviderId, $defaultEntryPointId); return [$container, $entryPointId]; } diff --git a/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php b/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php index c4c4e93c47180..45cfe2f19324d 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php @@ -76,7 +76,7 @@ public function getNames(Profile $profile) continue; } - list($name, $template) = $arguments; + [$name, $template] = $arguments; if (!$this->profiler->has($name) || !$profile->hasCollector($name)) { continue; diff --git a/src/Symfony/Bundle/WebServerBundle/Command/ServerStatusCommand.php b/src/Symfony/Bundle/WebServerBundle/Command/ServerStatusCommand.php index 385179a42e229..19659d6ff01a2 100644 --- a/src/Symfony/Bundle/WebServerBundle/Command/ServerStatusCommand.php +++ b/src/Symfony/Bundle/WebServerBundle/Command/ServerStatusCommand.php @@ -80,7 +80,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $server = new WebServer($this->pidFileDirectory); if ($filter = $input->getOption('filter')) { if ($server->isRunning($input->getOption('pidfile'))) { - list($host, $port) = explode(':', $address = $server->getAddress($input->getOption('pidfile'))); + [$host, $port] = explode(':', $address = $server->getAddress($input->getOption('pidfile'))); if ('address' === $filter) { $output->write($address); } elseif ('host' === $filter) { diff --git a/src/Symfony/Component/BrowserKit/Cookie.php b/src/Symfony/Component/BrowserKit/Cookie.php index 096c41501c3a6..e0232e5150dc9 100644 --- a/src/Symfony/Component/BrowserKit/Cookie.php +++ b/src/Symfony/Component/BrowserKit/Cookie.php @@ -136,7 +136,7 @@ public static function fromString($cookie, $url = null) throw new \InvalidArgumentException(sprintf('The cookie string "%s" is not valid.', $parts[0])); } - list($name, $value) = explode('=', array_shift($parts), 2); + [$name, $value] = explode('=', array_shift($parts), 2); $values = [ 'name' => trim($name), diff --git a/src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterTest.php index 69f334656d58e..58318f6a25294 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterTest.php @@ -155,7 +155,7 @@ public function save(CacheItemInterface $item): bool $this->keys[$key] = $id = \count($this->values); $this->data[$key] = $this->values[$id] = $item->get(); $this->warmUp($this->data); - list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6)); + [$this->keys, $this->values] = eval(substr(file_get_contents($this->file), 6)); }, $this, PhpArrayAdapter::class))(); return true; diff --git a/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheWrapper.php b/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheWrapper.php index 4dfb2236d5c3d..ea6b97c2c5807 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheWrapper.php +++ b/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheWrapper.php @@ -22,7 +22,7 @@ public function set($key, $value, $ttl = null): bool (\Closure::bind(function () use ($key, $value) { $this->data[$key] = $value; $this->warmUp($this->data); - list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6)); + [$this->keys, $this->values] = eval(substr(file_get_contents($this->file), 6)); }, $this, PhpArrayCache::class))(); return true; @@ -38,7 +38,7 @@ public function setMultiple($values, $ttl = null): bool $this->data[$key] = $value; } $this->warmUp($this->data); - list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6)); + [$this->keys, $this->values] = eval(substr(file_get_contents($this->file), 6)); }, $this, PhpArrayCache::class))(); return true; diff --git a/src/Symfony/Component/Cache/Traits/MemcachedTrait.php b/src/Symfony/Component/Cache/Traits/MemcachedTrait.php index 468656e333fa3..34b8aa73a5fc1 100644 --- a/src/Symfony/Component/Cache/Traits/MemcachedTrait.php +++ b/src/Symfony/Component/Cache/Traits/MemcachedTrait.php @@ -111,7 +111,7 @@ public static function createConnection($servers, array $options = []) } $params = preg_replace_callback('#^memcached:(//)?(?:([^@]*+)@)?#', function ($m) use (&$username, &$password) { if (!empty($m[2])) { - list($username, $password) = explode(':', $m[2], 2) + [1 => null]; + [$username, $password] = explode(':', $m[2], 2) + [1 => null]; } return 'file:'.($m[1] ?? ''); diff --git a/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php b/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php index be352e0c43d46..b68c5a3d2463b 100644 --- a/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php +++ b/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php @@ -163,7 +163,7 @@ private function initialize() if (2 !== \count($values) || !isset($values[0], $values[1])) { $this->keys = $this->values = []; } else { - list($this->keys, $this->values) = $values; + [$this->keys, $this->values] = $values; } } } diff --git a/src/Symfony/Component/Cache/Traits/RedisTrait.php b/src/Symfony/Component/Cache/Traits/RedisTrait.php index 103c320f73b88..edd0210711c0c 100644 --- a/src/Symfony/Component/Cache/Traits/RedisTrait.php +++ b/src/Symfony/Component/Cache/Traits/RedisTrait.php @@ -469,7 +469,7 @@ private function pipeline(\Closure $generator, $redis = null): \Generator foreach ($connections as $h => $c) { $connections[$h] = $c[0]->exec(); } - foreach ($results as $k => list($h, $c)) { + foreach ($results as $k => [$h, $c]) { $results[$k] = $connections[$h][$c]; } } else { diff --git a/src/Symfony/Component/Config/Definition/ArrayNode.php b/src/Symfony/Component/Config/Definition/ArrayNode.php index 64ca2d72832a7..4a3461119bcfc 100644 --- a/src/Symfony/Component/Config/Definition/ArrayNode.php +++ b/src/Symfony/Component/Config/Definition/ArrayNode.php @@ -342,7 +342,7 @@ protected function normalizeValue($value) */ protected function remapXml($value) { - foreach ($this->xmlRemappings as list($singular, $plural)) { + foreach ($this->xmlRemappings as [$singular, $plural]) { if (!isset($value[$singular])) { continue; } diff --git a/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php b/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php index 42b5ba4ad6883..77d1664c74bde 100644 --- a/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php +++ b/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php @@ -53,7 +53,7 @@ private function writeNode(NodeInterface $node, int $depth = 0, bool $root = fal }); if (\count($remapping)) { - list($singular) = current($remapping); + [$singular] = current($remapping); $rootName = $singular; } } diff --git a/src/Symfony/Component/Console/Helper/Table.php b/src/Symfony/Component/Console/Helper/Table.php index 82aeb3fc8e7cb..facffa683f227 100644 --- a/src/Symfony/Component/Console/Helper/Table.php +++ b/src/Symfony/Component/Console/Helper/Table.php @@ -430,13 +430,13 @@ private function renderRowSeparator(int $type = self::SEPARATOR_MID, string $tit $crossings = $this->style->getCrossingChars(); if (self::SEPARATOR_MID === $type) { - list($horizontal, $leftChar, $midChar, $rightChar) = [$borders[2], $crossings[8], $crossings[0], $crossings[4]]; + [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[2], $crossings[8], $crossings[0], $crossings[4]]; } elseif (self::SEPARATOR_TOP === $type) { - list($horizontal, $leftChar, $midChar, $rightChar) = [$borders[0], $crossings[1], $crossings[2], $crossings[3]]; + [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[1], $crossings[2], $crossings[3]]; } elseif (self::SEPARATOR_TOP_BOTTOM === $type) { - list($horizontal, $leftChar, $midChar, $rightChar) = [$borders[0], $crossings[9], $crossings[10], $crossings[11]]; + [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[9], $crossings[10], $crossings[11]]; } else { - list($horizontal, $leftChar, $midChar, $rightChar) = [$borders[0], $crossings[7], $crossings[6], $crossings[5]]; + [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[7], $crossings[6], $crossings[5]]; } $markup = $leftChar; diff --git a/src/Symfony/Component/CssSelector/Parser/Parser.php b/src/Symfony/Component/CssSelector/Parser/Parser.php index e8a46c062ce7f..a03f1527f144b 100644 --- a/src/Symfony/Component/CssSelector/Parser/Parser.php +++ b/src/Symfony/Component/CssSelector/Parser/Parser.php @@ -113,7 +113,7 @@ private function parseSelectorList(TokenStream $stream): array private function parserSelectorNode(TokenStream $stream): Node\SelectorNode { - list($result, $pseudoElement) = $this->parseSimpleSelector($stream); + [$result, $pseudoElement] = $this->parseSimpleSelector($stream); while (true) { $stream->skipWhitespace(); @@ -134,7 +134,7 @@ private function parserSelectorNode(TokenStream $stream): Node\SelectorNode $combinator = ' '; } - list($nextSelector, $pseudoElement) = $this->parseSimpleSelector($stream); + [$nextSelector, $pseudoElement] = $this->parseSimpleSelector($stream); $result = new Node\CombinedSelectorNode($result, $combinator, $nextSelector); } @@ -209,7 +209,7 @@ private function parseSimpleSelector(TokenStream $stream, bool $insideNegation = throw SyntaxErrorException::nestedNot(); } - list($argument, $argumentPseudoElement) = $this->parseSimpleSelector($stream, true); + [$argument, $argumentPseudoElement] = $this->parseSimpleSelector($stream, true); $next = $stream->getNext(); if (null !== $argumentPseudoElement) { diff --git a/src/Symfony/Component/CssSelector/XPath/Extension/FunctionExtension.php b/src/Symfony/Component/CssSelector/XPath/Extension/FunctionExtension.php index 2b79aaafc9fcb..d3f7222a4d0ab 100644 --- a/src/Symfony/Component/CssSelector/XPath/Extension/FunctionExtension.php +++ b/src/Symfony/Component/CssSelector/XPath/Extension/FunctionExtension.php @@ -51,7 +51,7 @@ public function getFunctionTranslators(): array public function translateNthChild(XPathExpr $xpath, FunctionNode $function, bool $last = false, bool $addNameTest = true): XPathExpr { try { - list($a, $b) = Parser::parseSeries($function->getArguments()); + [$a, $b] = Parser::parseSeries($function->getArguments()); } catch (SyntaxErrorException $e) { throw new ExpressionErrorException(sprintf('Invalid series: "%s".', implode('", "', $function->getArguments())), 0, $e); } diff --git a/src/Symfony/Component/Debug/DebugClassLoader.php b/src/Symfony/Component/Debug/DebugClassLoader.php index 519a3c8f2fd8b..cf27907ce0d36 100644 --- a/src/Symfony/Component/Debug/DebugClassLoader.php +++ b/src/Symfony/Component/Debug/DebugClassLoader.php @@ -300,7 +300,7 @@ public function checkAnnotations(\ReflectionClass $refl, $class) $hasCall = $refl->hasMethod('__call'); $hasStaticCall = $refl->hasMethod('__callStatic'); foreach (self::$method[$use] as $method) { - list($interface, $name, $static, $description) = $method; + [$interface, $name, $static, $description] = $method; if ($static ? $hasStaticCall : $hasCall) { continue; } @@ -335,12 +335,12 @@ public function checkAnnotations(\ReflectionClass $refl, $class) } if ($parent && isset(self::$finalMethods[$parent][$method->name])) { - list($declaringClass, $message) = self::$finalMethods[$parent][$method->name]; + [$declaringClass, $message] = self::$finalMethods[$parent][$method->name]; $deprecations[] = sprintf('The "%s::%s()" method is considered final%s. It may change without further notice as of its next major version. You should not extend it from "%s".', $declaringClass, $method->name, $message, $class); } if (isset(self::$internalMethods[$class][$method->name])) { - list($declaringClass, $message) = self::$internalMethods[$class][$method->name]; + [$declaringClass, $message] = self::$internalMethods[$class][$method->name]; if (strncmp($ns, $declaringClass, $len)) { $deprecations[] = sprintf('The "%s::%s()" method is considered internal%s. It may change without further notice. You should not extend it from "%s".', $declaringClass, $method->name, $message, $class); } @@ -388,7 +388,7 @@ public function checkAnnotations(\ReflectionClass $refl, $class) $definedParameters[$parameter->name] = true; } } - foreach ($matches as list(, $parameterType, $parameterName)) { + foreach ($matches as [, $parameterType, $parameterName]) { if (!isset($definedParameters[$parameterName])) { $parameterType = trim($parameterType); self::$annotatedParameters[$class][$method->name][$parameterName] = sprintf('The "%%s::%s()" method will require a new "%s$%s" argument in the next major version of its %s "%s", not defining it is deprecated.', $method->name, $parameterType ? $parameterType.' ' : '', $parameterName, interface_exists($class) ? 'interface' : 'parent class', $method->class); diff --git a/src/Symfony/Component/DependencyInjection/Argument/BoundArgument.php b/src/Symfony/Component/DependencyInjection/Argument/BoundArgument.php index 60059267beea4..f3535d68b0fe5 100644 --- a/src/Symfony/Component/DependencyInjection/Argument/BoundArgument.php +++ b/src/Symfony/Component/DependencyInjection/Argument/BoundArgument.php @@ -54,9 +54,9 @@ public function getValues(): array public function setValues(array $values) { if (5 === \count($values)) { - list($this->value, $this->identifier, $this->used, $this->type, $this->file) = $values; + [$this->value, $this->identifier, $this->used, $this->type, $this->file] = $values; } else { - list($this->value, $this->identifier, $this->used) = $values; + [$this->value, $this->identifier, $this->used] = $values; } } } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php index e068314c8d2d2..73ed14a60a42e 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php @@ -130,7 +130,7 @@ protected function getConstructor(Definition $definition, $required) } if ($factory) { - list($class, $method) = $factory; + [$class, $method] = $factory; if ($class instanceof Reference) { $class = $this->container->findDefinition((string) $class)->getClass(); } elseif ($class instanceof Definition) { diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php index 8d46fd6311035..a53df4e933237 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php @@ -126,7 +126,7 @@ private function doProcessValue($value, bool $isRoot = false) $this->methodCalls = $this->autowireCalls($reflectionClass, $isRoot); if ($constructor) { - list(, $arguments) = array_shift($this->methodCalls); + [, $arguments] = array_shift($this->methodCalls); if ($arguments !== $value->getArguments()) { $value->setArguments($arguments); @@ -152,7 +152,7 @@ private function autowireCalls(\ReflectionClass $reflectionClass, bool $isRoot): foreach ($this->methodCalls as $i => $call) { $this->decoratedMethodIndex = $i; - list($method, $arguments) = $call; + [$method, $arguments] = $call; if ($method instanceof \ReflectionFunctionAbstract) { $reflectionMethod = $method; diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowireRequiredMethodsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowireRequiredMethodsPass.php index 20d31135a73ce..4e80bb4f4c051 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AutowireRequiredMethodsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowireRequiredMethodsPass.php @@ -37,7 +37,7 @@ protected function processValue($value, $isRoot = false) $alreadyCalledMethods = []; $withers = []; - foreach ($value->getMethodCalls() as list($method)) { + foreach ($value->getMethodCalls() as [$method]) { $alreadyCalledMethods[strtolower($method)] = true; } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php index c88e9eceb8a4c..7659b8336e7bd 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php @@ -39,9 +39,9 @@ public function process(ContainerBuilder $container) } $decoratingDefinitions = []; - foreach ($definitions as list($id, $definition)) { + foreach ($definitions as [$id, $definition]) { $decoratedService = $definition->getDecoratedService(); - list($inner, $renamedId) = $decoratedService; + [$inner, $renamedId] = $decoratedService; $invalidBehavior = $decoratedService[3] ?? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; $definition->setDecoratedService(null); diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php index 82f222f23acc0..d99730d776e6a 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php @@ -41,11 +41,11 @@ public function process(ContainerBuilder $container) try { parent::process($container); - foreach ($this->unusedBindings as list($key, $serviceId, $bindingType, $file)) { + foreach ($this->unusedBindings as [$key, $serviceId, $bindingType, $file]) { $argumentType = $argumentName = $message = null; if (false !== strpos($key, ' ')) { - list($argumentType, $argumentName) = explode(' ', $key, 2); + [$argumentType, $argumentName] = explode(' ', $key, 2); } elseif ('$' === $key[0]) { $argumentName = $key; } else { @@ -117,7 +117,7 @@ protected function processValue($value, $isRoot = false) $bindingNames = []; foreach ($bindings as $key => $binding) { - list($bindingValue, $bindingId, $used, $bindingType, $file) = $binding->getValues(); + [$bindingValue, $bindingId, $used, $bindingType, $file] = $binding->getValues(); if ($used) { $this->usedBindings[$bindingId] = true; unset($this->unusedBindings[$bindingId]); @@ -156,7 +156,7 @@ protected function processValue($value, $isRoot = false) } foreach ($calls as $i => $call) { - list($method, $arguments) = $call; + [$method, $arguments] = $call; if ($method instanceof \ReflectionFunctionAbstract) { $reflectionMethod = $method; @@ -210,7 +210,7 @@ protected function processValue($value, $isRoot = false) } if ($constructor) { - list(, $arguments) = array_pop($calls); + [, $arguments] = array_pop($calls); if ($arguments !== $value->getArguments()) { $value->setArguments($arguments); @@ -229,7 +229,7 @@ protected function processValue($value, $isRoot = false) */ private function getBindingValue(BoundArgument $binding) { - list($bindingValue, $bindingId) = $binding->getValues(); + [$bindingValue, $bindingId] = $binding->getValues(); $this->usedBindings[$bindingId] = true; unset($this->unusedBindings[$bindingId]); diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveNamedArgumentsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveNamedArgumentsPass.php index 84dc2dd32245b..ab8ac1d0b677a 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveNamedArgumentsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveNamedArgumentsPass.php @@ -36,7 +36,7 @@ protected function processValue($value, $isRoot = false) $calls[] = ['__construct', $value->getArguments()]; foreach ($calls as $i => $call) { - list($method, $arguments) = $call; + [$method, $arguments] = $call; $parameters = null; $resolvedArguments = []; @@ -98,7 +98,7 @@ protected function processValue($value, $isRoot = false) } } - list(, $arguments) = array_pop($calls); + [, $arguments] = array_pop($calls); if ($arguments !== $value->getArguments()) { $value->setArguments($arguments); diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 9f5cbfc8283a2..2f9d7d0a008d9 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -1511,7 +1511,7 @@ public function removeBindings(string $id) { if ($this->hasDefinition($id)) { foreach ($this->getDefinition($id)->getBindings() as $key => $binding) { - list(, $bindingId) = $binding->getValues(); + [, $bindingId] = $binding->getValues(); $this->removedBindingIds[(int) $bindingId] = true; } } diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 70917f86cafff..4c0c656da0a38 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -568,7 +568,7 @@ private function addServiceInclude(string $cId, Definition $definition): string } } - foreach ($this->serviceCalls as $id => list($callCount, $behavior)) { + foreach ($this->serviceCalls as $id => [$callCount, $behavior]) { if ('service_container' !== $id && $id !== $cId && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $behavior && $this->container->has($id) @@ -878,7 +878,7 @@ private function addInlineReference(string $id, Definition $definition, string $ $targetId = (string) $this->container->getAlias($targetId); } - list($callCount, $behavior) = $this->serviceCalls[$targetId]; + [$callCount, $behavior] = $this->serviceCalls[$targetId]; if ($id === $targetId) { return $this->addInlineService($id, $definition, $definition); @@ -934,7 +934,7 @@ private function addInlineService(string $id, Definition $definition, Definition $code = ''; if ($isSimpleInstance = $isRootInstance = null === $inlineDef) { - foreach ($this->serviceCalls as $targetId => list($callCount, $behavior, $byConstructor)) { + foreach ($this->serviceCalls as $targetId => [$callCount, $behavior, $byConstructor]) { if ($byConstructor && isset($this->circularReferences[$id][$targetId]) && !$this->circularReferences[$id][$targetId]) { $code .= $this->addInlineReference($id, $definition, $targetId, $forConstructor); } @@ -1004,7 +1004,7 @@ private function addServices(array &$services = null): string } foreach ($definitions as $id => $definition) { - if (!(list($file, $code) = $services[$id]) || null !== $file) { + if (!([$file, $code] = $services[$id]) || null !== $file) { continue; } if ($definition->isPublic()) { @@ -1022,7 +1022,7 @@ private function generateServiceFiles(array $services): iterable $definitions = $this->container->getDefinitions(); ksort($definitions); foreach ($definitions as $id => $definition) { - if ((list($file, $code) = $services[$id]) && null !== $file && ($definition->isPublic() || !$this->isTrivialInstance($definition) || isset($this->locatedIds[$id]))) { + if (([$file, $code] = $services[$id]) && null !== $file && ($definition->isPublic() || !$this->isTrivialInstance($definition) || isset($this->locatedIds[$id]))) { if (!$definition->isShared()) { $i = strpos($code, "\n\ninclude_once "); if (false !== $i && false !== $i = strpos($code, "\n\n", 2 + $i)) { @@ -1732,7 +1732,7 @@ private function dumpValue($value, bool $interpolate = true): string return sprintf('new \%s($this->getService, [%s%s], [%s%s])', ServiceLocator::class, $serviceMap, $serviceMap ? "\n " : '', $serviceTypes, $serviceTypes ? "\n " : ''); } } finally { - list($this->definitionVariables, $this->referenceVariables) = $scope; + [$this->definitionVariables, $this->referenceVariables] = $scope; } } elseif ($value instanceof Definition) { if ($value->hasErrors() && $e = $value->getErrors()) { diff --git a/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php index fb5d827acdc0a..c968a54b298de 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php @@ -117,7 +117,7 @@ private function addService(Definition $definition, ?string $id, \DOMElement $pa $service->setAttribute('lazy', 'true'); } if (null !== $decoratedService = $definition->getDecoratedService()) { - list($decorated, $renamedId, $priority) = $decoratedService; + [$decorated, $renamedId, $priority] = $decoratedService; $service->setAttribute('decorates', $decorated); $decorationOnInvalid = $decoratedService[3] ?? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; diff --git a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php index 2effbe57119a6..523ea2026a686 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php @@ -132,7 +132,7 @@ private function addService(string $id, Definition $definition): string } if (null !== $decoratedService = $definition->getDecoratedService()) { - list($decorated, $renamedId, $priority) = $decoratedService; + [$decorated, $renamedId, $priority] = $decoratedService; $code .= sprintf(" decorates: %s\n", $decorated); if (null !== $renamedId) { $code .= sprintf(" decoration_inner_name: %s\n", $renamedId); diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php index 621f2eb859b3e..19566e9aa7050 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php @@ -443,7 +443,7 @@ private function processAnonymousServices(\DOMDocument $xml, string $file) // resolve definitions uksort($definitions, 'strnatcmp'); - foreach (array_reverse($definitions) as $id => list($domElement, $file)) { + foreach (array_reverse($definitions) as $id => [$domElement, $file]) { if (null !== $definition = $this->parseDefinition($domElement, $file, [])) { $this->setDefinition($id, $definition); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveParameterPlaceHoldersPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveParameterPlaceHoldersPassTest.php index 2504ff112cf86..c586e72c2acbc 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveParameterPlaceHoldersPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveParameterPlaceHoldersPassTest.php @@ -67,7 +67,7 @@ public function testAliasParametersShouldBeResolved() public function testBindingsShouldBeResolved() { - list($boundValue) = $this->container->getDefinition('foo')->getBindings()['$baz']->getValues(); + [$boundValue] = $this->container->getDefinition('foo')->getBindings()['$baz']->getValues(); $this->assertSame($this->container->getParameterBag()->resolveValue('%env(BAZ)%'), $boundValue); } diff --git a/src/Symfony/Component/ErrorHandler/DebugClassLoader.php b/src/Symfony/Component/ErrorHandler/DebugClassLoader.php index 79ab0b07d6911..6385d28db2aad 100644 --- a/src/Symfony/Component/ErrorHandler/DebugClassLoader.php +++ b/src/Symfony/Component/ErrorHandler/DebugClassLoader.php @@ -494,7 +494,7 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array $hasCall = $refl->hasMethod('__call'); $hasStaticCall = $refl->hasMethod('__callStatic'); foreach (self::$method[$use] as $method) { - list($interface, $name, $static, $description) = $method; + [$interface, $name, $static, $description] = $method; if ($static ? $hasStaticCall : $hasCall) { continue; } @@ -556,12 +556,12 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array } if ($parent && isset(self::$finalMethods[$parent][$method->name])) { - list($declaringClass, $message) = self::$finalMethods[$parent][$method->name]; + [$declaringClass, $message] = self::$finalMethods[$parent][$method->name]; $deprecations[] = sprintf('The "%s::%s()" method is considered final%s. It may change without further notice as of its next major version. You should not extend it from "%s".', $declaringClass, $method->name, $message, $className); } if (isset(self::$internalMethods[$class][$method->name])) { - list($declaringClass, $message) = self::$internalMethods[$class][$method->name]; + [$declaringClass, $message] = self::$internalMethods[$class][$method->name]; if (strncmp($ns, $declaringClass, $len)) { $deprecations[] = sprintf('The "%s::%s()" method is considered internal%s. It may change without further notice. You should not extend it from "%s".', $declaringClass, $method->name, $message, $className); } @@ -601,7 +601,7 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array } if (null !== ($returnType = self::$returnTypes[$class][$method->name] ?? self::MAGIC_METHODS[$method->name] ?? null) && !$method->hasReturnType() && !($doc && preg_match('/\n\s+\* @return +(\S+)/', $doc))) { - list($normalizedType, $returnType, $declaringClass, $declaringFile) = \is_string($returnType) ? [$returnType, $returnType, '', ''] : $returnType; + [$normalizedType, $returnType, $declaringClass, $declaringFile] = \is_string($returnType) ? [$returnType, $returnType, '', ''] : $returnType; if ('void' === $normalizedType) { $canAddReturnType = false; @@ -669,7 +669,7 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array $definedParameters[$parameter->name] = true; } } - foreach ($matches as list(, $parameterType, $parameterName)) { + foreach ($matches as [, $parameterType, $parameterName]) { if (!isset($definedParameters[$parameterName])) { $parameterType = trim($parameterType); self::$annotatedParameters[$class][$method->name][$parameterName] = sprintf('The "%%s::%s()" method will require a new "%s$%s" argument in the next major version of its %s "%s", not defining it is deprecated.', $method->name, $parameterType ? $parameterType.' ' : '', $parameterName, interface_exists($className) ? 'interface' : 'parent class', $className); @@ -940,10 +940,10 @@ private function patchMethod(\ReflectionMethod $method, string $returnType, stri continue; } - list($namespace, $useOffset, $useMap) = $useStatements[$file] ?? $useStatements[$file] = self::getUseStatements($file); + [$namespace, $useOffset, $useMap] = $useStatements[$file] ?? $useStatements[$file] = self::getUseStatements($file); if ('\\' !== $type[0]) { - list($declaringNamespace, , $declaringUseMap) = $useStatements[$declaringFile] ?? $useStatements[$declaringFile] = self::getUseStatements($declaringFile); + [$declaringNamespace, , $declaringUseMap] = $useStatements[$declaringFile] ?? $useStatements[$declaringFile] = self::getUseStatements($declaringFile); $p = strpos($type, '\\', 1); $alias = $p ? substr($type, 0, $p) : $type; diff --git a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php index d320a2620be4a..e79d1a8e304cc 100644 --- a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php @@ -196,7 +196,7 @@ public function getCalledListeners(/* Request $request = null */) $hash = 1 <= \func_num_args() && null !== ($request = func_get_arg(0)) ? spl_object_hash($request) : null; $called = []; foreach ($this->callStack as $listener) { - list($eventName, $requestHash) = $this->callStack->getInfo(); + [$eventName, $requestHash] = $this->callStack->getInfo(); if (null === $hash || $hash === $requestHash) { $called[] = $listener->getInfo($eventName); } @@ -228,7 +228,7 @@ public function getNotCalledListeners(/* Request $request = null */) if (null !== $this->callStack) { foreach ($this->callStack as $calledListener) { - list(, $requestHash) = $this->callStack->getInfo(); + [, $requestHash] = $this->callStack->getInfo(); if (null === $hash || $hash === $requestHash) { $calledListeners[] = $calledListener->getWrappedListener(); diff --git a/src/Symfony/Component/ExpressionLanguage/Lexer.php b/src/Symfony/Component/ExpressionLanguage/Lexer.php index b65128e695b6a..46d3e1c0c38e6 100644 --- a/src/Symfony/Component/ExpressionLanguage/Lexer.php +++ b/src/Symfony/Component/ExpressionLanguage/Lexer.php @@ -62,7 +62,7 @@ public function tokenize($expression) throw new SyntaxError(sprintf('Unexpected "%s".', $expression[$cursor]), $cursor, $expression); } - list($expect, $cur) = array_pop($brackets); + [$expect, $cur] = array_pop($brackets); if ($expression[$cursor] != strtr($expect, '([{', ')]}')) { throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $cur, $expression); } @@ -94,7 +94,7 @@ public function tokenize($expression) $tokens[] = new Token(Token::EOF_TYPE, null, $cursor + 1); if (!empty($brackets)) { - list($expect, $cur) = array_pop($brackets); + [$expect, $cur] = array_pop($brackets); throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $cur, $expression); } diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index 9f29d8ed186b8..5d698e1da2a64 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -474,8 +474,8 @@ public function makePathRelative($endPath, $startPath) return $result; }; - list($endPath, $endDriveLetter) = $splitDriveLetter($endPath); - list($startPath, $startDriveLetter) = $splitDriveLetter($startPath); + [$endPath, $endDriveLetter] = $splitDriveLetter($endPath); + [$startPath, $startDriveLetter] = $splitDriveLetter($startPath); $startPathArr = $splitPath($startPath); $endPathArr = $splitPath($endPath); @@ -617,7 +617,7 @@ public function isAbsolutePath($file) */ public function tempnam($dir, $prefix) { - list($scheme, $hierarchy) = $this->getSchemeAndHierarchy($dir); + [$scheme, $hierarchy] = $this->getSchemeAndHierarchy($dir); // If no scheme or scheme is "file" or "gs" (Google Cloud) create temp file in local filesystem if (null === $scheme || 'file' === $scheme || 'gs' === $scheme) { diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php index 5e3148a0b9c35..207944bf5ad6d 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php @@ -153,7 +153,7 @@ private function getFileUploadError(int $errorCode) $messageParameters = []; if (\UPLOAD_ERR_INI_SIZE === $errorCode) { - list($limitAsString, $suffix) = $this->factorizeSizes(0, self::getMaxFilesize()); + [$limitAsString, $suffix] = $this->factorizeSizes(0, self::getMaxFilesize()); $messageTemplate = 'The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.'; $messageParameters = [ '{{ limit }}' => $limitAsString, diff --git a/src/Symfony/Component/Form/FormBuilder.php b/src/Symfony/Component/Form/FormBuilder.php index e9c7213a98944..efbd6f86a180e 100644 --- a/src/Symfony/Component/Form/FormBuilder.php +++ b/src/Symfony/Component/Form/FormBuilder.php @@ -228,7 +228,7 @@ public function getIterator() */ private function resolveChild(string $name): FormBuilderInterface { - list($type, $options) = $this->unresolvedChildren[$name]; + [$type, $options] = $this->unresolvedChildren[$name]; unset($this->unresolvedChildren[$name]); diff --git a/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php index 07ecb1fc8a749..5dd473becff51 100644 --- a/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php +++ b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php @@ -220,7 +220,7 @@ public function prepare(Request $request) // @link https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/#x-accel-redirect $parts = HeaderUtils::split($request->headers->get('X-Accel-Mapping', ''), ',='); foreach ($parts as $part) { - list($pathPrefix, $location) = $part; + [$pathPrefix, $location] = $part; if (substr($path, 0, \strlen($pathPrefix)) === $pathPrefix) { $path = $location.substr($path, \strlen($pathPrefix)); // Only set X-Accel-Redirect header if a valid URI can be produced @@ -240,7 +240,7 @@ public function prepare(Request $request) $range = $request->headers->get('Range'); if (0 === strpos($range, 'bytes=')) { - list($start, $end) = explode('-', substr($range, 6), 2) + [0]; + [$start, $end] = explode('-', substr($range, 6), 2) + [0]; $end = ('' === $end) ? $fileSize - 1 : (int) $end; diff --git a/src/Symfony/Component/HttpFoundation/IpUtils.php b/src/Symfony/Component/HttpFoundation/IpUtils.php index a61d3e53f930e..b23d8819dd9f3 100644 --- a/src/Symfony/Component/HttpFoundation/IpUtils.php +++ b/src/Symfony/Component/HttpFoundation/IpUtils.php @@ -73,7 +73,7 @@ public static function checkIp4($requestIp, $ip) } if (false !== strpos($ip, '/')) { - list($address, $netmask) = explode('/', $ip, 2); + [$address, $netmask] = explode('/', $ip, 2); if ('0' === $netmask) { return self::$checkedIps[$cacheKey] = filter_var($address, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4); @@ -121,7 +121,7 @@ public static function checkIp6($requestIp, $ip) } if (false !== strpos($ip, '/')) { - list($address, $netmask) = explode('/', $ip, 2); + [$address, $netmask] = explode('/', $ip, 2); if ('0' === $netmask) { return (bool) unpack('n*', @inet_pton($address)); diff --git a/src/Symfony/Component/HttpFoundation/ServerBag.php b/src/Symfony/Component/HttpFoundation/ServerBag.php index 02c70911c19f1..ed2d7812ac31b 100644 --- a/src/Symfony/Component/HttpFoundation/ServerBag.php +++ b/src/Symfony/Component/HttpFoundation/ServerBag.php @@ -66,7 +66,7 @@ public function getHeaders() // Decode AUTHORIZATION header into PHP_AUTH_USER and PHP_AUTH_PW when authorization header is basic $exploded = explode(':', base64_decode(substr($authorizationHeader, 6)), 2); if (2 == \count($exploded)) { - list($headers['PHP_AUTH_USER'], $headers['PHP_AUTH_PW']) = $exploded; + [$headers['PHP_AUTH_USER'], $headers['PHP_AUTH_PW']] = $exploded; } } elseif (empty($this->parameters['PHP_AUTH_DIGEST']) && (0 === stripos($authorizationHeader, 'digest '))) { // In some circumstances PHP_AUTH_DIGEST needs to be set diff --git a/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php b/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php index 44f34d8ee8359..9c2fdd9807000 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php @@ -116,7 +116,7 @@ protected function createController($controller) return $controller; } - list($class, $method) = explode('::', $controller, 2); + [$class, $method] = explode('::', $controller, 2); try { $controller = [$this->instantiateController($class), $method]; @@ -176,7 +176,7 @@ private function getControllerError($callable): string return 'Invalid array callable, expected [controller, method].'; } - list($controller, $method) = $callable; + [$controller, $method] = $callable; if (\is_string($controller) && !class_exists($controller)) { return sprintf('Class "%s" does not exist.', $controller); diff --git a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php index 4e430f8f37e99..f864e355f90d8 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php @@ -75,7 +75,7 @@ public function dump(Data $data) $this->stopwatch->start('dump'); } - list('name' => $name, 'file' => $file, 'line' => $line, 'file_excerpt' => $fileExcerpt) = $this->sourceContextProvider->getContext(); + ['name' => $name, 'file' => $file, 'line' => $line, 'file_excerpt' => $fileExcerpt] = $this->sourceContextProvider->getContext(); if ($this->dumper instanceof Connection) { if (!$this->dumper->write($data)) { diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php b/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php index f214fd125a3ef..40c850cf66e65 100644 --- a/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php @@ -99,7 +99,7 @@ public function process(ContainerBuilder $container) if (!isset($methods[$action = strtolower($attributes['action'])])) { throw new InvalidArgumentException(sprintf('Invalid "action" attribute on tag "%s" for service "%s": no public "%s()" method found on class "%s".', $this->controllerTag, $id, $attributes['action'], $class)); } - list($r, $parameters) = $methods[$action]; + [$r, $parameters] = $methods[$action]; $found = false; foreach ($parameters as $p) { @@ -117,7 +117,7 @@ public function process(ContainerBuilder $container) } } - foreach ($methods as list($r, $parameters)) { + foreach ($methods as [$r, $parameters]) { /** @var \ReflectionMethod $r */ // create a per-method map of argument-names to service/type-references @@ -139,7 +139,7 @@ public function process(ContainerBuilder $container) } elseif (isset($bindings[$bindingName = $type.' $'.$p->name]) || isset($bindings[$bindingName = '$'.$p->name]) || isset($bindings[$bindingName = $type])) { $binding = $bindings[$bindingName]; - list($bindingValue, $bindingId, , $bindingType, $bindingFile) = $binding->getValues(); + [$bindingValue, $bindingId, , $bindingType, $bindingFile] = $binding->getValues(); $binding->setValues([$bindingValue, $bindingId, true, $bindingType, $bindingFile]); if (!$bindingValue instanceof Reference) { diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php b/src/Symfony/Component/HttpKernel/DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php index 596b6188f66cb..c09f2bfdf3113 100644 --- a/src/Symfony/Component/HttpKernel/DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php @@ -42,9 +42,9 @@ public function process(ContainerBuilder $container) } else { // any methods listed for call-at-instantiation cannot be actions $reason = false; - list($id, $action) = explode('::', $controller); + [$id, $action] = explode('::', $controller); $controllerDef = $container->getDefinition($id); - foreach ($controllerDef->getMethodCalls() as list($method)) { + foreach ($controllerDef->getMethodCalls() as [$method]) { if (0 === strcasecmp($action, $method)) { $reason = sprintf('Removing method "%s" of service "%s" from controller candidates: the method is called at instantiation, thus cannot be an action.', $action, $id); break; diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 079d375abafbd..746eec8869ce8 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -262,7 +262,7 @@ public function locateResource($name/*, $dir = null, $first = true, $triggerDepr $bundleName = substr($name, 1); $path = ''; if (false !== strpos($bundleName, '/')) { - list($bundleName, $path) = explode('/', $bundleName, 2); + [$bundleName, $path] = explode('/', $bundleName, 2); } $isResource = 0 === strpos($path, 'Resources') && null !== $dir; @@ -893,7 +893,7 @@ public function serialize() public function unserialize($data) { @trigger_error(sprintf('The "%s" method is deprecated since Symfony 4.3.', __METHOD__), \E_USER_DEPRECATED); - list($environment, $debug) = unserialize($data, ['allowed_classes' => false]); + [$environment, $debug] = unserialize($data, ['allowed_classes' => false]); $this->__construct($environment, $debug); } diff --git a/src/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php b/src/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php index 5f23e5e05dab6..b74563ac13a90 100644 --- a/src/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php +++ b/src/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php @@ -61,7 +61,7 @@ public function find($ip, $url, $limit, $method, $start = null, $end = null, $st $result = []; while (\count($result) < $limit && $line = $this->readLineFromFile($file)) { $values = str_getcsv($line); - list($csvToken, $csvIp, $csvMethod, $csvUrl, $csvTime, $csvParent, $csvStatusCode) = $values; + [$csvToken, $csvIp, $csvMethod, $csvUrl, $csvTime, $csvParent, $csvStatusCode] = $values; $csvTime = (int) $csvTime; if ($ip && false === strpos($csvIp, $ip) || $url && false === strpos($csvUrl, $url) || $method && false === strpos($csvMethod, $method) || $statusCode && false === strpos($csvStatusCode, $statusCode)) { diff --git a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/ControllerArgumentValueResolverPassTest.php b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/ControllerArgumentValueResolverPassTest.php index 2694d002cf5b6..c95a7fb52468c 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/ControllerArgumentValueResolverPassTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/ControllerArgumentValueResolverPassTest.php @@ -39,7 +39,7 @@ public function testServicesAreOrderedAccordingToPriority() $container = new ContainerBuilder(); $container->setDefinition('argument_resolver', $definition); - foreach ($services as $id => list($tag)) { + foreach ($services as $id => [$tag]) { $container->register($id)->addTag('controller.argument_value_resolver', $tag); } @@ -72,7 +72,7 @@ public function testInDebugWithStopWatchDefinition() $container->register('debug.stopwatch', Stopwatch::class); $container->setDefinition('argument_resolver', $definition); - foreach ($services as $id => list($tag)) { + foreach ($services as $id => [$tag]) { $container->register($id)->addTag('controller.argument_value_resolver', $tag); } diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php index 1f5f472802e7a..fc1ef64663cf7 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php @@ -92,7 +92,7 @@ public function testSetsTheXContentDigestResponseHeaderBeforeStoring() { $cacheKey = $this->storeSimpleEntry(); $entries = $this->getStoreMetadata($cacheKey); - list(, $res) = $entries[0]; + [, $res] = $entries[0]; $this->assertEquals('en9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', $res['x-content-digest'][0]); } @@ -103,7 +103,7 @@ public function testDoesNotTrustXContentDigestFromUpstream() $cacheKey = $this->store->write($this->request, $response); $entries = $this->getStoreMetadata($cacheKey); - list(, $res) = $entries[0]; + [, $res] = $entries[0]; $this->assertEquals('en9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', $res['x-content-digest'][0]); $this->assertEquals('en9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', $response->headers->get('X-Content-Digest')); diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestHttpKernel.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestHttpKernel.php index 5b204d82698ba..c116c31b65777 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestHttpKernel.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestHttpKernel.php @@ -43,13 +43,13 @@ public function assert(\Closure $callback) { $trustedConfig = [Request::getTrustedProxies(), Request::getTrustedHeaderSet()]; - list($trustedProxies, $trustedHeaderSet, $backendRequest) = $this->backendRequest; + [$trustedProxies, $trustedHeaderSet, $backendRequest] = $this->backendRequest; Request::setTrustedProxies($trustedProxies, $trustedHeaderSet); try { $callback($backendRequest); } finally { - list($trustedProxies, $trustedHeaderSet) = $trustedConfig; + [$trustedProxies, $trustedHeaderSet] = $trustedConfig; Request::setTrustedProxies($trustedProxies, $trustedHeaderSet); } } diff --git a/src/Symfony/Component/Lock/Store/MemcachedStore.php b/src/Symfony/Component/Lock/Store/MemcachedStore.php index ec832b9d7d359..d941daa7624dc 100644 --- a/src/Symfony/Component/Lock/Store/MemcachedStore.php +++ b/src/Symfony/Component/Lock/Store/MemcachedStore.php @@ -94,7 +94,7 @@ public function putOffExpiration(Key $key, $ttl) $token = $this->getUniqueToken($key); - list($value, $cas) = $this->getValueAndCas($key); + [$value, $cas] = $this->getValueAndCas($key); $key->reduceLifetime($ttl); // Could happens when we ask a putOff after a timeout but in luck nobody steal the lock @@ -126,7 +126,7 @@ public function delete(Key $key) { $token = $this->getUniqueToken($key); - list($value, $cas) = $this->getValueAndCas($key); + [$value, $cas] = $this->getValueAndCas($key); if ($value !== $token) { // we are not the owner of the lock. Nothing to do. diff --git a/src/Symfony/Component/Lock/Tests/Store/SemaphoreStoreTest.php b/src/Symfony/Component/Lock/Tests/Store/SemaphoreStoreTest.php index 0611e2802c07c..782151a9d0539 100644 --- a/src/Symfony/Component/Lock/Tests/Store/SemaphoreStoreTest.php +++ b/src/Symfony/Component/Lock/Tests/Store/SemaphoreStoreTest.php @@ -60,7 +60,7 @@ private function getOpenedSemaphores() if ('------ Semaphore Status --------' !== $lines[0]) { throw new \Exception('Failed to extract list of opened semaphores. Expected a Semaphore status, got '.implode(\PHP_EOL, $lines)); } - list($key, $value) = explode(' = ', $lines[1]); + [$key, $value] = explode(' = ', $lines[1]); if ('used arrays' !== $key) { throw new \Exception('Failed to extract list of opened semaphores. Expected a "used arrays" key, got '.implode(\PHP_EOL, $lines)); } diff --git a/src/Symfony/Component/Mailer/Transport.php b/src/Symfony/Component/Mailer/Transport.php index c0cd0c5fb9dad..80fc636265e17 100644 --- a/src/Symfony/Component/Mailer/Transport.php +++ b/src/Symfony/Component/Mailer/Transport.php @@ -83,7 +83,7 @@ public function fromStrings(array $dsns): Transports public function fromString(string $dsn): TransportInterface { - list($transport, $offset) = $this->parseDsn($dsn); + [$transport, $offset] = $this->parseDsn($dsn); if ($offset !== \strlen($dsn)) { throw new InvalidArgumentException(sprintf('The DSN has some garbage at the end: "%s".', substr($dsn, $offset))); } @@ -111,7 +111,7 @@ private function parseDsn(string $dsn, int $offset = 0): array ++$offset; $args = []; while (true) { - list($arg, $offset) = $this->parseDsn($dsn, $offset); + [$arg, $offset] = $this->parseDsn($dsn, $offset); $args[] = $arg; if (\strlen($dsn) === $offset) { break; diff --git a/src/Symfony/Component/Mailer/Transport/Smtp/SmtpTransport.php b/src/Symfony/Component/Mailer/Transport/Smtp/SmtpTransport.php index 365bcd1f8ba9a..5ef8a8825509f 100644 --- a/src/Symfony/Component/Mailer/Transport/Smtp/SmtpTransport.php +++ b/src/Symfony/Component/Mailer/Transport/Smtp/SmtpTransport.php @@ -290,7 +290,7 @@ private function assertResponseCode(string $response, array $codes): void throw new TransportException(sprintf('Expected response code "%s" but got an empty response.', implode('/', $codes))); } - list($code) = sscanf($response, '%3d'); + [$code] = sscanf($response, '%3d'); $valid = \in_array($code, $codes); if (!$valid) { diff --git a/src/Symfony/Component/Mime/Email.php b/src/Symfony/Component/Mime/Email.php index 7ecea4711aee5..74cb93c689765 100644 --- a/src/Symfony/Component/Mime/Email.php +++ b/src/Symfony/Component/Mime/Email.php @@ -266,7 +266,7 @@ public function priority(int $priority) */ public function getPriority(): int { - list($priority) = sscanf($this->getHeaders()->getHeaderBody('X-Priority'), '%[1-5]'); + [$priority] = sscanf($this->getHeaders()->getHeaderBody('X-Priority'), '%[1-5]'); return $priority ?? 3; } diff --git a/src/Symfony/Component/Mime/Part/DataPart.php b/src/Symfony/Component/Mime/Part/DataPart.php index 5d1d91061b35f..213f3c10c8826 100644 --- a/src/Symfony/Component/Mime/Part/DataPart.php +++ b/src/Symfony/Component/Mime/Part/DataPart.php @@ -35,7 +35,7 @@ public function __construct($body, string $filename = null, string $contentType if (null === $contentType) { $contentType = 'application/octet-stream'; } - list($this->mediaType, $subtype) = explode('/', $contentType); + [$this->mediaType, $subtype] = explode('/', $contentType); parent::__construct($body, null, $subtype, $encoding); diff --git a/src/Symfony/Component/Process/Tests/ErrorProcessInitiator.php b/src/Symfony/Component/Process/Tests/ErrorProcessInitiator.php index 37c1e65846fd1..ae90c6518626d 100755 --- a/src/Symfony/Component/Process/Tests/ErrorProcessInitiator.php +++ b/src/Symfony/Component/Process/Tests/ErrorProcessInitiator.php @@ -16,7 +16,7 @@ require \dirname(__DIR__).'/vendor/autoload.php'; -list('e' => $php) = getopt('e:') + ['e' => 'php']; +['e' => $php] = getopt('e:') + ['e' => 'php']; try { $process = new Process("exec $php -r \"echo 'ready'; trigger_error('error', E_USER_ERROR);\""); diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php index c0fb4d7beed37..f23383a8d929b 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -202,7 +202,7 @@ private static function throwInvalidArgumentException(string $message, array $tr } if (preg_match('/^\S+::\S+\(\): Argument #\d+ \(\$\S+\) must be of type (\S+), (\S+) given/', $message, $matches)) { - list(, $expectedType, $actualType) = $matches; + [, $expectedType, $actualType] = $matches; throw new InvalidArgumentException(sprintf('Expected argument of type "%s", "%s" given at property path "%s".', $expectedType, 'NULL' === $actualType ? 'null' : $actualType, $propertyPath), 0, $previous); } @@ -392,7 +392,7 @@ private function readProperty(array $zval, string $property, bool $ignoreInvalid try { $result[self::VALUE] = $object->{$access[self::ACCESS_NAME]}(); } catch (\TypeError $e) { - list($trace) = $e->getTrace(); + [$trace] = $e->getTrace(); // handle uninitialized properties in PHP >= 7 if (__FILE__ === $trace['file'] diff --git a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php index cbabce9eb6c27..fd6421c2b12fc 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php @@ -77,7 +77,7 @@ public function __construct(DocBlockFactoryInterface $docBlockFactory = null, ar public function getShortDescription($class, $property, array $context = []): ?string { /** @var $docBlock DocBlock */ - list($docBlock) = $this->getDocBlock($class, $property); + [$docBlock] = $this->getDocBlock($class, $property); if (!$docBlock) { return null; } @@ -107,7 +107,7 @@ public function getShortDescription($class, $property, array $context = []): ?st public function getLongDescription($class, $property, array $context = []): ?string { /** @var $docBlock DocBlock */ - list($docBlock) = $this->getDocBlock($class, $property); + [$docBlock] = $this->getDocBlock($class, $property); if (!$docBlock) { return null; } @@ -123,7 +123,7 @@ public function getLongDescription($class, $property, array $context = []): ?str public function getTypes($class, $property, array $context = []): ?array { /** @var $docBlock DocBlock */ - list($docBlock, $source, $prefix) = $this->getDocBlock($class, $property); + [$docBlock, $source, $prefix] = $this->getDocBlock($class, $property); if (!$docBlock) { return null; } @@ -176,11 +176,11 @@ private function getDocBlock(string $class, string $property): array $data = [$docBlock, self::PROPERTY, null]; break; - case list($docBlock) = $this->getDocBlockFromMethod($class, $ucFirstProperty, self::ACCESSOR): + case [$docBlock] = $this->getDocBlockFromMethod($class, $ucFirstProperty, self::ACCESSOR): $data = [$docBlock, self::ACCESSOR, null]; break; - case list($docBlock, $prefix) = $this->getDocBlockFromMethod($class, $ucFirstProperty, self::MUTATOR): + case [$docBlock, $prefix] = $this->getDocBlockFromMethod($class, $ucFirstProperty, self::MUTATOR): $data = [$docBlock, self::MUTATOR, $prefix]; break; diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index d8301e955ecea..7b8687ee0b868 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -182,7 +182,7 @@ public function isReadable($class, $property, array $context = []): ?bool return true; } - list($reflectionMethod) = $this->getAccessorMethod($class, $property); + [$reflectionMethod] = $this->getAccessorMethod($class, $property); return null !== $reflectionMethod; } @@ -196,7 +196,7 @@ public function isWritable($class, $property, array $context = []): ?bool return true; } - list($reflectionMethod) = $this->getMutatorMethod($class, $property); + [$reflectionMethod] = $this->getMutatorMethod($class, $property); return null !== $reflectionMethod; } @@ -234,7 +234,7 @@ public function isInitializable(string $class, string $property, array $context */ private function extractFromMutator(string $class, string $property): ?array { - list($reflectionMethod, $prefix) = $this->getMutatorMethod($class, $property); + [$reflectionMethod, $prefix] = $this->getMutatorMethod($class, $property); if (null === $reflectionMethod) { return null; } @@ -261,7 +261,7 @@ private function extractFromMutator(string $class, string $property): ?array */ private function extractFromAccessor(string $class, string $property): ?array { - list($reflectionMethod, $prefix) = $this->getAccessorMethod($class, $property); + [$reflectionMethod, $prefix] = $this->getAccessorMethod($class, $property); if (null === $reflectionMethod) { return null; } diff --git a/src/Symfony/Component/PropertyInfo/Util/PhpDocTypeHelper.php b/src/Symfony/Component/PropertyInfo/Util/PhpDocTypeHelper.php index e7b06f1e32b39..06b7489201217 100644 --- a/src/Symfony/Component/PropertyInfo/Util/PhpDocTypeHelper.php +++ b/src/Symfony/Component/PropertyInfo/Util/PhpDocTypeHelper.php @@ -90,7 +90,7 @@ private function createType(DocType $type, bool $nullable, string $docType = nul $docType = $docType ?? (string) $type; if ($type instanceof Collection) { - list($phpType, $class) = $this->getPhpTypeAndClass((string) $type->getFqsen()); + [$phpType, $class] = $this->getPhpTypeAndClass((string) $type->getFqsen()); $key = $this->getTypes($type->getKeyType()); $value = $this->getTypes($type->getValueType()); @@ -121,7 +121,7 @@ private function createType(DocType $type, bool $nullable, string $docType = nul } $docType = $this->normalizeType($docType); - list($phpType, $class) = $this->getPhpTypeAndClass($docType); + [$phpType, $class] = $this->getPhpTypeAndClass($docType); if ('array' === $docType) { return new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true, null, null); diff --git a/src/Symfony/Component/Routing/Generator/CompiledUrlGenerator.php b/src/Symfony/Component/Routing/Generator/CompiledUrlGenerator.php index adcc99e31015a..05a01f2875ebf 100644 --- a/src/Symfony/Component/Routing/Generator/CompiledUrlGenerator.php +++ b/src/Symfony/Component/Routing/Generator/CompiledUrlGenerator.php @@ -50,7 +50,7 @@ public function generate($name, $parameters = [], $referenceType = self::ABSOLUT throw new RouteNotFoundException(sprintf('Unable to generate a URL for the named route "%s" as such route does not exist.', $name)); } - list($variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes) = $this->compiledRoutes[$name]; + [$variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes] = $this->compiledRoutes[$name]; if (isset($defaults['_canonical_route']) && isset($defaults['_locale'])) { if (!\in_array('_locale', $variables, true)) { diff --git a/src/Symfony/Component/Routing/Loader/XmlFileLoader.php b/src/Symfony/Component/Routing/Loader/XmlFileLoader.php index e8732b3d6a12d..3b40e3d2a1970 100644 --- a/src/Symfony/Component/Routing/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/Routing/Loader/XmlFileLoader.php @@ -113,7 +113,7 @@ protected function parseRoute(RouteCollection $collection, \DOMElement $node, $p $schemes = preg_split('/[\s,\|]++/', $node->getAttribute('schemes'), -1, \PREG_SPLIT_NO_EMPTY); $methods = preg_split('/[\s,\|]++/', $node->getAttribute('methods'), -1, \PREG_SPLIT_NO_EMPTY); - list($defaults, $requirements, $options, $condition, $paths) = $this->parseConfigs($node, $path); + [$defaults, $requirements, $options, $condition, $paths] = $this->parseConfigs($node, $path); if (!$paths && '' === $node->getAttribute('path')) { throw new \InvalidArgumentException(sprintf('The element in file "%s" must have a "path" attribute or child nodes.', $path)); @@ -159,7 +159,7 @@ protected function parseImport(RouteCollection $collection, \DOMElement $node, $ $methods = $node->hasAttribute('methods') ? preg_split('/[\s,\|]++/', $node->getAttribute('methods'), -1, \PREG_SPLIT_NO_EMPTY) : null; $trailingSlashOnRoot = $node->hasAttribute('trailing-slash-on-root') ? XmlUtils::phpize($node->getAttribute('trailing-slash-on-root')) : true; - list($defaults, $requirements, $options, $condition, /* $paths */, $prefixes) = $this->parseConfigs($node, $path); + [$defaults, $requirements, $options, $condition, /* $paths */, $prefixes] = $this->parseConfigs($node, $path); if ('' !== $prefix && $prefixes) { throw new \InvalidArgumentException(sprintf('The element in file "%s" must not have both a "prefix" attribute and child nodes.', $path)); diff --git a/src/Symfony/Component/Routing/Matcher/CompiledUrlMatcher.php b/src/Symfony/Component/Routing/Matcher/CompiledUrlMatcher.php index e15cda7786585..ae13fd7011e37 100644 --- a/src/Symfony/Component/Routing/Matcher/CompiledUrlMatcher.php +++ b/src/Symfony/Component/Routing/Matcher/CompiledUrlMatcher.php @@ -26,6 +26,6 @@ class CompiledUrlMatcher extends UrlMatcher public function __construct(array $compiledRoutes, RequestContext $context) { $this->context = $context; - list($this->matchHost, $this->staticRoutes, $this->regexpList, $this->dynamicRoutes, $this->checkCondition) = $compiledRoutes; + [$this->matchHost, $this->staticRoutes, $this->regexpList, $this->dynamicRoutes, $this->checkCondition] = $compiledRoutes; } } diff --git a/src/Symfony/Component/Routing/Matcher/Dumper/CompiledUrlMatcherDumper.php b/src/Symfony/Component/Routing/Matcher/Dumper/CompiledUrlMatcherDumper.php index 73e2e1e0a06af..e77d24aecf9c1 100644 --- a/src/Symfony/Component/Routing/Matcher/Dumper/CompiledUrlMatcherDumper.php +++ b/src/Symfony/Component/Routing/Matcher/Dumper/CompiledUrlMatcherDumper.php @@ -83,7 +83,7 @@ public function getCompiledRoutes(bool $forDump = false): array $routes = $this->getRoutes(); } - list($staticRoutes, $dynamicRoutes) = $this->groupStaticRoutes($routes); + [$staticRoutes, $dynamicRoutes] = $this->groupStaticRoutes($routes); $conditions = [null]; $compiledRoutes[] = $this->compileStaticRoutes($staticRoutes, $conditions); @@ -131,7 +131,7 @@ static function (\$condition, \$context, \$request) { // \$checkCondition private function generateCompiledRoutes(): string { - list($matchHost, $staticRoutes, $regexpCode, $dynamicRoutes, $checkConditionCode) = $this->getCompiledRoutes(true); + [$matchHost, $staticRoutes, $regexpCode, $dynamicRoutes, $checkConditionCode] = $this->getCompiledRoutes(true); $code = self::export($matchHost).', // $matchHost'."\n"; @@ -186,7 +186,7 @@ private function groupStaticRoutes(RouteCollection $collection): array if ($hasTrailingSlash) { $url = substr($url, 0, -1); } - foreach ($dynamicRegex as list($hostRx, $rx, $prefix)) { + foreach ($dynamicRegex as [$hostRx, $rx, $prefix]) { if (('' === $prefix || 0 === strpos($url, $prefix)) && (preg_match($rx, $url) || preg_match($rx, $url.'/')) && (!$host || !$hostRx || preg_match($hostRx, $host))) { $dynamicRegex[] = [$hostRegex, $regex, $staticPrefix]; $dynamicRoutes->add($name, $route); @@ -221,7 +221,7 @@ private function compileStaticRoutes(array $staticRoutes, array &$conditions): a foreach ($staticRoutes as $url => $routes) { $compiledRoutes[$url] = []; - foreach ($routes as $name => list($route, $hasTrailingSlash)) { + foreach ($routes as $name => [$route, $hasTrailingSlash]) { $compiledRoutes[$url][] = $this->compileRoute($route, $name, (!$route->compile()->getHostVariables() ? $route->getHost() : $route->compile()->getHostRegex()) ?: null, $hasTrailingSlash, false, $conditions); } } @@ -287,7 +287,7 @@ private function compileDynamicRoutes(RouteCollection $collection, bool $matchHo $routes->add($name, $route); } - foreach ($perModifiers as list($modifiers, $routes)) { + foreach ($perModifiers as [$modifiers, $routes]) { $prev = false; $perHost = []; foreach ($routes->all() as $name => $route) { @@ -306,7 +306,7 @@ private function compileDynamicRoutes(RouteCollection $collection, bool $matchHo $state->mark += \strlen($rx); $state->regex = $rx; - foreach ($perHost as list($hostRegex, $routes)) { + foreach ($perHost as [$hostRegex, $routes]) { if ($matchHost) { if ($hostRegex) { preg_match('#^.\^(.*)\$.[a-zA-Z]*$#', $hostRegex, $rx); @@ -391,7 +391,7 @@ private function compileStaticPrefixCollection(StaticPrefixCollection $tree, \st continue; } - list($name, $regex, $vars, $route, $hasTrailingSlash, $hasTrailingVar) = $route; + [$name, $regex, $vars, $route, $hasTrailingSlash, $hasTrailingVar] = $route; $compiledRoute = $route->compile(); $vars = array_merge($state->hostVars, $vars); diff --git a/src/Symfony/Component/Routing/Matcher/Dumper/CompiledUrlMatcherTrait.php b/src/Symfony/Component/Routing/Matcher/Dumper/CompiledUrlMatcherTrait.php index 8ef76df8f8ccd..f78a6cb726652 100644 --- a/src/Symfony/Component/Routing/Matcher/Dumper/CompiledUrlMatcherTrait.php +++ b/src/Symfony/Component/Routing/Matcher/Dumper/CompiledUrlMatcherTrait.php @@ -87,7 +87,7 @@ private function doMatch(string $pathinfo, array &$allow = [], array &$allowSche } $supportsRedirections = 'GET' === $canonicalMethod && $this instanceof RedirectableUrlMatcherInterface; - foreach ($this->staticRoutes[$trimmedPathinfo] ?? [] as list($ret, $requiredHost, $requiredMethods, $requiredSchemes, $hasTrailingSlash, , $condition)) { + foreach ($this->staticRoutes[$trimmedPathinfo] ?? [] as [$ret, $requiredHost, $requiredMethods, $requiredSchemes, $hasTrailingSlash, , $condition]) { if ($condition && !($this->checkCondition)($condition, $context, 0 < $condition ? $request ?? $request = $this->request ?: $this->createRequest($pathinfo) : null)) { continue; } @@ -127,7 +127,7 @@ private function doMatch(string $pathinfo, array &$allow = [], array &$allowSche foreach ($this->regexpList as $offset => $regex) { while (preg_match($regex, $matchedPathinfo, $matches)) { - foreach ($this->dynamicRoutes[$m = (int) $matches['MARK']] as list($ret, $vars, $requiredMethods, $requiredSchemes, $hasTrailingSlash, $hasTrailingVar, $condition)) { + foreach ($this->dynamicRoutes[$m = (int) $matches['MARK']] as [$ret, $vars, $requiredMethods, $requiredSchemes, $hasTrailingSlash, $hasTrailingVar, $condition]) { if (null !== $condition) { if (0 === $condition) { // marks the last route in the regexp continue 3; diff --git a/src/Symfony/Component/Routing/Matcher/Dumper/StaticPrefixCollection.php b/src/Symfony/Component/Routing/Matcher/Dumper/StaticPrefixCollection.php index 65b6c0718b316..1c5c5fdeb0c99 100644 --- a/src/Symfony/Component/Routing/Matcher/Dumper/StaticPrefixCollection.php +++ b/src/Symfony/Component/Routing/Matcher/Dumper/StaticPrefixCollection.php @@ -65,12 +65,12 @@ public function getRoutes(): array */ public function addRoute(string $prefix, $route) { - list($prefix, $staticPrefix) = $this->getCommonPrefix($prefix, $prefix); + [$prefix, $staticPrefix] = $this->getCommonPrefix($prefix, $prefix); for ($i = \count($this->items) - 1; 0 <= $i; --$i) { $item = $this->items[$i]; - list($commonPrefix, $commonStaticPrefix) = $this->getCommonPrefix($prefix, $this->prefixes[$i]); + [$commonPrefix, $commonStaticPrefix] = $this->getCommonPrefix($prefix, $this->prefixes[$i]); if ($this->prefix === $commonPrefix) { // the new route and a previous one have no common prefix, let's see if they are exclusive to each others @@ -104,8 +104,8 @@ public function addRoute(string $prefix, $route) } else { // the new route and a previous one have a common prefix, let's merge them $child = new self($commonPrefix); - list($child->prefixes[0], $child->staticPrefixes[0]) = $child->getCommonPrefix($this->prefixes[$i], $this->prefixes[$i]); - list($child->prefixes[1], $child->staticPrefixes[1]) = $child->getCommonPrefix($prefix, $prefix); + [$child->prefixes[0], $child->staticPrefixes[0]] = $child->getCommonPrefix($this->prefixes[$i], $this->prefixes[$i]); + [$child->prefixes[1], $child->staticPrefixes[1]] = $child->getCommonPrefix($prefix, $prefix); $child->items = [$this->items[$i], $route]; $this->staticPrefixes[$i] = $commonStaticPrefix; diff --git a/src/Symfony/Component/Routing/Tests/Matcher/Dumper/StaticPrefixCollectionTest.php b/src/Symfony/Component/Routing/Tests/Matcher/Dumper/StaticPrefixCollectionTest.php index fe5014fc80007..36b2756690cdb 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/Dumper/StaticPrefixCollectionTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/Dumper/StaticPrefixCollectionTest.php @@ -16,7 +16,7 @@ public function testGrouping(array $routes, $expected) $collection = new StaticPrefixCollection('/'); foreach ($routes as $route) { - list($path, $name) = $route; + [$path, $name] = $route; $staticPrefix = (new Route($path))->compile()->getStaticPrefix(); $collection->addRoute($staticPrefix, [$name]); } diff --git a/src/Symfony/Component/Security/Core/Tests/Authorization/TraceableAccessDecisionManagerTest.php b/src/Symfony/Component/Security/Core/Tests/Authorization/TraceableAccessDecisionManagerTest.php index f9e157c6978e0..cad08eb9e8753 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authorization/TraceableAccessDecisionManagerTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authorization/TraceableAccessDecisionManagerTest.php @@ -40,7 +40,7 @@ public function testDecideLog(array $expectedLog, array $attributes, $object, ar ->with($token, $attributes, $object) ->willReturnCallback(function ($token, $attributes, $object) use ($voterVotes, $adm, $result) { foreach ($voterVotes as $voterVote) { - list($voter, $vote) = $voterVote; + [$voter, $vote] = $voterVote; $adm->addVoterVote($voter, $attributes, $vote); } diff --git a/src/Symfony/Component/Security/Csrf/Tests/CsrfTokenManagerTest.php b/src/Symfony/Component/Security/Csrf/Tests/CsrfTokenManagerTest.php index 3a7993c501bbe..bf1026fc395c7 100644 --- a/src/Symfony/Component/Security/Csrf/Tests/CsrfTokenManagerTest.php +++ b/src/Symfony/Component/Security/Csrf/Tests/CsrfTokenManagerTest.php @@ -175,28 +175,28 @@ public function getManagerGeneratorAndStorage() { $data = []; - list($generator, $storage) = $this->getGeneratorAndStorage(); + [$generator, $storage] = $this->getGeneratorAndStorage(); $data[] = ['', new CsrfTokenManager($generator, $storage, ''), $storage, $generator]; - list($generator, $storage) = $this->getGeneratorAndStorage(); + [$generator, $storage] = $this->getGeneratorAndStorage(); $data[] = ['https-', new CsrfTokenManager($generator, $storage), $storage, $generator]; - list($generator, $storage) = $this->getGeneratorAndStorage(); + [$generator, $storage] = $this->getGeneratorAndStorage(); $data[] = ['aNamespace-', new CsrfTokenManager($generator, $storage, 'aNamespace-'), $storage, $generator]; $requestStack = new RequestStack(); $requestStack->push(new Request([], [], [], [], [], ['HTTPS' => 'on'])); - list($generator, $storage) = $this->getGeneratorAndStorage(); + [$generator, $storage] = $this->getGeneratorAndStorage(); $data[] = ['https-', new CsrfTokenManager($generator, $storage, $requestStack), $storage, $generator]; - list($generator, $storage) = $this->getGeneratorAndStorage(); + [$generator, $storage] = $this->getGeneratorAndStorage(); $data[] = ['generated-', new CsrfTokenManager($generator, $storage, function () { return 'generated-'; }), $storage, $generator]; $requestStack = new RequestStack(); $requestStack->push(new Request()); - list($generator, $storage) = $this->getGeneratorAndStorage(); + [$generator, $storage] = $this->getGeneratorAndStorage(); $data[] = ['', new CsrfTokenManager($generator, $storage, $requestStack), $storage, $generator]; return $data; diff --git a/src/Symfony/Component/Security/Http/Firewall/ChannelListener.php b/src/Symfony/Component/Security/Http/Firewall/ChannelListener.php index 1033aa47ed3b4..f803fde39ce71 100644 --- a/src/Symfony/Component/Security/Http/Firewall/ChannelListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/ChannelListener.php @@ -45,7 +45,7 @@ public function __construct(AccessMapInterface $map, AuthenticationEntryPointInt */ public function supports(Request $request): ?bool { - list(, $channel) = $this->map->getPatterns($request); + [, $channel] = $this->map->getPatterns($request); if ('https' === $channel && !$request->isSecure()) { if (null !== $this->logger) { diff --git a/src/Symfony/Component/Security/Http/Logout/LogoutUrlGenerator.php b/src/Symfony/Component/Security/Http/Logout/LogoutUrlGenerator.php index 2d032cf388fe6..0ec1d60c90649 100644 --- a/src/Symfony/Component/Security/Http/Logout/LogoutUrlGenerator.php +++ b/src/Symfony/Component/Security/Http/Logout/LogoutUrlGenerator.php @@ -92,7 +92,7 @@ public function setCurrentFirewall($key, $context = null) */ private function generateLogoutUrl(?string $key, int $referenceType): string { - list($logoutPath, $csrfTokenId, $csrfParameter, $csrfTokenManager) = $this->getListener($key); + [$logoutPath, $csrfTokenId, $csrfParameter, $csrfTokenManager] = $this->getListener($key); if (null === $logoutPath) { throw new \LogicException('Unable to generate the logout URL without a path.'); @@ -154,7 +154,7 @@ private function getListener(?string $key): array } // Fetch from injected current firewall information, if possible - list($key, $context) = $this->currentFirewall; + [$key, $context] = $this->currentFirewall; if (isset($this->listeners[$key])) { return $this->listeners[$key]; diff --git a/src/Symfony/Component/Security/Http/RememberMe/PersistentTokenBasedRememberMeServices.php b/src/Symfony/Component/Security/Http/RememberMe/PersistentTokenBasedRememberMeServices.php index 167a094741357..574af6b0596ca 100644 --- a/src/Symfony/Component/Security/Http/RememberMe/PersistentTokenBasedRememberMeServices.php +++ b/src/Symfony/Component/Security/Http/RememberMe/PersistentTokenBasedRememberMeServices.php @@ -49,7 +49,7 @@ protected function cancelCookie(Request $request) if (null !== ($cookie = $request->cookies->get($this->options['name'])) && 2 === \count($parts = $this->decodeCookie($cookie)) ) { - list($series) = $parts; + [$series] = $parts; $this->tokenProvider->deleteTokenBySeries($series); } } @@ -63,7 +63,7 @@ protected function processAutoLoginCookie(array $cookieParts, Request $request) throw new AuthenticationException('The cookie is invalid.'); } - list($series, $tokenValue) = $cookieParts; + [$series, $tokenValue] = $cookieParts; $persistentToken = $this->tokenProvider->loadTokenBySeries($series); if (!hash_equals($persistentToken->getTokenValue(), $tokenValue)) { diff --git a/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php b/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php index 8dfce95ae45bb..5db8329e4b3e7 100644 --- a/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php +++ b/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php @@ -35,7 +35,7 @@ protected function processAutoLoginCookie(array $cookieParts, Request $request) throw new AuthenticationException('The cookie is invalid.'); } - list($class, $username, $expires, $hash) = $cookieParts; + [$class, $username, $expires, $hash] = $cookieParts; if (false === $username = base64_decode($username, true)) { throw new AuthenticationException('$username contains a character from outside the base64 alphabet.'); } diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/LogoutListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/LogoutListenerTest.php index 3d51a26196a76..ea13d1f2cf91e 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/LogoutListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/LogoutListenerTest.php @@ -21,9 +21,9 @@ class LogoutListenerTest extends TestCase { public function testHandleUnmatchedPath() { - list($listener, , $httpUtils, $options) = $this->getListener(); + [$listener, , $httpUtils, $options] = $this->getListener(); - list($event, $request) = $this->getGetResponseEvent(); + [$event, $request] = $this->getGetResponseEvent(); $event->expects($this->never()) ->method('setResponse'); @@ -41,9 +41,9 @@ public function testHandleMatchedPathWithSuccessHandlerAndCsrfValidation() $successHandler = $this->getSuccessHandler(); $tokenManager = $this->getTokenManager(); - list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener($successHandler, $tokenManager); + [$listener, $tokenStorage, $httpUtils, $options] = $this->getListener($successHandler, $tokenManager); - list($event, $request) = $this->getGetResponseEvent(); + [$event, $request] = $this->getGetResponseEvent(); $request->query->set('_csrf_token', 'token'); @@ -87,9 +87,9 @@ public function testHandleMatchedPathWithoutSuccessHandlerAndCsrfValidation() { $successHandler = $this->getSuccessHandler(); - list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener($successHandler); + [$listener, $tokenStorage, $httpUtils, $options] = $this->getListener($successHandler); - list($event, $request) = $this->getGetResponseEvent(); + [$event, $request] = $this->getGetResponseEvent(); $httpUtils->expects($this->once()) ->method('checkRequestPath') @@ -128,9 +128,9 @@ public function testSuccessHandlerReturnsNonResponse() $this->expectException('RuntimeException'); $successHandler = $this->getSuccessHandler(); - list($listener, , $httpUtils, $options) = $this->getListener($successHandler); + [$listener, , $httpUtils, $options] = $this->getListener($successHandler); - list($event, $request) = $this->getGetResponseEvent(); + [$event, $request] = $this->getGetResponseEvent(); $httpUtils->expects($this->once()) ->method('checkRequestPath') @@ -150,9 +150,9 @@ public function testCsrfValidationFails() $this->expectException('Symfony\Component\Security\Core\Exception\LogoutException'); $tokenManager = $this->getTokenManager(); - list($listener, , $httpUtils, $options) = $this->getListener(null, $tokenManager); + [$listener, , $httpUtils, $options] = $this->getListener(null, $tokenManager); - list($event, $request) = $this->getGetResponseEvent(); + [$event, $request] = $this->getGetResponseEvent(); $request->query->set('_csrf_token', 'token'); diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/RememberMeListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/RememberMeListenerTest.php index d321ed68921bd..2dccec5b9acff 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/RememberMeListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/RememberMeListenerTest.php @@ -25,7 +25,7 @@ class RememberMeListenerTest extends TestCase { public function testOnCoreSecurityDoesNotTryToPopulateNonEmptyTokenStorage() { - list($listener, $tokenStorage) = $this->getListener(); + [$listener, $tokenStorage] = $this->getListener(); $tokenStorage ->expects($this->any()) @@ -43,7 +43,7 @@ public function testOnCoreSecurityDoesNotTryToPopulateNonEmptyTokenStorage() public function testOnCoreSecurityDoesNothingWhenNoCookieIsSet() { - list($listener, $tokenStorage, $service) = $this->getListener(); + [$listener, $tokenStorage, $service] = $this->getListener(); $tokenStorage ->expects($this->any()) @@ -64,7 +64,7 @@ public function testOnCoreSecurityDoesNothingWhenNoCookieIsSet() public function testOnCoreSecurityIgnoresAuthenticationExceptionThrownByAuthenticationManagerImplementation() { - list($listener, $tokenStorage, $service, $manager) = $this->getListener(); + [$listener, $tokenStorage, $service, $manager] = $this->getListener(); $request = new Request(); $exception = new AuthenticationException('Authentication failed.'); @@ -101,7 +101,7 @@ public function testOnCoreSecurityIgnoresAuthenticationOptionallyRethrowsExcepti { $this->expectException('Symfony\Component\Security\Core\Exception\AuthenticationException'); $this->expectExceptionMessage('Authentication failed.'); - list($listener, $tokenStorage, $service, $manager) = $this->getListener(false, false); + [$listener, $tokenStorage, $service, $manager] = $this->getListener(false, false); $tokenStorage ->expects($this->any()) @@ -134,7 +134,7 @@ public function testOnCoreSecurityIgnoresAuthenticationOptionallyRethrowsExcepti public function testOnCoreSecurityAuthenticationExceptionDuringAutoLoginTriggersLoginFail() { - list($listener, $tokenStorage, $service, $manager) = $this->getListener(); + [$listener, $tokenStorage, $service, $manager] = $this->getListener(); $tokenStorage ->expects($this->any()) @@ -166,7 +166,7 @@ public function testOnCoreSecurityAuthenticationExceptionDuringAutoLoginTriggers public function testOnCoreSecurity() { - list($listener, $tokenStorage, $service, $manager) = $this->getListener(); + [$listener, $tokenStorage, $service, $manager] = $this->getListener(); $tokenStorage ->expects($this->any()) @@ -200,7 +200,7 @@ public function testOnCoreSecurity() public function testSessionStrategy() { - list($listener, $tokenStorage, $service, $manager, , , $sessionStrategy) = $this->getListener(false, true, true); + [$listener, $tokenStorage, $service, $manager, , , $sessionStrategy] = $this->getListener(false, true, true); $tokenStorage ->expects($this->any()) @@ -250,7 +250,7 @@ public function testSessionStrategy() public function testSessionIsMigratedByDefault() { - list($listener, $tokenStorage, $service, $manager) = $this->getListener(false, true, false); + [$listener, $tokenStorage, $service, $manager] = $this->getListener(false, true, false); $tokenStorage ->expects($this->any()) @@ -298,7 +298,7 @@ public function testSessionIsMigratedByDefault() public function testOnCoreSecurityInteractiveLoginEventIsDispatchedIfDispatcherIsPresent() { - list($listener, $tokenStorage, $service, $manager, , $dispatcher) = $this->getListener(true); + [$listener, $tokenStorage, $service, $manager, , $dispatcher] = $this->getListener(true); $tokenStorage ->expects($this->any()) diff --git a/src/Symfony/Component/Security/Http/Tests/FirewallMapTest.php b/src/Symfony/Component/Security/Http/Tests/FirewallMapTest.php index c464a4da3ccaf..50675a6003425 100644 --- a/src/Symfony/Component/Security/Http/Tests/FirewallMapTest.php +++ b/src/Symfony/Component/Security/Http/Tests/FirewallMapTest.php @@ -53,7 +53,7 @@ public function testGetListeners() $map->add($tooLateMatcher, [function () {}]); - list($listeners, $exception) = $map->getListeners($request); + [$listeners, $exception] = $map->getListeners($request); $this->assertEquals([$theListener], $listeners); $this->assertEquals($theException, $exception); @@ -88,7 +88,7 @@ public function testGetListenersWithAnEntryHavingNoRequestMatcher() $map->add($tooLateMatcher, [function () {}]); - list($listeners, $exception) = $map->getListeners($request); + [$listeners, $exception] = $map->getListeners($request); $this->assertEquals([$theListener], $listeners); $this->assertEquals($theException, $exception); @@ -110,7 +110,7 @@ public function testGetListenersWithNoMatchingEntry() $map->add($notMatchingMatcher, [function () {}]); - list($listeners, $exception) = $map->getListeners($request); + [$listeners, $exception] = $map->getListeners($request); $this->assertEquals([], $listeners); $this->assertNull($exception); diff --git a/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php b/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php index c108380f7e544..dfe3fbfc1964a 100644 --- a/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php +++ b/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php @@ -96,7 +96,7 @@ public function encode($data, $format, array $context = []) } } - list($delimiter, $enclosure, $escapeChar, $keySeparator, $headers, $escapeFormulas, $outputBom) = $this->getCsvOptions($context); + [$delimiter, $enclosure, $escapeChar, $keySeparator, $headers, $escapeFormulas, $outputBom] = $this->getCsvOptions($context); foreach ($data as &$value) { $flattened = []; @@ -157,7 +157,7 @@ public function decode($data, $format, array $context = []) $headerCount = []; $result = []; - list($delimiter, $enclosure, $escapeChar, $keySeparator) = $this->getCsvOptions($context); + [$delimiter, $enclosure, $escapeChar, $keySeparator] = $this->getCsvOptions($context); while (false !== ($cols = fgetcsv($handle, 0, $delimiter, $enclosure, $escapeChar))) { $nbCols = \count($cols); diff --git a/src/Symfony/Component/Translation/DependencyInjection/TranslatorPathsPass.php b/src/Symfony/Component/Translation/DependencyInjection/TranslatorPathsPass.php index 8ff2587dd53e1..a91aef6175f44 100644 --- a/src/Symfony/Component/Translation/DependencyInjection/TranslatorPathsPass.php +++ b/src/Symfony/Component/Translation/DependencyInjection/TranslatorPathsPass.php @@ -48,7 +48,7 @@ public function process(ContainerBuilder $container) foreach ($this->findControllerArguments($container) as $controller => $argument) { $id = substr($controller, 0, strpos($controller, ':') ?: \strlen($controller)); if ($container->hasDefinition($id)) { - list($locatorRef) = $argument->getValues(); + [$locatorRef] = $argument->getValues(); $this->controllers[(string) $locatorRef][$container->getDefinition($id)->getClass()] = true; } } diff --git a/src/Symfony/Component/Translation/Loader/MoFileLoader.php b/src/Symfony/Component/Translation/Loader/MoFileLoader.php index d344c6e21af1c..1d90136bdb40c 100644 --- a/src/Symfony/Component/Translation/Loader/MoFileLoader.php +++ b/src/Symfony/Component/Translation/Loader/MoFileLoader.php @@ -90,7 +90,7 @@ protected function loadResource($resource) $singularId = fread($stream, $length); if (false !== strpos($singularId, "\000")) { - list($singularId, $pluralId) = explode("\000", $singularId); + [$singularId, $pluralId] = explode("\000", $singularId); } fseek($stream, $offsetTranslated + $i * 8); diff --git a/src/Symfony/Component/Validator/Constraints/FileValidator.php b/src/Symfony/Component/Validator/Constraints/FileValidator.php index 3c946ff96ce8b..e5a756d893c8f 100644 --- a/src/Symfony/Component/Validator/Constraints/FileValidator.php +++ b/src/Symfony/Component/Validator/Constraints/FileValidator.php @@ -63,7 +63,7 @@ public function validate($value, Constraint $constraint) $binaryFormat = null === $constraint->binaryFormat ? true : $constraint->binaryFormat; } - list(, $limitAsString, $suffix) = $this->factorizeSizes(0, $limitInBytes, $binaryFormat); + [, $limitAsString, $suffix] = $this->factorizeSizes(0, $limitInBytes, $binaryFormat); $this->context->buildViolation($constraint->uploadIniSizeErrorMessage) ->setParameter('{{ limit }}', $limitAsString) ->setParameter('{{ suffix }}', $suffix) @@ -157,7 +157,7 @@ public function validate($value, Constraint $constraint) $limitInBytes = $constraint->maxSize; if ($sizeInBytes > $limitInBytes) { - list($sizeAsString, $limitAsString, $suffix) = $this->factorizeSizes($sizeInBytes, $limitInBytes, $constraint->binaryFormat); + [$sizeAsString, $limitAsString, $suffix] = $this->factorizeSizes($sizeInBytes, $limitInBytes, $constraint->binaryFormat); $this->context->buildViolation($constraint->maxSizeMessage) ->setParameter('{{ file }}', $this->formatValue($path)) ->setParameter('{{ size }}', $sizeAsString) diff --git a/src/Symfony/Component/Validator/Constraints/NotCompromisedPasswordValidator.php b/src/Symfony/Component/Validator/Constraints/NotCompromisedPasswordValidator.php index 7b8dd423532ba..adcdb7a59ff54 100644 --- a/src/Symfony/Component/Validator/Constraints/NotCompromisedPasswordValidator.php +++ b/src/Symfony/Component/Validator/Constraints/NotCompromisedPasswordValidator.php @@ -91,7 +91,7 @@ public function validate($value, Constraint $constraint) } foreach (explode("\r\n", $result) as $line) { - list($hashSuffix, $count) = explode(':', $line); + [$hashSuffix, $count] = explode(':', $line); if ($hashPrefix.$hashSuffix === $hash && $constraint->threshold <= (int) $count) { $this->context->buildViolation($constraint->message) diff --git a/src/Symfony/Component/Validator/DependencyInjection/AddValidatorInitializersPass.php b/src/Symfony/Component/Validator/DependencyInjection/AddValidatorInitializersPass.php index d7bea0fb73d94..b6f3a076774b2 100644 --- a/src/Symfony/Component/Validator/DependencyInjection/AddValidatorInitializersPass.php +++ b/src/Symfony/Component/Validator/DependencyInjection/AddValidatorInitializersPass.php @@ -51,7 +51,7 @@ public function process(ContainerBuilder $container) $builder = $container->getDefinition($this->builderService); $calls = []; - foreach ($builder->getMethodCalls() as list($method, $arguments)) { + foreach ($builder->getMethodCalls() as [$method, $arguments]) { if ('setTranslator' === $method) { if (!$arguments[0] instanceof Reference) { $translator = $arguments[0]; diff --git a/src/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php index 1d3d90132b4db..dde17cb17ff67 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php @@ -72,7 +72,7 @@ protected function newConstraint($name, $options = null) if (false !== strpos($name, '\\') && class_exists($name)) { $className = (string) $name; } elseif (false !== strpos($name, ':')) { - list($prefix, $className) = explode(':', $name, 2); + [$prefix, $className] = explode(':', $name, 2); if (!isset($this->namespaces[$prefix])) { throw new MappingException(sprintf('Undefined namespace prefix "%s".', $prefix)); diff --git a/src/Symfony/Component/Validator/Test/ConstraintValidatorTestCase.php b/src/Symfony/Component/Validator/Test/ConstraintValidatorTestCase.php index 9a048d3cacdf2..040e40d660c4d 100644 --- a/src/Symfony/Component/Validator/Test/ConstraintValidatorTestCase.php +++ b/src/Symfony/Component/Validator/Test/ConstraintValidatorTestCase.php @@ -413,7 +413,7 @@ public function doValidate($value, $constraints = null, $groups = null) { Assert::assertFalse($this->expectNoValidate, 'No validation calls have been expected.'); - list($expectedValue, $expectedGroup, $expectedConstraints) = $this->expectedValidate[++$this->validateCalls]; + [$expectedValue, $expectedGroup, $expectedConstraints] = $this->expectedValidate[++$this->validateCalls]; Assert::assertSame($expectedValue, $value); $expectedConstraints($constraints); diff --git a/src/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php b/src/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php index 2e6c47a48cb59..6a0e738ee0f83 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php @@ -202,7 +202,7 @@ public function testInvalidComparisonToValue($dirtyValue, $dirtyValueAsString, $ public function testInvalidComparisonToPropertyPathAddsPathAsParameter() { - list($dirtyValue, $dirtyValueAsString, $comparedValue, $comparedValueString, $comparedValueType) = current($this->provideAllInvalidComparisons()); + [$dirtyValue, $dirtyValueAsString, $comparedValue, $comparedValueString, $comparedValueType] = current($this->provideAllInvalidComparisons()); $constraint = $this->createConstraint(['propertyPath' => 'value']); $constraint->message = 'Constraint Message'; diff --git a/src/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php index ee0798f611dc6..a61e212e01c90 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php @@ -456,7 +456,7 @@ public function uploadedFileErrorProvider() $reflection = new \ReflectionClass(\get_class(new FileValidator())); $method = $reflection->getMethod('factorizeSizes'); $method->setAccessible(true); - list(, $limit, $suffix) = $method->invokeArgs(new FileValidator(), [0, UploadedFile::getMaxFilesize(), false]); + [, $limit, $suffix] = $method->invokeArgs(new FileValidator(), [0, UploadedFile::getMaxFilesize(), false]); // it correctly parses the maxSize option and not only uses simple string comparison // 1000M should be bigger than the ini value diff --git a/src/Symfony/Component/VarDumper/Caster/ArgsStub.php b/src/Symfony/Component/VarDumper/Caster/ArgsStub.php index 591c7e2a844a0..f8b485bd40c3f 100644 --- a/src/Symfony/Component/VarDumper/Caster/ArgsStub.php +++ b/src/Symfony/Component/VarDumper/Caster/ArgsStub.php @@ -24,7 +24,7 @@ class ArgsStub extends EnumStub public function __construct(array $args, string $function, ?string $class) { - list($variadic, $params) = self::getParameters($function, $class); + [$variadic, $params] = self::getParameters($function, $class); $values = []; foreach ($args as $k => $v) { diff --git a/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php b/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php index 43051ab479893..9d50da90577a7 100644 --- a/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php +++ b/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php @@ -296,7 +296,7 @@ protected function castObject(Stub $stub, $isNested) $stub->class = get_debug_type($obj); } if (isset($this->classInfo[$class])) { - list($i, $parents, $hasDebugInfo, $fileInfo) = $this->classInfo[$class]; + [$i, $parents, $hasDebugInfo, $fileInfo] = $this->classInfo[$class]; } else { $i = 2; $parents = [$class]; diff --git a/src/Symfony/Component/VarDumper/Server/DumpServer.php b/src/Symfony/Component/VarDumper/Server/DumpServer.php index 23b35b2f54db3..55510c0e224e6 100644 --- a/src/Symfony/Component/VarDumper/Server/DumpServer.php +++ b/src/Symfony/Component/VarDumper/Server/DumpServer.php @@ -71,7 +71,7 @@ public function listen(callable $callback): void continue; } - list($data, $context) = $payload; + [$data, $context] = $payload; $callback($data, $context, $clientId); } diff --git a/src/Symfony/Component/VarExporter/Tests/VarExporterTest.php b/src/Symfony/Component/VarExporter/Tests/VarExporterTest.php index 8dbcc06e8ddc6..84bb15254159f 100644 --- a/src/Symfony/Component/VarExporter/Tests/VarExporterTest.php +++ b/src/Symfony/Component/VarExporter/Tests/VarExporterTest.php @@ -338,7 +338,7 @@ public function unserialize($data) if ('' === $data) { throw new \InvalidArgumentException('Serialized data is empty.'); } - list(, $data) = unserialize($data); + [, $data] = unserialize($data); parent::unserialize($data); } } @@ -392,7 +392,7 @@ public function serialize(): string public function unserialize($str) { - list($this->foo) = unserialize($str); + [$this->foo] = unserialize($str); } } @@ -405,7 +405,7 @@ public function __serialize(): array public function __unserialize(array $data) { - list($this->foo) = $data; + [$this->foo] = $data; } public function __sleep(): array diff --git a/src/Symfony/Component/VarExporter/VarExporter.php b/src/Symfony/Component/VarExporter/VarExporter.php index da9a8d43736fa..f1260d152dd87 100644 --- a/src/Symfony/Component/VarExporter/VarExporter.php +++ b/src/Symfony/Component/VarExporter/VarExporter.php @@ -71,7 +71,7 @@ public static function export($value, bool &$isStaticValue = null): string $values = []; $states = []; foreach ($objectsPool as $i => $v) { - list(, $classes[], $values[], $wakeup) = $objectsPool[$v]; + [, $classes[], $values[], $wakeup] = $objectsPool[$v]; if (0 < $wakeup) { $states[$wakeup] = $i; } elseif (0 > $wakeup) { diff --git a/src/Symfony/Component/Workflow/Registry.php b/src/Symfony/Component/Workflow/Registry.php index 2363b8040594a..f556c9209a7de 100644 --- a/src/Symfony/Component/Workflow/Registry.php +++ b/src/Symfony/Component/Workflow/Registry.php @@ -49,7 +49,7 @@ public function get($subject, $workflowName = null) { $matched = []; - foreach ($this->workflows as list($workflow, $supportStrategy)) { + foreach ($this->workflows as [$workflow, $supportStrategy]) { if ($this->supports($workflow, $supportStrategy, $subject, $workflowName)) { $matched[] = $workflow; } @@ -78,7 +78,7 @@ public function get($subject, $workflowName = null) public function all($subject): array { $matched = []; - foreach ($this->workflows as list($workflow, $supportStrategy)) { + foreach ($this->workflows as [$workflow, $supportStrategy]) { if ($supportStrategy->supports($workflow, $subject)) { $matched[] = $workflow; } From 53f7f5f27eea66f09cfebaaad80d2f3c3c7878a3 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Wed, 28 Oct 2020 22:33:29 +0100 Subject: [PATCH 023/136] Fix CS --- .../DependencyInjection/SecurityExtension.php | 4 ++-- .../Cache/Adapter/CouchbaseBucketAdapter.php | 2 +- .../Component/Cache/Adapter/MemcachedAdapter.php | 2 +- .../Component/Cache/Adapter/PhpArrayAdapter.php | 2 +- .../DependencyInjection/Dumper/PhpDumper.php | 2 +- .../DependencyInjection/Loader/XmlFileLoader.php | 2 +- src/Symfony/Component/Filesystem/Filesystem.php | 2 +- .../RemoveEmptyControllerArgumentLocatorsPass.php | 2 +- .../Component/PropertyAccess/PropertyAccessor.php | 2 +- .../Component/Routing/Loader/XmlFileLoader.php | 4 ++-- .../Http/Tests/Firewall/LogoutListenerTest.php | 12 ++++++------ .../Component/Serializer/Encoder/CsvEncoder.php | 2 +- .../Validator/Test/ConstraintValidatorTestCase.php | 2 +- src/Symfony/Component/Workflow/Registry.php | 2 +- 14 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index 4a8286a0946dd..a1a972cb32d26 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -449,7 +449,7 @@ private function createFirewall(ContainerBuilder $container, string $id, array $ // Authentication listeners $firewallAuthenticationProviders = []; - list($authListeners, $defaultEntryPoint) = $this->createAuthenticationListeners($container, $id, $firewall, $firewallAuthenticationProviders, $defaultProvider, $providerIds, $configuredEntryPoint, $contextListenerId); + [$authListeners, $defaultEntryPoint] = $this->createAuthenticationListeners($container, $id, $firewall, $firewallAuthenticationProviders, $defaultProvider, $providerIds, $configuredEntryPoint, $contextListenerId); if (!$this->authenticatorManagerEnabled) { $authenticationProviders = array_merge($authenticationProviders, $firewallAuthenticationProviders); @@ -567,7 +567,7 @@ private function createAuthenticationListeners(ContainerBuilder $container, stri $entryPoints[$key] = $entryPoint; } } else { - list($provider, $listenerId, $defaultEntryPoint) = $factory->create($container, $id, $firewall[$key], $userProvider, $defaultEntryPoint); + [$provider, $listenerId, $defaultEntryPoint] = $factory->create($container, $id, $firewall[$key], $userProvider, $defaultEntryPoint); $listeners[] = new Reference($listenerId); $authenticationProviders[] = $provider; diff --git a/src/Symfony/Component/Cache/Adapter/CouchbaseBucketAdapter.php b/src/Symfony/Component/Cache/Adapter/CouchbaseBucketAdapter.php index 0fd272700198c..a0e8f4027181c 100644 --- a/src/Symfony/Component/Cache/Adapter/CouchbaseBucketAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/CouchbaseBucketAdapter.php @@ -134,7 +134,7 @@ private static function getOptions(string $options): array $optionsInArray = explode('&', $options); foreach ($optionsInArray as $option) { - list($key, $value) = explode('=', $option); + [$key, $value] = explode('=', $option); if (\in_array($key, static::VALID_DSN_OPTIONS, true)) { $results[$key] = $value; diff --git a/src/Symfony/Component/Cache/Adapter/MemcachedAdapter.php b/src/Symfony/Component/Cache/Adapter/MemcachedAdapter.php index 038892eabc3ba..53ead840c4eee 100644 --- a/src/Symfony/Component/Cache/Adapter/MemcachedAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/MemcachedAdapter.php @@ -123,7 +123,7 @@ public static function createConnection($servers, array $options = []) } $params = preg_replace_callback('#^memcached:(//)?(?:([^@]*+)@)?#', function ($m) use (&$username, &$password) { if (!empty($m[2])) { - list($username, $password) = explode(':', $m[2], 2) + [1 => null]; + [$username, $password] = explode(':', $m[2], 2) + [1 => null]; } return 'file:'.($m[1] ?? ''); diff --git a/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php b/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php index 0abf787f44ddb..a8f8f3038a652 100644 --- a/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php @@ -401,7 +401,7 @@ private function initialize() if (2 !== \count($values) || !isset($values[0], $values[1])) { $this->keys = $this->values = []; } else { - list($this->keys, $this->values) = $values; + [$this->keys, $this->values] = $values; } } diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 4bceb4960ab1c..17935162870c7 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -1094,7 +1094,7 @@ private function generateServiceFiles(array $services): iterable $definitions = $this->container->getDefinitions(); ksort($definitions); foreach ($definitions as $id => $definition) { - if ((list($file, $code) = $services[$id]) && null !== $file && ($definition->isPublic() || !$this->isTrivialInstance($definition) || isset($this->locatedIds[$id]))) { + if (([$file, $code] = $services[$id]) && null !== $file && ($definition->isPublic() || !$this->isTrivialInstance($definition) || isset($this->locatedIds[$id]))) { yield $file => [$code, $definition->hasTag($this->hotPathTag) || !$definition->hasTag($this->preloadTags[1]) && !$definition->isDeprecated() && !$definition->hasErrors()]; } } diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php index 33b5a009f7b4c..e4620912cb874 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php @@ -430,7 +430,7 @@ private function processAnonymousServices(\DOMDocument $xml, string $file) // resolve definitions uksort($definitions, 'strnatcmp'); - foreach (array_reverse($definitions) as $id => list($domElement, $file)) { + foreach (array_reverse($definitions) as $id => [$domElement, $file]) { if (null !== $definition = $this->parseDefinition($domElement, $file, new Definition())) { $this->setDefinition($id, $definition); } diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index 1a1f1cc59b126..d9609f5484c2d 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -590,7 +590,7 @@ public function isAbsolutePath(string $file) public function tempnam(string $dir, string $prefix/*, string $suffix = ''*/) { $suffix = \func_num_args() > 2 ? func_get_arg(2) : ''; - list($scheme, $hierarchy) = $this->getSchemeAndHierarchy($dir); + [$scheme, $hierarchy] = $this->getSchemeAndHierarchy($dir); // If no scheme or scheme is "file" or "gs" (Google Cloud) create temp file in local filesystem if ((null === $scheme || 'file' === $scheme || 'gs' === $scheme) && '' === $suffix) { diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php b/src/Symfony/Component/HttpKernel/DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php index 0d4bfb9f1847c..5f54e9c164d5f 100644 --- a/src/Symfony/Component/HttpKernel/DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php @@ -42,7 +42,7 @@ public function process(ContainerBuilder $container) } else { // any methods listed for call-at-instantiation cannot be actions $reason = false; - list($id, $action) = explode('::', $controller); + [$id, $action] = explode('::', $controller); if ($container->hasAlias($id)) { continue; diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php index 0bc7b5c66b2c3..cb4051d3a069e 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -404,7 +404,7 @@ private function readProperty(array $zval, string $property, bool $ignoreInvalid try { $result[self::VALUE] = $object->$name(); } catch (\TypeError $e) { - list($trace) = $e->getTrace(); + [$trace] = $e->getTrace(); // handle uninitialized properties in PHP >= 7 if (__FILE__ === $trace['file'] diff --git a/src/Symfony/Component/Routing/Loader/XmlFileLoader.php b/src/Symfony/Component/Routing/Loader/XmlFileLoader.php index e64089fb30a9a..dbff4a87b37c0 100644 --- a/src/Symfony/Component/Routing/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/Routing/Loader/XmlFileLoader.php @@ -118,7 +118,7 @@ protected function parseRoute(RouteCollection $collection, \DOMElement $node, st $schemes = preg_split('/[\s,\|]++/', $node->getAttribute('schemes'), -1, \PREG_SPLIT_NO_EMPTY); $methods = preg_split('/[\s,\|]++/', $node->getAttribute('methods'), -1, \PREG_SPLIT_NO_EMPTY); - list($defaults, $requirements, $options, $condition, $paths, /* $prefixes */, $hosts) = $this->parseConfigs($node, $path); + [$defaults, $requirements, $options, $condition, $paths, /* $prefixes */, $hosts] = $this->parseConfigs($node, $path); if (!$paths && '' === $node->getAttribute('path')) { throw new \InvalidArgumentException(sprintf('The element in file "%s" must have a "path" attribute or child nodes.', $path)); @@ -163,7 +163,7 @@ protected function parseImport(RouteCollection $collection, \DOMElement $node, s $trailingSlashOnRoot = $node->hasAttribute('trailing-slash-on-root') ? XmlUtils::phpize($node->getAttribute('trailing-slash-on-root')) : true; $namePrefix = $node->getAttribute('name-prefix') ?: null; - list($defaults, $requirements, $options, $condition, /* $paths */, $prefixes, $hosts) = $this->parseConfigs($node, $path); + [$defaults, $requirements, $options, $condition, /* $paths */, $prefixes, $hosts] = $this->parseConfigs($node, $path); if ('' !== $prefix && $prefixes) { throw new \InvalidArgumentException(sprintf('The element in file "%s" must not have both a "prefix" attribute and child nodes.', $path)); diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/LogoutListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/LogoutListenerTest.php index 71c4c0916db3f..109c841af76d3 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/LogoutListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/LogoutListenerTest.php @@ -28,7 +28,7 @@ class LogoutListenerTest extends TestCase public function testHandleUnmatchedPath() { $dispatcher = $this->getEventDispatcher(); - list($listener, , $httpUtils, $options) = $this->getListener($dispatcher); + [$listener, , $httpUtils, $options] = $this->getListener($dispatcher); [$event, $request] = $this->getGetResponseEvent(); @@ -52,7 +52,7 @@ public function testHandleMatchedPathWithCsrfValidation() $tokenManager = $this->getTokenManager(); $dispatcher = $this->getEventDispatcher(); - list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener($dispatcher, $tokenManager); + [$listener, $tokenStorage, $httpUtils, $options] = $this->getListener($dispatcher, $tokenManager); [$event, $request] = $this->getGetResponseEvent(); @@ -90,7 +90,7 @@ public function testHandleMatchedPathWithCsrfValidation() public function testHandleMatchedPathWithoutCsrfValidation() { $dispatcher = $this->getEventDispatcher(); - list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener($dispatcher); + [$listener, $tokenStorage, $httpUtils, $options] = $this->getListener($dispatcher); [$event, $request] = $this->getGetResponseEvent(); @@ -123,7 +123,7 @@ public function testNoResponseSet() { $this->expectException('RuntimeException'); - list($listener, , $httpUtils, $options) = $this->getListener(); + [$listener, , $httpUtils, $options] = $this->getListener(); [$event, $request] = $this->getGetResponseEvent(); @@ -168,12 +168,12 @@ public function testLegacyLogoutHandlers() $this->expectDeprecation('Since symfony/security-http 5.1: Calling "%s::addHandler" is deprecated, register a listener on the "%s" event instead.'); $logoutSuccessHandler = $this->createMock(LogoutSuccessHandlerInterface::class); - list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener($logoutSuccessHandler); + [$listener, $tokenStorage, $httpUtils, $options] = $this->getListener($logoutSuccessHandler); $token = $this->getToken(); $tokenStorage->expects($this->any())->method('getToken')->willReturn($token); - list($event, $request) = $this->getGetResponseEvent(); + [$event, $request] = $this->getGetResponseEvent(); $httpUtils->expects($this->once()) ->method('checkRequestPath') diff --git a/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php b/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php index b939e8557e5ba..631defab32764 100644 --- a/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php +++ b/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php @@ -142,7 +142,7 @@ public function decode(string $data, string $format, array $context = []) $headerCount = []; $result = []; - list($delimiter, $enclosure, $escapeChar, $keySeparator, , , , $asCollection) = $this->getCsvOptions($context); + [$delimiter, $enclosure, $escapeChar, $keySeparator, , , , $asCollection] = $this->getCsvOptions($context); while (false !== ($cols = fgetcsv($handle, 0, $delimiter, $enclosure, $escapeChar))) { $nbCols = \count($cols); diff --git a/src/Symfony/Component/Validator/Test/ConstraintValidatorTestCase.php b/src/Symfony/Component/Validator/Test/ConstraintValidatorTestCase.php index cce35db0dd0b9..7a5518c699152 100644 --- a/src/Symfony/Component/Validator/Test/ConstraintValidatorTestCase.php +++ b/src/Symfony/Component/Validator/Test/ConstraintValidatorTestCase.php @@ -473,7 +473,7 @@ public function doValidate($value, $constraints = null, $groups = null) return $this; } - list($expectedValue, $expectedGroup, $expectedConstraints, $violation) = $this->expectedValidate[$this->validateCalls]; + [$expectedValue, $expectedGroup, $expectedConstraints, $violation] = $this->expectedValidate[$this->validateCalls]; Assert::assertSame($expectedValue, $value); $expectedConstraints($constraints); diff --git a/src/Symfony/Component/Workflow/Registry.php b/src/Symfony/Component/Workflow/Registry.php index 6fef168244a55..3474e953fa637 100644 --- a/src/Symfony/Component/Workflow/Registry.php +++ b/src/Symfony/Component/Workflow/Registry.php @@ -29,7 +29,7 @@ public function addWorkflow(WorkflowInterface $workflow, WorkflowSupportStrategy public function has(object $subject, string $workflowName = null): bool { - foreach ($this->workflows as list($workflow, $supportStrategy)) { + foreach ($this->workflows as [$workflow, $supportStrategy]) { if ($this->supports($workflow, $supportStrategy, $subject, $workflowName)) { return true; } From 9e4859c87b379568475ae1ee3b50254b5c22e458 Mon Sep 17 00:00:00 2001 From: Mas Iting Date: Wed, 28 Oct 2020 18:23:20 +0700 Subject: [PATCH 024/136] Complete the Language for Hungarian and Norwegian --- .../Resources/translations/validators.hu.xlf | 116 +++++++++++++++++ .../Resources/translations/validators.no.xlf | 120 ++++++++++++++++++ .../Resources/translations/security.hu.xlf | 8 ++ .../Resources/translations/security.no.xlf | 8 ++ .../Resources/translations/validators.hu.xlf | 4 + .../Resources/translations/validators.no.xlf | 20 +++ 6 files changed, 276 insertions(+) diff --git a/src/Symfony/Component/Form/Resources/translations/validators.hu.xlf b/src/Symfony/Component/Form/Resources/translations/validators.hu.xlf index bc7f6055e4845..3b70461d394b7 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.hu.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.hu.xlf @@ -18,6 +18,122 @@ This value is not a valid HTML5 color. Ez az érték nem egy érvényes HTML5 szín. + + Please enter a valid birthdate. + Kérjük, adjon meg egy valós születési dátumot. + + + The selected choice is invalid. + A kiválasztott opció érvénytelen. + + + The collection is invalid. + A gyűjtemény érvénytelen. + + + Please select a valid color. + Kérjük, válasszon egy érvényes színt. + + + Please select a valid country. + Kérjük, válasszon egy érvényes országot. + + + Please select a valid currency. + Kérjük, válasszon egy érvényes pénznemet. + + + Please choose a valid date interval. + Kérjük, válasszon egy érvényes dátumintervallumot. + + + Please enter a valid date and time. + Kérjük, adjon meg egy érvényes dátumot és időpontot. + + + Please enter a valid date. + Kérjük, adjon meg egy érvényes dátumot. + + + Please select a valid file. + Kérjük, válasszon egy érvényes fájlt. + + + The hidden field is invalid. + A rejtett mező érvénytelen. + + + Please enter an integer. + Kérjük, adjon meg egy egész számot. + + + Please select a valid language. + Kérjük, válasszon egy érvényes nyelvet. + + + Please select a valid locale. + Kérjük, válasszon egy érvényes területi beállítást. + + + Please enter a valid money amount. + Kérjük, adjon meg egy érvényes pénzösszeget. + + + Please enter a number. + Kérjük, adjon meg egy számot. + + + The password is invalid. + A jelszó érvénytelen. + + + Please enter a percentage value. + Kérjük, adjon meg egy százalékos értéket. + + + The values do not match. + Az értékek nem egyeznek. + + + Please enter a valid time. + Kérjük, adjon meg egy érvényes időpontot. + + + Please select a valid timezone. + Kérjük, válasszon érvényes időzónát. + + + Please enter a valid URL. + Kérjük, adjon meg egy érvényes URL-t. + + + Please enter a valid search term. + Kérjük, adjon meg egy érvényes keresési kifejezést. + + + Please provide a valid phone number. + Kérjük, adjon egy érvényes telefonszámot + + + The checkbox has an invalid value. + A jelölőnégyzet értéke érvénytelen. + + + Please enter a valid email address. + Kérjük valós e-mail címet adjon meg. + + + Please select a valid option. + Kérjük, válasszon egy érvényes beállítást. + + + Please select a valid range. + Kérjük, válasszon egy érvényes tartományt. + + + Please enter a valid week. + Kérjük, adjon meg egy érvényes hetet. + diff --git a/src/Symfony/Component/Form/Resources/translations/validators.no.xlf b/src/Symfony/Component/Form/Resources/translations/validators.no.xlf index c64266c99189b..1d8385086aa82 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.no.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.no.xlf @@ -14,6 +14,126 @@ The CSRF token is invalid. CSRF nøkkelen er ugyldig. + + This value is not a valid HTML5 color. + Denne verdien er ikke en gyldig HTML5-farge. + + + Please enter a valid birthdate. + Vennligst oppgi gyldig fødselsdato. + + + The selected choice is invalid. + Det valgte valget er ugyldig. + + + The collection is invalid. + Samlingen er ugyldig. + + + Please select a valid color. + Velg en gyldig farge. + + + Please select a valid country. + Vennligst velg et gyldig land. + + + Please select a valid currency. + Vennligst velg en gyldig valuta. + + + Please choose a valid date interval. + Vennligst velg et gyldig datointervall. + + + Please enter a valid date and time. + Vennligst angi en gyldig dato og tid. + + + Please enter a valid date. + Vennligst oppgi en gyldig dato. + + + Please select a valid file. + Vennligst velg en gyldig fil. + + + The hidden field is invalid. + Det skjulte feltet er ugyldig. + + + Please enter an integer. + Vennligst skriv inn et heltall. + + + Please select a valid language. + Vennligst velg et gyldig språk. + + + Please select a valid locale. + Vennligst velg et gyldig sted. + + + Please enter a valid money amount. + Vennligst angi et gyldig pengebeløp. + + + Please enter a number. + Vennligst skriv inn et nummer. + + + The password is invalid. + Passordet er ugyldig. + + + Please enter a percentage value. + Vennligst angi en prosentverdi. + + + The values do not match. + Verdiene stemmer ikke overens. + + + Please enter a valid time. + Vennligst angi et gyldig tidspunkt. + + + Please select a valid timezone. + Vennligst velg en gyldig tidssone. + + + Please enter a valid URL. + Vennligst skriv inn en gyldig URL. + + + Please enter a valid search term. + Vennligst angi et gyldig søketerm. + + + Please provide a valid phone number. + Vennligst oppgi et gyldig telefonnummer. + + + The checkbox has an invalid value. + Avkrysningsboksen har en ugyldig verdi. + + + Please enter a valid email address. + Vennligst skriv inn en gyldig e-post adresse. + + + Please select a valid option. + Vennligst velg et gyldig alternativ. + + + Please select a valid range. + Vennligst velg et gyldig område. + + + Please enter a valid week. + Vennligst skriv inn en gyldig uke. + diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.hu.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.hu.xlf index f3a163904d367..e27a7b4505c53 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.hu.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.hu.xlf @@ -62,6 +62,14 @@ Account is locked. Zárolt fiók. + + Too many failed login attempts, please try again later. + Túl sok sikertelen bejelentkezési kísérlet, kérjük próbálja újra később. + + + Invalid or expired login link. + Érvénytelen vagy lejárt bejelentkezési link. + diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.no.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.no.xlf index 57016a4a4c23f..2d3a87c793ddf 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.no.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.no.xlf @@ -62,6 +62,14 @@ Account is locked. Brukerkonto er sperret. + + Too many failed login attempts, please try again later. + For mange mislykkede påloggingsforsøk. Prøv igjen senere. + + + Invalid or expired login link. + Ugyldig eller utløpt påloggingskobling. + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.hu.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.hu.xlf index 23ca5618097c5..acd69a1009c13 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.hu.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.hu.xlf @@ -382,6 +382,10 @@ Each element of this collection should satisfy its own set of constraints. A gyűjtemény minden elemének meg kell felelni a saját feltételeinek. + + This value is not a valid International Securities Identification Number (ISIN). + Ez az érték nem egy érvényes nemzetközi értékpapír-azonosító szám (ISIN). + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.no.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.no.xlf index bfa9b1284e8d9..93132ec57cdfc 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.no.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.no.xlf @@ -366,6 +366,26 @@ This value should be between {{ min }} and {{ max }}. Verdien må være mellom {{ min }} og {{ max }}. + + This value is not a valid hostname. + Denne verdien er ikke et gyldig vertsnavn. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Antall elementer i denne samlingen bør være et multiplum av {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Denne verdien skal tilfredsstille minst en av følgende begrensninger: + + + Each element of this collection should satisfy its own set of constraints. + Hvert element i denne samlingen skal tilfredsstille sitt eget sett med begrensninger. + + + This value is not a valid International Securities Identification Number (ISIN). + Denne verdien er ikke et gyldig International Securities Identification Number (ISIN). + From 268816f26cc3d49a0878ba796d7af290b1b7bf06 Mon Sep 17 00:00:00 2001 From: Viet Pham Date: Thu, 29 Oct 2020 16:58:29 +0700 Subject: [PATCH 025/136] [Cache] Fixed expiry maybe int due too race conditions --- src/Symfony/Component/Cache/Adapter/ChainAdapter.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Cache/Adapter/ChainAdapter.php b/src/Symfony/Component/Cache/Adapter/ChainAdapter.php index 4c086c3d55c74..a045a5d5a121c 100644 --- a/src/Symfony/Component/Cache/Adapter/ChainAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ChainAdapter.php @@ -74,7 +74,11 @@ static function ($sourceItem, $item, $sourceMetadata = null) use ($defaultLifeti $item->metadata = $item->newMetadata = $sourceItem->metadata = $sourceMetadata; if (isset($item->metadata[CacheItem::METADATA_EXPIRY])) { - $item->expiresAt(\DateTime::createFromFormat('U.u', $item->metadata[CacheItem::METADATA_EXPIRY])); + if (\is_int($expiry = $item->metadata[CacheItem::METADATA_EXPIRY])) { + $item->expiresAt(\DateTime::createFromFormat('U', $expiry)); + } else { + $item->expiresAt(\DateTime::createFromFormat('U.u', sprintf('%.3F', $expiry))); + } } elseif (0 < $defaultLifetime) { $item->expiresAfter($defaultLifetime); } From 13af58c57f225f748c109ccb010c290ca40f0754 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 29 Oct 2020 11:44:04 +0100 Subject: [PATCH 026/136] [Cache] minor improvement in expiry handling --- src/Symfony/Component/Cache/Adapter/ChainAdapter.php | 6 +----- src/Symfony/Component/Cache/Adapter/ProxyAdapter.php | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/ChainAdapter.php b/src/Symfony/Component/Cache/Adapter/ChainAdapter.php index a045a5d5a121c..b84d9f03705af 100644 --- a/src/Symfony/Component/Cache/Adapter/ChainAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ChainAdapter.php @@ -74,11 +74,7 @@ static function ($sourceItem, $item, $sourceMetadata = null) use ($defaultLifeti $item->metadata = $item->newMetadata = $sourceItem->metadata = $sourceMetadata; if (isset($item->metadata[CacheItem::METADATA_EXPIRY])) { - if (\is_int($expiry = $item->metadata[CacheItem::METADATA_EXPIRY])) { - $item->expiresAt(\DateTime::createFromFormat('U', $expiry)); - } else { - $item->expiresAt(\DateTime::createFromFormat('U.u', sprintf('%.3F', $expiry))); - } + $item->expiresAt(\DateTime::createFromFormat('U.u', sprintf('%.6F', $item->metadata[CacheItem::METADATA_EXPIRY]))); } elseif (0 < $defaultLifetime) { $item->expiresAfter($defaultLifetime); } diff --git a/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php b/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php index b126b5a7c8eba..8fd6f474511f7 100644 --- a/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php @@ -88,7 +88,7 @@ static function (CacheItemInterface $innerItem, array $item) { $item["\0*\0value"] = ["\x9D".pack('VN', (int) (0.1 + $metadata[self::METADATA_EXPIRY] - self::METADATA_EXPIRY_OFFSET), $metadata[self::METADATA_CTIME])."\x5F" => $item["\0*\0value"]]; } $innerItem->set($item["\0*\0value"]); - $innerItem->expiresAt(null !== $item["\0*\0expiry"] ? \DateTime::createFromFormat('U.u', sprintf('%.6f', 0 === $item["\0*\0expiry"] ? \PHP_INT_MAX : $item["\0*\0expiry"])) : null); + $innerItem->expiresAt(null !== $item["\0*\0expiry"] ? \DateTime::createFromFormat('U.u', sprintf('%.6F', 0 === $item["\0*\0expiry"] ? \PHP_INT_MAX : $item["\0*\0expiry"])) : null); }, null, CacheItem::class From 656d7b8df56095b4595460dde878e9c77230cb97 Mon Sep 17 00:00:00 2001 From: luffy1727 Date: Thu, 29 Oct 2020 17:19:29 +0800 Subject: [PATCH 027/136] Form, Security and Validator mn translation --- .../Resources/translations/validators.mn.xlf | 120 ++++++++++++++++++ .../Resources/translations/security.mn.xlf | 75 +++++++++++ .../Resources/translations/validators.mn.xlf | 20 +++ 3 files changed, 215 insertions(+) create mode 100644 src/Symfony/Component/Security/Core/Resources/translations/security.mn.xlf diff --git a/src/Symfony/Component/Form/Resources/translations/validators.mn.xlf b/src/Symfony/Component/Form/Resources/translations/validators.mn.xlf index 171df74d63c0c..620112d8814a9 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.mn.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.mn.xlf @@ -14,6 +14,126 @@ The CSRF token is invalid. Please try to resubmit the form. CSRF token буруу байна. Формоо дахин илгээнэ үү. + + This value is not a valid HTML5 color. + Энэ утга зөв HTML5 өнгө биш байна. + + + Please enter a valid birthdate. + Зөв төрсөн он сар оруулна уу. + + + The selected choice is invalid. + Сонгосон утга буруу байна. + + + The collection is invalid. + Цуглуулга буруу байна. + + + Please select a valid color. + Үнэн зөв өнгө сонгоно уу. + + + Please select a valid country. + Үнэн зөв улс сонгоно уу. + + + Please select a valid currency. + Үнэн зөв мөнгөн тэмдэгт сонгоно уу. + + + Please choose a valid date interval. + Үнэн зөв цагын зай сонгоно уу. + + + Please enter a valid date and time. + Үнэн зөв он цаг оруулна уу. + + + Please enter a valid date. + Үнэн зөв он цаг өдөр оруулна уу. + + + Please select a valid file. + Үнэн зөв файл сонгоно уу. + + + The hidden field is invalid. + Нууц талбарын утга буруу байна. + + + Please enter an integer. + Бүхэл тоо оруулна уу. + + + Please select a valid language. + Үнэн зөв хэл сонгоно уу. + + + Please select a valid locale. + Үнэн зөв бүс сонгоно уу. + + + Please enter a valid money amount. + Үнэн зөв мөнгөний хэмжээ сонгоно уу. + + + Please enter a number. + Тоо оруулна уу. + + + The password is invalid. + Нууц үг буруу байна. + + + Please enter a percentage value. + Хувь утга оруулна уу. + + + The values do not match. + Утга хоорондоо таарахгүй байна. + + + Please enter a valid time. + Үнэн зөв цаг оруулна уу. + + + Please select a valid timezone. + Үнэн зөв цагын бүс оруулна уу. + + + Please enter a valid URL. + Үнэн зөв URL оруулна уу. + + + Please enter a valid search term. + Үнэн зөв хайх утга оруулна уу. + + + Please provide a valid phone number. + Үнэн зөв утасны дугаар оруулна уу. + + + The checkbox has an invalid value. + Сонгох хайрцаг буруу утгатай байна. + + + Please enter a valid email address. + Үнэн зөв и-мэйл хаяг оруулна уу. + + + Please select a valid option. + Үнэн зөв сонголт сонгоно уу. + + + Please select a valid range. + Үнэн зөв хязгаарын утга сонгоно уу. + + + Please enter a valid week. + Үнэн зөв долоо хоног сонгоно уу. + diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.mn.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.mn.xlf new file mode 100644 index 0000000000000..7310e660a4479 --- /dev/null +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.mn.xlf @@ -0,0 +1,75 @@ + + + + + + An authentication exception occurred. + Нэвтрэх хүсэлтийн алдаа гарав. + + + Authentication credentials could not be found. + Нэвтрэх эрхийн мэдээлэл олдсонгүй. + + + Authentication request could not be processed due to a system problem. + Системийн алдаанаас болон нэвтрэх хүсэлтийг гүйцэтгэх боломжгүй байна. + + + Invalid credentials. + Буруу нэвтрэх эрхийн мэдээлэл. + + + Cookie has already been used by someone else. + Күүки файлыг аль хэдийн өөр хүн хэрэглэж байна. + + + Not privileged to request the resource. + Энэхүү мэдээллийг авах эрх хүрэхгүй байна. + + + Invalid CSRF token. + Тохиромжгүй CSRF токен. + + + No authentication provider found to support the authentication token. + Нэвтрэх токенг дэмжих нэвтрэх эрхийн хангагч олдсонгүй. + + + No available, it either timed out or cookies are not enabled. + Хэрэглэгчийн session олдсонгүй, хугацаа нь дууссан эсвэл күүки идэвхижүүлээгүй байна. + + + No token could be found. + Токен олдсонгүй. + + + Username could not be found. + Нэвтрэх нэр олсонгүй. + + + Account has expired. + Бүртгэлийн хугацаа дууссан байна. + + + Credentials have expired. + Нэвтрэх эрхийн хугацаа дууссан байна. + + + Account is disabled. + Бүртгэлийг хаасан байна. + + + Account is locked. + Бүртгэлийг цоожилсон байна. + + + Too many failed login attempts, please try again later. + Хэтэрхий олон амжилтгүй оролдлого, түр хүлээгээд дахин оролдоно уу. + + + Invalid or expired login link. + Буруу эсвэл хугацаа нь дууссан нэвтрэх зам. + + + + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.mn.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.mn.xlf index b1458eee1ac0b..f9126998b626b 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.mn.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.mn.xlf @@ -366,6 +366,26 @@ This value should be between {{ min }} and {{ max }}. Энэ утга {{ min }} -с {{ max }} хооронд байх ёстой. + + This value is not a valid hostname. + Энэ утга буруу hostname байна. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Энэхүү цуглуулган дахь элемэнтийн тоо, {{ compared_value }}-н үржвэр байх ёстой. + + + This value should satisfy at least one of the following constraints: + Энэ утга доорх болзолуудын ядаж нэгийг хангах ёстой: + + + Each element of this collection should satisfy its own set of constraints. + Энэхүү цуглуулган дахь элемэнтүүд өөр өөрсдийн болзолуудаа хангах ёстой. + + + This value is not a valid International Securities Identification Number (ISIN). + Энэ утга зөв International Securities Identification Number (ISIN) биш байна. + From ecb477952a6a74ce65469f97253bf2b31041fdba Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Fri, 30 Oct 2020 14:45:28 +0100 Subject: [PATCH 028/136] Fix wrong check for exporter in ConstraintTrait --- src/Symfony/Bridge/PhpUnit/Legacy/ConstraintTraitForV7.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/ConstraintTraitForV7.php b/src/Symfony/Bridge/PhpUnit/Legacy/ConstraintTraitForV7.php index 1e625e463a1e8..b132f473c547e 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/ConstraintTraitForV7.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/ConstraintTraitForV7.php @@ -45,7 +45,7 @@ protected function additionalFailureDescription($other): string protected function exporter(): Exporter { - if (null !== $this->exporter) { + if (null === $this->exporter) { $this->exporter = new Exporter(); } From 02d5985a31faf6ba45444e7d88cc3d0bcea95ad4 Mon Sep 17 00:00:00 2001 From: Antonios Pavlakis Date: Mon, 26 Oct 2020 16:57:56 +0000 Subject: [PATCH 029/136] Missing translations for Greek (el) --- .../Resources/translations/validators.el.xlf | 120 ++++++++++++++++++ .../Resources/translations/security.el.xlf | 8 ++ .../Resources/translations/validators.el.xlf | 60 ++++++++- 3 files changed, 186 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Form/Resources/translations/validators.el.xlf b/src/Symfony/Component/Form/Resources/translations/validators.el.xlf index ba2ced74b0111..595630e76f453 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.el.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.el.xlf @@ -14,6 +14,126 @@ The CSRF token is invalid. Please try to resubmit the form. Το CSRF token δεν είναι έγκυρο. Παρακαλούμε δοκιμάστε να υποβάλετε τη φόρμα ξανά. + + This value is not a valid HTML5 color. + Αυτή η τιμή δέν έναι έγκυρο χρώμα HTML5. + + + Please enter a valid birthdate. + Παρακαλόυμε ειχάγεται μία έγκυρη ημερομηνία γέννησης. + + + The selected choice is invalid. + Η επιλεγμένη επιλογή δέν είναι έγκυρη. + + + The collection is invalid. + Η συλλογή δέν είναι έγκυρη. + + + Please select a valid color. + Παρακαλούμε επιλέξτε ένα έγκυρο χρώμα. + + + Please select a valid country. + Παρακαλούμε επιλέξτε μία έγκυρη χώρα. + + + Please select a valid currency. + Παρακαλούμε επιλέξτε ένα έγυρο νόμισμα. + + + Please choose a valid date interval. + Παρακαλούμε επιλέξτε ένα έγκυρο διάστημα ημερομηνίας. + + + Please enter a valid date and time. + Παρακαλούμε εισαγάγετε μια έγκυρη ημερομηνία και ώρα. + + + Please enter a valid date. + Παρακαλούμε εισάγετε μία έγκυρη ημερομηνία. + + + Please select a valid file. + Παρακαλούμε επιλέξτε ένα έγκυρο αρχείο. + + + The hidden field is invalid. + Το κρυφό πεδίο δέν είναι έγκυρο. + + + Please enter an integer. + Παρακαλούμε εισάγετε έναν ακέραιο αριθμό. + + + Please select a valid language. + Παρακαλούμε επιλέξτε μία έγκυρη γλώσσα. + + + Please select a valid locale. + Παρακαλούμε επιλέξτε μία έγκυρη τοπικοποίηση. + + + Please enter a valid money amount. + Παρακαλούμε εισάγετε ένα έγκυρο χρηματικό ποσό. + + + Please enter a number. + Παρακαλούμε εισάγετε έναν αριθμό. + + + The password is invalid. + Ο κωδικός δέν είναι έγκυρος. + + + Please enter a percentage value. + Παρακαλούμε εισάγετε μία ποσοστιαία τιμή. + + + The values do not match. + Οι τιμές δέν ταιριάζουν. + + + Please enter a valid time. + Παρακαλούμε εισάγετε μία έγκυρη ώρα. + + + Please select a valid timezone. + Παρακαλούμε επιλέξτε μία έγυρη ζώνη ώρας. + + + Please enter a valid URL. + Παρακαλούμε εισάγετε μια έγκυρη διεύθυνση URL. + + + Please enter a valid search term. + Παρακαλούμε εισάγετε έναν έγκυρο όρο αναζήτησης. + + + Please provide a valid phone number. + Παρακαλούμε καταχωρίστε έναν έγκυρο αριθμό τηλεφώνου. + + + The checkbox has an invalid value. + Το πλαίσιο ελέγχου έχει μή έγκυρη τιμή. + + + Please enter a valid email address. + Παρακαλούμε εισάγετε μία έγκυρη ηλεκτρονική διεύθυνση. + + + Please select a valid option. + Παρακαλούμε επιλέξτε μία έγκυρη επιλογή. + + + Please select a valid range. + Παρακαλούμε επιλέξτε ένα έγυρο εύρος. + + + Please enter a valid week. + Παρακαλούμε εισάγετε μία έγκυρη εβδομάδα. + diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.el.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.el.xlf index 07eabe7ed29e2..2791325508d77 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.el.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.el.xlf @@ -66,6 +66,14 @@ Account is locked. Ο λογαριασμός είναι κλειδωμένος. + + Too many failed login attempts, please try again later. + Πολλαπλές αποτυχημένες απόπειρες σύνδεσης, παρακαλούμε ξαναδοκιμάστε αργότερα. + + + Invalid or expired login link. + Μη έγκυρος ή ληγμένος σύνδεσμος σύνδεσης. + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.el.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.el.xlf index 3b9bbef66e5a4..c8882d2ae6667 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.el.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.el.xlf @@ -24,11 +24,11 @@ You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. - Πρέπει να επιλέξετε τουλάχιστον {{ limit }} επιλογή.|Πρέπει να επιλέξετε τουλάχιστον {{ limit }} επιλογές. + Πρέπει να επιλέξτε τουλάχιστον {{ limit }} επιλογή.|Πρέπει να επιλέξτε τουλάχιστον {{ limit }} επιλογές. You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. - Πρέπει να επιλέξετε το πολύ {{ limit }} επιλογή.|Πρέπει να επιλέξετε το πολύ {{ limit }} επιλογές. + Πρέπει να επιλέξτε το πολύ {{ limit }} επιλογή.|Πρέπει να επιλέξτε το πολύ {{ limit }} επιλογές. One or more of the given values is invalid. @@ -330,6 +330,62 @@ This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. Αυτός ο κωδικός BIC δεν σχετίζεται με το IBAN {{ iban }}. + + This value should be valid JSON. + Αυτή η τιμή θα πρέπει να είναι έγκυρο JSON. + + + This collection should contain only unique elements. + Αυτή η συλλογή θα πρέπει να περιέχει μόνο μοναδικά στοιχεία. + + + This value should be positive. + Αυτή η τιμή θα πρέπει να είναι θετική. + + + This value should be either positive or zero. + Αυτή η τιμή θα πρέπει να είναι θετική ή μηδενική. + + + This value should be negative. + Αυτή η τιμή θα πρέπει να είναι αρνητική. + + + This value should be either negative or zero. + Αυτή η τιμή θα πρέπει να είναι αρνητική ή μηδενική. + + + This value is not a valid timezone. + Αυτή η τιμή θα δέν είναι έγκυρη ζώνη ώρας. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Αυτός ο κωδικός πρόσβασης έχει διερρεύσει σε παραβίαση δεδομένων. Παρακαλούμε να χρησιμοποιήσετε έναν άλλο κωδικό. + + + This value should be between {{ min }} and {{ max }}. + Αυτή η τιμή θα πρέπει να είναι μεταξύ {{ min }} και {{ max }}. + + + This value is not a valid hostname. + Αυτή η τιμή δέν είναι έγκυρο όνομα υποδοχής. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Το νούμερο των στοιχείων σε αυτή τη συλλογή θα πρέπει να είναι πολλαπλάσιο του {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Αυτή η τιμή θα πρέπει να ικανοποιεί τουλάχιστον έναν απο τους παρακάτω περιορισμούς: + + + Each element of this collection should satisfy its own set of constraints. + Κάθε στοιχείο σε αυτή τη συλλογή θα πρέπει να ικανοποιεί το δικό του σύνολο περιορισμών. + + + This value is not a valid International Securities Identification Number (ISIN). + Αυτή η τιμή δέν είναι έγυρο International Securities Identification Number (ISIN). + From b28505abd5ee322d6f9835bc664560ee8061c007 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Fri, 30 Oct 2020 15:01:38 +0100 Subject: [PATCH 030/136] Fixed translations for Norwegian --- .../Resources/translations/validators.nb.xlf | 120 ++++++++++++++++++ .../Resources/translations/security.nb.xlf | 8 ++ .../Resources/translations/validators.nb.xlf | 20 +++ 3 files changed, 148 insertions(+) diff --git a/src/Symfony/Component/Form/Resources/translations/validators.nb.xlf b/src/Symfony/Component/Form/Resources/translations/validators.nb.xlf index c64266c99189b..1d8385086aa82 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.nb.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.nb.xlf @@ -14,6 +14,126 @@ The CSRF token is invalid. CSRF nøkkelen er ugyldig. + + This value is not a valid HTML5 color. + Denne verdien er ikke en gyldig HTML5-farge. + + + Please enter a valid birthdate. + Vennligst oppgi gyldig fødselsdato. + + + The selected choice is invalid. + Det valgte valget er ugyldig. + + + The collection is invalid. + Samlingen er ugyldig. + + + Please select a valid color. + Velg en gyldig farge. + + + Please select a valid country. + Vennligst velg et gyldig land. + + + Please select a valid currency. + Vennligst velg en gyldig valuta. + + + Please choose a valid date interval. + Vennligst velg et gyldig datointervall. + + + Please enter a valid date and time. + Vennligst angi en gyldig dato og tid. + + + Please enter a valid date. + Vennligst oppgi en gyldig dato. + + + Please select a valid file. + Vennligst velg en gyldig fil. + + + The hidden field is invalid. + Det skjulte feltet er ugyldig. + + + Please enter an integer. + Vennligst skriv inn et heltall. + + + Please select a valid language. + Vennligst velg et gyldig språk. + + + Please select a valid locale. + Vennligst velg et gyldig sted. + + + Please enter a valid money amount. + Vennligst angi et gyldig pengebeløp. + + + Please enter a number. + Vennligst skriv inn et nummer. + + + The password is invalid. + Passordet er ugyldig. + + + Please enter a percentage value. + Vennligst angi en prosentverdi. + + + The values do not match. + Verdiene stemmer ikke overens. + + + Please enter a valid time. + Vennligst angi et gyldig tidspunkt. + + + Please select a valid timezone. + Vennligst velg en gyldig tidssone. + + + Please enter a valid URL. + Vennligst skriv inn en gyldig URL. + + + Please enter a valid search term. + Vennligst angi et gyldig søketerm. + + + Please provide a valid phone number. + Vennligst oppgi et gyldig telefonnummer. + + + The checkbox has an invalid value. + Avkrysningsboksen har en ugyldig verdi. + + + Please enter a valid email address. + Vennligst skriv inn en gyldig e-post adresse. + + + Please select a valid option. + Vennligst velg et gyldig alternativ. + + + Please select a valid range. + Vennligst velg et gyldig område. + + + Please enter a valid week. + Vennligst skriv inn en gyldig uke. + diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.nb.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.nb.xlf index 57016a4a4c23f..2d3a87c793ddf 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.nb.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.nb.xlf @@ -62,6 +62,14 @@ Account is locked. Brukerkonto er sperret. + + Too many failed login attempts, please try again later. + For mange mislykkede påloggingsforsøk. Prøv igjen senere. + + + Invalid or expired login link. + Ugyldig eller utløpt påloggingskobling. + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.nb.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.nb.xlf index bfa9b1284e8d9..93132ec57cdfc 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.nb.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.nb.xlf @@ -366,6 +366,26 @@ This value should be between {{ min }} and {{ max }}. Verdien må være mellom {{ min }} og {{ max }}. + + This value is not a valid hostname. + Denne verdien er ikke et gyldig vertsnavn. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Antall elementer i denne samlingen bør være et multiplum av {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Denne verdien skal tilfredsstille minst en av følgende begrensninger: + + + Each element of this collection should satisfy its own set of constraints. + Hvert element i denne samlingen skal tilfredsstille sitt eget sett med begrensninger. + + + This value is not a valid International Securities Identification Number (ISIN). + Denne verdien er ikke et gyldig International Securities Identification Number (ISIN). + From b9ca866bdd3c92f2990f2ce7ef9914020ded21d4 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Fri, 30 Oct 2020 14:31:03 +0100 Subject: [PATCH 031/136] Remove Symfony 3 compatibility code. --- src/Symfony/Component/HttpFoundation/Request.php | 2 +- .../HttpKernel/EventListener/AbstractSessionListener.php | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index faaa65f991225..7387fce74b934 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -179,7 +179,7 @@ class Request protected $format; /** - * @var SessionInterface + * @var SessionInterface|callable */ protected $session; diff --git a/src/Symfony/Component/HttpKernel/EventListener/AbstractSessionListener.php b/src/Symfony/Component/HttpKernel/EventListener/AbstractSessionListener.php index 0a6789d85ae2e..3da47dd8d0975 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/AbstractSessionListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/AbstractSessionListener.php @@ -55,12 +55,8 @@ public function onKernelRequest(GetResponseEvent $event) $session = null; $request = $event->getRequest(); - if ($request->hasSession()) { - // no-op - } elseif (method_exists($request, 'setSessionFactory')) { + if (!$request->hasSession()) { $request->setSessionFactory(function () { return $this->getSession(); }); - } elseif ($session = $this->getSession()) { - $request->setSession($session); } $session = $session ?? ($this->container && $this->container->has('initialized_session') ? $this->container->get('initialized_session') : null); From 29ac49741b4aa951480d2a57e0e3dfff522eea7d Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 30 Oct 2020 16:31:03 +0100 Subject: [PATCH 032/136] Add Serbian (Lat & Cyrl) & Bosnian translations for Form Validator & Security --- .../Resources/translations/validators.bs.xlf | 20 +++++ .../translations/validators.sr_Cyrl.xlf | 22 +++++- .../translations/validators.sr_Latn.xlf | 22 +++++- .../Resources/translations/security.bs.xlf | 79 +++++++++++++++++++ .../translations/security.sr_Cyrl.xlf | 8 ++ .../translations/security.sr_Latn.xlf | 8 ++ 6 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Component/Security/Core/Resources/translations/security.bs.xlf diff --git a/src/Symfony/Component/Form/Resources/translations/validators.bs.xlf b/src/Symfony/Component/Form/Resources/translations/validators.bs.xlf index cfe681e3b0534..259b05f842995 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.bs.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.bs.xlf @@ -114,6 +114,26 @@ Please provide a valid phone number. Molim navedite ispravan broj telefona. + + The checkbox has an invalid value. + Polje za potvrdu sadrži neispravnu vrijednost. + + + Please enter a valid email address. + Molim upišite ispravnu email adresu. + + + Please select a valid option. + Molim izaberite ispravnu opciju. + + + Please select a valid range. + Molim izaberite ispravan opseg. + + + Please enter a valid week. + Molim upišite ispravnu sedmicu. + diff --git a/src/Symfony/Component/Form/Resources/translations/validators.sr_Cyrl.xlf b/src/Symfony/Component/Form/Resources/translations/validators.sr_Cyrl.xlf index 1aa242f4186a4..a5610e0ead295 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.sr_Cyrl.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.sr_Cyrl.xlf @@ -114,6 +114,26 @@ Please provide a valid phone number. Молим наведите исправан број телефона. + + The checkbox has an invalid value. + Поље за потврду садржи неисправну вредност. + + + Please enter a valid email address. + Молим упишите исправну email адресу. + + + Please select a valid option. + Молим изаберите исправну опцију. + + + Please select a valid range. + Молим изаберите исправан опсег. + + + Please enter a valid week. + Молим упишите исправну седмицу. + - \ No newline at end of file + diff --git a/src/Symfony/Component/Form/Resources/translations/validators.sr_Latn.xlf b/src/Symfony/Component/Form/Resources/translations/validators.sr_Latn.xlf index 75a2aaab70e2e..02fb5aa56ead4 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.sr_Latn.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.sr_Latn.xlf @@ -114,6 +114,26 @@ Please provide a valid phone number. Molim navedite ispravan broj telefona. + + The checkbox has an invalid value. + Polje za potvrdu sadrži neispravnu vrednost. + + + Please enter a valid email address. + Molim upišite ispravnu email adresu. + + + Please select a valid option. + Molim izaberite ispravnu opciju. + + + Please select a valid range. + Molim izaberite ispravan opseg. + + + Please enter a valid week. + Molim upišite ispravnu sedmicu. + - \ No newline at end of file + diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.bs.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.bs.xlf new file mode 100644 index 0000000000000..56bab910e42b2 --- /dev/null +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.bs.xlf @@ -0,0 +1,79 @@ + + + + + + An authentication exception occurred. + Došlo je do autentifikacijskog izuzetka (exception). + + + Authentication credentials could not be found. + Autentifikacijski podaci nisu pronađeni. + + + Authentication request could not be processed due to a system problem. + Autentifikacijski zahtjev ne može biti obrađen zbog sistemskog problema. + + + Invalid credentials. + Autentifikacijski podaci su neispravni. + + + Cookie has already been used by someone else. + Neko drugi je već iskoristio ovaj kolačić (cookie). + + + Not privileged to request the resource. + Nemate privilegije potrebne za pristup ovom resursu. + + + Invalid CSRF token. + CSRF žeton (token) je neispravan. + + + Digest nonce has expired. + Digest nonce je istekao. + + + No authentication provider found to support the authentication token. + Nije pronađen autentifikacijski provajder koji bi podržao dati autentifikacijski žeton (token). + + + No session available, it either timed out or cookies are not enabled. + Nema dostupnih sesija; ili je istekla ili su kolačići (cookies) iksljučeni. + + + No token could be found. + Nije pronađen nijedan žeton (token). + + + Username could not be found. + Korisničko ime nije pronađeno. + + + Account has expired. + Nalog je istekao. + + + Credentials have expired. + Autentifikacijski podaci su istekli. + + + Account is disabled. + Nalog je onemogućen. + + + Account is locked. + Nalog je zaključan. + + + Too many failed login attempts, please try again later. + Previše neuspješnih pokušaja prijavljivanja, molim pokušajte ponovo kasnije. + + + Invalid or expired login link. + Link za prijavljivanje je istekao ili je neispravan. + + + + diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.sr_Cyrl.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.sr_Cyrl.xlf index 35e4ddf29b28c..b9538eff17973 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.sr_Cyrl.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.sr_Cyrl.xlf @@ -66,6 +66,14 @@ Account is locked. Налог је закључан. + + Too many failed login attempts, please try again later. + Превише неуспешних покушаја пријављивања, молим покушајте поново касније. + + + Invalid or expired login link. + Линк за пријављивање је истекао или је неисправан. + diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.sr_Latn.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.sr_Latn.xlf index ddc48076a2a6e..4edc1eca3e00e 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.sr_Latn.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.sr_Latn.xlf @@ -66,6 +66,14 @@ Account is locked. Nalog je zaključan. + + Too many failed login attempts, please try again later. + Previše neuspešnih pokušaja prijavljivanja, molim pokušajte ponovo kasnije. + + + Invalid or expired login link. + Link za prijavljivanje je istekao ili je neispravan. + From 703f156a9e07f3827c40a533bfe9f3602934ef86 Mon Sep 17 00:00:00 2001 From: Luis Tacon Date: Fri, 30 Oct 2020 20:13:58 +0100 Subject: [PATCH 033/136] Update Galician translations. --- .../Resources/translations/validators.gl.xlf | 120 ++++++++++++++++++ .../Resources/translations/security.gl.xlf | 8 ++ .../Resources/translations/validators.gl.xlf | 56 ++++++++ 3 files changed, 184 insertions(+) diff --git a/src/Symfony/Component/Form/Resources/translations/validators.gl.xlf b/src/Symfony/Component/Form/Resources/translations/validators.gl.xlf index 88cc6536ead7f..e454185fece75 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.gl.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.gl.xlf @@ -14,6 +14,126 @@ The CSRF token is invalid. Please try to resubmit the form. O token CSRF non é válido. Por favor, probe a enviar novamente o formulario. + + This value is not a valid HTML5 color. + Este valor non é unha cor HTML5 válida. + . + + Please enter a valid birthdate. + Insire unha data de aniversario válida. + + + The selected choice is invalid. + A opción seleccionada non é válida. + + + The collection is invalid. + A colección non é válida. + + + Please select a valid color. + Por favor, seleccione unha cor válida. + + + Please select a valid country. + Por favor, seleccione un país válido. + + + Please select a valid currency. + Por favor, seleccione unha moeda válida. + + + Please choose a valid date interval. + Por favor, escolla un intervalo de datas válido. + + + Please enter a valid date and time. + Por favor, introduza unha data e hora válidas. + + + Please enter a valid date. + Por favor, introduce unha data válida. + + + Please select a valid file. + Por favor, seleccione un ficheiro válido. + + + The hidden field is invalid. + O campo oculto non é válido. + + + Please enter an integer. + Por favor, introduza un número enteiro. + + + Please select a valid language. + Por favor, selecciona un idioma válido. + + + Please select a valid locale. + Por favor, seleccione unha configuración rexional válida. + + + Please enter a valid money amount. + Por favor, introduza unha cantidade de diñeiro válida. + + + Please enter a number. + Por favor, introduza un número. + + + The password is invalid. + O contrasinal non é válido. + + + Please enter a percentage value. + Por favor, introduza un valor porcentual. + + + The values do not match. + Os valores non coinciden. + + + Please enter a valid time. + Por favor, introduza unha hora válida. + + + Please select a valid timezone. + Por favor, selecciona unha zona horaria válida. + + + Please enter a valid URL. + Por favor, introduce un URL válido. + + + Please enter a valid search term. + Por favor, introduce un termo de busca válido. + + + Please provide a valid phone number. + Por favor, fornecer un número de teléfono válido. + + + The checkbox has an invalid value. + A caixa de verificación ten un valor non válido. + + + Please enter a valid email address. + Por favor, introduce un enderezo de correo electrónico válido. + + + Please select a valid option. + Por favor, seleccione unha opción válida. + + + Please select a valid range. + Por favor, seleccione un intervalo válido. + + + Please enter a valid week. + Por favor, introduce unha semana válida. + diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.gl.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.gl.xlf index ddc838e66af8b..651810d452cb6 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.gl.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.gl.xlf @@ -62,6 +62,14 @@ Account is locked. A conta está bloqueada. + + Too many failed login attempts, please try again later. + Demasiados intentos de inicio de sesión fallados. Téntao de novo máis tarde. + + + Invalid or expired login link. + Ligazón de inicio de sesión non válida ou caducada. + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.gl.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.gl.xlf index 71df1d240bde7..4bfd7a09c23f5 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.gl.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.gl.xlf @@ -330,6 +330,62 @@ This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. Este Código de identificación bancaria (BIC) non está asociado co IBAN {{ iban }}. + + This value should be valid JSON. + Este valor debería ser un JSON válido. + + + This collection should contain only unique elements. + Esta colección só debería ter elementos únicos. + + + This value should be positive. + Este valor debería ser positivo. + + + This value should be either positive or zero. + Este valor debe ser positivo ou igual a cero. + + + This value should be negative. + Este valor debe ser negativo. + + + This value should be either negative or zero. + Este valor debe ser negativo ou igual a cero. + + + This value is not a valid timezone. + Este valor non é unha zona horaria válida. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Este contrasinal non se pode usar porque está incluído nunha lista de contrasinais públicos obtidos grazas a fallos de seguridade noutros sitios e aplicacións. Utiliza outro contrasinal. + + + This value should be between {{ min }} and {{ max }}. + Este valor debe estar comprendido entre {{min}} e {{max}}. + + + This value is not a valid hostname. + Este valor non é un nome de host válido. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + O número de elementos desta colección debería ser múltiplo de {{compare_value}}. + + + This value should satisfy at least one of the following constraints: + Este valor debe cumprir polo menos unha das seguintes restricións: + + + Each element of this collection should satisfy its own set of constraints. + Cada elemento desta colección debe satisfacer o seu propio conxunto de restricións. + + + This value is not a valid International Securities Identification Number (ISIN). + Este valor non é un número de identificación de valores internacionais (ISIN) válido. + From b1d868c35fac0a6939d2cfa35533bb6fc67f8e75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rokas=20Mikalk=C4=97nas?= Date: Fri, 30 Oct 2020 22:02:07 +0200 Subject: [PATCH 034/136] [Form] Added missing Lithuanian translations --- .../Resources/translations/validators.lt.xlf | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/src/Symfony/Component/Form/Resources/translations/validators.lt.xlf b/src/Symfony/Component/Form/Resources/translations/validators.lt.xlf index e9eebc7389739..5613c42b5bf16 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.lt.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.lt.xlf @@ -14,6 +14,126 @@ The CSRF token is invalid. Please try to resubmit the form. CSRF kodas nepriimtinas. Bandykite siųsti formos užklausą dar kartą. + + This value is not a valid HTML5 color. + Ši reikšmė nėra HTML5 spalva. + + + Please enter a valid birthdate. + Prašome įvesti tinkamą gimimo datą. + + + The selected choice is invalid. + Pasirinktas pasirinkimas yra neteisingas. + + + The collection is invalid. + Neteisingas sąrašas. + + + Please select a valid color. + Prašome pasirinkti tinkamą spalvą. + + + Please select a valid country. + Prašome pasirinkti tinkamą šalį. + + + Please select a valid currency. + Prašome pasirinkti tinkamą valiutą. + + + Please choose a valid date interval. + Prašome pasirinkti tinkamą datos intervalą. + + + Please enter a valid date and time. + Prašome įvesti tinkamą datą ir laiką. + + + Please enter a valid date. + Prašome įvesti tinkamą datą. + + + Please select a valid file. + Prašome pasirinkti tinkamą bylą. + + + The hidden field is invalid. + Klaidingas paslėptasis laukas. + + + Please enter an integer. + Prašome įvesti sveiką skaičių. + + + Please select a valid language. + Prašome pasirinkti tinkamą kalbą. + + + Please select a valid locale. + Prašome pasirinkti tinkamą lokalę. + + + Please enter a valid money amount. + Prašome įvesti tinkamą pinigų sumą. + + + Please enter a number. + Prašome įvesti numerį. + + + The password is invalid. + Klaidingas slaptažodis. + + + Please enter a percentage value. + Prašome įvesti procentinę reikšmę. + + + The values do not match. + Reikšmės nesutampa. + + + Please enter a valid time. + Prašome įvesti tinkamą laiką. + + + Please select a valid timezone. + Prašome pasirinkti tinkamą laiko zoną. + + + Please enter a valid URL. + Prašome įvesti tinkamą URL. + + + Please enter a valid search term. + Prašome įvesti tinkamą paieškos terminą. + + + Please provide a valid phone number. + Prašome pateikti tinkamą telefono numerį. + + + The checkbox has an invalid value. + Klaidinga žymimajo langelio reikšmė. + + + Please enter a valid email address. + Prašome įvesti tinkamą el. pašto adresą. + + + Please select a valid option. + Prašome pasirinkti tinkamą parinktį. + + + Please select a valid range. + Prašome pasirinkti tinkamą diapozoną. + + + Please enter a valid week. + Prašome įvesti tinkamą savaitę. + From a9c4a06c3d0a783811f3107e2bb5ba0ea6ba9a08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rokas=20Mikalk=C4=97nas?= Date: Fri, 30 Oct 2020 22:13:53 +0200 Subject: [PATCH 035/136] [Security] Added missing Lithuanian translations --- .../Security/Core/Resources/translations/security.lt.xlf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.lt.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.lt.xlf index b7909033a6e67..37487b79d71b4 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.lt.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.lt.xlf @@ -62,6 +62,14 @@ Account is locked. Paskyra yra užblokuota. + + Too many failed login attempts, please try again later. + Per daug nepavykusių prisijungimo bandymų, pabandykite dar kartą vėliau. + + + Invalid or expired login link. + Netinkama arba pasibaigusio galiojimo laiko prisijungimo nuoroda. + From 30a3c7c87b2f19a346a3c2c6b612b9e539d1b079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Fri, 30 Oct 2020 21:47:32 +0100 Subject: [PATCH 036/136] Fix session called initized several time --- .../EventListener/AbstractSessionListener.php | 3 +- .../EventListener/SessionListenerTest.php | 34 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/EventListener/AbstractSessionListener.php b/src/Symfony/Component/HttpKernel/EventListener/AbstractSessionListener.php index 3da47dd8d0975..ce38d88608f22 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/AbstractSessionListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/AbstractSessionListener.php @@ -56,7 +56,8 @@ public function onKernelRequest(GetResponseEvent $event) $session = null; $request = $event->getRequest(); if (!$request->hasSession()) { - $request->setSessionFactory(function () { return $this->getSession(); }); + $sess = null; + $request->setSessionFactory(function () use (&$sess) { return $sess ?? $sess = $this->getSession(); }); } $session = $session ?? ($this->container && $this->container->has('initialized_session') ? $this->container->get('initialized_session') : null); diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php index 8fc9f6bc9c377..b3799bdb41e62 100644 --- a/src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php @@ -20,11 +20,13 @@ use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage; use Symfony\Component\HttpKernel\Event\FinishRequestEvent; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\Event\ResponseEvent; use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener; use Symfony\Component\HttpKernel\EventListener\SessionListener; use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\KernelInterface; class SessionListenerTest extends TestCase { @@ -178,4 +180,36 @@ public function testSurrogateMasterRequestIsPublic() $this->assertTrue($response->headers->has('Expires')); $this->assertLessThanOrEqual((new \DateTime('now', new \DateTimeZone('UTC'))), (new \DateTime($response->headers->get('Expires')))); } + + public function testGetSessionIsCalledOnce() + { + $session = $this->getMockBuilder(Session::class)->disableOriginalConstructor()->getMock(); + $sessionStorage = $this->getMockBuilder(NativeSessionStorage::class)->getMock(); + $kernel = $this->getMockBuilder(KernelInterface::class)->getMock(); + + $sessionStorage->expects($this->once()) + ->method('setOptions') + ->with(['cookie_secure' => true]); + + $requestStack = new RequestStack(); + $requestStack->push($masterRequest = new Request([], [], [], [], [], ['HTTPS' => 'on'])); + + $container = new Container(); + $container->set('session_storage', $sessionStorage); + $container->set('session', $session); + $container->set('request_stack', $requestStack); + + $event = new GetResponseEvent($kernel, $masterRequest, HttpKernelInterface::MASTER_REQUEST); + + $listener = new SessionListener($container); + $listener->onKernelRequest($event); + + $subRequest = $masterRequest->duplicate(); + // at this point both master and subrequest have a closure to build the session + + $masterRequest->getSession(); + + // calling the factory on the subRequest should not trigger a second call to storage->sesOptions() + $subRequest->getSession(); + } } From 48d0ed5886842529901ae1256e3e11c2aa6da2bd Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Sat, 31 Oct 2020 11:40:44 +0200 Subject: [PATCH 037/136] Add missing translations for Afrikaans --- .../Resources/translations/validators.af.xlf | 139 ++++++++++++++++++ .../Resources/translations/security.af.xlf | 79 ++++++++++ .../Resources/translations/validators.af.xlf | 52 +++++++ 3 files changed, 270 insertions(+) create mode 100644 src/Symfony/Component/Form/Resources/translations/validators.af.xlf create mode 100644 src/Symfony/Component/Security/Core/Resources/translations/security.af.xlf diff --git a/src/Symfony/Component/Form/Resources/translations/validators.af.xlf b/src/Symfony/Component/Form/Resources/translations/validators.af.xlf new file mode 100644 index 0000000000000..58cd939cf793f --- /dev/null +++ b/src/Symfony/Component/Form/Resources/translations/validators.af.xlf @@ -0,0 +1,139 @@ + + + + + + This form should not contain extra fields. + Hierdie vorm moet nie ekstra velde bevat nie. + + + The uploaded file was too large. Please try to upload a smaller file. + Die opgelaaide lêer was te groot. Probeer asseblief 'n kleiner lêer. + + + The CSRF token is invalid. Please try to resubmit the form. + Die CSRF-teken is ongeldig. Probeer asseblief om die vorm weer in te dien. + + + This value is not a valid HTML5 color. + Hierdie waarde is nie 'n geldige HTML5 kleur nie. + + + Please enter a valid birthdate. + Voer asseblief 'n geldige geboortedatum in. + + + The selected choice is invalid. + Die gekiesde opsie is nie geldig nie. + + + The collection is invalid. + Die versameling is nie geldig nie. + + + Please select a valid color. + Kies asseblief 'n geldige kleur. + + + Please select a valid country. + Kies asseblief 'n geldige land. + + + Please select a valid currency. + Kies asseblief 'n geldige geldeenheid. + + + Please choose a valid date interval. + Kies asseblief 'n geldige datum interval. + + + Please enter a valid date and time. + Voer asseblilef 'n geldige datum en tyd in. + + + Please enter a valid date. + Voer asseblief 'n geldige datum in. + + + Please select a valid file. + Kies asseblief 'n geldige lêer. + + + The hidden field is invalid. + Die versteekte veld is nie geldig nie. + + + Please enter an integer. + Voer asseblief 'n geldige heeltal in. + + + Please select a valid language. + Kies assblief 'n geldige taal. + + + Please select a valid locale. + Voer assebliefn 'n geldige locale in. + + + Please enter a valid money amount. + Voer asseblief 'n geldige bedrag in. + + + Please enter a number. + Voer asseblief 'n nommer in. + + + The password is invalid. + Die wagwoord is ongeldig. + + + Please enter a percentage value. + Voer asseblief 'n geldige persentasie waarde in. + + + The values do not match. + Die waardes is nie dieselfde nie. + + + Please enter a valid time. + Voer asseblief 'n geldige tyd in time. + + + Please select a valid timezone. + Kies asseblief 'n geldige tydsone. + + + Please enter a valid URL. + Voer asseblief 'n geldige URL in. + + + Please enter a valid search term. + Voer asseblief 'n geldige soek term in. + + + Please provide a valid phone number. + Verskaf asseblief 'n geldige telefoonnommer. + + + The checkbox has an invalid value. + Die blokkie het 'n ongeldige waarde. + + + Please enter a valid email address. + Voer asseblief 'n geldige e-pos adres in. + + + Please select a valid option. + Kies asseblief 'n geldige opsie. + + + Please select a valid range. + Kies asseblief 'n geldige reeks. + + + Please enter a valid week. + Voer assblief 'n geldige week in. + + + + diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.af.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.af.xlf new file mode 100644 index 0000000000000..61793d5c51435 --- /dev/null +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.af.xlf @@ -0,0 +1,79 @@ + + + + + + An authentication exception occurred. + 'n Verifikasie probleem het voorgekom. + + + Authentication credentials could not be found. + Verifikasiebewyse kon nie gevind word nie. + + + Authentication request could not be processed due to a system problem. + Verifikasieversoek kon weens 'n stelselprobleem nie verwerk word nie. + + + Invalid credentials. + Ongedige verifikasiebewyse. + + + Cookie has already been used by someone else. + Die koekie is alreeds deur iemand anders gebruik. + + + Not privileged to request the resource. + Nie bevoorreg om die hulpbron aan te vra nie. + + + Invalid CSRF token. + Ongeldige CSRF-teken. + + + Digest nonce has expired. + Digest nonce het verval. + + + No authentication provider found to support the authentication token. + Geen verifikasieverskaffer is gevind wat die verifikasietoken kan ondersteun nie. + + + No session available, it either timed out or cookies are not enabled. + Geen sessie is beskikbaar, die het verval of koekies is nie geaktiveer nie. + + + No token could be found. + Geen teken kon gevind word nie. + + + Username could not be found. + Gebruikersnaam kon nie gevind word nie. + + + Account has expired. + Rekening het verval. + + + Credentials have expired. + Verifikasiebewyse het verval. + + + Account is disabled. + Rekening is deaktiveer. + + + Account is locked. + Rekening is gesluit. + + + Too many failed login attempts, please try again later. + Te veel mislukte aanmeldpogings, probeer asseblief later weer. + + + Invalid or expired login link. + Ongeldige of vervalde aanmeldskakel. + + + + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.af.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.af.xlf index 731e64aa7f2a4..cbee3bb9d31b8 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.af.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.af.xlf @@ -334,6 +334,58 @@ This value should be valid JSON. Hierdie waarde moet geldige JSON wees. + + This collection should contain only unique elements. + Hierdie versameling moet net unieke elemente bevat. + + + This value should be positive. + Hierdie waarde moet positief wees. + + + This value should be either positive or zero. + Hierdie waarde moet positief of nul wees. + + + This value should be negative. + Hierdie waarde moet negatief wees. + + + This value should be either negative or zero. + Hierdie waarde moet negatief of nul wees. + + + This value is not a valid timezone. + Hierdie waarde is nie 'n geldige tydsone nie. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + This password has been leaked in a data breach, it must not be used. Please use another password. + + + This value should be between {{ min }} and {{ max }}. + Hierdie waarde moet tussen {{ min }} en {{ max }} wees. + + + This value is not a valid hostname. + Hierdie waarde is nie 'n geldige gasheernaam nie. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Die hoeveelheid elemente in hierdie versameling moet 'n meelvoud van {{ compared_value }} wees. + + + This value should satisfy at least one of the following constraints: + Hierdie waarde moet voldoen aan ten minste een van hierdie beperkings: + + + Each element of this collection should satisfy its own set of constraints. + Elke element van hierdie versameling moet voldoen aan hulle eie beperkings. + + + This value is not a valid International Securities Identification Number (ISIN). + Hierdie waarde is nie 'n geldige Internasionale veiligheidsidentifikasienommer (ISIN) nie. + From d915e44dd002f8d3f037d18c7c33988dc6e89c32 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Wed, 28 Oct 2020 18:59:35 +0100 Subject: [PATCH 038/136] inject only compatible token storage implementations for usage tracking --- .../RegisterTokenUsageTrackingPass.php | 8 +- .../RegisterTokenUsageTrackingPassTest.php | 89 +++++++++++++++++++ 2 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/RegisterTokenUsageTrackingPassTest.php diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/RegisterTokenUsageTrackingPass.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/RegisterTokenUsageTrackingPass.php index 94d5a184727e8..1cd90fe70af1a 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/RegisterTokenUsageTrackingPass.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/RegisterTokenUsageTrackingPass.php @@ -45,8 +45,12 @@ public function process(ContainerBuilder $container) $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']); + $tokenStorageClass = $container->getParameterBag()->resolveValue($container->findDefinition('security.token_storage')->getClass()); + + if (method_exists($tokenStorageClass, 'enableUsageTracking')) { + $container->getDefinition('security.context_listener') + ->setArgument(6, [new Reference('security.token_storage'), 'enableUsageTracking']); + } } } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/RegisterTokenUsageTrackingPassTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/RegisterTokenUsageTrackingPassTest.php new file mode 100644 index 0000000000000..afdbf9afaf60f --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/RegisterTokenUsageTrackingPassTest.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\SecurityBundle\Tests\DependencyInjection\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\RegisterTokenUsageTrackingPass; +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\HttpFoundation\Session\Session; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; +use Symfony\Component\Security\Core\Authentication\Token\Storage\UsageTrackingTokenStorage; +use Symfony\Component\Security\Http\Firewall\ContextListener; + +class RegisterTokenUsageTrackingPassTest extends TestCase +{ + public function testTokenStorageIsUntrackedIfSessionIsMissing() + { + $container = new ContainerBuilder(); + $container->register('security.untracked_token_storage', TokenStorage::class); + + $compilerPass = new RegisterTokenUsageTrackingPass(); + $compilerPass->process($container); + + $this->assertTrue($container->hasAlias('security.token_storage')); + $this->assertEquals(new Alias('security.untracked_token_storage', true), $container->getAlias('security.token_storage')); + } + + public function testContextListenerIsNotModifiedIfTokenStorageDoesNotSupportUsageTracking() + { + $container = new ContainerBuilder(); + + $container->setParameter('security.token_storage.class', TokenStorage::class); + $container->register('session', Session::class); + $container->register('security.context_listener', ContextListener::class) + ->setArguments([ + new Reference('security.untracked_token_storage'), + [], + 'main', + new Reference('logger', ContainerInterface::NULL_ON_INVALID_REFERENCE), + new Reference('event_dispatcher', ContainerInterface::NULL_ON_INVALID_REFERENCE), + new Reference('security.authentication.trust_resolver'), + ]); + $container->register('security.token_storage', '%security.token_storage.class%'); + $container->register('security.untracked_token_storage', TokenStorage::class); + + $compilerPass = new RegisterTokenUsageTrackingPass(); + $compilerPass->process($container); + + $this->assertCount(6, $container->getDefinition('security.context_listener')->getArguments()); + } + + public function testContextListenerEnablesUsageTrackingIfSupportedByTokenStorage() + { + $container = new ContainerBuilder(); + + $container->setParameter('security.token_storage.class', UsageTrackingTokenStorage::class); + $container->register('session', Session::class); + $container->register('security.context_listener', ContextListener::class) + ->setArguments([ + new Reference('security.untracked_token_storage'), + [], + 'main', + new Reference('logger', ContainerInterface::NULL_ON_INVALID_REFERENCE), + new Reference('event_dispatcher', ContainerInterface::NULL_ON_INVALID_REFERENCE), + new Reference('security.authentication.trust_resolver'), + ]); + $container->register('security.token_storage', '%security.token_storage.class%'); + $container->register('security.untracked_token_storage', TokenStorage::class); + + $compilerPass = new RegisterTokenUsageTrackingPass(); + $compilerPass->process($container); + + $contextListener = $container->getDefinition('security.context_listener'); + + $this->assertCount(7, $container->getDefinition('security.context_listener')->getArguments()); + $this->assertEquals([new Reference('security.token_storage'), 'enableUsageTracking'], $contextListener->getArgument(6)); + } +} From 4b958917fd06a957370c0582ebd3960ef6ccde37 Mon Sep 17 00:00:00 2001 From: Fabien Villepinte Date: Sat, 31 Oct 2020 13:49:56 +0000 Subject: [PATCH 039/136] [PHPUnitBridge] Fixed crash on Windows with PHP 8 The install command crashed with the message "The filename, directory name, or volume label syntax is incorrect.". It happens only on Windows with PHP 8. Probably due to https://github.com/php/php-src/blob/PHP-8.0/UPGRADING#L1121-L1123 --- src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php index 08be74fc721a8..7cfd6665d14bd 100644 --- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php +++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php @@ -231,7 +231,7 @@ } $prevRoot = getenv('COMPOSER_ROOT_VERSION'); putenv("COMPOSER_ROOT_VERSION=$PHPUNIT_VERSION.99"); - $q = '\\' === \DIRECTORY_SEPARATOR ? '"' : ''; + $q = '\\' === \DIRECTORY_SEPARATOR && \PHP_VERSION_ID < 80000 ? '"' : ''; // --no-suggest is not in the list to keep compat with composer 1.0, which is shipped with Ubuntu 16.04LTS $exit = proc_close(proc_open("$q$COMPOSER install --no-dev --prefer-dist --no-progress $q", [], $p, getcwd())); putenv('COMPOSER_ROOT_VERSION'.(false !== $prevRoot ? '='.$prevRoot : '')); From d4db75692b7aefb8ff9318900a31a235cc6f5dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Thu, 29 Oct 2020 19:50:46 +0100 Subject: [PATCH 040/136] Improve performances in CircualReference detection --- .../DependencyInjection/Dumper/PhpDumper.php | 126 ++++++++++-------- 1 file changed, 71 insertions(+), 55 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 4c0c656da0a38..fcc0ad33e11ee 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -180,25 +180,7 @@ public function dump(array $options = []) } } - (new AnalyzeServiceReferencesPass(false, !$this->getProxyDumper() instanceof NullDumper))->process($this->container); - $checkedNodes = []; - $this->circularReferences = []; - $this->singleUsePrivateIds = []; - foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) { - if (!$node->getValue() instanceof Definition) { - continue; - } - if (!isset($checkedNodes[$id])) { - $this->analyzeCircularReferences($id, $node->getOutEdges(), $checkedNodes); - } - if ($this->isSingleUsePrivateNode($node)) { - $this->singleUsePrivateIds[$id] = $id; - } - } - $this->container->getCompiler()->getServiceReferenceGraph()->clear(); - $checkedNodes = []; - $this->singleUsePrivateIds = array_diff_key($this->singleUsePrivateIds, $this->circularReferences); - + $this->analyzeReferences(); $this->docStar = $options['debug'] ? '*' : ''; if (!empty($options['file']) && is_dir($dir = \dirname($options['file']))) { @@ -409,58 +391,92 @@ private function getProxyDumper(): ProxyDumper return $this->proxyDumper; } - private function analyzeCircularReferences(string $sourceId, array $edges, array &$checkedNodes, array &$currentPath = [], bool $byConstructor = true) + private function analyzeReferences() { - $checkedNodes[$sourceId] = true; - $currentPath[$sourceId] = $byConstructor; + (new AnalyzeServiceReferencesPass(false, !$this->getProxyDumper() instanceof NullDumper))->process($this->container); + $checkedNodes = []; + $this->circularReferences = []; + $this->singleUsePrivateIds = []; + foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) { + if (!$node->getValue() instanceof Definition) { + continue; + } - foreach ($edges as $edge) { - $node = $edge->getDestNode(); - $id = $node->getId(); + if ($this->isSingleUsePrivateNode($node)) { + $this->singleUsePrivateIds[$id] = $id; + } - if (!$node->getValue() instanceof Definition || $sourceId === $id || $edge->isLazy() || $edge->isWeak()) { - // no-op - } elseif (isset($currentPath[$id])) { - $this->addCircularReferences($id, $currentPath, $edge->isReferencedByConstructor()); - } elseif (!isset($checkedNodes[$id])) { - $this->analyzeCircularReferences($id, $node->getOutEdges(), $checkedNodes, $currentPath, $edge->isReferencedByConstructor()); - } elseif (isset($this->circularReferences[$id])) { - $this->connectCircularReferences($id, $currentPath, $edge->isReferencedByConstructor()); + $newNodes = []; + if (!$this->collectCircularReferences($id, $node->getOutEdges(), $checkedNodes, $newNodes)) { + foreach ($newNodes as $newNodeId => $_) { + $checkedNodes[$newNodeId] = []; + } + continue; } - } - unset($currentPath[$sourceId]); - } - private function connectCircularReferences(string $sourceId, array &$currentPath, bool $byConstructor, array &$subPath = []) - { - $currentPath[$sourceId] = $subPath[$sourceId] = $byConstructor; + $nodesToFlatten = $newNodes; + do { + $changedNodes = []; + foreach ($nodesToFlatten as $newNodeId => $_) { + $deps = &$checkedNodes[$newNodeId]; + foreach ($deps as $id => [$path, $depsByConstructor]) { + foreach ($checkedNodes[$id] as $depsId => [$subPath, $subDepsByConstructor]) { + if (!isset($deps[$depsId]) || ($depsByConstructor && $subDepsByConstructor && !$deps[$depsId][1])) { + array_unshift($subPath, $id); + $deps[$depsId] = [$subPath, $depsByConstructor && $subDepsByConstructor]; + $changedNodes += $newNodes[$newNodeId] ?? []; + } + } + } + } + } while ($nodesToFlatten = $changedNodes); - foreach ($this->circularReferences[$sourceId] as $id => $byConstructor) { - if (isset($currentPath[$id])) { - $this->addCircularReferences($id, $currentPath, $byConstructor); - } elseif (!isset($subPath[$id]) && isset($this->circularReferences[$id])) { - $this->connectCircularReferences($id, $currentPath, $byConstructor, $subPath); + foreach ($newNodes as $newNodeId => $_) { + if (null !== $n = $checkedNodes[$newNodeId][$newNodeId] ?? null) { + $this->addCircularReferences($newNodeId, $n[0], $n[1]); + } } } - unset($currentPath[$sourceId], $subPath[$sourceId]); + + $this->container->getCompiler()->getServiceReferenceGraph()->clear(); + $this->singleUsePrivateIds = array_diff_key($this->singleUsePrivateIds, $this->circularReferences); } - private function addCircularReferences(string $id, array $currentPath, bool $byConstructor) + private function collectCircularReferences(string $sourceId, array $edges, array &$checkedNodes, array &$newNodes, array $path = []): bool { - $currentPath[$id] = $byConstructor; - $circularRefs = []; + $path[$sourceId] = true; + $checkedNodes[$sourceId] = []; + $newNodes[$sourceId] = []; + $circular = false; + foreach ($edges as $edge) { + $node = $edge->getDestNode(); + $id = $node->getId(); + if (!$node->getValue() instanceof Definition || $sourceId === $id || $edge->isLazy() || $edge->isWeak()) { + continue; + } - foreach (array_reverse($currentPath) as $parentId => $v) { - $byConstructor = $byConstructor && $v; - $circularRefs[] = $parentId; + if (isset($path[$id])) { + $circular = true; + } elseif (!isset($checkedNodes[$id])) { + $circular = $this->collectCircularReferences($id, $node->getOutEdges(), $checkedNodes, $newNodes, $path) || $circular; + } - if ($parentId === $id) { - break; + $checkedNodes[$sourceId][$id] = [[], $edge->isReferencedByConstructor()]; + if (isset($newNodes[$id])) { + $newNodes[$id][$sourceId] = true; } } + unset($path[$sourceId]); - $currentId = $id; - foreach ($circularRefs as $parentId) { + return $circular; + } + + private function addCircularReferences(string $sourceId, array $currentPath, bool $byConstructor) + { + $currentId = $sourceId; + $currentPath = array_reverse($currentPath); + $currentPath[] = $currentId; + foreach ($currentPath as $parentId) { if (empty($this->circularReferences[$parentId][$currentId])) { $this->circularReferences[$parentId][$currentId] = $byConstructor; } From 935a3b23e2bb112e77dd9d8c78f6c5353d9e2e99 Mon Sep 17 00:00:00 2001 From: hugovms <38090843+hugovms@users.noreply.github.com> Date: Sat, 31 Oct 2020 14:29:46 -0300 Subject: [PATCH 041/136] fix: solving pt-br translation issues --- .../Resources/translations/validators.pt.xlf | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.pt.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.pt.xlf index e5cf660686358..f140e1a45c00e 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.pt.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.pt.xlf @@ -176,27 +176,27 @@ This value should be the user's current password. - Este valor deveria de ser a password atual do utilizador. + Este valor deveria de ser a senha atual do usuário. This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. - Este valor tem de ter exatamente {{ limit }} carateres. + Este valor deve possuir exatamente {{ limit }} carateres. The file was only partially uploaded. - Só foi enviado parte do ficheiro. + Só foi enviado uma parte do arquivo. No file was uploaded. - Nenhum ficheiro foi enviado. + Nenhum arquivo foi enviado. No temporary folder was configured in php.ini. - Não existe nenhum directório temporária configurado no ficheiro php.ini. + Não existe nenhuma pasta temporária configurada no arquivo do php.ini. Cannot write temporary file to disk. - Não foi possível escrever ficheiros temporários no disco. + Não foi possível escrever os arquivos temporários no disco. A PHP extension caused the upload to fail. @@ -292,15 +292,15 @@ The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. - A imagem está orientada à paisagem ({{ width }}x{{ height }}px). Imagens orientadas à paisagem não são permitidas. + A imagem está em orientação de paisagem com ({{ width }}x{{ height }}px). Imagens orientadas em paisagem não são permitidas. The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. - A imagem está orientada ao retrato ({{ width }}x{{ height }}px). Imagens orientadas ao retrato não são permitidas. + A imagem está em orientação de retrato com ({{ width }}x{{ height }}px). Imagens orientadas em retrato não são permitidas. An empty file is not allowed. - Ficheiro vazio não é permitido. + Um arquivo vazio não é permitido. The host could not be resolved. From 31d120d0ee434537fb65cae5016ef34cdfd12162 Mon Sep 17 00:00:00 2001 From: AnneKir <57183946+AnneKir@users.noreply.github.com> Date: Sat, 31 Oct 2020 18:44:53 +0100 Subject: [PATCH 042/136] Update security.da.xlf Added case 17 and 18 --- .../Core/Resources/translations/security.da.xlf | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.da.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.da.xlf index 183ebe83e71dd..c83d27c5e0b59 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.da.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.da.xlf @@ -8,7 +8,7 @@ Authentication credentials could not be found. - Loginoplysninger kan findes. + Loginoplysninger kan ikke findes. Authentication request could not be processed due to a system problem. @@ -62,6 +62,14 @@ Account is locked. Brugerkonto er låst. + + Too many failed login attempts, please try again later. + For mange fejlede login forsøg, prøv venligst senere. + + + Invalid or expired login link. + Ugyldigt eller udløbet login link. + From e193c2b9855df46e93438c29d482a45f3cc0cb79 Mon Sep 17 00:00:00 2001 From: AnneKir <57183946+AnneKir@users.noreply.github.com> Date: Sat, 31 Oct 2020 18:45:33 +0100 Subject: [PATCH 043/136] Update validators.da.xlf Addded cases 95-99 in Danish --- .../Resources/translations/validators.da.xlf | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.da.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.da.xlf index 2bc33a7b437cd..6716585e7c9e3 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.da.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.da.xlf @@ -124,7 +124,7 @@ The file could not be uploaded. - Filen kunne ikke blive uploadet. + Filen kunne ikke uploades. This value should be a valid number. @@ -324,7 +324,7 @@ This value should be a multiple of {{ compared_value }}. - Denne værdi skal være et flertal af {{ compared_value }}. + Denne værdi skal være et multiplikation af {{ compared_value }}. This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. @@ -366,6 +366,26 @@ This value should be between {{ min }} and {{ max }}. Værdien skal være mellem {{ min }} og {{ max }}. + + This value is not a valid hostname. + Værdien er ikke et gyldigt værtsnavn. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Antallet af elementer i denne samling skal være en multiplikation af {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Værdien skal overholde mindst én af følgende krav:: + + + Each element of this collection should satisfy its own set of constraints. + Hvert element i denne samling skal overholde dens egne krav. + + + This value is not a valid International Securities Identification Number (ISIN). + Værdien er ikke et gyldig International Securities Identification Number (ISIN). + From 43ce6dfe44c41f5701ead77b6b70ec71cc9469d5 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sat, 31 Oct 2020 23:44:29 +0100 Subject: [PATCH 044/136] Set constant visibility in tests to private where possible. --- .../Form/Type/EntityTypePerformanceTest.php | 2 +- .../Doctrine/Tests/Form/Type/EntityTypeTest.php | 16 ++++++++-------- .../PropertyInfo/Fixtures/DoctrineFooType.php | 2 +- .../Constraints/UniqueEntityValidatorTest.php | 2 +- .../Tests/Security/FirewallMapTest.php | 2 +- .../Tests/EventDispatcherTest.php | 7 +++---- .../BooleanToStringTransformerTest.php | 2 +- .../ViolationMapper/ViolationMapperTest.php | 8 ++++---- .../Handler/MemcachedSessionHandlerTest.php | 4 ++-- .../Data/Bundle/Reader/BundleEntryReaderTest.php | 2 +- .../Intl/Tests/Util/GitRepositoryTest.php | 2 +- .../Ldap/Tests/Adapter/ExtLdap/AdapterTest.php | 2 +- .../Tests/PropertyPathBuilderTest.php | 2 +- .../Tests/Encoder/Argon2iPasswordEncoderTest.php | 2 +- .../Tests/Encoder/BCryptPasswordEncoderTest.php | 4 ++-- .../Constraints/UserPasswordValidatorTest.php | 4 ++-- .../TokenGenerator/UriSafeTokenGeneratorTest.php | 2 +- .../NativeSessionTokenStorageTest.php | 2 +- .../TokenStorage/SessionTokenStorageTest.php | 2 +- .../Authenticator/FormLoginAuthenticatorTest.php | 5 ++--- .../Tests/Encoder/ChainDecoderTest.php | 6 +++--- .../Tests/Encoder/ChainEncoderTest.php | 6 +++--- .../Tests/Normalizer/DataUriNormalizerTest.php | 6 +++--- .../Stopwatch/Tests/StopwatchEventTest.php | 2 +- .../Component/Stopwatch/Tests/StopwatchTest.php | 2 +- .../Tests/Mapping/ClassMetadataTest.php | 8 ++++---- .../Factory/LazyLoadingMetadataFactoryTest.php | 8 +++----- .../Tests/Mapping/GetterMetadataTest.php | 2 +- .../Tests/Mapping/PropertyMetadataTest.php | 8 ++++---- 29 files changed, 59 insertions(+), 63 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypePerformanceTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypePerformanceTest.php index 89aa779301350..33e6a6fd87235 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypePerformanceTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypePerformanceTest.php @@ -24,7 +24,7 @@ */ class EntityTypePerformanceTest extends FormPerformanceTestCase { - const ENTITY_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity'; + private const ENTITY_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity'; /** * @var \Doctrine\ORM\EntityManager diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php index 6f4cdb4346125..f7683a579cac2 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php @@ -39,14 +39,14 @@ class EntityTypeTest extends BaseTypeTest { const TESTED_TYPE = 'Symfony\Bridge\Doctrine\Form\Type\EntityType'; - const ITEM_GROUP_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\GroupableEntity'; - const SINGLE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity'; - const SINGLE_IDENT_NO_TO_STRING_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdNoToStringEntity'; - const SINGLE_STRING_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdEntity'; - const SINGLE_ASSOC_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleAssociationToIntIdEntity'; - const SINGLE_STRING_CASTABLE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringCastableIdEntity'; - const COMPOSITE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity'; - const COMPOSITE_STRING_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeStringIdEntity'; + private const ITEM_GROUP_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\GroupableEntity'; + private const SINGLE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity'; + private const SINGLE_IDENT_NO_TO_STRING_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdNoToStringEntity'; + private const SINGLE_STRING_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdEntity'; + private const SINGLE_ASSOC_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleAssociationToIntIdEntity'; + private const SINGLE_STRING_CASTABLE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringCastableIdEntity'; + private const COMPOSITE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity'; + private const COMPOSITE_STRING_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeStringIdEntity'; /** * @var EntityManager diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineFooType.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineFooType.php index 6e4807c58fb7a..37853b4815cfc 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineFooType.php +++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineFooType.php @@ -23,7 +23,7 @@ class DoctrineFooType extends Type /** * Type name. */ - const NAME = 'foo'; + private const NAME = 'foo'; /** * {@inheritdoc} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php index 98377acdeaf4b..1ccc4b7cc4feb 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php @@ -40,7 +40,7 @@ */ class UniqueEntityValidatorTest extends ConstraintValidatorTestCase { - const EM_NAME = 'foo'; + private const EM_NAME = 'foo'; /** * @var ObjectManager diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php index fa590a54e908d..7e49cd4fde9b5 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php @@ -23,7 +23,7 @@ class FirewallMapTest extends TestCase { - const ATTRIBUTE_FIREWALL_CONTEXT = '_firewall_context'; + private const ATTRIBUTE_FIREWALL_CONTEXT = '_firewall_context'; public function testGetListenersWithEmptyMap() { diff --git a/src/Symfony/Component/EventDispatcher/Tests/EventDispatcherTest.php b/src/Symfony/Component/EventDispatcher/Tests/EventDispatcherTest.php index 7c8b5dc9b20fe..5fb165838858a 100644 --- a/src/Symfony/Component/EventDispatcher/Tests/EventDispatcherTest.php +++ b/src/Symfony/Component/EventDispatcher/Tests/EventDispatcherTest.php @@ -20,10 +20,9 @@ class EventDispatcherTest extends TestCase { /* Some pseudo events */ - const preFoo = 'pre.foo'; - const postFoo = 'post.foo'; - const preBar = 'pre.bar'; - const postBar = 'post.bar'; + private const preFoo = 'pre.foo'; + private const postFoo = 'post.foo'; + private const preBar = 'pre.bar'; /** * @var EventDispatcher diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/BooleanToStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/BooleanToStringTransformerTest.php index 3694e49f4292c..e9f9ea6bdc759 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/BooleanToStringTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/BooleanToStringTransformerTest.php @@ -16,7 +16,7 @@ class BooleanToStringTransformerTest extends TestCase { - const TRUE_VALUE = '1'; + private const TRUE_VALUE = '1'; /** * @var BooleanToStringTransformer diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php index 100c54ad462eb..822e36e6a1dcc 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php @@ -32,10 +32,10 @@ */ class ViolationMapperTest extends TestCase { - const LEVEL_0 = 0; - const LEVEL_1 = 1; - const LEVEL_1B = 2; - const LEVEL_2 = 3; + private const LEVEL_0 = 0; + private const LEVEL_1 = 1; + private const LEVEL_1B = 2; + private const LEVEL_2 = 3; /** * @var EventDispatcherInterface diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php index e9c17703a7173..6fe43a0027aef 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php @@ -20,8 +20,8 @@ */ class MemcachedSessionHandlerTest extends TestCase { - const PREFIX = 'prefix_'; - const TTL = 1000; + private const PREFIX = 'prefix_'; + private const TTL = 1000; /** * @var MemcachedSessionHandler diff --git a/src/Symfony/Component/Intl/Tests/Data/Bundle/Reader/BundleEntryReaderTest.php b/src/Symfony/Component/Intl/Tests/Data/Bundle/Reader/BundleEntryReaderTest.php index 482999c60dd5f..3624295353161 100644 --- a/src/Symfony/Component/Intl/Tests/Data/Bundle/Reader/BundleEntryReaderTest.php +++ b/src/Symfony/Component/Intl/Tests/Data/Bundle/Reader/BundleEntryReaderTest.php @@ -21,7 +21,7 @@ */ class BundleEntryReaderTest extends TestCase { - const RES_DIR = '/res/dir'; + private const RES_DIR = '/res/dir'; /** * @var BundleEntryReader diff --git a/src/Symfony/Component/Intl/Tests/Util/GitRepositoryTest.php b/src/Symfony/Component/Intl/Tests/Util/GitRepositoryTest.php index ecbeb0eb520a5..5868174332def 100644 --- a/src/Symfony/Component/Intl/Tests/Util/GitRepositoryTest.php +++ b/src/Symfony/Component/Intl/Tests/Util/GitRepositoryTest.php @@ -23,7 +23,7 @@ class GitRepositoryTest extends TestCase { private $targetDir; - const REPO_URL = 'https://github.com/symfony/intl.git'; + private const REPO_URL = 'https://github.com/symfony/intl.git'; /** * @before diff --git a/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/AdapterTest.php b/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/AdapterTest.php index e6369549fa7d8..11ad46544e834 100644 --- a/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/AdapterTest.php +++ b/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/AdapterTest.php @@ -25,7 +25,7 @@ */ class AdapterTest extends LdapTestCase { - const PAGINATION_REQUIRED_CONFIG = [ + private const PAGINATION_REQUIRED_CONFIG = [ 'options' => [ 'protocol_version' => 3, ], diff --git a/src/Symfony/Component/PropertyAccess/Tests/PropertyPathBuilderTest.php b/src/Symfony/Component/PropertyAccess/Tests/PropertyPathBuilderTest.php index 1ae8fdd31d31d..b121a48087df7 100644 --- a/src/Symfony/Component/PropertyAccess/Tests/PropertyPathBuilderTest.php +++ b/src/Symfony/Component/PropertyAccess/Tests/PropertyPathBuilderTest.php @@ -20,7 +20,7 @@ */ class PropertyPathBuilderTest extends TestCase { - const PREFIX = 'old1[old2].old3[old4][old5].old6'; + private const PREFIX = 'old1[old2].old3[old4][old5].old6'; /** * @var PropertyPathBuilder diff --git a/src/Symfony/Component/Security/Core/Tests/Encoder/Argon2iPasswordEncoderTest.php b/src/Symfony/Component/Security/Core/Tests/Encoder/Argon2iPasswordEncoderTest.php index 50e84e8de152c..a66932cc446a4 100644 --- a/src/Symfony/Component/Security/Core/Tests/Encoder/Argon2iPasswordEncoderTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Encoder/Argon2iPasswordEncoderTest.php @@ -21,7 +21,7 @@ */ class Argon2iPasswordEncoderTest extends TestCase { - const PASSWORD = 'password'; + private const PASSWORD = 'password'; protected function setUp(): void { diff --git a/src/Symfony/Component/Security/Core/Tests/Encoder/BCryptPasswordEncoderTest.php b/src/Symfony/Component/Security/Core/Tests/Encoder/BCryptPasswordEncoderTest.php index 4ff5bc31f749b..d0372a86eba0b 100644 --- a/src/Symfony/Component/Security/Core/Tests/Encoder/BCryptPasswordEncoderTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Encoder/BCryptPasswordEncoderTest.php @@ -21,8 +21,8 @@ */ class BCryptPasswordEncoderTest extends TestCase { - const PASSWORD = 'password'; - const VALID_COST = '04'; + private const PASSWORD = 'password'; + private const VALID_COST = '04'; public function testCostBelowRange() { diff --git a/src/Symfony/Component/Security/Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php b/src/Symfony/Component/Security/Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php index efdc8585f0a31..4e11c47f8ca7d 100644 --- a/src/Symfony/Component/Security/Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php @@ -23,8 +23,8 @@ */ abstract class UserPasswordValidatorTest extends ConstraintValidatorTestCase { - const PASSWORD = 's3Cr3t'; - const SALT = '^S4lt$'; + private const PASSWORD = 's3Cr3t'; + private const SALT = '^S4lt$'; /** * @var TokenStorageInterface diff --git a/src/Symfony/Component/Security/Csrf/Tests/TokenGenerator/UriSafeTokenGeneratorTest.php b/src/Symfony/Component/Security/Csrf/Tests/TokenGenerator/UriSafeTokenGeneratorTest.php index dc97acc239ddc..ad545aa784bcc 100644 --- a/src/Symfony/Component/Security/Csrf/Tests/TokenGenerator/UriSafeTokenGeneratorTest.php +++ b/src/Symfony/Component/Security/Csrf/Tests/TokenGenerator/UriSafeTokenGeneratorTest.php @@ -19,7 +19,7 @@ */ class UriSafeTokenGeneratorTest extends TestCase { - const ENTROPY = 1000; + private const ENTROPY = 1000; /** * A non alpha-numeric byte string. diff --git a/src/Symfony/Component/Security/Csrf/Tests/TokenStorage/NativeSessionTokenStorageTest.php b/src/Symfony/Component/Security/Csrf/Tests/TokenStorage/NativeSessionTokenStorageTest.php index ead39789979b1..5acbedc6e9335 100644 --- a/src/Symfony/Component/Security/Csrf/Tests/TokenStorage/NativeSessionTokenStorageTest.php +++ b/src/Symfony/Component/Security/Csrf/Tests/TokenStorage/NativeSessionTokenStorageTest.php @@ -22,7 +22,7 @@ */ class NativeSessionTokenStorageTest extends TestCase { - const SESSION_NAMESPACE = 'foobar'; + private const SESSION_NAMESPACE = 'foobar'; /** * @var NativeSessionTokenStorage diff --git a/src/Symfony/Component/Security/Csrf/Tests/TokenStorage/SessionTokenStorageTest.php b/src/Symfony/Component/Security/Csrf/Tests/TokenStorage/SessionTokenStorageTest.php index 7ddd965e51d7b..af5b0ebc8b779 100644 --- a/src/Symfony/Component/Security/Csrf/Tests/TokenStorage/SessionTokenStorageTest.php +++ b/src/Symfony/Component/Security/Csrf/Tests/TokenStorage/SessionTokenStorageTest.php @@ -21,7 +21,7 @@ */ class SessionTokenStorageTest extends TestCase { - const SESSION_NAMESPACE = 'foobar'; + private const SESSION_NAMESPACE = 'foobar'; /** * @var Session diff --git a/src/Symfony/Component/Security/Guard/Tests/Authenticator/FormLoginAuthenticatorTest.php b/src/Symfony/Component/Security/Guard/Tests/Authenticator/FormLoginAuthenticatorTest.php index e0cd29131e125..2b7f25f7915e6 100644 --- a/src/Symfony/Component/Security/Guard/Tests/Authenticator/FormLoginAuthenticatorTest.php +++ b/src/Symfony/Component/Security/Guard/Tests/Authenticator/FormLoginAuthenticatorTest.php @@ -29,9 +29,8 @@ class FormLoginAuthenticatorTest extends TestCase private $requestWithSession; private $authenticator; - const LOGIN_URL = 'http://login'; - const DEFAULT_SUCCESS_URL = 'http://defaultsuccess'; - const CUSTOM_SUCCESS_URL = 'http://customsuccess'; + private const LOGIN_URL = 'http://login'; + private const DEFAULT_SUCCESS_URL = 'http://defaultsuccess'; public function testAuthenticationFailureWithoutSession() { diff --git a/src/Symfony/Component/Serializer/Tests/Encoder/ChainDecoderTest.php b/src/Symfony/Component/Serializer/Tests/Encoder/ChainDecoderTest.php index 301b43586970a..215e73386176a 100644 --- a/src/Symfony/Component/Serializer/Tests/Encoder/ChainDecoderTest.php +++ b/src/Symfony/Component/Serializer/Tests/Encoder/ChainDecoderTest.php @@ -16,9 +16,9 @@ class ChainDecoderTest extends TestCase { - const FORMAT_1 = 'format1'; - const FORMAT_2 = 'format2'; - const FORMAT_3 = 'format3'; + private const FORMAT_1 = 'format1'; + private const FORMAT_2 = 'format2'; + private const FORMAT_3 = 'format3'; private $chainDecoder; private $decoder1; diff --git a/src/Symfony/Component/Serializer/Tests/Encoder/ChainEncoderTest.php b/src/Symfony/Component/Serializer/Tests/Encoder/ChainEncoderTest.php index 82aa2934d92d4..e7b02256e65e5 100644 --- a/src/Symfony/Component/Serializer/Tests/Encoder/ChainEncoderTest.php +++ b/src/Symfony/Component/Serializer/Tests/Encoder/ChainEncoderTest.php @@ -18,9 +18,9 @@ class ChainEncoderTest extends TestCase { - const FORMAT_1 = 'format1'; - const FORMAT_2 = 'format2'; - const FORMAT_3 = 'format3'; + private const FORMAT_1 = 'format1'; + private const FORMAT_2 = 'format2'; + private const FORMAT_3 = 'format3'; private $chainEncoder; private $encoder1; diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/DataUriNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/DataUriNormalizerTest.php index d1829f759ddac..f1a906b593836 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/DataUriNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/DataUriNormalizerTest.php @@ -20,9 +20,9 @@ */ class DataUriNormalizerTest extends TestCase { - const TEST_GIF_DATA = 'data:image/gif;base64,R0lGODdhAQABAIAAAP///////ywAAAAAAQABAAACAkQBADs='; - const TEST_TXT_DATA = 'data:text/plain,K%C3%A9vin%20Dunglas%0A'; - const TEST_TXT_CONTENT = "Kévin Dunglas\n"; + private const TEST_GIF_DATA = 'data:image/gif;base64,R0lGODdhAQABAIAAAP///////ywAAAAAAQABAAACAkQBADs='; + private const TEST_TXT_DATA = 'data:text/plain,K%C3%A9vin%20Dunglas%0A'; + private const TEST_TXT_CONTENT = "Kévin Dunglas\n"; /** * @var DataUriNormalizer diff --git a/src/Symfony/Component/Stopwatch/Tests/StopwatchEventTest.php b/src/Symfony/Component/Stopwatch/Tests/StopwatchEventTest.php index 1647d7bf8d47f..06808616e3307 100644 --- a/src/Symfony/Component/Stopwatch/Tests/StopwatchEventTest.php +++ b/src/Symfony/Component/Stopwatch/Tests/StopwatchEventTest.php @@ -23,7 +23,7 @@ */ class StopwatchEventTest extends TestCase { - const DELTA = 37; + private const DELTA = 37; public function testGetOrigin() { diff --git a/src/Symfony/Component/Stopwatch/Tests/StopwatchTest.php b/src/Symfony/Component/Stopwatch/Tests/StopwatchTest.php index b8efa373b4cd1..5dd0c3c2d8a19 100644 --- a/src/Symfony/Component/Stopwatch/Tests/StopwatchTest.php +++ b/src/Symfony/Component/Stopwatch/Tests/StopwatchTest.php @@ -23,7 +23,7 @@ */ class StopwatchTest extends TestCase { - const DELTA = 20; + private const DELTA = 20; public function testStart() { diff --git a/src/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php b/src/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php index f0635266e29c5..93834fbf447f4 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php @@ -24,10 +24,10 @@ class ClassMetadataTest extends TestCase { - const CLASSNAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity'; - const PARENTCLASS = 'Symfony\Component\Validator\Tests\Fixtures\EntityParent'; - const PROVIDERCLASS = 'Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity'; - const PROVIDERCHILDCLASS = 'Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderChildEntity'; + private const CLASSNAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity'; + private const PARENTCLASS = 'Symfony\Component\Validator\Tests\Fixtures\EntityParent'; + private const PROVIDERCLASS = 'Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity'; + private const PROVIDERCHILDCLASS = 'Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderChildEntity'; protected $metadata; diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Factory/LazyLoadingMetadataFactoryTest.php b/src/Symfony/Component/Validator/Tests/Mapping/Factory/LazyLoadingMetadataFactoryTest.php index b3f699b6f2227..2a06dcd1b899c 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Factory/LazyLoadingMetadataFactoryTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/Factory/LazyLoadingMetadataFactoryTest.php @@ -26,11 +26,9 @@ class LazyLoadingMetadataFactoryTest extends TestCase { - const CLASS_NAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity'; - const PARENT_CLASS = 'Symfony\Component\Validator\Tests\Fixtures\EntityParent'; - const INTERFACE_A_CLASS = 'Symfony\Component\Validator\Tests\Fixtures\EntityInterfaceA'; - const INTERFACE_B_CLASS = 'Symfony\Component\Validator\Tests\Fixtures\EntityInterfaceB'; - const PARENT_INTERFACE_CLASS = 'Symfony\Component\Validator\Tests\Fixtures\EntityParentInterface'; + private const CLASS_NAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity'; + private const PARENT_CLASS = 'Symfony\Component\Validator\Tests\Fixtures\EntityParent'; + private const INTERFACE_A_CLASS = 'Symfony\Component\Validator\Tests\Fixtures\EntityInterfaceA'; public function testLoadClassMetadataWithInterface() { diff --git a/src/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php b/src/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php index 127bd5a164b47..442afaf134331 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php @@ -17,7 +17,7 @@ class GetterMetadataTest extends TestCase { - const CLASSNAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity'; + private const CLASSNAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity'; public function testInvalidPropertyName() { diff --git a/src/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php b/src/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php index 8868ec64aac9f..3796677294553 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php @@ -19,10 +19,10 @@ class PropertyMetadataTest extends TestCase { - const CLASSNAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity'; - const CLASSNAME_74 = 'Symfony\Component\Validator\Tests\Fixtures\Entity_74'; - const CLASSNAME_74_PROXY = 'Symfony\Component\Validator\Tests\Fixtures\Entity_74_Proxy'; - const PARENTCLASS = 'Symfony\Component\Validator\Tests\Fixtures\EntityParent'; + private const CLASSNAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity'; + private const CLASSNAME_74 = 'Symfony\Component\Validator\Tests\Fixtures\Entity_74'; + private const CLASSNAME_74_PROXY = 'Symfony\Component\Validator\Tests\Fixtures\Entity_74_Proxy'; + private const PARENTCLASS = 'Symfony\Component\Validator\Tests\Fixtures\EntityParent'; public function testInvalidPropertyName() { From 6822774d37e335e259c5d88e9911340482403efe Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sat, 31 Oct 2020 23:59:36 +0100 Subject: [PATCH 045/136] [Validator] Merge RecursiveValidatorTest with its parents. --- .../Tests/Validator/AbstractTest.php | 722 ------ .../Tests/Validator/AbstractValidatorTest.php | 1281 ----------- .../Validator/RecursiveValidatorTest.php | 1935 ++++++++++++++++- 3 files changed, 1934 insertions(+), 2004 deletions(-) delete mode 100644 src/Symfony/Component/Validator/Tests/Validator/AbstractTest.php delete mode 100644 src/Symfony/Component/Validator/Tests/Validator/AbstractValidatorTest.php diff --git a/src/Symfony/Component/Validator/Tests/Validator/AbstractTest.php b/src/Symfony/Component/Validator/Tests/Validator/AbstractTest.php deleted file mode 100644 index 06f7e85775276..0000000000000 --- a/src/Symfony/Component/Validator/Tests/Validator/AbstractTest.php +++ /dev/null @@ -1,722 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator\Tests\Validator; - -use Symfony\Component\Validator\Constraints\Callback; -use Symfony\Component\Validator\Constraints\Collection; -use Symfony\Component\Validator\Constraints\Expression; -use Symfony\Component\Validator\Constraints\GroupSequence; -use Symfony\Component\Validator\Constraints\NotBlank; -use Symfony\Component\Validator\Constraints\NotNull; -use Symfony\Component\Validator\Constraints\Traverse; -use Symfony\Component\Validator\Constraints\Valid; -use Symfony\Component\Validator\ConstraintViolationInterface; -use Symfony\Component\Validator\Context\ExecutionContextInterface; -use Symfony\Component\Validator\Mapping\ClassMetadata; -use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface; -use Symfony\Component\Validator\Tests\Fixtures\Entity; -use Symfony\Component\Validator\Tests\Fixtures\FailingConstraint; -use Symfony\Component\Validator\Tests\Fixtures\Reference; -use Symfony\Component\Validator\Validator\ValidatorInterface; - -/** - * @author Bernhard Schussek - */ -abstract class AbstractTest extends AbstractValidatorTest -{ - /** - * @var ValidatorInterface - */ - protected $validator; - - abstract protected function createValidator(MetadataFactoryInterface $metadataFactory, array $objectInitializers = []): ValidatorInterface; - - protected function setUp(): void - { - parent::setUp(); - - $this->validator = $this->createValidator($this->metadataFactory); - } - - protected function validate($value, $constraints = null, $groups = null) - { - return $this->validator->validate($value, $constraints, $groups); - } - - protected function validateProperty($object, $propertyName, $groups = null) - { - return $this->validator->validateProperty($object, $propertyName, $groups); - } - - protected function validatePropertyValue($object, $propertyName, $value, $groups = null) - { - return $this->validator->validatePropertyValue($object, $propertyName, $value, $groups); - } - - public function testValidateConstraintWithoutGroup() - { - $violations = $this->validator->validate(null, new NotNull()); - - $this->assertCount(1, $violations); - } - - public function testValidateWithEmptyArrayAsConstraint() - { - $violations = $this->validator->validate('value', []); - $this->assertCount(0, $violations); - } - - public function testGroupSequenceAbortsAfterFailedGroup() - { - $entity = new Entity(); - - $callback1 = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Message 1'); - }; - $callback2 = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Message 2'); - }; - - $this->metadata->addConstraint(new Callback([ - 'callback' => function () {}, - 'groups' => 'Group 1', - ])); - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback1, - 'groups' => 'Group 2', - ])); - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback2, - 'groups' => 'Group 3', - ])); - - $sequence = new GroupSequence(['Group 1', 'Group 2', 'Group 3']); - $violations = $this->validator->validate($entity, new Valid(), $sequence); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message 1', $violations[0]->getMessage()); - } - - public function testGroupSequenceIncludesReferences() - { - $entity = new Entity(); - $entity->reference = new Reference(); - - $callback1 = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Reference violation 1'); - }; - $callback2 = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Reference violation 2'); - }; - - $this->metadata->addPropertyConstraint('reference', new Valid()); - $this->referenceMetadata->addConstraint(new Callback([ - 'callback' => $callback1, - 'groups' => 'Group 1', - ])); - $this->referenceMetadata->addConstraint(new Callback([ - 'callback' => $callback2, - 'groups' => 'Group 2', - ])); - - $sequence = new GroupSequence(['Group 1', 'Entity']); - $violations = $this->validator->validate($entity, new Valid(), $sequence); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Reference violation 1', $violations[0]->getMessage()); - } - - public function testValidateInSeparateContext() - { - $entity = new Entity(); - $entity->reference = new Reference(); - - $callback1 = function ($value, ExecutionContextInterface $context) use ($entity) { - $violations = $context - ->getValidator() - // Since the validator is not context aware, the group must - // be passed explicitly - ->validate($value->reference, new Valid(), 'Group') - ; - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('', $violations[0]->getPropertyPath()); - - // The root is different as we're in a new context - $this->assertSame($entity->reference, $violations[0]->getRoot()); - $this->assertSame($entity->reference, $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - - // Verify that this method is called - $context->addViolation('Separate violation'); - }; - - $callback2 = function ($value, ExecutionContextInterface $context) use ($entity) { - $this->assertSame($this::REFERENCE_CLASS, $context->getClassName()); - $this->assertNull($context->getPropertyName()); - $this->assertSame('', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($this->referenceMetadata, $context->getMetadata()); - $this->assertSame($entity->reference, $context->getRoot()); - $this->assertSame($entity->reference, $context->getValue()); - $this->assertSame($entity->reference, $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback1, - 'groups' => 'Group', - ])); - $this->referenceMetadata->addConstraint(new Callback([ - 'callback' => $callback2, - 'groups' => 'Group', - ])); - - $violations = $this->validator->validate($entity, new Valid(), 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Separate violation', $violations[0]->getMessage()); - } - - public function testValidateInContext() - { - $entity = new Entity(); - $entity->reference = new Reference(); - - $callback1 = function ($value, ExecutionContextInterface $context) { - $previousValue = $context->getValue(); - $previousObject = $context->getObject(); - $previousMetadata = $context->getMetadata(); - $previousPath = $context->getPropertyPath(); - $previousGroup = $context->getGroup(); - - $context - ->getValidator() - ->inContext($context) - ->atPath('subpath') - ->validate($value->reference) - ; - - // context changes shouldn't leak out of the validate() call - $this->assertSame($previousValue, $context->getValue()); - $this->assertSame($previousObject, $context->getObject()); - $this->assertSame($previousMetadata, $context->getMetadata()); - $this->assertSame($previousPath, $context->getPropertyPath()); - $this->assertSame($previousGroup, $context->getGroup()); - }; - - $callback2 = function ($value, ExecutionContextInterface $context) use ($entity) { - $this->assertSame($this::REFERENCE_CLASS, $context->getClassName()); - $this->assertNull($context->getPropertyName()); - $this->assertSame('subpath', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($this->referenceMetadata, $context->getMetadata()); - $this->assertSame($entity, $context->getRoot()); - $this->assertSame($entity->reference, $context->getValue()); - $this->assertSame($entity->reference, $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback1, - 'groups' => 'Group', - ])); - $this->referenceMetadata->addConstraint(new Callback([ - 'callback' => $callback2, - 'groups' => 'Group', - ])); - - $violations = $this->validator->validate($entity, new Valid(), 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('subpath', $violations[0]->getPropertyPath()); - $this->assertSame($entity, $violations[0]->getRoot()); - $this->assertSame($entity->reference, $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - public function testValidateArrayInContext() - { - $entity = new Entity(); - $entity->reference = new Reference(); - - $callback1 = function ($value, ExecutionContextInterface $context) { - $previousValue = $context->getValue(); - $previousObject = $context->getObject(); - $previousMetadata = $context->getMetadata(); - $previousPath = $context->getPropertyPath(); - $previousGroup = $context->getGroup(); - - $context - ->getValidator() - ->inContext($context) - ->atPath('subpath') - ->validate(['key' => $value->reference]) - ; - - // context changes shouldn't leak out of the validate() call - $this->assertSame($previousValue, $context->getValue()); - $this->assertSame($previousObject, $context->getObject()); - $this->assertSame($previousMetadata, $context->getMetadata()); - $this->assertSame($previousPath, $context->getPropertyPath()); - $this->assertSame($previousGroup, $context->getGroup()); - }; - - $callback2 = function ($value, ExecutionContextInterface $context) use ($entity) { - $this->assertSame($this::REFERENCE_CLASS, $context->getClassName()); - $this->assertNull($context->getPropertyName()); - $this->assertSame('subpath[key]', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($this->referenceMetadata, $context->getMetadata()); - $this->assertSame($entity, $context->getRoot()); - $this->assertSame($entity->reference, $context->getValue()); - $this->assertSame($entity->reference, $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback1, - 'groups' => 'Group', - ])); - $this->referenceMetadata->addConstraint(new Callback([ - 'callback' => $callback2, - 'groups' => 'Group', - ])); - - $violations = $this->validator->validate($entity, new Valid(), 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('subpath[key]', $violations[0]->getPropertyPath()); - $this->assertSame($entity, $violations[0]->getRoot()); - $this->assertSame($entity->reference, $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - public function testTraverseTraversableByDefault() - { - $entity = new Entity(); - $traversable = new \ArrayIterator(['key' => $entity]); - - $callback = function ($value, ExecutionContextInterface $context) use ($entity, $traversable) { - $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); - $this->assertNull($context->getPropertyName()); - $this->assertSame('[key]', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($this->metadata, $context->getMetadata()); - $this->assertSame($traversable, $context->getRoot()); - $this->assertSame($entity, $context->getValue()); - $this->assertSame($entity, $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadataFactory->addMetadata(new ClassMetadata('ArrayIterator')); - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - - $violations = $this->validate($traversable, new Valid(), 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('[key]', $violations[0]->getPropertyPath()); - $this->assertSame($traversable, $violations[0]->getRoot()); - $this->assertSame($entity, $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - public function testTraversalEnabledOnClass() - { - $entity = new Entity(); - $traversable = new \ArrayIterator(['key' => $entity]); - - $callback = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Message'); - }; - - $traversableMetadata = new ClassMetadata('ArrayIterator'); - $traversableMetadata->addConstraint(new Traverse(true)); - - $this->metadataFactory->addMetadata($traversableMetadata); - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - - $violations = $this->validate($traversable, new Valid(), 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - } - - public function testTraversalDisabledOnClass() - { - $entity = new Entity(); - $traversable = new \ArrayIterator(['key' => $entity]); - - $callback = function ($value, ExecutionContextInterface $context) { - $this->fail('Should not be called'); - }; - - $traversableMetadata = new ClassMetadata('ArrayIterator'); - $traversableMetadata->addConstraint(new Traverse(false)); - - $this->metadataFactory->addMetadata($traversableMetadata); - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - - $violations = $this->validate($traversable, new Valid(), 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(0, $violations); - } - - public function testExpectTraversableIfTraversalEnabledOnClass() - { - $this->expectException('Symfony\Component\Validator\Exception\ConstraintDefinitionException'); - $entity = new Entity(); - - $this->metadata->addConstraint(new Traverse(true)); - - $this->validator->validate($entity); - } - - public function testReferenceTraversalDisabledOnClass() - { - $entity = new Entity(); - $entity->reference = new \ArrayIterator(['key' => new Reference()]); - - $callback = function ($value, ExecutionContextInterface $context) { - $this->fail('Should not be called'); - }; - - $traversableMetadata = new ClassMetadata('ArrayIterator'); - $traversableMetadata->addConstraint(new Traverse(false)); - - $this->metadataFactory->addMetadata($traversableMetadata); - $this->referenceMetadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - $this->metadata->addPropertyConstraint('reference', new Valid()); - - $violations = $this->validate($entity, new Valid(), 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(0, $violations); - } - - public function testReferenceTraversalEnabledOnReferenceDisabledOnClass() - { - $entity = new Entity(); - $entity->reference = new \ArrayIterator(['key' => new Reference()]); - - $callback = function ($value, ExecutionContextInterface $context) { - $this->fail('Should not be called'); - }; - - $traversableMetadata = new ClassMetadata('ArrayIterator'); - $traversableMetadata->addConstraint(new Traverse(false)); - - $this->metadataFactory->addMetadata($traversableMetadata); - $this->referenceMetadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - $this->metadata->addPropertyConstraint('reference', new Valid([ - 'traverse' => true, - ])); - - $violations = $this->validate($entity, new Valid(), 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(0, $violations); - } - - public function testReferenceTraversalDisabledOnReferenceEnabledOnClass() - { - $entity = new Entity(); - $entity->reference = new \ArrayIterator(['key' => new Reference()]); - - $callback = function ($value, ExecutionContextInterface $context) { - $this->fail('Should not be called'); - }; - - $traversableMetadata = new ClassMetadata('ArrayIterator'); - $traversableMetadata->addConstraint(new Traverse(true)); - - $this->metadataFactory->addMetadata($traversableMetadata); - $this->referenceMetadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - $this->metadata->addPropertyConstraint('reference', new Valid([ - 'traverse' => false, - ])); - - $violations = $this->validate($entity, new Valid(), 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(0, $violations); - } - - public function testAddCustomizedViolation() - { - $entity = new Entity(); - - $callback = function ($value, ExecutionContextInterface $context) { - $context->buildViolation('Message %param%') - ->setParameter('%param%', 'value') - ->setInvalidValue('Invalid value') - ->setPlural(2) - ->setCode('42') - ->addViolation(); - }; - - $this->metadata->addConstraint(new Callback($callback)); - - $violations = $this->validator->validate($entity); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('', $violations[0]->getPropertyPath()); - $this->assertSame($entity, $violations[0]->getRoot()); - $this->assertSame('Invalid value', $violations[0]->getInvalidValue()); - $this->assertSame(2, $violations[0]->getPlural()); - $this->assertSame('42', $violations[0]->getCode()); - } - - public function testNoDuplicateValidationIfClassConstraintInMultipleGroups() - { - $entity = new Entity(); - - $callback = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Message'); - }; - - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => ['Group 1', 'Group 2'], - ])); - - $violations = $this->validator->validate($entity, new Valid(), ['Group 1', 'Group 2']); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - } - - public function testNoDuplicateValidationIfPropertyConstraintInMultipleGroups() - { - $entity = new Entity(); - - $callback = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Message'); - }; - - $this->metadata->addPropertyConstraint('firstName', new Callback([ - 'callback' => $callback, - 'groups' => ['Group 1', 'Group 2'], - ])); - - $violations = $this->validator->validate($entity, new Valid(), ['Group 1', 'Group 2']); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - } - - public function testValidateFailsIfNoConstraintsAndNoObjectOrArray() - { - $this->expectException('Symfony\Component\Validator\Exception\RuntimeException'); - $this->validate('Foobar'); - } - - public function testAccessCurrentObject() - { - $called = false; - $entity = new Entity(); - $entity->firstName = 'Bernhard'; - $entity->data = ['firstName' => 'Bernhard']; - - $callback = function ($value, ExecutionContextInterface $context) use ($entity, &$called) { - $called = true; - $this->assertSame($entity, $context->getObject()); - }; - - $this->metadata->addConstraint(new Callback($callback)); - $this->metadata->addPropertyConstraint('firstName', new Callback($callback)); - $this->metadata->addPropertyConstraint('data', new Collection(['firstName' => new Expression('value == this.firstName')])); - - $this->validator->validate($entity); - - $this->assertTrue($called); - } - - public function testInitializeObjectsOnFirstValidation() - { - $entity = new Entity(); - $entity->initialized = false; - - // prepare initializers that set "initialized" to true - $initializer1 = $this->getMockBuilder('Symfony\\Component\\Validator\\ObjectInitializerInterface')->getMock(); - $initializer2 = $this->getMockBuilder('Symfony\\Component\\Validator\\ObjectInitializerInterface')->getMock(); - - $initializer1->expects($this->once()) - ->method('initialize') - ->with($entity) - ->willReturnCallback(function ($object) { - $object->initialized = true; - }); - - $initializer2->expects($this->once()) - ->method('initialize') - ->with($entity); - - $this->validator = $this->createValidator($this->metadataFactory, [ - $initializer1, - $initializer2, - ]); - - // prepare constraint which - // * checks that "initialized" is set to true - // * validates the object again - $callback = function ($object, ExecutionContextInterface $context) { - $this->assertTrue($object->initialized); - - // validate again in same group - $validator = $context->getValidator()->inContext($context); - - $validator->validate($object); - - // validate again in other group - $validator->validate($object, null, 'SomeGroup'); - }; - - $this->metadata->addConstraint(new Callback($callback)); - - $this->validate($entity); - - $this->assertTrue($entity->initialized); - } - - public function testPassConstraintToViolation() - { - $constraint = new FailingConstraint(); - $violations = $this->validate('Foobar', $constraint); - - $this->assertCount(1, $violations); - $this->assertSame($constraint, $violations[0]->getConstraint()); - } - - public function testCollectionConstraitViolationHasCorrectContext() - { - $data = [ - 'foo' => 'fooValue', - ]; - - // Missing field must not be the first in the collection validation - $constraint = new Collection([ - 'foo' => new NotNull(), - 'bar' => new NotNull(), - ]); - - $violations = $this->validate($data, $constraint); - - $this->assertCount(1, $violations); - $this->assertSame($constraint, $violations[0]->getConstraint()); - } - - public function testNestedObjectIsNotValidatedIfGroupInValidConstraintIsNotValidated() - { - $entity = new Entity(); - $entity->firstName = ''; - $reference = new Reference(); - $reference->value = ''; - $entity->childA = $reference; - - $this->metadata->addPropertyConstraint('firstName', new NotBlank(['groups' => 'group1'])); - $this->metadata->addPropertyConstraint('childA', new Valid(['groups' => 'group1'])); - $this->referenceMetadata->addPropertyConstraint('value', new NotBlank()); - - $violations = $this->validator->validate($entity, null, []); - - $this->assertCount(0, $violations); - } - - public function testNestedObjectIsValidatedIfGroupInValidConstraintIsValidated() - { - $entity = new Entity(); - $entity->firstName = ''; - $reference = new Reference(); - $reference->value = ''; - $entity->childA = $reference; - - $this->metadata->addPropertyConstraint('firstName', new NotBlank(['groups' => 'group1'])); - $this->metadata->addPropertyConstraint('childA', new Valid(['groups' => 'group1'])); - $this->referenceMetadata->addPropertyConstraint('value', new NotBlank(['groups' => 'group1'])); - - $violations = $this->validator->validate($entity, null, ['Default', 'group1']); - - $this->assertCount(2, $violations); - } - - public function testNestedObjectIsValidatedInMultipleGroupsIfGroupInValidConstraintIsValidated() - { - $entity = new Entity(); - $entity->firstName = null; - - $reference = new Reference(); - $reference->value = null; - - $entity->childA = $reference; - - $this->metadata->addPropertyConstraint('firstName', new NotBlank()); - $this->metadata->addPropertyConstraint('childA', new Valid(['groups' => ['group1', 'group2']])); - - $this->referenceMetadata->addPropertyConstraint('value', new NotBlank(['groups' => 'group1'])); - $this->referenceMetadata->addPropertyConstraint('value', new NotNull(['groups' => 'group2'])); - - $violations = $this->validator->validate($entity, null, ['Default', 'group1', 'group2']); - - $this->assertCount(3, $violations); - } -} diff --git a/src/Symfony/Component/Validator/Tests/Validator/AbstractValidatorTest.php b/src/Symfony/Component/Validator/Tests/Validator/AbstractValidatorTest.php deleted file mode 100644 index e9bad07096664..0000000000000 --- a/src/Symfony/Component/Validator/Tests/Validator/AbstractValidatorTest.php +++ /dev/null @@ -1,1281 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator\Tests\Validator; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Validator\Constraints\Callback; -use Symfony\Component\Validator\Constraints\GroupSequence; -use Symfony\Component\Validator\Constraints\Valid; -use Symfony\Component\Validator\ConstraintViolationInterface; -use Symfony\Component\Validator\Context\ExecutionContextInterface; -use Symfony\Component\Validator\Mapping\ClassMetadata; -use Symfony\Component\Validator\Tests\Fixtures\Entity; -use Symfony\Component\Validator\Tests\Fixtures\FakeMetadataFactory; -use Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity; -use Symfony\Component\Validator\Tests\Fixtures\Reference; - -/** - * @author Bernhard Schussek - */ -abstract class AbstractValidatorTest extends TestCase -{ - const ENTITY_CLASS = 'Symfony\Component\Validator\Tests\Fixtures\Entity'; - - const REFERENCE_CLASS = 'Symfony\Component\Validator\Tests\Fixtures\Reference'; - - const LAZY_PROPERTY = 'Symfony\Component\Validator\Validator\LazyProperty'; - - /** - * @var FakeMetadataFactory - */ - public $metadataFactory; - - /** - * @var ClassMetadata - */ - public $metadata; - - /** - * @var ClassMetadata - */ - public $referenceMetadata; - - protected function setUp(): void - { - $this->metadataFactory = new FakeMetadataFactory(); - $this->metadata = new ClassMetadata(self::ENTITY_CLASS); - $this->referenceMetadata = new ClassMetadata(self::REFERENCE_CLASS); - $this->metadataFactory->addMetadata($this->metadata); - $this->metadataFactory->addMetadata($this->referenceMetadata); - $this->metadataFactory->addMetadata(new ClassMetadata(self::LAZY_PROPERTY)); - } - - protected function tearDown(): void - { - $this->metadataFactory = null; - $this->metadata = null; - $this->referenceMetadata = null; - } - - abstract protected function validate($value, $constraints = null, $groups = null); - - abstract protected function validateProperty($object, $propertyName, $groups = null); - - abstract protected function validatePropertyValue($object, $propertyName, $value, $groups = null); - - public function testValidate() - { - $callback = function ($value, ExecutionContextInterface $context) { - $this->assertNull($context->getClassName()); - $this->assertNull($context->getPropertyName()); - $this->assertSame('', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame('Bernhard', $context->getRoot()); - $this->assertSame('Bernhard', $context->getValue()); - $this->assertSame('Bernhard', $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $constraint = new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ]); - - $violations = $this->validate('Bernhard', $constraint, 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('', $violations[0]->getPropertyPath()); - $this->assertSame('Bernhard', $violations[0]->getRoot()); - $this->assertSame('Bernhard', $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - public function testClassConstraint() - { - $entity = new Entity(); - - $callback = function ($value, ExecutionContextInterface $context) use ($entity) { - $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); - $this->assertNull($context->getPropertyName()); - $this->assertSame('', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($this->metadata, $context->getMetadata()); - $this->assertSame($entity, $context->getRoot()); - $this->assertSame($entity, $context->getValue()); - $this->assertSame($entity, $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - - $violations = $this->validate($entity, null, 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('', $violations[0]->getPropertyPath()); - $this->assertSame($entity, $violations[0]->getRoot()); - $this->assertSame($entity, $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - public function testPropertyConstraint() - { - $entity = new Entity(); - $entity->firstName = 'Bernhard'; - - $callback = function ($value, ExecutionContextInterface $context) use ($entity) { - $propertyMetadatas = $this->metadata->getPropertyMetadata('firstName'); - - $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); - $this->assertSame('firstName', $context->getPropertyName()); - $this->assertSame('firstName', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($propertyMetadatas[0], $context->getMetadata()); - $this->assertSame($entity, $context->getRoot()); - $this->assertSame('Bernhard', $context->getValue()); - $this->assertSame('Bernhard', $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadata->addPropertyConstraint('firstName', new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - - $violations = $this->validate($entity, null, 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('firstName', $violations[0]->getPropertyPath()); - $this->assertSame($entity, $violations[0]->getRoot()); - $this->assertSame('Bernhard', $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - public function testGetterConstraint() - { - $entity = new Entity(); - $entity->setLastName('Schussek'); - - $callback = function ($value, ExecutionContextInterface $context) use ($entity) { - $propertyMetadatas = $this->metadata->getPropertyMetadata('lastName'); - - $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); - $this->assertSame('lastName', $context->getPropertyName()); - $this->assertSame('lastName', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($propertyMetadatas[0], $context->getMetadata()); - $this->assertSame($entity, $context->getRoot()); - $this->assertSame('Schussek', $context->getValue()); - $this->assertSame('Schussek', $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadata->addGetterConstraint('lastName', new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - - $violations = $this->validate($entity, null, 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('lastName', $violations[0]->getPropertyPath()); - $this->assertSame($entity, $violations[0]->getRoot()); - $this->assertSame('Schussek', $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - public function testArray() - { - $entity = new Entity(); - $array = ['key' => $entity]; - - $callback = function ($value, ExecutionContextInterface $context) use ($entity, $array) { - $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); - $this->assertNull($context->getPropertyName()); - $this->assertSame('[key]', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($this->metadata, $context->getMetadata()); - $this->assertSame($array, $context->getRoot()); - $this->assertSame($entity, $context->getValue()); - $this->assertSame($entity, $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - - $violations = $this->validate($array, null, 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('[key]', $violations[0]->getPropertyPath()); - $this->assertSame($array, $violations[0]->getRoot()); - $this->assertSame($entity, $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - public function testRecursiveArray() - { - $entity = new Entity(); - $array = [2 => ['key' => $entity]]; - - $callback = function ($value, ExecutionContextInterface $context) use ($entity, $array) { - $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); - $this->assertNull($context->getPropertyName()); - $this->assertSame('[2][key]', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($this->metadata, $context->getMetadata()); - $this->assertSame($array, $context->getRoot()); - $this->assertSame($entity, $context->getValue()); - $this->assertSame($entity, $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - - $violations = $this->validate($array, null, 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('[2][key]', $violations[0]->getPropertyPath()); - $this->assertSame($array, $violations[0]->getRoot()); - $this->assertSame($entity, $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - public function testTraversable() - { - $entity = new Entity(); - $traversable = new \ArrayIterator(['key' => $entity]); - - $callback = function ($value, ExecutionContextInterface $context) use ($entity, $traversable) { - $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); - $this->assertNull($context->getPropertyName()); - $this->assertSame('[key]', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($this->metadata, $context->getMetadata()); - $this->assertSame($traversable, $context->getRoot()); - $this->assertSame($entity, $context->getValue()); - $this->assertSame($entity, $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - - $violations = $this->validate($traversable, null, 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('[key]', $violations[0]->getPropertyPath()); - $this->assertSame($traversable, $violations[0]->getRoot()); - $this->assertSame($entity, $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - public function testRecursiveTraversable() - { - $entity = new Entity(); - $traversable = new \ArrayIterator([ - 2 => new \ArrayIterator(['key' => $entity]), - ]); - - $callback = function ($value, ExecutionContextInterface $context) use ($entity, $traversable) { - $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); - $this->assertNull($context->getPropertyName()); - $this->assertSame('[2][key]', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($this->metadata, $context->getMetadata()); - $this->assertSame($traversable, $context->getRoot()); - $this->assertSame($entity, $context->getValue()); - $this->assertSame($entity, $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - - $violations = $this->validate($traversable, null, 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('[2][key]', $violations[0]->getPropertyPath()); - $this->assertSame($traversable, $violations[0]->getRoot()); - $this->assertSame($entity, $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - public function testReferenceClassConstraint() - { - $entity = new Entity(); - $entity->reference = new Reference(); - - $callback = function ($value, ExecutionContextInterface $context) use ($entity) { - $this->assertSame($this::REFERENCE_CLASS, $context->getClassName()); - $this->assertNull($context->getPropertyName()); - $this->assertSame('reference', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($this->referenceMetadata, $context->getMetadata()); - $this->assertSame($entity, $context->getRoot()); - $this->assertSame($entity->reference, $context->getValue()); - $this->assertSame($entity->reference, $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadata->addPropertyConstraint('reference', new Valid()); - $this->referenceMetadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - - $violations = $this->validate($entity, null, 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('reference', $violations[0]->getPropertyPath()); - $this->assertSame($entity, $violations[0]->getRoot()); - $this->assertSame($entity->reference, $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - public function testReferencePropertyConstraint() - { - $entity = new Entity(); - $entity->reference = new Reference(); - $entity->reference->value = 'Foobar'; - - $callback = function ($value, ExecutionContextInterface $context) use ($entity) { - $propertyMetadatas = $this->referenceMetadata->getPropertyMetadata('value'); - - $this->assertSame($this::REFERENCE_CLASS, $context->getClassName()); - $this->assertSame('value', $context->getPropertyName()); - $this->assertSame('reference.value', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($propertyMetadatas[0], $context->getMetadata()); - $this->assertSame($entity, $context->getRoot()); - $this->assertSame('Foobar', $context->getValue()); - $this->assertSame('Foobar', $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadata->addPropertyConstraint('reference', new Valid()); - $this->referenceMetadata->addPropertyConstraint('value', new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - - $violations = $this->validate($entity, null, 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('reference.value', $violations[0]->getPropertyPath()); - $this->assertSame($entity, $violations[0]->getRoot()); - $this->assertSame('Foobar', $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - public function testReferenceGetterConstraint() - { - $entity = new Entity(); - $entity->reference = new Reference(); - $entity->reference->setPrivateValue('Bamboo'); - - $callback = function ($value, ExecutionContextInterface $context) use ($entity) { - $propertyMetadatas = $this->referenceMetadata->getPropertyMetadata('privateValue'); - - $this->assertSame($this::REFERENCE_CLASS, $context->getClassName()); - $this->assertSame('privateValue', $context->getPropertyName()); - $this->assertSame('reference.privateValue', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($propertyMetadatas[0], $context->getMetadata()); - $this->assertSame($entity, $context->getRoot()); - $this->assertSame('Bamboo', $context->getValue()); - $this->assertSame('Bamboo', $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadata->addPropertyConstraint('reference', new Valid()); - $this->referenceMetadata->addPropertyConstraint('privateValue', new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - - $violations = $this->validate($entity, null, 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('reference.privateValue', $violations[0]->getPropertyPath()); - $this->assertSame($entity, $violations[0]->getRoot()); - $this->assertSame('Bamboo', $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - public function testsIgnoreNullReference() - { - $entity = new Entity(); - $entity->reference = null; - - $this->metadata->addPropertyConstraint('reference', new Valid()); - - $violations = $this->validate($entity); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(0, $violations); - } - - public function testFailOnScalarReferences() - { - $this->expectException('Symfony\Component\Validator\Exception\NoSuchMetadataException'); - $entity = new Entity(); - $entity->reference = 'string'; - - $this->metadata->addPropertyConstraint('reference', new Valid()); - - $this->validate($entity); - } - - /** - * @dataProvider getConstraintMethods - */ - public function testArrayReference($constraintMethod) - { - $entity = new Entity(); - $entity->reference = ['key' => new Reference()]; - - $callback = function ($value, ExecutionContextInterface $context) use ($entity) { - $this->assertSame($this::REFERENCE_CLASS, $context->getClassName()); - $this->assertNull($context->getPropertyName()); - $this->assertSame('reference[key]', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($this->referenceMetadata, $context->getMetadata()); - $this->assertSame($entity, $context->getRoot()); - $this->assertSame($entity->reference['key'], $context->getValue()); - $this->assertSame($entity->reference['key'], $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadata->$constraintMethod('reference', new Valid()); - $this->referenceMetadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - - $violations = $this->validate($entity, null, 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('reference[key]', $violations[0]->getPropertyPath()); - $this->assertSame($entity, $violations[0]->getRoot()); - $this->assertSame($entity->reference['key'], $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - /** - * @dataProvider getConstraintMethods - */ - public function testRecursiveArrayReference($constraintMethod) - { - $entity = new Entity(); - $entity->reference = [2 => ['key' => new Reference()]]; - - $callback = function ($value, ExecutionContextInterface $context) use ($entity) { - $this->assertSame($this::REFERENCE_CLASS, $context->getClassName()); - $this->assertNull($context->getPropertyName()); - $this->assertSame('reference[2][key]', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($this->referenceMetadata, $context->getMetadata()); - $this->assertSame($entity, $context->getRoot()); - $this->assertSame($entity->reference[2]['key'], $context->getValue()); - $this->assertSame($entity->reference[2]['key'], $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadata->$constraintMethod('reference', new Valid()); - $this->referenceMetadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - - $violations = $this->validate($entity, null, 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('reference[2][key]', $violations[0]->getPropertyPath()); - $this->assertSame($entity, $violations[0]->getRoot()); - $this->assertSame($entity->reference[2]['key'], $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - public function testOnlyCascadedArraysAreTraversed() - { - $entity = new Entity(); - $entity->reference = ['key' => new Reference()]; - - $callback = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadata->addPropertyConstraint('reference', new Callback([ - 'callback' => function () {}, - 'groups' => 'Group', - ])); - $this->referenceMetadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - - $violations = $this->validate($entity, null, 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(0, $violations); - } - - /** - * @dataProvider getConstraintMethods - */ - public function testArrayTraversalCannotBeDisabled($constraintMethod) - { - $entity = new Entity(); - $entity->reference = ['key' => new Reference()]; - - $callback = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadata->$constraintMethod('reference', new Valid([ - 'traverse' => false, - ])); - $this->referenceMetadata->addConstraint(new Callback($callback)); - - $violations = $this->validate($entity); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - } - - /** - * @dataProvider getConstraintMethods - */ - public function testRecursiveArrayTraversalCannotBeDisabled($constraintMethod) - { - $entity = new Entity(); - $entity->reference = [2 => ['key' => new Reference()]]; - - $callback = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadata->$constraintMethod('reference', new Valid([ - 'traverse' => false, - ])); - - $this->referenceMetadata->addConstraint(new Callback($callback)); - - $violations = $this->validate($entity); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - } - - /** - * @dataProvider getConstraintMethods - */ - public function testIgnoreScalarsDuringArrayTraversal($constraintMethod) - { - $entity = new Entity(); - $entity->reference = ['string', 1234]; - - $this->metadata->$constraintMethod('reference', new Valid()); - - $violations = $this->validate($entity); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(0, $violations); - } - - /** - * @dataProvider getConstraintMethods - */ - public function testIgnoreNullDuringArrayTraversal($constraintMethod) - { - $entity = new Entity(); - $entity->reference = [null]; - - $this->metadata->$constraintMethod('reference', new Valid()); - - $violations = $this->validate($entity); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(0, $violations); - } - - public function testTraversableReference() - { - $entity = new Entity(); - $entity->reference = new \ArrayIterator(['key' => new Reference()]); - - $callback = function ($value, ExecutionContextInterface $context) use ($entity) { - $this->assertSame($this::REFERENCE_CLASS, $context->getClassName()); - $this->assertNull($context->getPropertyName()); - $this->assertSame('reference[key]', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($this->referenceMetadata, $context->getMetadata()); - $this->assertSame($entity, $context->getRoot()); - $this->assertSame($entity->reference['key'], $context->getValue()); - $this->assertSame($entity->reference['key'], $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadata->addPropertyConstraint('reference', new Valid()); - $this->referenceMetadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - - $violations = $this->validate($entity, null, 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('reference[key]', $violations[0]->getPropertyPath()); - $this->assertSame($entity, $violations[0]->getRoot()); - $this->assertSame($entity->reference['key'], $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - public function testDisableTraversableTraversal() - { - $entity = new Entity(); - $entity->reference = new \ArrayIterator(['key' => new Reference()]); - - $callback = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadataFactory->addMetadata(new ClassMetadata('ArrayIterator')); - $this->metadata->addPropertyConstraint('reference', new Valid([ - 'traverse' => false, - ])); - $this->referenceMetadata->addConstraint(new Callback($callback)); - - $violations = $this->validate($entity); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(0, $violations); - } - - public function testMetadataMustExistIfTraversalIsDisabled() - { - $this->expectException('Symfony\Component\Validator\Exception\NoSuchMetadataException'); - $entity = new Entity(); - $entity->reference = new \ArrayIterator(); - - $this->metadata->addPropertyConstraint('reference', new Valid([ - 'traverse' => false, - ])); - - $this->validate($entity); - } - - public function testEnableRecursiveTraversableTraversal() - { - $entity = new Entity(); - $entity->reference = new \ArrayIterator([ - 2 => new \ArrayIterator(['key' => new Reference()]), - ]); - - $callback = function ($value, ExecutionContextInterface $context) use ($entity) { - $this->assertSame($this::REFERENCE_CLASS, $context->getClassName()); - $this->assertNull($context->getPropertyName()); - $this->assertSame('reference[2][key]', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($this->referenceMetadata, $context->getMetadata()); - $this->assertSame($entity, $context->getRoot()); - $this->assertSame($entity->reference[2]['key'], $context->getValue()); - $this->assertSame($entity->reference[2]['key'], $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $this->metadata->addPropertyConstraint('reference', new Valid([ - 'traverse' => true, - ])); - $this->referenceMetadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group', - ])); - - $violations = $this->validate($entity, null, 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('reference[2][key]', $violations[0]->getPropertyPath()); - $this->assertSame($entity, $violations[0]->getRoot()); - $this->assertSame($entity->reference[2]['key'], $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - public function testValidateProperty() - { - $entity = new Entity(); - $entity->firstName = 'Bernhard'; - $entity->setLastName('Schussek'); - - $callback1 = function ($value, ExecutionContextInterface $context) use ($entity) { - $propertyMetadatas = $this->metadata->getPropertyMetadata('firstName'); - - $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); - $this->assertSame('firstName', $context->getPropertyName()); - $this->assertSame('firstName', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($propertyMetadatas[0], $context->getMetadata()); - $this->assertSame($entity, $context->getRoot()); - $this->assertSame('Bernhard', $context->getValue()); - $this->assertSame('Bernhard', $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $callback2 = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Other violation'); - }; - - $this->metadata->addPropertyConstraint('firstName', new Callback([ - 'callback' => $callback1, - 'groups' => 'Group', - ])); - $this->metadata->addPropertyConstraint('lastName', new Callback([ - 'callback' => $callback2, - 'groups' => 'Group', - ])); - - $violations = $this->validateProperty($entity, 'firstName', 'Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('firstName', $violations[0]->getPropertyPath()); - $this->assertSame($entity, $violations[0]->getRoot()); - $this->assertSame('Bernhard', $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - /** - * https://github.com/symfony/symfony/issues/11604. - */ - public function testValidatePropertyWithoutConstraints() - { - $entity = new Entity(); - $violations = $this->validateProperty($entity, 'lastName'); - - $this->assertCount(0, $violations, '->validateProperty() returns no violations if no constraints have been configured for the property being validated'); - } - - public function testValidatePropertyValue() - { - $entity = new Entity(); - $entity->setLastName('Schussek'); - - $callback1 = function ($value, ExecutionContextInterface $context) use ($entity) { - $propertyMetadatas = $this->metadata->getPropertyMetadata('firstName'); - - $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); - $this->assertSame('firstName', $context->getPropertyName()); - $this->assertSame('firstName', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($propertyMetadatas[0], $context->getMetadata()); - $this->assertSame($entity, $context->getRoot()); - $this->assertSame('Bernhard', $context->getValue()); - $this->assertSame('Bernhard', $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $callback2 = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Other violation'); - }; - - $this->metadata->addPropertyConstraint('firstName', new Callback([ - 'callback' => $callback1, - 'groups' => 'Group', - ])); - $this->metadata->addPropertyConstraint('lastName', new Callback([ - 'callback' => $callback2, - 'groups' => 'Group', - ])); - - $violations = $this->validatePropertyValue( - $entity, - 'firstName', - 'Bernhard', - 'Group' - ); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('firstName', $violations[0]->getPropertyPath()); - $this->assertSame($entity, $violations[0]->getRoot()); - $this->assertSame('Bernhard', $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - public function testValidatePropertyValueWithClassName() - { - $callback1 = function ($value, ExecutionContextInterface $context) { - $propertyMetadatas = $this->metadata->getPropertyMetadata('firstName'); - - $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); - $this->assertSame('firstName', $context->getPropertyName()); - $this->assertSame('', $context->getPropertyPath()); - $this->assertSame('Group', $context->getGroup()); - $this->assertSame($propertyMetadatas[0], $context->getMetadata()); - $this->assertSame('Bernhard', $context->getRoot()); - $this->assertSame('Bernhard', $context->getValue()); - $this->assertSame('Bernhard', $value); - - $context->addViolation('Message %param%', ['%param%' => 'value']); - }; - - $callback2 = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Other violation'); - }; - - $this->metadata->addPropertyConstraint('firstName', new Callback([ - 'callback' => $callback1, - 'groups' => 'Group', - ])); - $this->metadata->addPropertyConstraint('lastName', new Callback([ - 'callback' => $callback2, - 'groups' => 'Group', - ])); - - $violations = $this->validatePropertyValue( - self::ENTITY_CLASS, - 'firstName', - 'Bernhard', - 'Group' - ); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Message value', $violations[0]->getMessage()); - $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); - $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); - $this->assertSame('', $violations[0]->getPropertyPath()); - $this->assertSame('Bernhard', $violations[0]->getRoot()); - $this->assertSame('Bernhard', $violations[0]->getInvalidValue()); - $this->assertNull($violations[0]->getPlural()); - $this->assertNull($violations[0]->getCode()); - } - - /** - * https://github.com/symfony/symfony/issues/11604. - */ - public function testValidatePropertyValueWithoutConstraints() - { - $entity = new Entity(); - $violations = $this->validatePropertyValue($entity, 'lastName', 'foo'); - - $this->assertCount(0, $violations, '->validatePropertyValue() returns no violations if no constraints have been configured for the property being validated'); - } - - public function testValidateObjectOnlyOncePerGroup() - { - $entity = new Entity(); - $entity->reference = new Reference(); - $entity->reference2 = $entity->reference; - - $callback = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Message'); - }; - - $this->metadata->addPropertyConstraint('reference', new Valid()); - $this->metadata->addPropertyConstraint('reference2', new Valid()); - $this->referenceMetadata->addConstraint(new Callback($callback)); - - $violations = $this->validate($entity); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - } - - public function testValidateDifferentObjectsSeparately() - { - $entity = new Entity(); - $entity->reference = new Reference(); - $entity->reference2 = new Reference(); - - $callback = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Message'); - }; - - $this->metadata->addPropertyConstraint('reference', new Valid()); - $this->metadata->addPropertyConstraint('reference2', new Valid()); - $this->referenceMetadata->addConstraint(new Callback($callback)); - - $violations = $this->validate($entity); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(2, $violations); - } - - public function testValidateSingleGroup() - { - $entity = new Entity(); - - $callback = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Message'); - }; - - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group 1', - ])); - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group 2', - ])); - - $violations = $this->validate($entity, null, 'Group 2'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - } - - public function testValidateMultipleGroups() - { - $entity = new Entity(); - - $callback = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Message'); - }; - - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group 1', - ])); - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback, - 'groups' => 'Group 2', - ])); - - $violations = $this->validate($entity, null, ['Group 1', 'Group 2']); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(2, $violations); - } - - public function testReplaceDefaultGroupByGroupSequenceObject() - { - $entity = new Entity(); - - $callback1 = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Violation in Group 2'); - }; - $callback2 = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Violation in Group 3'); - }; - - $this->metadata->addConstraint(new Callback([ - 'callback' => function () {}, - 'groups' => 'Group 1', - ])); - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback1, - 'groups' => 'Group 2', - ])); - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback2, - 'groups' => 'Group 3', - ])); - - $sequence = new GroupSequence(['Group 1', 'Group 2', 'Group 3', 'Entity']); - $this->metadata->setGroupSequence($sequence); - - $violations = $this->validate($entity, null, 'Default'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Violation in Group 2', $violations[0]->getMessage()); - } - - public function testReplaceDefaultGroupByGroupSequenceArray() - { - $entity = new Entity(); - - $callback1 = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Violation in Group 2'); - }; - $callback2 = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Violation in Group 3'); - }; - - $this->metadata->addConstraint(new Callback([ - 'callback' => function () {}, - 'groups' => 'Group 1', - ])); - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback1, - 'groups' => 'Group 2', - ])); - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback2, - 'groups' => 'Group 3', - ])); - - $sequence = ['Group 1', 'Group 2', 'Group 3', 'Entity']; - $this->metadata->setGroupSequence($sequence); - - $violations = $this->validate($entity, null, 'Default'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Violation in Group 2', $violations[0]->getMessage()); - } - - public function testPropagateDefaultGroupToReferenceWhenReplacingDefaultGroup() - { - $entity = new Entity(); - $entity->reference = new Reference(); - - $callback1 = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Violation in Default group'); - }; - $callback2 = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Violation in group sequence'); - }; - - $this->metadata->addPropertyConstraint('reference', new Valid()); - $this->referenceMetadata->addConstraint(new Callback([ - 'callback' => $callback1, - 'groups' => 'Default', - ])); - $this->referenceMetadata->addConstraint(new Callback([ - 'callback' => $callback2, - 'groups' => 'Group 1', - ])); - - $sequence = new GroupSequence(['Group 1', 'Entity']); - $this->metadata->setGroupSequence($sequence); - - $violations = $this->validate($entity, null, 'Default'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Violation in Default group', $violations[0]->getMessage()); - } - - public function testValidateCustomGroupWhenDefaultGroupWasReplaced() - { - $entity = new Entity(); - - $callback1 = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Violation in other group'); - }; - $callback2 = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Violation in group sequence'); - }; - - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback1, - 'groups' => 'Other Group', - ])); - $this->metadata->addConstraint(new Callback([ - 'callback' => $callback2, - 'groups' => 'Group 1', - ])); - - $sequence = new GroupSequence(['Group 1', 'Entity']); - $this->metadata->setGroupSequence($sequence); - - $violations = $this->validate($entity, null, 'Other Group'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - $this->assertSame('Violation in other group', $violations[0]->getMessage()); - } - - /** - * @dataProvider getTestReplaceDefaultGroup - */ - public function testReplaceDefaultGroup($sequence, array $assertViolations) - { - $entity = new GroupSequenceProviderEntity($sequence); - - $callback1 = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Violation in Group 2'); - }; - $callback2 = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Violation in Group 3'); - }; - - $metadata = new ClassMetadata(\get_class($entity)); - $metadata->addConstraint(new Callback([ - 'callback' => function () {}, - 'groups' => 'Group 1', - ])); - $metadata->addConstraint(new Callback([ - 'callback' => $callback1, - 'groups' => 'Group 2', - ])); - $metadata->addConstraint(new Callback([ - 'callback' => $callback2, - 'groups' => 'Group 3', - ])); - $metadata->setGroupSequenceProvider(true); - - $this->metadataFactory->addMetadata($metadata); - - $violations = $this->validate($entity, null, 'Default'); - - /* @var ConstraintViolationInterface[] $violations */ - $this->assertCount(\count($assertViolations), $violations); - foreach ($assertViolations as $key => $message) { - $this->assertSame($message, $violations[$key]->getMessage()); - } - } - - public function getConstraintMethods() - { - return [ - ['addPropertyConstraint'], - ['addGetterConstraint'], - ]; - } - - public function getTestReplaceDefaultGroup() - { - return [ - [ - 'sequence' => new GroupSequence(['Group 1', 'Group 2', 'Group 3', 'Entity']), - 'assertViolations' => [ - 'Violation in Group 2', - ], - ], - [ - 'sequence' => ['Group 1', 'Group 2', 'Group 3', 'Entity'], - 'assertViolations' => [ - 'Violation in Group 2', - ], - ], - [ - 'sequence' => new GroupSequence(['Group 1', ['Group 2', 'Group 3'], 'Entity']), - 'assertViolations' => [ - 'Violation in Group 2', - 'Violation in Group 3', - ], - ], - [ - 'sequence' => ['Group 1', ['Group 2', 'Group 3'], 'Entity'], - 'assertViolations' => [ - 'Violation in Group 2', - 'Violation in Group 3', - ], - ], - ]; - } -} diff --git a/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php b/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php index 48de5820fc106..1af4c9acfa9bd 100644 --- a/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php @@ -11,9 +11,12 @@ namespace Symfony\Component\Validator\Tests\Validator; +use PHPUnit\Framework\TestCase; use Symfony\Component\Translation\IdentityTranslator; use Symfony\Component\Validator\Constraints\All; +use Symfony\Component\Validator\Constraints\Callback; use Symfony\Component\Validator\Constraints\Collection; +use Symfony\Component\Validator\Constraints\Expression; use Symfony\Component\Validator\Constraints\GroupSequence; use Symfony\Component\Validator\Constraints\IsTrue; use Symfony\Component\Validator\Constraints\Length; @@ -21,9 +24,12 @@ use Symfony\Component\Validator\Constraints\NotNull; use Symfony\Component\Validator\Constraints\Optional; use Symfony\Component\Validator\Constraints\Required; +use Symfony\Component\Validator\Constraints\Traverse; use Symfony\Component\Validator\Constraints\Valid; use Symfony\Component\Validator\ConstraintValidatorFactory; +use Symfony\Component\Validator\ConstraintViolationInterface; use Symfony\Component\Validator\Context\ExecutionContextFactory; +use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface; use Symfony\Component\Validator\Tests\Constraints\Fixtures\ChildA; @@ -31,11 +37,1938 @@ use Symfony\Component\Validator\Tests\Fixtures\Entity; use Symfony\Component\Validator\Tests\Fixtures\EntityParent; use Symfony\Component\Validator\Tests\Fixtures\EntityWithGroupedConstraintOnMethods; +use Symfony\Component\Validator\Tests\Fixtures\FailingConstraint; +use Symfony\Component\Validator\Tests\Fixtures\FakeMetadataFactory; +use Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity; +use Symfony\Component\Validator\Tests\Fixtures\Reference; +use Symfony\Component\Validator\Validator\LazyProperty; use Symfony\Component\Validator\Validator\RecursiveValidator; use Symfony\Component\Validator\Validator\ValidatorInterface; -class RecursiveValidatorTest extends AbstractTest +class RecursiveValidatorTest extends TestCase { + private const ENTITY_CLASS = Entity::class; + private const REFERENCE_CLASS = Reference::class; + + /** + * @var FakeMetadataFactory + */ + private $metadataFactory; + + /** + * @var ClassMetadata + */ + private $metadata; + + /** + * @var ClassMetadata + */ + private $referenceMetadata; + + /** + * @var ValidatorInterface + */ + private $validator; + + protected function setUp(): void + { + $this->metadataFactory = new FakeMetadataFactory(); + $this->metadata = new ClassMetadata(self::ENTITY_CLASS); + $this->referenceMetadata = new ClassMetadata(self::REFERENCE_CLASS); + $this->metadataFactory->addMetadata($this->metadata); + $this->metadataFactory->addMetadata($this->referenceMetadata); + $this->metadataFactory->addMetadata(new ClassMetadata(LazyProperty::class)); + + $this->validator = $this->createValidator($this->metadataFactory); + } + + protected function tearDown(): void + { + $this->metadataFactory = null; + $this->metadata = null; + $this->referenceMetadata = null; + } + + protected function validate($value, $constraints = null, $groups = null) + { + return $this->validator->validate($value, $constraints, $groups); + } + + protected function validateProperty($object, $propertyName, $groups = null) + { + return $this->validator->validateProperty($object, $propertyName, $groups); + } + + protected function validatePropertyValue($object, $propertyName, $value, $groups = null) + { + return $this->validator->validatePropertyValue($object, $propertyName, $value, $groups); + } + + public function testValidate() + { + $callback = function ($value, ExecutionContextInterface $context) { + $this->assertNull($context->getClassName()); + $this->assertNull($context->getPropertyName()); + $this->assertSame('', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame('Bernhard', $context->getRoot()); + $this->assertSame('Bernhard', $context->getValue()); + $this->assertSame('Bernhard', $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $constraint = new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ]); + + $violations = $this->validate('Bernhard', $constraint, 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('', $violations[0]->getPropertyPath()); + $this->assertSame('Bernhard', $violations[0]->getRoot()); + $this->assertSame('Bernhard', $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + public function testClassConstraint() + { + $entity = new Entity(); + + $callback = function ($value, ExecutionContextInterface $context) use ($entity) { + $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); + $this->assertNull($context->getPropertyName()); + $this->assertSame('', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($this->metadata, $context->getMetadata()); + $this->assertSame($entity, $context->getRoot()); + $this->assertSame($entity, $context->getValue()); + $this->assertSame($entity, $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + + $violations = $this->validate($entity, null, 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('', $violations[0]->getPropertyPath()); + $this->assertSame($entity, $violations[0]->getRoot()); + $this->assertSame($entity, $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + public function testPropertyConstraint() + { + $entity = new Entity(); + $entity->firstName = 'Bernhard'; + + $callback = function ($value, ExecutionContextInterface $context) use ($entity) { + $propertyMetadatas = $this->metadata->getPropertyMetadata('firstName'); + + $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); + $this->assertSame('firstName', $context->getPropertyName()); + $this->assertSame('firstName', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($propertyMetadatas[0], $context->getMetadata()); + $this->assertSame($entity, $context->getRoot()); + $this->assertSame('Bernhard', $context->getValue()); + $this->assertSame('Bernhard', $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadata->addPropertyConstraint('firstName', new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + + $violations = $this->validate($entity, null, 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('firstName', $violations[0]->getPropertyPath()); + $this->assertSame($entity, $violations[0]->getRoot()); + $this->assertSame('Bernhard', $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + public function testGetterConstraint() + { + $entity = new Entity(); + $entity->setLastName('Schussek'); + + $callback = function ($value, ExecutionContextInterface $context) use ($entity) { + $propertyMetadatas = $this->metadata->getPropertyMetadata('lastName'); + + $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); + $this->assertSame('lastName', $context->getPropertyName()); + $this->assertSame('lastName', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($propertyMetadatas[0], $context->getMetadata()); + $this->assertSame($entity, $context->getRoot()); + $this->assertSame('Schussek', $context->getValue()); + $this->assertSame('Schussek', $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadata->addGetterConstraint('lastName', new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + + $violations = $this->validate($entity, null, 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('lastName', $violations[0]->getPropertyPath()); + $this->assertSame($entity, $violations[0]->getRoot()); + $this->assertSame('Schussek', $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + public function testArray() + { + $entity = new Entity(); + $array = ['key' => $entity]; + + $callback = function ($value, ExecutionContextInterface $context) use ($entity, $array) { + $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); + $this->assertNull($context->getPropertyName()); + $this->assertSame('[key]', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($this->metadata, $context->getMetadata()); + $this->assertSame($array, $context->getRoot()); + $this->assertSame($entity, $context->getValue()); + $this->assertSame($entity, $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + + $violations = $this->validate($array, null, 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('[key]', $violations[0]->getPropertyPath()); + $this->assertSame($array, $violations[0]->getRoot()); + $this->assertSame($entity, $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + public function testRecursiveArray() + { + $entity = new Entity(); + $array = [2 => ['key' => $entity]]; + + $callback = function ($value, ExecutionContextInterface $context) use ($entity, $array) { + $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); + $this->assertNull($context->getPropertyName()); + $this->assertSame('[2][key]', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($this->metadata, $context->getMetadata()); + $this->assertSame($array, $context->getRoot()); + $this->assertSame($entity, $context->getValue()); + $this->assertSame($entity, $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + + $violations = $this->validate($array, null, 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('[2][key]', $violations[0]->getPropertyPath()); + $this->assertSame($array, $violations[0]->getRoot()); + $this->assertSame($entity, $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + public function testTraversable() + { + $entity = new Entity(); + $traversable = new \ArrayIterator(['key' => $entity]); + + $callback = function ($value, ExecutionContextInterface $context) use ($entity, $traversable) { + $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); + $this->assertNull($context->getPropertyName()); + $this->assertSame('[key]', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($this->metadata, $context->getMetadata()); + $this->assertSame($traversable, $context->getRoot()); + $this->assertSame($entity, $context->getValue()); + $this->assertSame($entity, $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + + $violations = $this->validate($traversable, null, 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('[key]', $violations[0]->getPropertyPath()); + $this->assertSame($traversable, $violations[0]->getRoot()); + $this->assertSame($entity, $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + public function testRecursiveTraversable() + { + $entity = new Entity(); + $traversable = new \ArrayIterator([ + 2 => new \ArrayIterator(['key' => $entity]), + ]); + + $callback = function ($value, ExecutionContextInterface $context) use ($entity, $traversable) { + $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); + $this->assertNull($context->getPropertyName()); + $this->assertSame('[2][key]', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($this->metadata, $context->getMetadata()); + $this->assertSame($traversable, $context->getRoot()); + $this->assertSame($entity, $context->getValue()); + $this->assertSame($entity, $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + + $violations = $this->validate($traversable, null, 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('[2][key]', $violations[0]->getPropertyPath()); + $this->assertSame($traversable, $violations[0]->getRoot()); + $this->assertSame($entity, $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + public function testReferenceClassConstraint() + { + $entity = new Entity(); + $entity->reference = new Reference(); + + $callback = function ($value, ExecutionContextInterface $context) use ($entity) { + $this->assertSame($this::REFERENCE_CLASS, $context->getClassName()); + $this->assertNull($context->getPropertyName()); + $this->assertSame('reference', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($this->referenceMetadata, $context->getMetadata()); + $this->assertSame($entity, $context->getRoot()); + $this->assertSame($entity->reference, $context->getValue()); + $this->assertSame($entity->reference, $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadata->addPropertyConstraint('reference', new Valid()); + $this->referenceMetadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + + $violations = $this->validate($entity, null, 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('reference', $violations[0]->getPropertyPath()); + $this->assertSame($entity, $violations[0]->getRoot()); + $this->assertSame($entity->reference, $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + public function testReferencePropertyConstraint() + { + $entity = new Entity(); + $entity->reference = new Reference(); + $entity->reference->value = 'Foobar'; + + $callback = function ($value, ExecutionContextInterface $context) use ($entity) { + $propertyMetadatas = $this->referenceMetadata->getPropertyMetadata('value'); + + $this->assertSame($this::REFERENCE_CLASS, $context->getClassName()); + $this->assertSame('value', $context->getPropertyName()); + $this->assertSame('reference.value', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($propertyMetadatas[0], $context->getMetadata()); + $this->assertSame($entity, $context->getRoot()); + $this->assertSame('Foobar', $context->getValue()); + $this->assertSame('Foobar', $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadata->addPropertyConstraint('reference', new Valid()); + $this->referenceMetadata->addPropertyConstraint('value', new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + + $violations = $this->validate($entity, null, 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('reference.value', $violations[0]->getPropertyPath()); + $this->assertSame($entity, $violations[0]->getRoot()); + $this->assertSame('Foobar', $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + public function testReferenceGetterConstraint() + { + $entity = new Entity(); + $entity->reference = new Reference(); + $entity->reference->setPrivateValue('Bamboo'); + + $callback = function ($value, ExecutionContextInterface $context) use ($entity) { + $propertyMetadatas = $this->referenceMetadata->getPropertyMetadata('privateValue'); + + $this->assertSame($this::REFERENCE_CLASS, $context->getClassName()); + $this->assertSame('privateValue', $context->getPropertyName()); + $this->assertSame('reference.privateValue', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($propertyMetadatas[0], $context->getMetadata()); + $this->assertSame($entity, $context->getRoot()); + $this->assertSame('Bamboo', $context->getValue()); + $this->assertSame('Bamboo', $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadata->addPropertyConstraint('reference', new Valid()); + $this->referenceMetadata->addPropertyConstraint('privateValue', new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + + $violations = $this->validate($entity, null, 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('reference.privateValue', $violations[0]->getPropertyPath()); + $this->assertSame($entity, $violations[0]->getRoot()); + $this->assertSame('Bamboo', $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + public function testsIgnoreNullReference() + { + $entity = new Entity(); + $entity->reference = null; + + $this->metadata->addPropertyConstraint('reference', new Valid()); + + $violations = $this->validate($entity); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(0, $violations); + } + + public function testFailOnScalarReferences() + { + $this->expectException('Symfony\Component\Validator\Exception\NoSuchMetadataException'); + $entity = new Entity(); + $entity->reference = 'string'; + + $this->metadata->addPropertyConstraint('reference', new Valid()); + + $this->validate($entity); + } + + /** + * @dataProvider getConstraintMethods + */ + public function testArrayReference($constraintMethod) + { + $entity = new Entity(); + $entity->reference = ['key' => new Reference()]; + + $callback = function ($value, ExecutionContextInterface $context) use ($entity) { + $this->assertSame($this::REFERENCE_CLASS, $context->getClassName()); + $this->assertNull($context->getPropertyName()); + $this->assertSame('reference[key]', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($this->referenceMetadata, $context->getMetadata()); + $this->assertSame($entity, $context->getRoot()); + $this->assertSame($entity->reference['key'], $context->getValue()); + $this->assertSame($entity->reference['key'], $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadata->$constraintMethod('reference', new Valid()); + $this->referenceMetadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + + $violations = $this->validate($entity, null, 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('reference[key]', $violations[0]->getPropertyPath()); + $this->assertSame($entity, $violations[0]->getRoot()); + $this->assertSame($entity->reference['key'], $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + /** + * @dataProvider getConstraintMethods + */ + public function testRecursiveArrayReference($constraintMethod) + { + $entity = new Entity(); + $entity->reference = [2 => ['key' => new Reference()]]; + + $callback = function ($value, ExecutionContextInterface $context) use ($entity) { + $this->assertSame($this::REFERENCE_CLASS, $context->getClassName()); + $this->assertNull($context->getPropertyName()); + $this->assertSame('reference[2][key]', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($this->referenceMetadata, $context->getMetadata()); + $this->assertSame($entity, $context->getRoot()); + $this->assertSame($entity->reference[2]['key'], $context->getValue()); + $this->assertSame($entity->reference[2]['key'], $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadata->$constraintMethod('reference', new Valid()); + $this->referenceMetadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + + $violations = $this->validate($entity, null, 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('reference[2][key]', $violations[0]->getPropertyPath()); + $this->assertSame($entity, $violations[0]->getRoot()); + $this->assertSame($entity->reference[2]['key'], $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + public function testOnlyCascadedArraysAreTraversed() + { + $entity = new Entity(); + $entity->reference = ['key' => new Reference()]; + + $callback = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadata->addPropertyConstraint('reference', new Callback([ + 'callback' => function () {}, + 'groups' => 'Group', + ])); + $this->referenceMetadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + + $violations = $this->validate($entity, null, 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(0, $violations); + } + + /** + * @dataProvider getConstraintMethods + */ + public function testArrayTraversalCannotBeDisabled($constraintMethod) + { + $entity = new Entity(); + $entity->reference = ['key' => new Reference()]; + + $callback = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadata->$constraintMethod('reference', new Valid([ + 'traverse' => false, + ])); + $this->referenceMetadata->addConstraint(new Callback($callback)); + + $violations = $this->validate($entity); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + } + + /** + * @dataProvider getConstraintMethods + */ + public function testRecursiveArrayTraversalCannotBeDisabled($constraintMethod) + { + $entity = new Entity(); + $entity->reference = [2 => ['key' => new Reference()]]; + + $callback = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadata->$constraintMethod('reference', new Valid([ + 'traverse' => false, + ])); + + $this->referenceMetadata->addConstraint(new Callback($callback)); + + $violations = $this->validate($entity); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + } + + /** + * @dataProvider getConstraintMethods + */ + public function testIgnoreScalarsDuringArrayTraversal($constraintMethod) + { + $entity = new Entity(); + $entity->reference = ['string', 1234]; + + $this->metadata->$constraintMethod('reference', new Valid()); + + $violations = $this->validate($entity); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(0, $violations); + } + + /** + * @dataProvider getConstraintMethods + */ + public function testIgnoreNullDuringArrayTraversal($constraintMethod) + { + $entity = new Entity(); + $entity->reference = [null]; + + $this->metadata->$constraintMethod('reference', new Valid()); + + $violations = $this->validate($entity); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(0, $violations); + } + + public function testTraversableReference() + { + $entity = new Entity(); + $entity->reference = new \ArrayIterator(['key' => new Reference()]); + + $callback = function ($value, ExecutionContextInterface $context) use ($entity) { + $this->assertSame($this::REFERENCE_CLASS, $context->getClassName()); + $this->assertNull($context->getPropertyName()); + $this->assertSame('reference[key]', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($this->referenceMetadata, $context->getMetadata()); + $this->assertSame($entity, $context->getRoot()); + $this->assertSame($entity->reference['key'], $context->getValue()); + $this->assertSame($entity->reference['key'], $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadata->addPropertyConstraint('reference', new Valid()); + $this->referenceMetadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + + $violations = $this->validate($entity, null, 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('reference[key]', $violations[0]->getPropertyPath()); + $this->assertSame($entity, $violations[0]->getRoot()); + $this->assertSame($entity->reference['key'], $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + public function testDisableTraversableTraversal() + { + $entity = new Entity(); + $entity->reference = new \ArrayIterator(['key' => new Reference()]); + + $callback = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadataFactory->addMetadata(new ClassMetadata('ArrayIterator')); + $this->metadata->addPropertyConstraint('reference', new Valid([ + 'traverse' => false, + ])); + $this->referenceMetadata->addConstraint(new Callback($callback)); + + $violations = $this->validate($entity); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(0, $violations); + } + + public function testMetadataMustExistIfTraversalIsDisabled() + { + $this->expectException('Symfony\Component\Validator\Exception\NoSuchMetadataException'); + $entity = new Entity(); + $entity->reference = new \ArrayIterator(); + + $this->metadata->addPropertyConstraint('reference', new Valid([ + 'traverse' => false, + ])); + + $this->validate($entity); + } + + public function testEnableRecursiveTraversableTraversal() + { + $entity = new Entity(); + $entity->reference = new \ArrayIterator([ + 2 => new \ArrayIterator(['key' => new Reference()]), + ]); + + $callback = function ($value, ExecutionContextInterface $context) use ($entity) { + $this->assertSame($this::REFERENCE_CLASS, $context->getClassName()); + $this->assertNull($context->getPropertyName()); + $this->assertSame('reference[2][key]', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($this->referenceMetadata, $context->getMetadata()); + $this->assertSame($entity, $context->getRoot()); + $this->assertSame($entity->reference[2]['key'], $context->getValue()); + $this->assertSame($entity->reference[2]['key'], $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadata->addPropertyConstraint('reference', new Valid([ + 'traverse' => true, + ])); + $this->referenceMetadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + + $violations = $this->validate($entity, null, 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('reference[2][key]', $violations[0]->getPropertyPath()); + $this->assertSame($entity, $violations[0]->getRoot()); + $this->assertSame($entity->reference[2]['key'], $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + public function testValidateProperty() + { + $entity = new Entity(); + $entity->firstName = 'Bernhard'; + $entity->setLastName('Schussek'); + + $callback1 = function ($value, ExecutionContextInterface $context) use ($entity) { + $propertyMetadatas = $this->metadata->getPropertyMetadata('firstName'); + + $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); + $this->assertSame('firstName', $context->getPropertyName()); + $this->assertSame('firstName', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($propertyMetadatas[0], $context->getMetadata()); + $this->assertSame($entity, $context->getRoot()); + $this->assertSame('Bernhard', $context->getValue()); + $this->assertSame('Bernhard', $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $callback2 = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Other violation'); + }; + + $this->metadata->addPropertyConstraint('firstName', new Callback([ + 'callback' => $callback1, + 'groups' => 'Group', + ])); + $this->metadata->addPropertyConstraint('lastName', new Callback([ + 'callback' => $callback2, + 'groups' => 'Group', + ])); + + $violations = $this->validateProperty($entity, 'firstName', 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('firstName', $violations[0]->getPropertyPath()); + $this->assertSame($entity, $violations[0]->getRoot()); + $this->assertSame('Bernhard', $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + /** + * https://github.com/symfony/symfony/issues/11604. + */ + public function testValidatePropertyWithoutConstraints() + { + $entity = new Entity(); + $violations = $this->validateProperty($entity, 'lastName'); + + $this->assertCount(0, $violations, '->validateProperty() returns no violations if no constraints have been configured for the property being validated'); + } + + public function testValidatePropertyValue() + { + $entity = new Entity(); + $entity->setLastName('Schussek'); + + $callback1 = function ($value, ExecutionContextInterface $context) use ($entity) { + $propertyMetadatas = $this->metadata->getPropertyMetadata('firstName'); + + $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); + $this->assertSame('firstName', $context->getPropertyName()); + $this->assertSame('firstName', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($propertyMetadatas[0], $context->getMetadata()); + $this->assertSame($entity, $context->getRoot()); + $this->assertSame('Bernhard', $context->getValue()); + $this->assertSame('Bernhard', $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $callback2 = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Other violation'); + }; + + $this->metadata->addPropertyConstraint('firstName', new Callback([ + 'callback' => $callback1, + 'groups' => 'Group', + ])); + $this->metadata->addPropertyConstraint('lastName', new Callback([ + 'callback' => $callback2, + 'groups' => 'Group', + ])); + + $violations = $this->validatePropertyValue( + $entity, + 'firstName', + 'Bernhard', + 'Group' + ); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('firstName', $violations[0]->getPropertyPath()); + $this->assertSame($entity, $violations[0]->getRoot()); + $this->assertSame('Bernhard', $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + public function testValidatePropertyValueWithClassName() + { + $callback1 = function ($value, ExecutionContextInterface $context) { + $propertyMetadatas = $this->metadata->getPropertyMetadata('firstName'); + + $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); + $this->assertSame('firstName', $context->getPropertyName()); + $this->assertSame('', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($propertyMetadatas[0], $context->getMetadata()); + $this->assertSame('Bernhard', $context->getRoot()); + $this->assertSame('Bernhard', $context->getValue()); + $this->assertSame('Bernhard', $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $callback2 = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Other violation'); + }; + + $this->metadata->addPropertyConstraint('firstName', new Callback([ + 'callback' => $callback1, + 'groups' => 'Group', + ])); + $this->metadata->addPropertyConstraint('lastName', new Callback([ + 'callback' => $callback2, + 'groups' => 'Group', + ])); + + $violations = $this->validatePropertyValue( + self::ENTITY_CLASS, + 'firstName', + 'Bernhard', + 'Group' + ); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('', $violations[0]->getPropertyPath()); + $this->assertSame('Bernhard', $violations[0]->getRoot()); + $this->assertSame('Bernhard', $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + /** + * https://github.com/symfony/symfony/issues/11604. + */ + public function testValidatePropertyValueWithoutConstraints() + { + $entity = new Entity(); + $violations = $this->validatePropertyValue($entity, 'lastName', 'foo'); + + $this->assertCount(0, $violations, '->validatePropertyValue() returns no violations if no constraints have been configured for the property being validated'); + } + + public function testValidateObjectOnlyOncePerGroup() + { + $entity = new Entity(); + $entity->reference = new Reference(); + $entity->reference2 = $entity->reference; + + $callback = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Message'); + }; + + $this->metadata->addPropertyConstraint('reference', new Valid()); + $this->metadata->addPropertyConstraint('reference2', new Valid()); + $this->referenceMetadata->addConstraint(new Callback($callback)); + + $violations = $this->validate($entity); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + } + + public function testValidateDifferentObjectsSeparately() + { + $entity = new Entity(); + $entity->reference = new Reference(); + $entity->reference2 = new Reference(); + + $callback = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Message'); + }; + + $this->metadata->addPropertyConstraint('reference', new Valid()); + $this->metadata->addPropertyConstraint('reference2', new Valid()); + $this->referenceMetadata->addConstraint(new Callback($callback)); + + $violations = $this->validate($entity); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(2, $violations); + } + + public function testValidateSingleGroup() + { + $entity = new Entity(); + + $callback = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Message'); + }; + + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group 1', + ])); + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group 2', + ])); + + $violations = $this->validate($entity, null, 'Group 2'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + } + + public function testValidateMultipleGroups() + { + $entity = new Entity(); + + $callback = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Message'); + }; + + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group 1', + ])); + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group 2', + ])); + + $violations = $this->validate($entity, null, ['Group 1', 'Group 2']); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(2, $violations); + } + + public function testReplaceDefaultGroupByGroupSequenceObject() + { + $entity = new Entity(); + + $callback1 = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Violation in Group 2'); + }; + $callback2 = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Violation in Group 3'); + }; + + $this->metadata->addConstraint(new Callback([ + 'callback' => function () {}, + 'groups' => 'Group 1', + ])); + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback1, + 'groups' => 'Group 2', + ])); + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback2, + 'groups' => 'Group 3', + ])); + + $sequence = new GroupSequence(['Group 1', 'Group 2', 'Group 3', 'Entity']); + $this->metadata->setGroupSequence($sequence); + + $violations = $this->validate($entity, null, 'Default'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Violation in Group 2', $violations[0]->getMessage()); + } + + public function testReplaceDefaultGroupByGroupSequenceArray() + { + $entity = new Entity(); + + $callback1 = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Violation in Group 2'); + }; + $callback2 = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Violation in Group 3'); + }; + + $this->metadata->addConstraint(new Callback([ + 'callback' => function () {}, + 'groups' => 'Group 1', + ])); + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback1, + 'groups' => 'Group 2', + ])); + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback2, + 'groups' => 'Group 3', + ])); + + $sequence = ['Group 1', 'Group 2', 'Group 3', 'Entity']; + $this->metadata->setGroupSequence($sequence); + + $violations = $this->validate($entity, null, 'Default'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Violation in Group 2', $violations[0]->getMessage()); + } + + public function testPropagateDefaultGroupToReferenceWhenReplacingDefaultGroup() + { + $entity = new Entity(); + $entity->reference = new Reference(); + + $callback1 = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Violation in Default group'); + }; + $callback2 = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Violation in group sequence'); + }; + + $this->metadata->addPropertyConstraint('reference', new Valid()); + $this->referenceMetadata->addConstraint(new Callback([ + 'callback' => $callback1, + 'groups' => 'Default', + ])); + $this->referenceMetadata->addConstraint(new Callback([ + 'callback' => $callback2, + 'groups' => 'Group 1', + ])); + + $sequence = new GroupSequence(['Group 1', 'Entity']); + $this->metadata->setGroupSequence($sequence); + + $violations = $this->validate($entity, null, 'Default'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Violation in Default group', $violations[0]->getMessage()); + } + + public function testValidateCustomGroupWhenDefaultGroupWasReplaced() + { + $entity = new Entity(); + + $callback1 = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Violation in other group'); + }; + $callback2 = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Violation in group sequence'); + }; + + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback1, + 'groups' => 'Other Group', + ])); + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback2, + 'groups' => 'Group 1', + ])); + + $sequence = new GroupSequence(['Group 1', 'Entity']); + $this->metadata->setGroupSequence($sequence); + + $violations = $this->validate($entity, null, 'Other Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Violation in other group', $violations[0]->getMessage()); + } + + /** + * @dataProvider getTestReplaceDefaultGroup + */ + public function testReplaceDefaultGroup($sequence, array $assertViolations) + { + $entity = new GroupSequenceProviderEntity($sequence); + + $callback1 = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Violation in Group 2'); + }; + $callback2 = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Violation in Group 3'); + }; + + $metadata = new ClassMetadata(\get_class($entity)); + $metadata->addConstraint(new Callback([ + 'callback' => function () {}, + 'groups' => 'Group 1', + ])); + $metadata->addConstraint(new Callback([ + 'callback' => $callback1, + 'groups' => 'Group 2', + ])); + $metadata->addConstraint(new Callback([ + 'callback' => $callback2, + 'groups' => 'Group 3', + ])); + $metadata->setGroupSequenceProvider(true); + + $this->metadataFactory->addMetadata($metadata); + + $violations = $this->validate($entity, null, 'Default'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(\count($assertViolations), $violations); + foreach ($assertViolations as $key => $message) { + $this->assertSame($message, $violations[$key]->getMessage()); + } + } + + public function getConstraintMethods() + { + return [ + ['addPropertyConstraint'], + ['addGetterConstraint'], + ]; + } + + public function getTestReplaceDefaultGroup() + { + return [ + [ + 'sequence' => new GroupSequence(['Group 1', 'Group 2', 'Group 3', 'Entity']), + 'assertViolations' => [ + 'Violation in Group 2', + ], + ], + [ + 'sequence' => ['Group 1', 'Group 2', 'Group 3', 'Entity'], + 'assertViolations' => [ + 'Violation in Group 2', + ], + ], + [ + 'sequence' => new GroupSequence(['Group 1', ['Group 2', 'Group 3'], 'Entity']), + 'assertViolations' => [ + 'Violation in Group 2', + 'Violation in Group 3', + ], + ], + [ + 'sequence' => ['Group 1', ['Group 2', 'Group 3'], 'Entity'], + 'assertViolations' => [ + 'Violation in Group 2', + 'Violation in Group 3', + ], + ], + ]; + } + + public function testValidateConstraintWithoutGroup() + { + $violations = $this->validator->validate(null, new NotNull()); + + $this->assertCount(1, $violations); + } + + public function testValidateWithEmptyArrayAsConstraint() + { + $violations = $this->validator->validate('value', []); + $this->assertCount(0, $violations); + } + + public function testGroupSequenceAbortsAfterFailedGroup() + { + $entity = new Entity(); + + $callback1 = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Message 1'); + }; + $callback2 = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Message 2'); + }; + + $this->metadata->addConstraint(new Callback([ + 'callback' => function () {}, + 'groups' => 'Group 1', + ])); + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback1, + 'groups' => 'Group 2', + ])); + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback2, + 'groups' => 'Group 3', + ])); + + $sequence = new GroupSequence(['Group 1', 'Group 2', 'Group 3']); + $violations = $this->validator->validate($entity, new Valid(), $sequence); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message 1', $violations[0]->getMessage()); + } + + public function testGroupSequenceIncludesReferences() + { + $entity = new Entity(); + $entity->reference = new Reference(); + + $callback1 = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Reference violation 1'); + }; + $callback2 = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Reference violation 2'); + }; + + $this->metadata->addPropertyConstraint('reference', new Valid()); + $this->referenceMetadata->addConstraint(new Callback([ + 'callback' => $callback1, + 'groups' => 'Group 1', + ])); + $this->referenceMetadata->addConstraint(new Callback([ + 'callback' => $callback2, + 'groups' => 'Group 2', + ])); + + $sequence = new GroupSequence(['Group 1', 'Entity']); + $violations = $this->validator->validate($entity, new Valid(), $sequence); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Reference violation 1', $violations[0]->getMessage()); + } + + public function testValidateInSeparateContext() + { + $entity = new Entity(); + $entity->reference = new Reference(); + + $callback1 = function ($value, ExecutionContextInterface $context) use ($entity) { + $violations = $context + ->getValidator() + // Since the validator is not context aware, the group must + // be passed explicitly + ->validate($value->reference, new Valid(), 'Group') + ; + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('', $violations[0]->getPropertyPath()); + + // The root is different as we're in a new context + $this->assertSame($entity->reference, $violations[0]->getRoot()); + $this->assertSame($entity->reference, $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + + // Verify that this method is called + $context->addViolation('Separate violation'); + }; + + $callback2 = function ($value, ExecutionContextInterface $context) use ($entity) { + $this->assertSame($this::REFERENCE_CLASS, $context->getClassName()); + $this->assertNull($context->getPropertyName()); + $this->assertSame('', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($this->referenceMetadata, $context->getMetadata()); + $this->assertSame($entity->reference, $context->getRoot()); + $this->assertSame($entity->reference, $context->getValue()); + $this->assertSame($entity->reference, $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback1, + 'groups' => 'Group', + ])); + $this->referenceMetadata->addConstraint(new Callback([ + 'callback' => $callback2, + 'groups' => 'Group', + ])); + + $violations = $this->validator->validate($entity, new Valid(), 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Separate violation', $violations[0]->getMessage()); + } + + public function testValidateInContext() + { + $entity = new Entity(); + $entity->reference = new Reference(); + + $callback1 = function ($value, ExecutionContextInterface $context) { + $previousValue = $context->getValue(); + $previousObject = $context->getObject(); + $previousMetadata = $context->getMetadata(); + $previousPath = $context->getPropertyPath(); + $previousGroup = $context->getGroup(); + + $context + ->getValidator() + ->inContext($context) + ->atPath('subpath') + ->validate($value->reference) + ; + + // context changes shouldn't leak out of the validate() call + $this->assertSame($previousValue, $context->getValue()); + $this->assertSame($previousObject, $context->getObject()); + $this->assertSame($previousMetadata, $context->getMetadata()); + $this->assertSame($previousPath, $context->getPropertyPath()); + $this->assertSame($previousGroup, $context->getGroup()); + }; + + $callback2 = function ($value, ExecutionContextInterface $context) use ($entity) { + $this->assertSame($this::REFERENCE_CLASS, $context->getClassName()); + $this->assertNull($context->getPropertyName()); + $this->assertSame('subpath', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($this->referenceMetadata, $context->getMetadata()); + $this->assertSame($entity, $context->getRoot()); + $this->assertSame($entity->reference, $context->getValue()); + $this->assertSame($entity->reference, $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback1, + 'groups' => 'Group', + ])); + $this->referenceMetadata->addConstraint(new Callback([ + 'callback' => $callback2, + 'groups' => 'Group', + ])); + + $violations = $this->validator->validate($entity, new Valid(), 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('subpath', $violations[0]->getPropertyPath()); + $this->assertSame($entity, $violations[0]->getRoot()); + $this->assertSame($entity->reference, $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + public function testValidateArrayInContext() + { + $entity = new Entity(); + $entity->reference = new Reference(); + + $callback1 = function ($value, ExecutionContextInterface $context) { + $previousValue = $context->getValue(); + $previousObject = $context->getObject(); + $previousMetadata = $context->getMetadata(); + $previousPath = $context->getPropertyPath(); + $previousGroup = $context->getGroup(); + + $context + ->getValidator() + ->inContext($context) + ->atPath('subpath') + ->validate(['key' => $value->reference]) + ; + + // context changes shouldn't leak out of the validate() call + $this->assertSame($previousValue, $context->getValue()); + $this->assertSame($previousObject, $context->getObject()); + $this->assertSame($previousMetadata, $context->getMetadata()); + $this->assertSame($previousPath, $context->getPropertyPath()); + $this->assertSame($previousGroup, $context->getGroup()); + }; + + $callback2 = function ($value, ExecutionContextInterface $context) use ($entity) { + $this->assertSame($this::REFERENCE_CLASS, $context->getClassName()); + $this->assertNull($context->getPropertyName()); + $this->assertSame('subpath[key]', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($this->referenceMetadata, $context->getMetadata()); + $this->assertSame($entity, $context->getRoot()); + $this->assertSame($entity->reference, $context->getValue()); + $this->assertSame($entity->reference, $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback1, + 'groups' => 'Group', + ])); + $this->referenceMetadata->addConstraint(new Callback([ + 'callback' => $callback2, + 'groups' => 'Group', + ])); + + $violations = $this->validator->validate($entity, new Valid(), 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('subpath[key]', $violations[0]->getPropertyPath()); + $this->assertSame($entity, $violations[0]->getRoot()); + $this->assertSame($entity->reference, $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + public function testTraverseTraversableByDefault() + { + $entity = new Entity(); + $traversable = new \ArrayIterator(['key' => $entity]); + + $callback = function ($value, ExecutionContextInterface $context) use ($entity, $traversable) { + $this->assertSame($this::ENTITY_CLASS, $context->getClassName()); + $this->assertNull($context->getPropertyName()); + $this->assertSame('[key]', $context->getPropertyPath()); + $this->assertSame('Group', $context->getGroup()); + $this->assertSame($this->metadata, $context->getMetadata()); + $this->assertSame($traversable, $context->getRoot()); + $this->assertSame($entity, $context->getValue()); + $this->assertSame($entity, $value); + + $context->addViolation('Message %param%', ['%param%' => 'value']); + }; + + $this->metadataFactory->addMetadata(new ClassMetadata('ArrayIterator')); + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + + $violations = $this->validate($traversable, new Valid(), 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('[key]', $violations[0]->getPropertyPath()); + $this->assertSame($traversable, $violations[0]->getRoot()); + $this->assertSame($entity, $violations[0]->getInvalidValue()); + $this->assertNull($violations[0]->getPlural()); + $this->assertNull($violations[0]->getCode()); + } + + public function testTraversalEnabledOnClass() + { + $entity = new Entity(); + $traversable = new \ArrayIterator(['key' => $entity]); + + $callback = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Message'); + }; + + $traversableMetadata = new ClassMetadata('ArrayIterator'); + $traversableMetadata->addConstraint(new Traverse(true)); + + $this->metadataFactory->addMetadata($traversableMetadata); + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + + $violations = $this->validate($traversable, new Valid(), 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + } + + public function testTraversalDisabledOnClass() + { + $entity = new Entity(); + $traversable = new \ArrayIterator(['key' => $entity]); + + $callback = function ($value, ExecutionContextInterface $context) { + $this->fail('Should not be called'); + }; + + $traversableMetadata = new ClassMetadata('ArrayIterator'); + $traversableMetadata->addConstraint(new Traverse(false)); + + $this->metadataFactory->addMetadata($traversableMetadata); + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + + $violations = $this->validate($traversable, new Valid(), 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(0, $violations); + } + + public function testExpectTraversableIfTraversalEnabledOnClass() + { + $this->expectException('Symfony\Component\Validator\Exception\ConstraintDefinitionException'); + $entity = new Entity(); + + $this->metadata->addConstraint(new Traverse(true)); + + $this->validator->validate($entity); + } + + public function testReferenceTraversalDisabledOnClass() + { + $entity = new Entity(); + $entity->reference = new \ArrayIterator(['key' => new Reference()]); + + $callback = function ($value, ExecutionContextInterface $context) { + $this->fail('Should not be called'); + }; + + $traversableMetadata = new ClassMetadata('ArrayIterator'); + $traversableMetadata->addConstraint(new Traverse(false)); + + $this->metadataFactory->addMetadata($traversableMetadata); + $this->referenceMetadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + $this->metadata->addPropertyConstraint('reference', new Valid()); + + $violations = $this->validate($entity, new Valid(), 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(0, $violations); + } + + public function testReferenceTraversalEnabledOnReferenceDisabledOnClass() + { + $entity = new Entity(); + $entity->reference = new \ArrayIterator(['key' => new Reference()]); + + $callback = function ($value, ExecutionContextInterface $context) { + $this->fail('Should not be called'); + }; + + $traversableMetadata = new ClassMetadata('ArrayIterator'); + $traversableMetadata->addConstraint(new Traverse(false)); + + $this->metadataFactory->addMetadata($traversableMetadata); + $this->referenceMetadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + $this->metadata->addPropertyConstraint('reference', new Valid([ + 'traverse' => true, + ])); + + $violations = $this->validate($entity, new Valid(), 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(0, $violations); + } + + public function testReferenceTraversalDisabledOnReferenceEnabledOnClass() + { + $entity = new Entity(); + $entity->reference = new \ArrayIterator(['key' => new Reference()]); + + $callback = function ($value, ExecutionContextInterface $context) { + $this->fail('Should not be called'); + }; + + $traversableMetadata = new ClassMetadata('ArrayIterator'); + $traversableMetadata->addConstraint(new Traverse(true)); + + $this->metadataFactory->addMetadata($traversableMetadata); + $this->referenceMetadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => 'Group', + ])); + $this->metadata->addPropertyConstraint('reference', new Valid([ + 'traverse' => false, + ])); + + $violations = $this->validate($entity, new Valid(), 'Group'); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(0, $violations); + } + + public function testAddCustomizedViolation() + { + $entity = new Entity(); + + $callback = function ($value, ExecutionContextInterface $context) { + $context->buildViolation('Message %param%') + ->setParameter('%param%', 'value') + ->setInvalidValue('Invalid value') + ->setPlural(2) + ->setCode('42') + ->addViolation(); + }; + + $this->metadata->addConstraint(new Callback($callback)); + + $violations = $this->validator->validate($entity); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + $this->assertSame('Message value', $violations[0]->getMessage()); + $this->assertSame('Message %param%', $violations[0]->getMessageTemplate()); + $this->assertSame(['%param%' => 'value'], $violations[0]->getParameters()); + $this->assertSame('', $violations[0]->getPropertyPath()); + $this->assertSame($entity, $violations[0]->getRoot()); + $this->assertSame('Invalid value', $violations[0]->getInvalidValue()); + $this->assertSame(2, $violations[0]->getPlural()); + $this->assertSame('42', $violations[0]->getCode()); + } + + public function testNoDuplicateValidationIfClassConstraintInMultipleGroups() + { + $entity = new Entity(); + + $callback = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Message'); + }; + + $this->metadata->addConstraint(new Callback([ + 'callback' => $callback, + 'groups' => ['Group 1', 'Group 2'], + ])); + + $violations = $this->validator->validate($entity, new Valid(), ['Group 1', 'Group 2']); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + } + + public function testNoDuplicateValidationIfPropertyConstraintInMultipleGroups() + { + $entity = new Entity(); + + $callback = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Message'); + }; + + $this->metadata->addPropertyConstraint('firstName', new Callback([ + 'callback' => $callback, + 'groups' => ['Group 1', 'Group 2'], + ])); + + $violations = $this->validator->validate($entity, new Valid(), ['Group 1', 'Group 2']); + + /* @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + } + + public function testValidateFailsIfNoConstraintsAndNoObjectOrArray() + { + $this->expectException('Symfony\Component\Validator\Exception\RuntimeException'); + $this->validate('Foobar'); + } + + public function testAccessCurrentObject() + { + $called = false; + $entity = new Entity(); + $entity->firstName = 'Bernhard'; + $entity->data = ['firstName' => 'Bernhard']; + + $callback = function ($value, ExecutionContextInterface $context) use ($entity, &$called) { + $called = true; + $this->assertSame($entity, $context->getObject()); + }; + + $this->metadata->addConstraint(new Callback($callback)); + $this->metadata->addPropertyConstraint('firstName', new Callback($callback)); + $this->metadata->addPropertyConstraint('data', new Collection(['firstName' => new Expression('value == this.firstName')])); + + $this->validator->validate($entity); + + $this->assertTrue($called); + } + + public function testInitializeObjectsOnFirstValidation() + { + $entity = new Entity(); + $entity->initialized = false; + + // prepare initializers that set "initialized" to true + $initializer1 = $this->getMockBuilder('Symfony\\Component\\Validator\\ObjectInitializerInterface')->getMock(); + $initializer2 = $this->getMockBuilder('Symfony\\Component\\Validator\\ObjectInitializerInterface')->getMock(); + + $initializer1->expects($this->once()) + ->method('initialize') + ->with($entity) + ->willReturnCallback(function ($object) { + $object->initialized = true; + }); + + $initializer2->expects($this->once()) + ->method('initialize') + ->with($entity); + + $this->validator = $this->createValidator($this->metadataFactory, [ + $initializer1, + $initializer2, + ]); + + // prepare constraint which + // * checks that "initialized" is set to true + // * validates the object again + $callback = function ($object, ExecutionContextInterface $context) { + $this->assertTrue($object->initialized); + + // validate again in same group + $validator = $context->getValidator()->inContext($context); + + $validator->validate($object); + + // validate again in other group + $validator->validate($object, null, 'SomeGroup'); + }; + + $this->metadata->addConstraint(new Callback($callback)); + + $this->validate($entity); + + $this->assertTrue($entity->initialized); + } + + public function testPassConstraintToViolation() + { + $constraint = new FailingConstraint(); + $violations = $this->validate('Foobar', $constraint); + + $this->assertCount(1, $violations); + $this->assertSame($constraint, $violations[0]->getConstraint()); + } + + public function testCollectionConstraitViolationHasCorrectContext() + { + $data = [ + 'foo' => 'fooValue', + ]; + + // Missing field must not be the first in the collection validation + $constraint = new Collection([ + 'foo' => new NotNull(), + 'bar' => new NotNull(), + ]); + + $violations = $this->validate($data, $constraint); + + $this->assertCount(1, $violations); + $this->assertSame($constraint, $violations[0]->getConstraint()); + } + + public function testNestedObjectIsNotValidatedIfGroupInValidConstraintIsNotValidated() + { + $entity = new Entity(); + $entity->firstName = ''; + $reference = new Reference(); + $reference->value = ''; + $entity->childA = $reference; + + $this->metadata->addPropertyConstraint('firstName', new NotBlank(['groups' => 'group1'])); + $this->metadata->addPropertyConstraint('childA', new Valid(['groups' => 'group1'])); + $this->referenceMetadata->addPropertyConstraint('value', new NotBlank()); + + $violations = $this->validator->validate($entity, null, []); + + $this->assertCount(0, $violations); + } + + public function testNestedObjectIsValidatedIfGroupInValidConstraintIsValidated() + { + $entity = new Entity(); + $entity->firstName = ''; + $reference = new Reference(); + $reference->value = ''; + $entity->childA = $reference; + + $this->metadata->addPropertyConstraint('firstName', new NotBlank(['groups' => 'group1'])); + $this->metadata->addPropertyConstraint('childA', new Valid(['groups' => 'group1'])); + $this->referenceMetadata->addPropertyConstraint('value', new NotBlank(['groups' => 'group1'])); + + $violations = $this->validator->validate($entity, null, ['Default', 'group1']); + + $this->assertCount(2, $violations); + } + + public function testNestedObjectIsValidatedInMultipleGroupsIfGroupInValidConstraintIsValidated() + { + $entity = new Entity(); + $entity->firstName = null; + + $reference = new Reference(); + $reference->value = null; + + $entity->childA = $reference; + + $this->metadata->addPropertyConstraint('firstName', new NotBlank()); + $this->metadata->addPropertyConstraint('childA', new Valid(['groups' => ['group1', 'group2']])); + + $this->referenceMetadata->addPropertyConstraint('value', new NotBlank(['groups' => 'group1'])); + $this->referenceMetadata->addPropertyConstraint('value', new NotNull(['groups' => 'group2'])); + + $violations = $this->validator->validate($entity, null, ['Default', 'group1', 'group2']); + + $this->assertCount(3, $violations); + } + protected function createValidator(MetadataFactoryInterface $metadataFactory, array $objectInitializers = []): ValidatorInterface { $translator = new IdentityTranslator(); From 3980a482f667029e1b3046e4053bd384b37043f4 Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Sun, 1 Nov 2020 10:31:07 +0100 Subject: [PATCH 046/136] Fix not well-formed validators.gl.xf --- .../Component/Form/Resources/translations/validators.gl.xlf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Form/Resources/translations/validators.gl.xlf b/src/Symfony/Component/Form/Resources/translations/validators.gl.xlf index e454185fece75..5ef404a481a45 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.gl.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.gl.xlf @@ -17,7 +17,7 @@ This value is not a valid HTML5 color. Este valor non é unha cor HTML5 válida. - . + Please enter a valid birthdate. Insire unha data de aniversario válida. From 32edd7facfd5fbcc9d8215c838683640eadeba17 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Sun, 1 Nov 2020 11:47:20 +0100 Subject: [PATCH 047/136] Remove translations that does not exists in English --- .../Security/Core/Resources/translations/security.af.xlf | 4 ---- .../Security/Core/Resources/translations/security.bs.xlf | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.af.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.af.xlf index 61793d5c51435..4fc8b1426e381 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.af.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.af.xlf @@ -30,10 +30,6 @@ Invalid CSRF token. Ongeldige CSRF-teken. - - Digest nonce has expired. - Digest nonce het verval. - No authentication provider found to support the authentication token. Geen verifikasieverskaffer is gevind wat die verifikasietoken kan ondersteun nie. diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.bs.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.bs.xlf index 56bab910e42b2..2eae0ff22ec62 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.bs.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.bs.xlf @@ -30,10 +30,6 @@ Invalid CSRF token. CSRF žeton (token) je neispravan. - - Digest nonce has expired. - Digest nonce je istekao. - No authentication provider found to support the authentication token. Nije pronađen autentifikacijski provajder koji bi podržao dati autentifikacijski žeton (token). From 17dfa1d5fcf65a5dc75fe393097a71d8a62635d5 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sun, 1 Nov 2020 11:46:42 +0100 Subject: [PATCH 048/136] Validate XLIFF files in tests using the XSD --- .../Form/Tests/Resources/TranslationFilesTest.php | 11 +++++------ .../Core/Tests/Resources/TranslationFilesTest.php | 11 +++++------ src/Symfony/Component/Security/Core/composer.json | 1 + .../Tests/Resources/TranslationFilesTest.php | 11 +++++------ 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php b/src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php index 3b0d926c2ee7a..53b2cee448805 100644 --- a/src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php +++ b/src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Form\Tests\Resources; use PHPUnit\Framework\TestCase; -use PHPUnit\Util\Xml\Loader; +use Symfony\Component\Translation\Util\XliffUtils; class TranslationFilesTest extends TestCase { @@ -21,13 +21,12 @@ class TranslationFilesTest extends TestCase */ public function testTranslationFileIsValid($filePath) { - $loader = class_exists(Loader::class) - ? [new Loader(), 'loadFile'] - : ['PHPUnit\Util\XML', 'loadfile']; + $document = new \DOMDocument(); + $document->loadXML(file_get_contents($filePath)); - $loader($filePath, false, false, true); + $errors = XliffUtils::validateSchema($document); - $this->addToAssertionCount(1); + $this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message')))); } public function provideTranslationFiles() diff --git a/src/Symfony/Component/Security/Core/Tests/Resources/TranslationFilesTest.php b/src/Symfony/Component/Security/Core/Tests/Resources/TranslationFilesTest.php index c45b5a0d36338..2402b0199824f 100644 --- a/src/Symfony/Component/Security/Core/Tests/Resources/TranslationFilesTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Resources/TranslationFilesTest.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Security\Core\Tests\Resources; use PHPUnit\Framework\TestCase; -use PHPUnit\Util\Xml\Loader; +use Symfony\Component\Translation\Util\XliffUtils; class TranslationFilesTest extends TestCase { @@ -21,13 +21,12 @@ class TranslationFilesTest extends TestCase */ public function testTranslationFileIsValid($filePath) { - $loader = class_exists(Loader::class) - ? [new Loader(), 'loadFile'] - : ['PHPUnit\Util\XML', 'loadfile']; + $document = new \DOMDocument(); + $document->loadXML(file_get_contents($filePath)); - $loader($filePath, false, false, true); + $errors = XliffUtils::validateSchema($document); - $this->addToAssertionCount(1); + $this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message')))); } public function provideTranslationFiles() diff --git a/src/Symfony/Component/Security/Core/composer.json b/src/Symfony/Component/Security/Core/composer.json index e1bc4c2143a53..c99f3a1d41da4 100644 --- a/src/Symfony/Component/Security/Core/composer.json +++ b/src/Symfony/Component/Security/Core/composer.json @@ -26,6 +26,7 @@ "symfony/expression-language": "^3.4|^4.0|^5.0", "symfony/http-foundation": "^3.4|^4.0|^5.0", "symfony/ldap": "^4.4|^5.0", + "symfony/translation": "^4.4|^5.0", "symfony/validator": "^3.4.31|^4.3.4|^5.0", "psr/log": "~1.0" }, diff --git a/src/Symfony/Component/Validator/Tests/Resources/TranslationFilesTest.php b/src/Symfony/Component/Validator/Tests/Resources/TranslationFilesTest.php index 9779f43727222..894ae55f10567 100644 --- a/src/Symfony/Component/Validator/Tests/Resources/TranslationFilesTest.php +++ b/src/Symfony/Component/Validator/Tests/Resources/TranslationFilesTest.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Validator\Tests\Resources; use PHPUnit\Framework\TestCase; -use PHPUnit\Util\Xml\Loader; +use Symfony\Component\Translation\Util\XliffUtils; class TranslationFilesTest extends TestCase { @@ -21,13 +21,12 @@ class TranslationFilesTest extends TestCase */ public function testTranslationFileIsValid($filePath) { - $loader = class_exists(Loader::class) - ? [new Loader(), 'loadFile'] - : ['PHPUnit\Util\XML', 'loadfile']; + $document = new \DOMDocument(); + $document->loadXML(file_get_contents($filePath)); - $loader($filePath, false, false, true); + $errors = XliffUtils::validateSchema($document); - $this->addToAssertionCount(1); + $this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message')))); } public function provideTranslationFiles() From e24d675368e59d8bb70817839651e7bc6a2534b6 Mon Sep 17 00:00:00 2001 From: AnneKir <57183946+AnneKir@users.noreply.github.com> Date: Sat, 31 Oct 2020 19:22:24 +0100 Subject: [PATCH 049/136] Update validators.da.xlf --- .../Resources/translations/validators.da.xlf | 122 +++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Form/Resources/translations/validators.da.xlf b/src/Symfony/Component/Form/Resources/translations/validators.da.xlf index f52f4e0a30db9..dafe20fa02c32 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.da.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.da.xlf @@ -12,7 +12,127 @@ The CSRF token is invalid. Please try to resubmit the form. - CSRF-token er ugyldig. + CSRF-token er ugyldig. Prøv venligst at genindsende. + + + This value is not a valid HTML5 color. + Værdien er ikke en gyldig HTML5 farve. + + + Please enter a valid birthdate. + Indtast venligst en gyldig fødselsdato. + + + The selected choice is invalid. + Den valgte mulighed er ugyldig . + + + The collection is invalid. + Samlingen er ugyldig. + + + Please select a valid color. + Vælg venligst en gyldig farve. + + + Please select a valid country. + Vælg venligst et gyldigt land. + + + Please select a valid currency. + Vælg venligst en gyldig valuta. + + + Please choose a valid date interval. + Vælg venligst et gyldigt datointerval. + + + Please enter a valid date and time. + Vælg venligst en gyldig dato og tid. + + + Please enter a valid date. + Vælg venligst en gyldig dato. + + + Please select a valid file. + Vælg venligst en gyldig fil. + + + The hidden field is invalid. + Det skjulte felt er ugyldigt. + + + Please enter an integer. + Indsæt veligst et heltal. + + + Please select a valid language. + Vælg venligst et gyldigt sprog. + + + Please select a valid locale. + Vælg venligst en gyldigt sprogkode. + + + Please enter a valid money amount. + Vælg venligst et gyldigt beløb. + + + Please enter a number. + Indtast venligst et nummer. + + + The password is invalid. + Passwordet er ugyldigt. + + + Please enter a percentage value. + Indtast venligst en procentværdi. + + + The values do not match. + Værdierne er ikke ens. + + + Please enter a valid time. + Indtast venligst en gyldig tid. + + + Please select a valid timezone. + Vælg venligst en gyldig tidszone. + + + Please enter a valid URL. + Indtast venligst en gyldig URL. + + + Please enter a valid search term. + Indtast venligst et gyldigt søgeord. + + + Please provide a valid phone number. + Giv venligst et gyldigt telefonnummer. + + + The checkbox has an invalid value. + Checkboxen har en ugyldigt værdi. + + + Please enter a valid email address. + Indtast venligst en gyldig emailaddresse. + + + Please select a valid option. + Vælg venligst en gyldig mulighed. + + + Please select a valid range. + Vælg venligst et gyldigt interval . + + + Please enter a valid week. + Indtast venligst en gyldig uge. From 3a8570e569a7143794b6ee95529de5bd121ed652 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 1 Nov 2020 19:34:19 +0100 Subject: [PATCH 050/136] Add symfony/translation to the dev dependencies of symfony/security. --- src/Symfony/Component/Security/composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/Security/composer.json b/src/Symfony/Component/Security/composer.json index 2e4ca6340b8d9..9571efeac0160 100644 --- a/src/Symfony/Component/Security/composer.json +++ b/src/Symfony/Component/Security/composer.json @@ -38,6 +38,7 @@ "symfony/validator": "^3.4.31|^4.3.4|^5.0", "symfony/expression-language": "^3.4|^4.0|^5.0", "symfony/ldap": "^4.4|^5.0", + "symfony/translation": "^4.4|^5.0", "psr/log": "~1.0" }, "conflict": { From c377f73304a71993ba261df244bf8e3fc8aea5bf Mon Sep 17 00:00:00 2001 From: Nyholm Date: Sun, 1 Nov 2020 19:04:36 +0100 Subject: [PATCH 051/136] [Messenger] Fixed tests with doctrine 3 --- .../Tests/Transport/Doctrine/DoctrineReceiverTest.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/DoctrineReceiverTest.php b/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/DoctrineReceiverTest.php index cf84a36006e72..82387f5c1af29 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/DoctrineReceiverTest.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/DoctrineReceiverTest.php @@ -14,6 +14,7 @@ use Doctrine\DBAL\Driver\PDO\Exception; use Doctrine\DBAL\Driver\PDOException; use Doctrine\DBAL\Exception\DeadlockException; +use Doctrine\DBAL\Version; use PHPUnit\Framework\TestCase; use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\Exception\MessageDecodingFailedException; @@ -77,7 +78,14 @@ public function testOccursRetryableExceptionFromConnection() $serializer = $this->createSerializer(); $connection = $this->createMock(Connection::class); $driverException = class_exists(Exception::class) ? Exception::new(new \PDOException('Deadlock', 40001)) : new PDOException(new \PDOException('Deadlock', 40001)); - $connection->method('get')->willThrowException(new DeadlockException('Deadlock', $driverException)); + if (!class_exists(Version::class)) { + // This is doctrine/dbal 3.x + $deadlockException = new DeadlockException($driverException, null); + } else { + $deadlockException = new DeadlockException('Deadlock', $driverException); + } + + $connection->method('get')->willThrowException($deadlockException); $receiver = new DoctrineReceiver($connection, $serializer); $this->assertSame([], $receiver->get()); $this->assertSame([], $receiver->get()); From c5ec51abdf68eb4bc02b9a7e3167e4070ac02c32 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Sun, 1 Nov 2020 18:27:51 +0100 Subject: [PATCH 052/136] [Finder] Force set access time in test --- .../Component/Finder/Tests/Iterator/SortableIteratorTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php b/src/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php index 5a47812bd3474..add8e7df596be 100644 --- a/src/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php +++ b/src/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php @@ -35,9 +35,10 @@ public function testAccept($mode, $expected) case SortableIterator::SORT_BY_ACCESSED_TIME: touch(self::toAbsolute('.git')); sleep(1); - file_get_contents(self::toAbsolute('.bar')); + touch(self::toAbsolute('.bar'), time()); break; case SortableIterator::SORT_BY_CHANGED_TIME: + sleep(1); file_put_contents(self::toAbsolute('test.php'), 'foo'); sleep(1); file_put_contents(self::toAbsolute('test.py'), 'foo'); From 317f17a2f310617b28fb8264cca2b7ad659a1961 Mon Sep 17 00:00:00 2001 From: Farhad Safarov Date: Sun, 1 Nov 2020 22:40:44 +0300 Subject: [PATCH 053/136] [Validator] Add missing Azerbaijani translation --- .../Resources/translations/validators.az.xlf | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.az.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.az.xlf index c3420f3db2a94..59480874fd387 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.az.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.az.xlf @@ -366,6 +366,26 @@ This value should be between {{ min }} and {{ max }}. Bu dəyər {{ min }} və {{ max }} arasında olmaldır. + + This value is not a valid hostname. + Bu dəyər doğru bir host adı deyil. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Bu kolleksiyadakı elementlerin sayı {{ compared_value }} tam bölünəni olmalıdır. + + + This value should satisfy at least one of the following constraints: + Bu dəyər aşağıdakı məcburiyyətlərdən birini qarşılamalıdır: + + + Each element of this collection should satisfy its own set of constraints. + Bu kolleksiyadakı hər element öz məcburiyyətlərini qarşılamalıdır. + + + This value is not a valid International Securities Identification Number (ISIN). + Bu dəyər doğru bir Qiymətli Kağızın Beynəlxalq İdentifikasiya Kodu (ISIN) deyil. + From 665b25cd1e18788006096d810c646fcd0a2212f2 Mon Sep 17 00:00:00 2001 From: Farhad Safarov Date: Sun, 1 Nov 2020 22:52:07 +0300 Subject: [PATCH 054/136] [Security] Add missing Azerbaijani translations --- .../Security/Core/Resources/translations/security.az.xlf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.az.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.az.xlf index a974ed0f024c8..cf19aaefc4400 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.az.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.az.xlf @@ -66,6 +66,14 @@ Account is locked. Hesab kilitlənib. + + Too many failed login attempts, please try again later. + Çoxlu uğursuz giriş təşəbbüsü, zəhmət olmasa daha sonra yeniden yoxlayın. + + + Invalid or expired login link. + Yanlış və ya müddəti keçmiş giriş keçidi. + From 833029ca7e342b36a2cc3c4d3c7fd480c0580a86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Wed, 28 Oct 2020 18:54:43 +0100 Subject: [PATCH 055/136] Fix transiant tests in 4.4 --- .../Cache/Tests/Adapter/AdapterTestCase.php | 4 ++-- .../ServiceRouterLoaderTest.php | 2 +- .../SimpleAuthenticationHandlerTest.php | 14 +++++++------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php b/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php index 57c355eaa43a6..d7fe3ebc60b9e 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php @@ -118,9 +118,9 @@ public function testGetMetadata() $metadata = $item->getMetadata(); $this->assertArrayHasKey(CacheItem::METADATA_CTIME, $metadata); - $this->assertEqualsWithDelta(1000, $metadata[CacheItem::METADATA_CTIME], 6); + $this->assertEqualsWithDelta(999, $metadata[CacheItem::METADATA_CTIME], 10); $this->assertArrayHasKey(CacheItem::METADATA_EXPIRY, $metadata); - $this->assertEqualsWithDelta(9.5 + time(), $metadata[CacheItem::METADATA_EXPIRY], 0.6); + $this->assertEqualsWithDelta(9 + time(), $metadata[CacheItem::METADATA_EXPIRY], 1); } public function testDefaultLifeTime() diff --git a/src/Symfony/Component/Routing/Tests/Loader/DependencyInjection/ServiceRouterLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/DependencyInjection/ServiceRouterLoaderTest.php index 497ce2f3b3658..925e59901e5ff 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/DependencyInjection/ServiceRouterLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/DependencyInjection/ServiceRouterLoaderTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\Routing\Tests\Loader; +namespace Symfony\Component\Routing\Tests\Loader\DependencyInjection; use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\Container; diff --git a/src/Symfony/Component/Security/Http/Tests/Authentication/SimpleAuthenticationHandlerTest.php b/src/Symfony/Component/Security/Http/Tests/Authentication/SimpleAuthenticationHandlerTest.php index 9fbdd6774052f..fa4c07e0b876b 100644 --- a/src/Symfony/Component/Security/Http/Tests/Authentication/SimpleAuthenticationHandlerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Authentication/SimpleAuthenticationHandlerTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\Security\Http\Tests; +namespace Symfony\Component\Security\Http\Tests\Authentication; use PHPUnit\Framework\TestCase; use Symfony\Component\HttpFoundation\Response; @@ -69,7 +69,7 @@ public function testOnAuthenticationSuccessCallsSimpleAuthenticator() $this->successHandler->expects($this->never()) ->method('onAuthenticationSuccess'); - $authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\TestSuccessHandlerInterface'); + $authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\Authentication\TestSuccessHandlerInterface'); $authenticator->expects($this->once()) ->method('onAuthenticationSuccess') ->with($this->request, $this->token) @@ -88,7 +88,7 @@ public function testOnAuthenticationSuccessThrowsAnExceptionIfNonResponseIsRetur $this->successHandler->expects($this->never()) ->method('onAuthenticationSuccess'); - $authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\TestSuccessHandlerInterface'); + $authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\Authentication\TestSuccessHandlerInterface'); $authenticator->expects($this->once()) ->method('onAuthenticationSuccess') ->with($this->request, $this->token) @@ -105,7 +105,7 @@ public function testOnAuthenticationSuccessFallsBackToDefaultHandlerIfNullIsRetu ->with($this->request, $this->token) ->willReturn($this->response); - $authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\TestSuccessHandlerInterface'); + $authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\Authentication\TestSuccessHandlerInterface'); $authenticator->expects($this->once()) ->method('onAuthenticationSuccess') ->with($this->request, $this->token) @@ -137,7 +137,7 @@ public function testOnAuthenticationFailureCallsSimpleAuthenticator() $this->failureHandler->expects($this->never()) ->method('onAuthenticationFailure'); - $authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\TestFailureHandlerInterface'); + $authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\Authentication\TestFailureHandlerInterface'); $authenticator->expects($this->once()) ->method('onAuthenticationFailure') ->with($this->request, $this->authenticationException) @@ -156,7 +156,7 @@ public function testOnAuthenticationFailureThrowsAnExceptionIfNonResponseIsRetur $this->failureHandler->expects($this->never()) ->method('onAuthenticationFailure'); - $authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\TestFailureHandlerInterface'); + $authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\Authentication\TestFailureHandlerInterface'); $authenticator->expects($this->once()) ->method('onAuthenticationFailure') ->with($this->request, $this->authenticationException) @@ -173,7 +173,7 @@ public function testOnAuthenticationFailureFallsBackToDefaultHandlerIfNullIsRetu ->with($this->request, $this->authenticationException) ->willReturn($this->response); - $authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\TestFailureHandlerInterface'); + $authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\Authentication\TestFailureHandlerInterface'); $authenticator->expects($this->once()) ->method('onAuthenticationFailure') ->with($this->request, $this->authenticationException) From b39ff818ca0b9162c0c8f0c3a37e062db00abc14 Mon Sep 17 00:00:00 2001 From: hugovms <38090843+hugovms@users.noreply.github.com> Date: Sat, 31 Oct 2020 14:26:12 -0300 Subject: [PATCH 056/136] fix: updating translation issues --- .../Component/Form/Resources/translations/validators.pt.xlf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Form/Resources/translations/validators.pt.xlf b/src/Symfony/Component/Form/Resources/translations/validators.pt.xlf index 554a810c68673..0108a660e4b4c 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.pt.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.pt.xlf @@ -4,15 +4,15 @@ This form should not contain extra fields. - Este formulário não deveria conter campos extra. + Este formulário não deveria possuir mais campos. The uploaded file was too large. Please try to upload a smaller file. - O arquivo enviado é muito grande. Por favor, tente enviar um ficheiro mais pequeno. + O arquivo enviado é muito grande. Por favor, tente enviar um arquivo menor. The CSRF token is invalid. Please try to resubmit the form. - O token CSRF é inválido. Por favor submeta o formulário novamente. + O token CSRF está inválido. Por favor, tente enviar o formulário novamente. From 6efa4ed7770afcb916626ab119b68cb937578b9d Mon Sep 17 00:00:00 2001 From: Roger Guasch Date: Sun, 1 Nov 2020 21:54:44 +0100 Subject: [PATCH 057/136] Missing translations for Catalan (ca) --- .../Resources/translations/validators.ca.xlf | 120 ++++++++++++++++++ .../Resources/translations/security.ca.xlf | 8 ++ .../Resources/translations/validators.ca.xlf | 56 ++++++++ 3 files changed, 184 insertions(+) diff --git a/src/Symfony/Component/Form/Resources/translations/validators.ca.xlf b/src/Symfony/Component/Form/Resources/translations/validators.ca.xlf index 3a2fa484f8496..69379608048c9 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.ca.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.ca.xlf @@ -14,6 +14,126 @@ The CSRF token is invalid. Please try to resubmit the form. El token CSRF no és vàlid. Per favor, provi d'enviar novament el formulari. + + This value is not a valid HTML5 color. + Aquest valor no és un color HTML5 valid. + + + Please enter a valid birthdate. + Per favor introdueix una data d'aniversari valida. + + + The selected choice is invalid. + L'opció escollida és invalida. + + + The collection is invalid. + La col·lecció és invalida. + + + Please select a valid color. + Per favor selecciona un color vàlid. + + + Please select a valid country. + Per favor selecciona una ciutat vàlida. + + + Please select a valid currency. + Per favor selecciona una moneda vàlida. + + + Please choose a valid date interval. + Per favor escull un interval de dates vàlides. + + + Please enter a valid date and time. + Per favor introdueix una data i temps vàlid. + + + Please enter a valid date. + Per favor introdueix una data vàlida. + + + Please select a valid file. + Per favor selecciona un arxiu vàlid. + + + The hidden field is invalid. + El camp ocult és invàlid. + + + Please enter an integer. + Per favor introdueix un enter. + + + Please select a valid language. + Per favor selecciona un idioma vàlid. + + + Please select a valid locale. + Per favor seleccioneu una configuració regional vàlida + + + Please enter a valid money amount. + Per favor introdueix una quantitat de diners vàlids. + + + Please enter a number. + Per favor introdueix un número. + + + The password is invalid. + La contrasenya es invàlida. + + + Please enter a percentage value. + Per favor introdueix un valor percentual. + + + The values do not match. + Els valors no coincideixen. + + + Please enter a valid time. + Per favor introdueix un temps vàlid. + + + Please select a valid timezone. + Per favor selecciona una zona horària vàlida. + + + Please enter a valid URL. + Per favor introdueix una URL vàlida. + + + Please enter a valid search term. + Per favor introdueix un concepte de cerca vàlid. + + + Please provide a valid phone number. + Per favor introdueix un número de telèfon vàlid. + + + The checkbox has an invalid value. + La casella de selecció te un valor invàlid. + + + Please enter a valid email address. + Per favor introdueix un correu electrònic vàlid. + + + Please select a valid option. + Per favor selecciona una opció vàlida. + + + Please select a valid range. + Per favor selecciona un rang vàlid. + + + Please enter a valid week. + Per favor introdueix una setmana vàlida. + diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.ca.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.ca.xlf index b009c6205c362..5a8d0c7d84880 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.ca.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.ca.xlf @@ -62,6 +62,14 @@ Account is locked. El compte està bloquejat. + + Too many failed login attempts, please try again later. + Massa intents d'inici de sessió fallits, torneu-ho a provar més tard. + + + Invalid or expired login link. + Enllaç d'inici de sessió no vàlid o caducat. + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.ca.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.ca.xlf index d6ae6e91bce2a..80e5364c1d756 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.ca.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.ca.xlf @@ -330,6 +330,62 @@ This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. Aquest Codi d'identificació bancari (BIC) no està associat amb l'IBAN {{ iban }}. + + This value should be valid JSON. + Aquest valor hauria de ser JSON vàlid. + + + This collection should contain only unique elements. + Aquesta col·lecció només hauria de contenir elements únics. + + + This value should be positive. + Aquest valor hauria de ser positiu. + + + This value should be either positive or zero. + Aquest valor ha de ser positiu o zero. + + + This value should be negative. + Aquest valor ha de ser negatiu. + + + This value should be either negative or zero. + Aquest valor ha de ser negatiu o zero. + + + This value is not a valid timezone. + Aquest valor no és una zona horària vàlida. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Aquesta contrasenya s'ha filtrat en cas de violació de dades, no s'ha d'utilitzar. Utilitzeu una altra contrasenya. + + + This value should be between {{ min }} and {{ max }}. + Aquest valor ha d'estar entre {{ min }} i {{ max }}. + + + This value is not a valid hostname. + Aquest valor no és un nom d'amfitrió vàlid. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + El nombre d'elements d'aquesta col·lecció ha de ser múltiple de {{compared_value}}. + + + This value should satisfy at least one of the following constraints: + Aquest valor ha de satisfer almenys una de les restriccions següents: + + + Each element of this collection should satisfy its own set of constraints. + Cada element d'aquesta col·lecció hauria de satisfer el seu propi conjunt de restriccions. + + + This value is not a valid International Securities Identification Number (ISIN). + Aquest valor no és un número d'identificació de valors internacionals (ISIN) vàlid. + From 142cfeed55ccb7c46efb63ee71c20176e61931a2 Mon Sep 17 00:00:00 2001 From: Farhad Safarov Date: Sun, 1 Nov 2020 23:22:25 +0300 Subject: [PATCH 058/136] [Form] Add missing Azerbaijani translation --- .../Resources/translations/validators.az.xlf | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/src/Symfony/Component/Form/Resources/translations/validators.az.xlf b/src/Symfony/Component/Form/Resources/translations/validators.az.xlf index 69e447385acda..b9269706db3e8 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.az.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.az.xlf @@ -14,6 +14,126 @@ The CSRF token is invalid. Please try to resubmit the form. CSRF nişanı yanlışdır. Lütfen formanı yenidən göndərin. + + This value is not a valid HTML5 color. + Bu dəyər doğru bir HTML5 rəngi deyil. + + + Please enter a valid birthdate. + Zəhmət olmasa doğru bir doğum günü daxil edin. + + + The selected choice is invalid. + Seçilmiş seçim doğru deyil. + + + The collection is invalid. + Kolleksiya doğru deyil. + + + Please select a valid color. + Zəhmət olmasa doğru bir rəng seçin. + + + Please select a valid country. + Zəhmət olmasa doğru bir ölkə seçin. + + + Please select a valid currency. + Zəhmət olmasa doğru bir valyuta seçin. + + + Please choose a valid date interval. + Zəhmət olmasa doğru bir tarix aralığı seçin. + + + Please enter a valid date and time. + Zəhmət olmasa doğru bir tarix ve saat daxil edin. + + + Please enter a valid date. + Zəhmət olmasa doğru bir tarix daxil edin. + + + Please select a valid file. + Zəhmət olmasa doğru bir fayl seçin. + + + The hidden field is invalid. + Gizli sahə doğru deyil. + + + Please enter an integer. + Zəhmət olmasa bir tam ədəd daxil edin. + + + Please select a valid language. + Zəhmət olmasa doğru bir dil seçin. + + + Please select a valid locale. + Zəhmət olmasa doğru bir yer seçin. + + + Please enter a valid money amount. + Zəhmət olmasa doğru bir pul miqdarı daxil edin. + + + Please enter a number. + Zəhmət olmasa doğru bir rəqəm daxil edin. + + + The password is invalid. + Parol doğru deyil. + + + Please enter a percentage value. + Zəhmət olmasa doğru bir faiz dəyəri daxil edin. + + + The values do not match. + Dəyərlər örtüşmür. + + + Please enter a valid time. + Zəhmət olmasa doğru bir saat daxil edin. + + + Please select a valid timezone. + Zəhmət olmasa doğru bir saat qurşağı seçin. + + + Please enter a valid URL. + Zəhmət olmasa doğru bir URL daxil edin. + + + Please enter a valid search term. + Zəhmət olmasa doğru bir axtarış termini daxil edin. + + + Please provide a valid phone number. + Zəhmət olmasa doğru bir telefon nömrəsi seçin. + + + The checkbox has an invalid value. + Seçim qutusunda doğru olmayan dəyər var. + + + Please enter a valid email address. + Zəhmət olmasa doğru bir e-poçt seçin. + + + Please select a valid option. + Zəhmət olmasa doğru bir variant seçin. + + + Please select a valid range. + Zəhmət olmasa doğru bir aralıq seçin. + + + Please enter a valid week. + Zəhmət olmasa doğru bir həftə seçin. + From 98a7e8e150fc34966cbf02073f69357515ce1a4f Mon Sep 17 00:00:00 2001 From: Ben Hakim Date: Mon, 2 Nov 2020 15:36:19 +0200 Subject: [PATCH 059/136] Update validators.he.xlf --- .../Resources/translations/validators.he.xlf | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/src/Symfony/Component/Form/Resources/translations/validators.he.xlf b/src/Symfony/Component/Form/Resources/translations/validators.he.xlf index 74a71d05a31a8..efd68b8807bfd 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.he.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.he.xlf @@ -14,6 +14,126 @@ The CSRF token is invalid. Please try to resubmit the form. אסימון CSRF אינו חוקי. אנא נסה לשלוח שוב את הטופס. + + This value is not a valid HTML5 color. + ערך זה אינו צבע HTML5 חוקי. + + + Please enter a valid birthdate. + נא להזין את תאריך לידה תקני. + + + The selected choice is invalid. + הבחירה שנבחרה אינה חוקית. + + + The collection is invalid. + האוסף אינו חוקי. + + + Please select a valid color. + אנא בחר צבע חוקי. + + + Please select a valid country. + אנא בחר מדינה חוקית. + + + Please select a valid currency. + אנא בחר מטבע חוקי. + + + Please choose a valid date interval. + אנא בחר מרווח תאריכים חוקי. + + + Please enter a valid date and time. + אנא הזן תאריך ושעה תקנים. + + + Please enter a valid date. + נא להזין תאריך חוקי. + + + Please select a valid file. + אנא בחר קובץ חוקי. + + + The hidden field is invalid. + השדה הנסתר אינו חוקי. + + + Please enter an integer. + אנא הזן מספר שלם. + + + Please select a valid language. + אנא בחר שפה חוקי. + + + Please select a valid locale. + אנא בחר שפה מקומית. + + + Please enter a valid money amount. + אנא הזן סכום כסף חוקי. + + + Please enter a number. + אנא הזן מספר. + + + The password is invalid. + הסיסמה אינה חוקית. + + + Please enter a percentage value. + אנא הזן ערך באחוזים. + + + The values do not match. + הערכים אינם תואמים. + + + Please enter a valid time. + אנא הזן שעה חוקי. + + + Please select a valid timezone. + אנא בחר אזור זמן חוקי. + + + Please enter a valid URL. + נא להזין את כתובת אתר חוקית. + + + Please enter a valid search term. + אנא הזן מונח חיפוש חוקי. + + + Please provide a valid phone number. + אנא ספק מספר טלפון חוקי. + + + The checkbox has an invalid value. + לתיבת הסימון יש ערך לא חוקי. + + + Please enter a valid email address. + אנא הזן כתובת דוא"ל תקנית. + + + Please select a valid option. + אנא בחר אפשרות חוקית. + + + Please select a valid range. + אנא בחר טווח חוקי. + + + Please enter a valid week. + אנא הזן שבוע תקף. + From c8ab10f427d937cd0aa4f6d4d40092177620b62b Mon Sep 17 00:00:00 2001 From: Ben Hakim Date: Mon, 2 Nov 2020 15:41:03 +0200 Subject: [PATCH 060/136] Update security.he.xlf --- .../Resources/translations/security.he.xlf | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.he.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.he.xlf index f30b68eddf1fc..adbb6cfd6ae00 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.he.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.he.xlf @@ -8,7 +8,7 @@ Authentication credentials could not be found. - Authentication credentials could not be found. + פרטי זיהוי לא נמצאו. Authentication request could not be processed due to a system problem. @@ -16,23 +16,23 @@ Invalid credentials. - שם משתמש או סיסמא שגויים + שם משתמש או סיסמא שגויים. Cookie has already been used by someone else. - Cookie has already been used by someone else. + עוגיה כבר שומשה. Not privileged to request the resource. - Not privileged to request the resource. + אין הרשאה מתאימה. Invalid CSRF token. - Invalid CSRF token. + אסימון CSRF לא חוקי. No authentication provider found to support the authentication token. - No authentication provider found to support the authentication token. + לא נמצא ספק אימות המתאימה לבקשה. No session available, it either timed out or cookies are not enabled. @@ -40,11 +40,11 @@ No token could be found. - No token could be found. + הטוקן לא נמצא. Username could not be found. - שם משתמש לא נמצא במערכת + שם משתמש לא נמצא. Account has expired. @@ -52,7 +52,7 @@ Credentials have expired. - פרטי התחברות פקעו תוקף + פרטי התחברות פקעו תוקף. Account is disabled. @@ -62,6 +62,14 @@ Account is locked. החשבון נעול. + + Too many failed login attempts, please try again later. + יותר מדי ניסיונות כניסה כושלים, אנא נסה שוב מאוחר יותר. + + + Invalid or expired login link. + קישור כניסה לא חוקי או שפג תוקפו. + From b99977efcebb56334797ef0e8bb02876264c13fd Mon Sep 17 00:00:00 2001 From: Ben Hakim Date: Mon, 2 Nov 2020 16:11:24 +0200 Subject: [PATCH 061/136] Update validators.he.xlf --- .../Resources/translations/validators.he.xlf | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.he.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.he.xlf index 6f9ab0a1cfa64..dfaed73d2f6da 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.he.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.he.xlf @@ -366,6 +366,26 @@ This value should be between {{ min }} and {{ max }}. הערך חייב להיות בין {{ min }} ו- {{ max }}. + + This value is not a valid hostname. + ערך זה אינו שם מארח חוקי. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + מספר האלמנטים באוסף זה צריך להיות מכפיל של {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + ערך זה אמור לעמוד לפחות באחד התנאים הבאים: + + + Each element of this collection should satisfy its own set of constraints. + כל אלמנט באוסף זה אמור לעמוד בקבוצת התנאים שלו. + + + This value is not a valid International Securities Identification Number (ISIN). + ערך זה אינו מספר זיהוי ניירות ערך בינלאומי תקף (ISIN). + From 427e31421221ee77d663cd9e0f32dd69ed6589d1 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 2 Nov 2020 15:30:42 +0100 Subject: [PATCH 062/136] Fix CI --- .appveyor.yml | 2 +- .travis.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index f0865f311d664..a43914c8b3eef 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -57,7 +57,7 @@ install: - php composer.phar global require --no-progress --no-scripts --no-plugins symfony/flex - git config --global user.email "" - git config --global user.name "Symfony" - - FOR /F "tokens=* USEBACKQ" %%F IN (`bash -c "grep branch-version composer.json | grep -o '[0-9.]*'"`) DO (SET SYMFONY_VERSION=%%F) + - FOR /F "tokens=* USEBACKQ" %%F IN (`bash -c "grep branch-version composer.json | grep -o '[0-9.x]*'"`) DO (SET SYMFONY_VERSION=%%F) - php .github/build-packages.php "HEAD^" %SYMFONY_VERSION% src\Symfony\Bridge\PhpUnit - SET "SYMFONY_REQUIRE=>=%SYMFONY_VERSION%" - SET COMPOSER_ROOT_VERSION=%SYMFONY_VERSION%.x-dev diff --git a/.travis.yml b/.travis.yml index 8a02ce10d5e13..b830033cdb24b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -213,7 +213,7 @@ install: git config --global user.email "" git config --global user.name "Symfony" - export SYMFONY_VERSION=$(grep branch-version composer.json | grep -o '[0-9.]*') + export SYMFONY_VERSION=$(grep branch-version composer.json | grep -o '[0-9.x]*') if [[ ! $deps ]]; then php .github/build-packages.php HEAD^ $SYMFONY_VERSION src/Symfony/Bridge/PhpUnit From c0524197a0fd6a10fe38adc53012114dc4bc709a Mon Sep 17 00:00:00 2001 From: Bruno Araujo Date: Mon, 26 Oct 2020 22:51:58 +0000 Subject: [PATCH 063/136] translating the validators for european portuguese language --- .../Resources/translations/validators.pt.xlf | 122 +++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Form/Resources/translations/validators.pt.xlf b/src/Symfony/Component/Form/Resources/translations/validators.pt.xlf index 0108a660e4b4c..6ce1c3242cab3 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.pt.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.pt.xlf @@ -8,12 +8,132 @@ The uploaded file was too large. Please try to upload a smaller file. - O arquivo enviado é muito grande. Por favor, tente enviar um arquivo menor. + O ficheiro enviado é muito grande. Por favor, tente enviar um ficheiro menor. The CSRF token is invalid. Please try to resubmit the form. O token CSRF está inválido. Por favor, tente enviar o formulário novamente. + + This value is not a valid HTML5 color. + Este valor não é uma cor HTML5 válida. + + + Please enter a valid birthdate. + Por favor, informe uma data de nascimento válida. + + + The selected choice is invalid. + A escolha seleccionada é inválida. + + + The collection is invalid. + A coleção é inválida. + + + Please select a valid color. + Por favor, selecione uma cor válida. + + + Please select a valid country. + Por favor, selecione um país válido. + + + Please select a valid currency. + Por favor, selecione uma moeda válida. + + + Please choose a valid date interval. + Por favor, escolha um intervalo de datas válido. + + + Please enter a valid date and time. + Por favor, informe uma data e horário válidos. + + + Please enter a valid date. + Por favor, informe uma data válida. + + + Please select a valid file. + Por favor, selecione um ficheiro válido. + + + The hidden field is invalid. + O campo oculto é inválido. + + + Please enter an integer. + Por favor, informe um inteiro. + + + Please select a valid language. + Por favor selecione um idioma válido. + + + Please select a valid locale. + Por favor, selecione um locale válido. + + + Please enter a valid money amount. + Por favor, informe um valor monetário válido. + + + Please enter a number. + Por favor, informe um número. + + + The password is invalid. + A palavra-passe é inválida. + + + Please enter a percentage value. + Por favor, informe um valor percentual. + + + The values do not match. + Os valores não correspondem. + + + Please enter a valid time. + Por favor, informe uma hora válida. + + + Please select a valid timezone. + Por favor, selecione um fuso horário válido. + + + Please enter a valid URL. + Por favor, informe uma URL válida. + + + Please enter a valid search term. + Por favor, informe um termo de busca válido. + + + Please provide a valid phone number. + Por favor, infome um número de telefone válido. + + + The checkbox has an invalid value. + O checkbox possui um valor inválido. + + + Please enter a valid email address. + Por favor, informe um endereço de email válido. + + + Please select a valid option. + Por favor, selecione uma opção válida. + + + Please select a valid range. + Por favor, selecione um intervalo válido. + + + Please enter a valid week. + Por favor, selecione uma semana válida. + From 5c848d979687a8014dec7baf8e18703b21f4638e Mon Sep 17 00:00:00 2001 From: Nyholm Date: Sat, 31 Oct 2020 10:16:35 +0100 Subject: [PATCH 064/136] Fixing some Mongolian --- .../Resources/translations/validators.mn.xlf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.mn.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.mn.xlf index f9126998b626b..b767dc87c8452 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.mn.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.mn.xlf @@ -131,20 +131,20 @@ Энэ утга зөвхөн тоо байна. - This value is not a valid country. - Энэ утга үнэн бодит улс биш байна. - - This file is not a valid image. Файл зураг биш байна. - + This is not a valid IP address. IP хаяг зөв биш байна. - + This value is not a valid language. - Энэ утга үнэн зөв хэл биш байна . + Энэ утга үнэн зөв хэл биш байна. + + + This value is not a valid locale. + Энэ утга үнэн зөв байршил биш байна. This value is not a valid country. From e918e5ab30c69475127e47546d2210296edfd227 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Sun, 1 Nov 2020 20:26:06 +0100 Subject: [PATCH 065/136] [Process] Dont test TTY if there is no TTY support --- .../Component/Process/Tests/ProcessTest.php | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/Process/Tests/ProcessTest.php b/src/Symfony/Component/Process/Tests/ProcessTest.php index 6b525d26846f0..62bffec88f59c 100644 --- a/src/Symfony/Component/Process/Tests/ProcessTest.php +++ b/src/Symfony/Component/Process/Tests/ProcessTest.php @@ -476,6 +476,10 @@ public function testTTYCommand() $this->markTestSkipped('Windows does not have /dev/tty support'); } + if (!Process::isTtySupported()) { + $this->markTestSkipped('There is no TTY support'); + } + $process = $this->getProcess('echo "foo" >> /dev/null && '.$this->getProcessForCode('usleep(100000);')->getCommandLine()); $process->setTty(true); $process->start(); @@ -491,6 +495,10 @@ public function testTTYCommandExitCode() $this->markTestSkipped('Windows does have /dev/tty support'); } + if (!Process::isTtySupported()) { + $this->markTestSkipped('There is no TTY support'); + } + $process = $this->getProcess('echo "foo" >> /dev/null'); $process->setTty(true); $process->run(); @@ -1433,16 +1441,7 @@ public function testRawCommandLine() $p = Process::fromShellCommandline(sprintf('"%s" -r %s "a" "" "b"', self::$phpBin, escapeshellarg('print_r($argv);'))); $p->run(); - $expected = << - - [1] => a - [2] => - [3] => b -) - -EOTXT; + $expected = "Array\n(\n [0] => -\n [1] => a\n [2] => \n [3] => b\n)\n"; $this->assertSame($expected, str_replace('Standard input code', '-', $p->getOutput())); } From 76c19393c8b21ebe37a7c19ff05d282069f9f57a Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 2 Nov 2020 17:05:56 +0100 Subject: [PATCH 066/136] [HttpKernel] fix merge --- .../HttpKernel/Tests/EventListener/SessionListenerTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php index b3799bdb41e62..8131ff2ea110f 100644 --- a/src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php @@ -20,7 +20,6 @@ use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage; use Symfony\Component\HttpKernel\Event\FinishRequestEvent; -use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\Event\ResponseEvent; use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener; @@ -199,7 +198,7 @@ public function testGetSessionIsCalledOnce() $container->set('session', $session); $container->set('request_stack', $requestStack); - $event = new GetResponseEvent($kernel, $masterRequest, HttpKernelInterface::MASTER_REQUEST); + $event = new RequestEvent($kernel, $masterRequest, HttpKernelInterface::MASTER_REQUEST); $listener = new SessionListener($container); $listener->onKernelRequest($event); From b4730cbe1d283a58f84dbcdb2c673d5dfe55ed09 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Mon, 2 Nov 2020 22:14:26 +0100 Subject: [PATCH 067/136] Switch nightly run to 8.0snapshot --- .travis.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index cf08a5f89214b..b69c4567dd0d7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,11 +28,11 @@ matrix: env: deps=high - php: 7.4 env: deps=low - - php: nightly + - php: 8.0snapshot services: [memcached] fast_finish: true allow_failures: - - php: nightly + - php: 8.0snapshot services: [memcached] cache: @@ -140,7 +140,7 @@ before_install: echo session.gc_probability = 0 >> $INI echo opcache.enable_cli = 1 >> $INI echo apc.enable_cli = 1 >> $INI - if [[ $PHP != nightly ]]; then + if [[ $PHP != 8.* ]]; then echo extension = memcached.so >> $INI fi done @@ -156,7 +156,7 @@ before_install: if ! php --ri sodium > /dev/null; then tfold ext.libsodium tpecl libsodium sodium.so $INI fi - if [[ $PHP = nightly ]]; then + if [[ $PHP = 8.* ]]; then tfold ext.memcached tpecl memcached-3.1.5 memcached.so $INI else tfold ext.mongodb tpecl mongodb-1.6.16 mongodb.so $INI @@ -234,7 +234,7 @@ install: - | # Set composer's platform to php 7.4 if we're on php 8. - if [[ $PHP = nightly ]]; then + if [[ $PHP = 8.* ]]; then composer config platform.php 7.4.99 export SYMFONY_DEPRECATIONS_HELPER=max[total]=999 fi From 849d1b3845a4ed2dc59a1a3eac1c55368b256b05 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 3 Nov 2020 12:50:26 +0100 Subject: [PATCH 068/136] [PhpUnitBridge] fix replaying skipped tests --- .../Legacy/SymfonyTestsListenerTrait.php | 35 +++++++++---------- .../Verification/IntlDateFormatterTest.php | 12 +++++++ 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php index 5afa18120e158..22ebd6688d1de 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php @@ -121,7 +121,7 @@ public function startTestSuite($suite) $suiteName = $suite->getName(); foreach ($suite->tests() as $test) { - if (!($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase)) { + if (!($test instanceof \PHPUnit_Framework_TestCase || $test instanceof TestCase)) { continue; } if (null === Test::getPreserveGlobalStateSettings(\get_class($test), $test->getName(false))) { @@ -156,7 +156,7 @@ public function startTestSuite($suite) $testSuites = [$suite]; for ($i = 0; isset($testSuites[$i]); ++$i) { foreach ($testSuites[$i]->tests() as $test) { - if ($test instanceof TestSuite) { + if ($test instanceof \PHPUnit_Framework_TestSuite || $test instanceof TestSuite) { if (!class_exists($test->getName(), false)) { $testSuites[] = $test; continue; @@ -172,12 +172,19 @@ public function startTestSuite($suite) } } } elseif (2 === $this->state) { + $suites = [$suite]; $skipped = []; - foreach ($suite->tests() as $test) { - if (!($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase) - || isset($this->wasSkipped[$suiteName]['*']) - || isset($this->wasSkipped[$suiteName][$test->getName()])) { - $skipped[] = $test; + while ($s = array_shift($suites)) { + foreach ($s->tests() as $test) { + if ($test instanceof \PHPUnit_Framework_TestSuite || $test instanceof TestSuite) { + $suites[] = $test; + continue + } + if (($test instanceof \PHPUnit_Framework_TestCase || $test instanceof TestCase) + && isset($this->wasSkipped[\get_class($test)][$test->getName()]) + ) { + $skipped[] = $test; + } } } $suite->setTests($skipped); @@ -187,21 +194,13 @@ public function startTestSuite($suite) public function addSkippedTest($test, \Exception $e, $time) { if (0 < $this->state) { - if ($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase) { - $class = \get_class($test); - $method = $test->getName(); - } else { - $class = $test->getName(); - $method = '*'; - } - - $this->isSkipped[$class][$method] = 1; + $this->isSkipped[\get_class($test)][$test->getName()] = 1; } } public function startTest($test) { - if (-2 < $this->state && ($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase)) { + if (-2 < $this->state && ($test instanceof \PHPUnit_Framework_TestCase || $test instanceof TestCase)) { // This event is triggered before the test is re-run in isolation if ($this->willBeIsolated($test)) { $this->runsInSeparateProcess = tempnam(sys_get_temp_dir(), 'deprec'); @@ -291,7 +290,7 @@ public function endTest($test, $time) $this->expectedDeprecations = $this->gatheredDeprecations = []; $this->previousErrorHandler = null; } - if (!$this->runsInSeparateProcess && -2 < $this->state && ($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase)) { + if (!$this->runsInSeparateProcess && -2 < $this->state && ($test instanceof \PHPUnit_Framework_TestCase || $test instanceof TestCase)) { if (\in_array('time-sensitive', $groups, true)) { ClockMock::withClockMock(false); } diff --git a/src/Symfony/Component/Intl/Tests/DateFormatter/Verification/IntlDateFormatterTest.php b/src/Symfony/Component/Intl/Tests/DateFormatter/Verification/IntlDateFormatterTest.php index 50cccd993b8fa..ed82ead532fd3 100644 --- a/src/Symfony/Component/Intl/Tests/DateFormatter/Verification/IntlDateFormatterTest.php +++ b/src/Symfony/Component/Intl/Tests/DateFormatter/Verification/IntlDateFormatterTest.php @@ -30,6 +30,18 @@ protected function setUp(): void parent::setUp(); } + /** + * @dataProvider formatProvider + */ + public function testFormat($pattern, $timestamp, $expected) + { + if (\PHP_VERSION_ID < 70105 && $timestamp instanceof \DateTimeImmutable) { + $this->markTestSkipped('PHP >= 7.1.5 required for DateTimeImmutable.'); + } + + parent::testFormat($pattern, $timestamp, $expected); + } + /** * @dataProvider formatTimezoneProvider */ From 75ff86811f137f5980513e9c3edb59c530f78633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Sat, 17 Oct 2020 21:11:34 +0200 Subject: [PATCH 069/136] [HttpFoundation] Fix for virtualhosts based on URL path --- .../Component/HttpFoundation/Request.php | 12 ++++++-- .../HttpFoundation/Tests/RequestTest.php | 30 +++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index 7387fce74b934..14775fdef3bb7 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -1848,9 +1848,15 @@ protected function prepareBaseUrl() } $basename = basename($baseUrl); - if (empty($basename) || !strpos(rawurldecode($truncatedRequestUri), $basename)) { - // no match whatsoever; set it blank - return ''; + if (empty($basename) || !strpos(rawurldecode($truncatedRequestUri).'/', '/'.$basename.'/')) { + // strip autoindex filename, for virtualhost based on URL path + $baseUrl = \dirname($baseUrl).'/'; + + $basename = basename($baseUrl); + if (empty($basename) || !strpos(rawurldecode($truncatedRequestUri).'/', '/'.$basename.'/')) { + // no match whatsoever; set it blank + return ''; + } } // If using mod_rewrite or ISAPI_Rewrite strip the script filename diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php index 7c53ec2d53655..ef15ea8eff426 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php @@ -1763,6 +1763,36 @@ public function getBaseUrlData() '/foo', '/bar+baz', ], + [ + '/sub/foo/bar', + [ + 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo/app.php', + 'SCRIPT_NAME' => '/foo/app.php', + 'PHP_SELF' => '/foo/app.php', + ], + '/sub/foo', + '/bar', + ], + [ + '/sub/foo/app.php/bar', + [ + 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo/app.php', + 'SCRIPT_NAME' => '/foo/app.php', + 'PHP_SELF' => '/foo/app.php', + ], + '/sub/foo/app.php', + '/bar', + ], + [ + '/sub/foo/bar/baz', + [ + 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo/app2.phpx', + 'SCRIPT_NAME' => '/foo/app2.phpx', + 'PHP_SELF' => '/foo/app2.phpx', + ], + '/sub/foo', + '/bar/baz', + ], ]; } From 6fe261a7aeb70e731b5f49366de0de994eff12ee Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 3 Nov 2020 13:14:11 +0100 Subject: [PATCH 070/136] fix typo --- src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php index 22ebd6688d1de..657ce0363b4fa 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php @@ -178,7 +178,7 @@ public function startTestSuite($suite) foreach ($s->tests() as $test) { if ($test instanceof \PHPUnit_Framework_TestSuite || $test instanceof TestSuite) { $suites[] = $test; - continue + continue; } if (($test instanceof \PHPUnit_Framework_TestCase || $test instanceof TestCase) && isset($this->wasSkipped[\get_class($test)][$test->getName()]) From 3dd385f319182a42738c8e2f770626098d5ade49 Mon Sep 17 00:00:00 2001 From: Thomas Lallement Date: Tue, 3 Nov 2020 17:58:31 +0100 Subject: [PATCH 071/136] Rename security.pt_PT.xlf to security.pt.xlf --- .../translations/{security.pt_PT.xlf => security.pt.xlf} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/Symfony/Component/Security/Core/Resources/translations/{security.pt_PT.xlf => security.pt.xlf} (100%) diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.pt_PT.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.pt.xlf similarity index 100% rename from src/Symfony/Component/Security/Core/Resources/translations/security.pt_PT.xlf rename to src/Symfony/Component/Security/Core/Resources/translations/security.pt.xlf From e5595dae73278dcaf0651e0c9272b72213e34b73 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Tue, 3 Nov 2020 17:55:17 +0100 Subject: [PATCH 072/136] [HttpClient] Check status code before decoding content in TraceableResponse --- .../HttpClient/Response/TraceableResponse.php | 24 +++++++++---------- .../Tests/TraceableHttpClientTest.php | 13 ++++++++++ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/Symfony/Component/HttpClient/Response/TraceableResponse.php b/src/Symfony/Component/HttpClient/Response/TraceableResponse.php index 2fe78f45748bc..b574310253de5 100644 --- a/src/Symfony/Component/HttpClient/Response/TraceableResponse.php +++ b/src/Symfony/Component/HttpClient/Response/TraceableResponse.php @@ -52,24 +52,24 @@ public function getHeaders(bool $throw = true): array public function getContent(bool $throw = true): string { - $this->content = $this->response->getContent(false); - - if ($throw) { - $this->checkStatusCode($this->response->getStatusCode()); + try { + return $this->content = $this->response->getContent(false); + } finally { + if ($throw) { + $this->checkStatusCode($this->response->getStatusCode()); + } } - - return $this->content; } public function toArray(bool $throw = true): array { - $this->content = $this->response->toArray(false); - - if ($throw) { - $this->checkStatusCode($this->response->getStatusCode()); + try { + return $this->content = $this->response->toArray(false); + } finally { + if ($throw) { + $this->checkStatusCode($this->response->getStatusCode()); + } } - - return $this->content; } public function cancel(): void diff --git a/src/Symfony/Component/HttpClient/Tests/TraceableHttpClientTest.php b/src/Symfony/Component/HttpClient/Tests/TraceableHttpClientTest.php index 9b6752f7b62cd..43012e99c20d5 100755 --- a/src/Symfony/Component/HttpClient/Tests/TraceableHttpClientTest.php +++ b/src/Symfony/Component/HttpClient/Tests/TraceableHttpClientTest.php @@ -16,6 +16,7 @@ use Symfony\Component\HttpClient\NativeHttpClient; use Symfony\Component\HttpClient\Response\MockResponse; use Symfony\Component\HttpClient\TraceableHttpClient; +use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; use Symfony\Contracts\HttpClient\Test\TestHttpServer; @@ -100,4 +101,16 @@ public function testStream() $this->assertGreaterThan(1, \count($chunks)); $this->assertSame('Symfony is awesome!', implode('', $chunks)); } + + public function testToArrayChecksStatusCodeBeforeDecoding() + { + $this->expectException(ClientExceptionInterface::class); + + $sut = new TraceableHttpClient(new MockHttpClient($responseFactory = function (): MockResponse { + return new MockResponse('Errored.', ['http_code' => 400]); + })); + + $response = $sut->request('GET', 'https://example.com/foo/bar'); + $response->toArray(); + } } From 51ff06060350229d87dd631401d06c50bc119a12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Wed, 4 Nov 2020 03:07:25 +0100 Subject: [PATCH 073/136] Fix circular referene with Factory and LazyIterator --- .../DependencyInjection/ContainerBuilder.php | 6 +- .../DependencyInjection/Dumper/PhpDumper.php | 2 +- .../Tests/ContainerBuilderTest.php | 4 + .../Tests/Dumper/PhpDumperTest.php | 3 + .../containers/container_almost_circular.php | 19 +++++ .../Tests/Fixtures/includes/classes.php | 17 ++++ .../php/services_almost_circular_private.php | 47 +++++++++++ .../php/services_almost_circular_public.php | 77 +++++++++++++++++++ 8 files changed, 171 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 2f9d7d0a008d9..def656ee133fe 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -1220,7 +1220,7 @@ private function doResolveServices($value, array &$inlineServices = [], bool $is return $this->resolveServices($reference); }; } elseif ($value instanceof IteratorArgument) { - $value = new RewindableGenerator(function () use ($value) { + $value = new RewindableGenerator(function () use ($value, &$inlineServices) { foreach ($value->getValues() as $k => $v) { foreach (self::getServiceConditionals($v) as $s) { if (!$this->has($s)) { @@ -1228,12 +1228,12 @@ private function doResolveServices($value, array &$inlineServices = [], bool $is } } foreach (self::getInitializedConditionals($v) as $s) { - if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)) { + if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE, $inlineServices)) { continue 2; } } - yield $k => $this->resolveServices($v); + yield $k => $this->doResolveServices($v, $inlineServices); } }, function () use ($value): int { $count = 0; diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index fcc0ad33e11ee..584eff5fd1d2f 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -451,7 +451,7 @@ private function collectCircularReferences(string $sourceId, array $edges, array foreach ($edges as $edge) { $node = $edge->getDestNode(); $id = $node->getId(); - if (!$node->getValue() instanceof Definition || $sourceId === $id || $edge->isLazy() || $edge->isWeak()) { + if (!$node->getValue() instanceof Definition || $sourceId === $id || $edge->isWeak()) { continue; } diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index ba664f767baf1..b78fbd72ea5a8 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -1372,6 +1372,10 @@ public function testUninitializedReference() public function testAlmostCircular($visibility) { $container = include __DIR__.'/Fixtures/containers/container_almost_circular.php'; + $container->compile(); + + $logger = $container->get('monolog.logger'); + $this->assertEquals(new \stdClass(), $logger->handler); $foo = $container->get('foo'); $this->assertSame($foo, $foo->bar->foobar->foo); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 5875253d862c1..663e3fe66dbaf 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -1054,6 +1054,9 @@ public function testAlmostCircular($visibility) $container = new $container(); + $logger = $container->get('monolog.logger'); + $this->assertEquals(new \stdClass(), $logger->handler); + $foo = $container->get('foo'); $this->assertSame($foo, $foo->bar->foobar->foo); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php index a1f885399bd58..96c714493e8f3 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php @@ -1,5 +1,6 @@ register('monolog.logger', 'stdClass')->setPublic(true) + ->setProperty('handler', new Reference('mailer.transport')); + +$container->register('mailer.transport', 'stdClass')->setPublic($public) + ->setFactory([new Reference('mailer.transport_factory'), 'create']); + +$container->register('mailer.transport_factory', FactoryCircular::class)->setPublic($public) + ->addArgument(new TaggedIteratorArgument('mailer.transport')); + +$container->register('mailer.transport_factory.amazon', 'stdClass')->setPublic($public) + ->addArgument(new Reference('monolog.logger_2')) + ->addTag('mailer.transport'); + +$container->register('monolog.logger_2', 'stdClass')->setPublic($public) + ->setProperty('handler', new Reference('mailer.transport')); + // same visibility for deps $container->register('foo', FooCircular::class)->setPublic(true) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php index f3a490691a41d..46efa450acfff 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php @@ -111,6 +111,23 @@ public function __construct($lazyValues, $lazyEmptyValues) } } +class FactoryCircular +{ + public $services; + + public function __construct($services) + { + $this->services = $services; + } + + public function create() + { + foreach ($this->services as $service) { + return $service; + } + } +} + class FoobarCircular { public function __construct(FooCircular $foo) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php index 7df41fb810a34..069878fff86d3 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php @@ -39,6 +39,7 @@ public function __construct() 'manager' => 'getManagerService', 'manager2' => 'getManager2Service', 'manager3' => 'getManager3Service', + 'monolog.logger' => 'getMonolog_LoggerService', 'root' => 'getRootService', 'subscriber' => 'getSubscriberService', ]; @@ -80,7 +81,11 @@ public function getRemovedIds(): array 'level5' => true, 'level6' => true, 'logger2' => true, + 'mailer.transport' => true, + 'mailer.transport_factory' => true, + 'mailer.transport_factory.amazon' => true, 'manager4' => true, + 'monolog.logger_2' => true, 'multiuse1' => true, 'subscriber2' => true, ]; @@ -355,6 +360,20 @@ protected function getManager3Service($lazyLoad = true) return $this->services['manager3'] = new \stdClass($b); } + /** + * Gets the public 'monolog.logger' shared service. + * + * @return \stdClass + */ + protected function getMonolog_LoggerService() + { + $this->services['monolog.logger'] = $instance = new \stdClass(); + + $instance->handler = ($this->privates['mailer.transport'] ?? $this->getMailer_TransportService()); + + return $instance; + } + /** * Gets the public 'root' shared service. * @@ -419,6 +438,34 @@ protected function getLevel5Service() return $instance; } + /** + * Gets the private 'mailer.transport' shared service. + * + * @return \stdClass + */ + protected function getMailer_TransportService() + { + return $this->privates['mailer.transport'] = (new \FactoryCircular(new RewindableGenerator(function () { + yield 0 => ($this->privates['mailer.transport_factory.amazon'] ?? $this->getMailer_TransportFactory_AmazonService()); + }, 1)))->create(); + } + + /** + * Gets the private 'mailer.transport_factory.amazon' shared service. + * + * @return \stdClass + */ + protected function getMailer_TransportFactory_AmazonService() + { + $a = new \stdClass(); + + $this->privates['mailer.transport_factory.amazon'] = $instance = new \stdClass($a); + + $a->handler = ($this->privates['mailer.transport'] ?? $this->getMailer_TransportService()); + + return $instance; + } + /** * Gets the private 'manager4' shared service. * diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php index dda3f7b497471..e42560198ab4f 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php @@ -45,9 +45,14 @@ public function __construct() 'listener3' => 'getListener3Service', 'listener4' => 'getListener4Service', 'logger' => 'getLoggerService', + 'mailer.transport' => 'getMailer_TransportService', + 'mailer.transport_factory' => 'getMailer_TransportFactoryService', + 'mailer.transport_factory.amazon' => 'getMailer_TransportFactory_AmazonService', 'manager' => 'getManagerService', 'manager2' => 'getManager2Service', 'manager3' => 'getManager3Service', + 'monolog.logger' => 'getMonolog_LoggerService', + 'monolog.logger_2' => 'getMonolog_Logger2Service', 'root' => 'getRootService', 'subscriber' => 'getSubscriberService', ]; @@ -433,6 +438,50 @@ protected function getLoggerService() return $instance; } + /** + * Gets the public 'mailer.transport' shared service. + * + * @return \stdClass + */ + protected function getMailer_TransportService() + { + $a = ($this->services['mailer.transport_factory'] ?? $this->getMailer_TransportFactoryService()); + + if (isset($this->services['mailer.transport'])) { + return $this->services['mailer.transport']; + } + + return $this->services['mailer.transport'] = $a->create(); + } + + /** + * Gets the public 'mailer.transport_factory' shared service. + * + * @return \FactoryCircular + */ + protected function getMailer_TransportFactoryService() + { + return $this->services['mailer.transport_factory'] = new \FactoryCircular(new RewindableGenerator(function () { + yield 0 => ($this->services['mailer.transport_factory.amazon'] ?? $this->getMailer_TransportFactory_AmazonService()); + }, 1)); + } + + /** + * Gets the public 'mailer.transport_factory.amazon' shared service. + * + * @return \stdClass + */ + protected function getMailer_TransportFactory_AmazonService() + { + $a = ($this->services['monolog.logger_2'] ?? $this->getMonolog_Logger2Service()); + + if (isset($this->services['mailer.transport_factory.amazon'])) { + return $this->services['mailer.transport_factory.amazon']; + } + + return $this->services['mailer.transport_factory.amazon'] = new \stdClass($a); + } + /** * Gets the public 'manager' shared service. * @@ -481,6 +530,34 @@ protected function getManager3Service($lazyLoad = true) return $this->services['manager3'] = new \stdClass($a); } + /** + * Gets the public 'monolog.logger' shared service. + * + * @return \stdClass + */ + protected function getMonolog_LoggerService() + { + $this->services['monolog.logger'] = $instance = new \stdClass(); + + $instance->handler = ($this->services['mailer.transport'] ?? $this->getMailer_TransportService()); + + return $instance; + } + + /** + * Gets the public 'monolog.logger_2' shared service. + * + * @return \stdClass + */ + protected function getMonolog_Logger2Service() + { + $this->services['monolog.logger_2'] = $instance = new \stdClass(); + + $instance->handler = ($this->services['mailer.transport'] ?? $this->getMailer_TransportService()); + + return $instance; + } + /** * Gets the public 'root' shared service. * From 60e506835a4e62735151c30b8863cac71b210849 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Thu, 5 Nov 2020 00:24:50 +0100 Subject: [PATCH 074/136] [Security] Fix docblock. --- .../Core/Authentication/Token/Storage/TokenStorageInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorageInterface.php b/src/Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorageInterface.php index 218d750b8e097..779109039bfe6 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorageInterface.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorageInterface.php @@ -30,7 +30,7 @@ public function getToken(); /** * Sets the authentication token. * - * @param TokenInterface $token A TokenInterface token, or null if no further authentication information should be stored + * @param TokenInterface|null $token A TokenInterface token, or null if no further authentication information should be stored */ public function setToken(TokenInterface $token = null); } From f3a398b5af994080285eec250b8cbf7deadab426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Wed, 4 Nov 2020 21:14:54 +0100 Subject: [PATCH 075/136] Fix ANSI when stdErr is not a tty --- .../Component/Console/Output/ConsoleOutput.php | 7 +++++++ .../Console/Tests/Output/ConsoleOutputTest.php | 13 +++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Console/Output/ConsoleOutput.php b/src/Symfony/Component/Console/Output/ConsoleOutput.php index ff02f86943aa2..966fca09942a3 100644 --- a/src/Symfony/Component/Console/Output/ConsoleOutput.php +++ b/src/Symfony/Component/Console/Output/ConsoleOutput.php @@ -41,6 +41,13 @@ public function __construct(int $verbosity = self::VERBOSITY_NORMAL, bool $decor { parent::__construct($this->openOutputStream(), $verbosity, $decorated, $formatter); + if (null === $formatter) { + // for BC reasons, stdErr has it own Formatter only when user don't inject a specific formatter. + $this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated); + + return; + } + $actualDecorated = $this->isDecorated(); $this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated, $this->getFormatter()); diff --git a/src/Symfony/Component/Console/Tests/Output/ConsoleOutputTest.php b/src/Symfony/Component/Console/Tests/Output/ConsoleOutputTest.php index db39a02b8a616..33a5371d6e4b9 100644 --- a/src/Symfony/Component/Console/Tests/Output/ConsoleOutputTest.php +++ b/src/Symfony/Component/Console/Tests/Output/ConsoleOutputTest.php @@ -18,11 +18,19 @@ class ConsoleOutputTest extends TestCase { - public function testConstructor() + public function testConstructorWithoutFormatter() { $output = new ConsoleOutput(Output::VERBOSITY_QUIET, true); $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '__construct() takes the verbosity as its first argument'); - $this->assertSame($output->getFormatter(), $output->getErrorOutput()->getFormatter(), '__construct() takes a formatter or null as the third argument'); + $this->assertNotSame($output->getFormatter(), $output->getErrorOutput()->getFormatter(), 'ErrorOutput should use it own formatter'); + } + + public function testConstructorWithFormatter() + { + $output = new ConsoleOutput(Output::VERBOSITY_QUIET, true, $formatter = new OutputFormatter()); + $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '__construct() takes the verbosity as its first argument'); + $this->assertSame($formatter, $output->getFormatter()); + $this->assertSame($formatter, $output->getErrorOutput()->getFormatter(), 'Output and ErrorOutput should use the same provided formatter'); } public function testSetFormatter() @@ -31,6 +39,7 @@ public function testSetFormatter() $outputFormatter = new OutputFormatter(); $output->setFormatter($outputFormatter); $this->assertSame($outputFormatter, $output->getFormatter()); + $this->assertSame($outputFormatter, $output->getErrorOutput()->getFormatter()); } public function testSetVerbosity() From 0ab3032c52c6ffac19ebf2f3814b831019524ccf Mon Sep 17 00:00:00 2001 From: Nyholm Date: Thu, 5 Nov 2020 21:54:48 +0100 Subject: [PATCH 076/136] [CI] Fixed invalid doctrine parameter syntax --- .../Tests/Transport/Doctrine/DoctrineIntegrationTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/DoctrineIntegrationTest.php b/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/DoctrineIntegrationTest.php index e88e00364701f..d0b531387033e 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/DoctrineIntegrationTest.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/DoctrineIntegrationTest.php @@ -62,7 +62,7 @@ public function testSendWithDelay() ->select('m.available_at') ->from('messenger_messages', 'm') ->where('m.body = :body') - ->setParameter(':body', '{"message": "Hi i am delayed"}') + ->setParameter('body', '{"message": "Hi i am delayed"}') ->execute(); $available_at = new \DateTime($stmt instanceof Result || $stmt instanceof DriverResult ? $stmt->fetchOne() : $stmt->fetchColumn()); From 5f77aad6ca74a77baf14f684d6eebbbd008c4158 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 6 Nov 2020 15:18:27 +0100 Subject: [PATCH 077/136] [ProxyManagerBridge] replace ProxyManager\Version by feature detection --- .../LazyProxy/PhpDumper/ProxyDumper.php | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php index c949ef3a9786a..c657e940dc74e 100644 --- a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php +++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php @@ -11,9 +11,10 @@ namespace Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper; +use ProxyManager\Exception\ExceptionInterface; use ProxyManager\Generator\ClassGenerator; +use ProxyManager\Generator\MethodGenerator; use ProxyManager\GeneratorStrategy\BaseGeneratorStrategy; -use ProxyManager\Version; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface; @@ -87,7 +88,7 @@ public function getProxyCode(Definition $definition): string $code = $this->classGenerator->generate($this->generateProxyClass($definition)); $code = preg_replace('/^(class [^ ]++ extends )([^\\\\])/', '$1\\\\$2', $code); - if (version_compare(self::getProxyManagerVersion(), '2.2', '<')) { + if (!method_exists(MethodGenerator::class, 'fromReflectionWithoutBodyAndDocBlock')) { // proxy-manager < 2.2 $code = preg_replace( '/((?:\$(?:this|initializer|instance)->)?(?:publicProperties|initializer|valueHolder))[0-9a-f]++/', '${1}'.$this->getIdentifierSuffix($definition), @@ -95,22 +96,13 @@ public function getProxyCode(Definition $definition): string ); } - if (version_compare(self::getProxyManagerVersion(), '2.5', '<')) { + if (!is_subclass_of(ExceptionInterface::class, 'Throwable')) { // proxy-manager < 2.5 $code = preg_replace('/ \\\\Closure::bind\(function ((?:& )?\(\$instance(?:, \$value)?\))/', ' \Closure::bind(static function \1', $code); } return $code; } - private static function getProxyManagerVersion(): string - { - if (!class_exists(Version::class)) { - return '0.0.1'; - } - - return \defined(Version::class.'::VERSION') ? Version::VERSION : Version::getVersion(); - } - /** * Produces the proxy class name for the given definition. */ From 969da48c98bbfeef88157c190a83ef3cb23fe930 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sat, 7 Nov 2020 15:21:55 +0100 Subject: [PATCH 078/136] [DoctrineBridge] Fix DBAL deprecations in middlewares. --- .../Doctrine/Messenger/DoctrinePingConnectionMiddleware.php | 5 +++-- .../Tests/Messenger/DoctrinePingConnectionMiddlewareTest.php | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Messenger/DoctrinePingConnectionMiddleware.php b/src/Symfony/Bridge/Doctrine/Messenger/DoctrinePingConnectionMiddleware.php index 3ec525d2cfd41..c6b219aa795ab 100644 --- a/src/Symfony/Bridge/Doctrine/Messenger/DoctrinePingConnectionMiddleware.php +++ b/src/Symfony/Bridge/Doctrine/Messenger/DoctrinePingConnectionMiddleware.php @@ -12,6 +12,7 @@ namespace Symfony\Bridge\Doctrine\Messenger; use Doctrine\DBAL\DBALException; +use Doctrine\DBAL\Exception; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\Middleware\StackInterface; @@ -38,8 +39,8 @@ private function pingConnection(EntityManagerInterface $entityManager) $connection = $entityManager->getConnection(); try { - $connection->query($connection->getDatabasePlatform()->getDummySelectSQL()); - } catch (DBALException $e) { + $connection->executeQuery($connection->getDatabasePlatform()->getDummySelectSQL()); + } catch (DBALException | Exception $e) { $connection->close(); $connection->connect(); } diff --git a/src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrinePingConnectionMiddlewareTest.php b/src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrinePingConnectionMiddlewareTest.php index e491558a2addf..f99a48527c442 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrinePingConnectionMiddlewareTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrinePingConnectionMiddlewareTest.php @@ -13,6 +13,7 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\DBALException; +use Doctrine\DBAL\Exception; use Doctrine\ORM\EntityManagerInterface; use Doctrine\Persistence\ManagerRegistry; use Symfony\Bridge\Doctrine\Messenger\DoctrinePingConnectionMiddleware; @@ -49,7 +50,7 @@ public function testMiddlewarePingOk() { $this->connection->expects($this->once()) ->method('getDatabasePlatform') - ->will($this->throwException(new DBALException())); + ->will($this->throwException(class_exists(Exception::class) ? new Exception() : new DBALException())); $this->connection->expects($this->once()) ->method('close') @@ -68,7 +69,7 @@ public function testMiddlewarePingResetEntityManager() { $this->connection->expects($this->once()) ->method('getDatabasePlatform') - ->will($this->throwException(new DBALException())); + ->will($this->throwException(class_exists(Exception::class) ? new Exception() : new DBALException())); $this->entityManager->expects($this->once()) ->method('isOpen') From bc42cf604e9ff2cf716bc087e144ade92a881dbc Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Sat, 7 Nov 2020 15:33:20 +0100 Subject: [PATCH 079/136] [Messenger] Fix DBAL deprecations in PostgreSQLConnection --- .../Messenger/Bridge/Doctrine/Transport/Connection.php | 2 +- .../Bridge/Doctrine/Transport/PostgreSqlConnection.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php index ba095f288cd3b..51d29c635343a 100644 --- a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php +++ b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php @@ -372,7 +372,7 @@ private function executeQuery(string $sql, array $parameters = [], array $types return $stmt; } - private function executeStatement(string $sql, array $parameters = [], array $types = []) + protected function executeStatement(string $sql, array $parameters = [], array $types = []) { try { if (method_exists($this->driverConnection, 'executeStatement')) { diff --git a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/PostgreSqlConnection.php b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/PostgreSqlConnection.php index 79a1dd68ba411..9dc8b77e38756 100644 --- a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/PostgreSqlConnection.php +++ b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/PostgreSqlConnection.php @@ -64,7 +64,7 @@ public function get(): ?array if (!$this->listening) { // This is secure because the table name must be a valid identifier: // https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS - $this->driverConnection->exec(sprintf('LISTEN "%s"', $this->configuration['table_name'])); + $this->executeStatement(sprintf('LISTEN "%s"', $this->configuration['table_name'])); $this->listening = true; } @@ -87,7 +87,7 @@ public function setup(): void { parent::setup(); - $this->driverConnection->exec(implode("\n", $this->getTriggerSql())); + $this->executeStatement(implode("\n", $this->getTriggerSql())); } /** @@ -134,7 +134,7 @@ private function unlisten() return; } - $this->driverConnection->exec(sprintf('UNLISTEN "%s"', $this->configuration['table_name'])); + $this->executeStatement(sprintf('UNLISTEN "%s"', $this->configuration['table_name'])); $this->listening = false; } } From 4fe0a6f2b941734c1e0f0f335d240723e331480c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Sat, 7 Nov 2020 21:18:28 +0100 Subject: [PATCH 080/136] Fix LDAP pagination --- src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php b/src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php index 151e47881143f..6bb798319c851 100644 --- a/src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php +++ b/src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php @@ -174,7 +174,7 @@ public function getResources(): array private function resetPagination() { $con = $this->connection->getResource(); - $this->controlPagedResultResponse($con, 0, ''); + $this->controlPagedResult($con, 0, ''); $this->serverctrls = []; // This is a workaround for a bit of a bug in the above invocation From 784bd0080d66624cb01b1e293559df7c43e099e9 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 9 Nov 2020 09:59:19 +0100 Subject: [PATCH 081/136] also reset id readers --- src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php b/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php index 97f5facf62e74..4ff2e508c18bb 100644 --- a/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php +++ b/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php @@ -279,6 +279,7 @@ public function getParent() public function reset() { + $this->idReaders = []; $this->choiceLoaders = []; } } From e649f47726dfe7d1375a7e4d7fa1abb1929f0cac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Fri, 6 Nov 2020 17:43:05 +0100 Subject: [PATCH 082/136] Optimize circular collection by removing flattening --- .../DependencyInjection/Dumper/PhpDumper.php | 63 ++++++------------- 1 file changed, 18 insertions(+), 45 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 584eff5fd1d2f..6d0120dfa4811 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -406,69 +406,42 @@ private function analyzeReferences() $this->singleUsePrivateIds[$id] = $id; } - $newNodes = []; - if (!$this->collectCircularReferences($id, $node->getOutEdges(), $checkedNodes, $newNodes)) { - foreach ($newNodes as $newNodeId => $_) { - $checkedNodes[$newNodeId] = []; - } - continue; - } - - $nodesToFlatten = $newNodes; - do { - $changedNodes = []; - foreach ($nodesToFlatten as $newNodeId => $_) { - $deps = &$checkedNodes[$newNodeId]; - foreach ($deps as $id => [$path, $depsByConstructor]) { - foreach ($checkedNodes[$id] as $depsId => [$subPath, $subDepsByConstructor]) { - if (!isset($deps[$depsId]) || ($depsByConstructor && $subDepsByConstructor && !$deps[$depsId][1])) { - array_unshift($subPath, $id); - $deps[$depsId] = [$subPath, $depsByConstructor && $subDepsByConstructor]; - $changedNodes += $newNodes[$newNodeId] ?? []; - } - } - } - } - } while ($nodesToFlatten = $changedNodes); - - foreach ($newNodes as $newNodeId => $_) { - if (null !== $n = $checkedNodes[$newNodeId][$newNodeId] ?? null) { - $this->addCircularReferences($newNodeId, $n[0], $n[1]); - } - } + $this->collectCircularReferences($id, $node->getOutEdges(), $checkedNodes); } $this->container->getCompiler()->getServiceReferenceGraph()->clear(); $this->singleUsePrivateIds = array_diff_key($this->singleUsePrivateIds, $this->circularReferences); } - private function collectCircularReferences(string $sourceId, array $edges, array &$checkedNodes, array &$newNodes, array $path = []): bool + private function collectCircularReferences(string $sourceId, array $edges, array &$checkedNodes, array $path = [], bool $byConstructor = true): void { - $path[$sourceId] = true; - $checkedNodes[$sourceId] = []; - $newNodes[$sourceId] = []; - $circular = false; + $path[$sourceId] = $byConstructor; + $checkedNodes[$sourceId] = true; foreach ($edges as $edge) { $node = $edge->getDestNode(); $id = $node->getId(); - if (!$node->getValue() instanceof Definition || $sourceId === $id || $edge->isWeak()) { + + if (!($definition = $node->getValue()) instanceof Definition || $sourceId === $id || ($edge->isLazy() && ($this->proxyDumper ?? $this->getProxyDumper())->isProxyCandidate($definition)) || $edge->isWeak()) { continue; } if (isset($path[$id])) { - $circular = true; + $loop = null; + $loopByConstructor = $edge->isReferencedByConstructor(); + foreach ($path as $k => $pathByConstructor) { + if (null !== $loop) { + $loop[] = $k; + $loopByConstructor = $loopByConstructor && $pathByConstructor; + } elseif ($k === $id) { + $loop = []; + } + } + $this->addCircularReferences($id, $loop, $loopByConstructor); } elseif (!isset($checkedNodes[$id])) { - $circular = $this->collectCircularReferences($id, $node->getOutEdges(), $checkedNodes, $newNodes, $path) || $circular; - } - - $checkedNodes[$sourceId][$id] = [[], $edge->isReferencedByConstructor()]; - if (isset($newNodes[$id])) { - $newNodes[$id][$sourceId] = true; + $this->collectCircularReferences($id, $node->getOutEdges(), $checkedNodes, $path, $edge->isReferencedByConstructor()); } } unset($path[$sourceId]); - - return $circular; } private function addCircularReferences(string $sourceId, array $currentPath, bool $byConstructor) From 4c361456644d7d7f7fadc79c8633572c33a94d72 Mon Sep 17 00:00:00 2001 From: Juan Miguel Besada Date: Mon, 19 Oct 2020 12:26:04 +0200 Subject: [PATCH 083/136] [DoctrineBridge] indexBy could reference to association columns --- .../PropertyInfo/DoctrineExtractor.php | 18 ++++++++++++++++-- .../PropertyInfo/DoctrineExtractorTest.php | 18 ++++++++++++++++++ .../PropertyInfo/Fixtures/DoctrineDummy.php | 10 ++++++++++ .../PropertyInfo/Fixtures/DoctrineRelation.php | 5 +++++ 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php b/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php index 0cfdc8768c9fe..651ff3e96c79d 100644 --- a/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php +++ b/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php @@ -110,10 +110,24 @@ public function getTypes($class, $property, array $context = []) $associationMapping = $metadata->getAssociationMapping($property); if (isset($associationMapping['indexBy'])) { - $indexColumn = $associationMapping['indexBy']; /** @var ClassMetadataInfo $subMetadata */ $subMetadata = $this->classMetadataFactory->getMetadataFor($associationMapping['targetEntity']); - $typeOfField = $subMetadata->getTypeOfField($subMetadata->getFieldForColumn($indexColumn)); + + // Check if indexBy value is a property + $fieldName = $associationMapping['indexBy']; + if (null === ($typeOfField = $subMetadata->getTypeOfField($fieldName))) { + $fieldName = $subMetadata->getFieldForColumn($associationMapping['indexBy']); + //Not a property, maybe a column name? + if (null === ($typeOfField = $subMetadata->getTypeOfField($fieldName))) { + //Maybe the column name is the association join column? + $associationMapping = $subMetadata->getAssociationMapping($fieldName); + + /** @var ClassMetadataInfo $subMetadata */ + $indexProperty = $subMetadata->getSingleAssociationReferencedJoinColumnName($fieldName); + $subMetadata = $this->classMetadataFactory->getMetadataFor($associationMapping['targetEntity']); + $typeOfField = $subMetadata->getTypeOfField($indexProperty); + } + } if (!$collectionKeyType = $this->getPhpType($typeOfField)) { return null; diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php index b9abd03347e83..845a0612b81af 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php @@ -72,8 +72,10 @@ public function testGetProperties() $expected = array_merge($expected, [ 'foo', 'bar', + 'indexedRguid', 'indexedBar', 'indexedFoo', + 'indexedBaz', 'indexedByDt', 'indexedByCustomType', ]); @@ -151,6 +153,14 @@ public function typesProvider() new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineRelation') )]], + ['indexedRguid', [new Type( + Type::BUILTIN_TYPE_OBJECT, + false, + 'Doctrine\Common\Collections\Collection', + true, + new Type(Type::BUILTIN_TYPE_STRING), + new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineRelation') + )]], ['indexedBar', [new Type( Type::BUILTIN_TYPE_OBJECT, false, @@ -167,6 +177,14 @@ public function typesProvider() new Type(Type::BUILTIN_TYPE_STRING), new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineRelation') )]], + ['indexedBaz', [new Type( + Type::BUILTIN_TYPE_OBJECT, + false, + Collection::class, + true, + new Type(Type::BUILTIN_TYPE_INT), + new Type(Type::BUILTIN_TYPE_OBJECT, false, DoctrineRelation::class) + )]], ['simpleArray', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING))]], ['customFoo', null], ['notMapped', null], diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php index 568efce33d382..46e5b2341476d 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php +++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php @@ -41,6 +41,11 @@ class DoctrineDummy */ public $bar; + /** + * @ManyToMany(targetEntity="DoctrineRelation", indexBy="rguid") + */ + protected $indexedRguid; + /** * @ManyToMany(targetEntity="DoctrineRelation", indexBy="rguid_column") */ @@ -51,6 +56,11 @@ class DoctrineDummy */ protected $indexedFoo; + /** + * @OneToMany(targetEntity="DoctrineRelation", mappedBy="baz", indexBy="baz_id") + */ + protected $indexedBaz; + /** * @Column(type="guid") */ diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineRelation.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineRelation.php index e480ca9d777ba..b40c0883e1213 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineRelation.php +++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineRelation.php @@ -40,6 +40,11 @@ class DoctrineRelation */ protected $foo; + /** + * @ManyToOne(targetEntity="DoctrineDummy") + */ + protected $baz; + /** * @Column(type="datetime") */ From f9a0e000e93773f6c44342d5376c0c03ce3c091a Mon Sep 17 00:00:00 2001 From: Bart Wach Date: Thu, 29 Oct 2020 21:30:43 +0100 Subject: [PATCH 084/136] failing test for issue 38861 --- .../Tests/PropertyInfo/DoctrineExtractorTest.php | 9 +++++++++ .../Tests/PropertyInfo/Fixtures/DoctrineDummy.php | 5 +++++ .../Tests/PropertyInfo/Fixtures/DoctrineRelation.php | 6 ++++++ 3 files changed, 20 insertions(+) diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php index 845a0612b81af..98d64cefd77e9 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php @@ -78,6 +78,7 @@ public function testGetProperties() 'indexedBaz', 'indexedByDt', 'indexedByCustomType', + 'indexedBuz', ]); $this->assertEquals( @@ -197,6 +198,14 @@ public function typesProvider() new Type(Type::BUILTIN_TYPE_OBJECT, false, DoctrineRelation::class) )]], ['indexedByCustomType', null], + ['indexedBuz', [new Type( + Type::BUILTIN_TYPE_OBJECT, + false, + Collection::class, + true, + new Type(Type::BUILTIN_TYPE_STRING), + new Type(Type::BUILTIN_TYPE_OBJECT, false, DoctrineRelation::class) + )]], ]; if (class_exists(Types::class)) { diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php index 46e5b2341476d..a065dc49cd2d4 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php +++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php @@ -132,4 +132,9 @@ class DoctrineDummy * @OneToMany(targetEntity="DoctrineRelation", mappedBy="customType", indexBy="customType") */ private $indexedByCustomType; + + /** + * @OneToMany(targetEntity="DoctrineRelation", mappedBy="buzField", indexBy="buzField") + */ + protected $indexedBuz; } diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineRelation.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineRelation.php index b40c0883e1213..d6d9af6d70c38 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineRelation.php +++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineRelation.php @@ -54,4 +54,10 @@ class DoctrineRelation * @Column(type="foo") */ private $customType; + + /** + * @Column(type="guid", name="different_than_field") + * @ManyToOne(targetEntity="DoctrineDummy", inversedBy="indexedBuz") + */ + protected $buzField; } From 7b733d651daddec4ea72a19d946de06ec94203fb Mon Sep 17 00:00:00 2001 From: Nyholm Date: Tue, 10 Nov 2020 15:44:29 +0100 Subject: [PATCH 085/136] [MimeType] Add missing alias for @mime_type --- .../Bundle/FrameworkBundle/Resources/config/mime_type.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/mime_type.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/mime_type.xml index d4c1eb15b9088..e91705d1c19ed 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/mime_type.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/mime_type.xml @@ -12,5 +12,7 @@ + + From 1c3721e8adb5b1908086c9246888c9965405d10e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Wed, 11 Nov 2020 19:12:08 +0100 Subject: [PATCH 086/136] Fix circular detection with multiple paths --- .../DependencyInjection/Dumper/PhpDumper.php | 40 ++++++++++- .../Tests/ContainerBuilderTest.php | 3 + .../Tests/Dumper/PhpDumperTest.php | 3 + .../containers/container_almost_circular.php | 15 ++++ .../php/services_almost_circular_private.php | 56 +++++++++++++++ .../php/services_almost_circular_public.php | 69 +++++++++++++++++++ 6 files changed, 183 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 6d0120dfa4811..a9c46edd66efe 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -413,14 +413,13 @@ private function analyzeReferences() $this->singleUsePrivateIds = array_diff_key($this->singleUsePrivateIds, $this->circularReferences); } - private function collectCircularReferences(string $sourceId, array $edges, array &$checkedNodes, array $path = [], bool $byConstructor = true): void + private function collectCircularReferences(string $sourceId, array $edges, array &$checkedNodes, array &$loops = [], array $path = [], bool $byConstructor = true): void { $path[$sourceId] = $byConstructor; $checkedNodes[$sourceId] = true; foreach ($edges as $edge) { $node = $edge->getDestNode(); $id = $node->getId(); - if (!($definition = $node->getValue()) instanceof Definition || $sourceId === $id || ($edge->isLazy() && ($this->proxyDumper ?? $this->getProxyDumper())->isProxyCandidate($definition)) || $edge->isWeak()) { continue; } @@ -428,9 +427,12 @@ private function collectCircularReferences(string $sourceId, array $edges, array if (isset($path[$id])) { $loop = null; $loopByConstructor = $edge->isReferencedByConstructor(); + $pathInLoop = [$id, []]; foreach ($path as $k => $pathByConstructor) { if (null !== $loop) { $loop[] = $k; + $pathInLoop[1][$k] = $pathByConstructor; + $loops[$k][] = &$pathInLoop; $loopByConstructor = $loopByConstructor && $pathByConstructor; } elseif ($k === $id) { $loop = []; @@ -438,7 +440,39 @@ private function collectCircularReferences(string $sourceId, array $edges, array } $this->addCircularReferences($id, $loop, $loopByConstructor); } elseif (!isset($checkedNodes[$id])) { - $this->collectCircularReferences($id, $node->getOutEdges(), $checkedNodes, $path, $edge->isReferencedByConstructor()); + $this->collectCircularReferences($id, $node->getOutEdges(), $checkedNodes, $loops, $path, $edge->isReferencedByConstructor()); + } elseif (isset($loops[$id])) { + // we already had detected loops for this edge + // let's check if we have a common ancestor in one of the detected loops + foreach ($loops[$id] as [$first, $loopPath]) { + if (!isset($path[$first])) { + continue; + } + // We have a common ancestor, let's fill the current path + $fillPath = null; + foreach ($loopPath as $k => $pathByConstructor) { + if (null !== $fillPath) { + $fillPath[$k] = $pathByConstructor; + } elseif ($k === $id) { + $fillPath = $path; + $fillPath[$k] = $pathByConstructor; + } + } + + // we can now build the loop + $loop = null; + $loopByConstructor = $edge->isReferencedByConstructor(); + foreach ($fillPath as $k => $pathByConstructor) { + if (null !== $loop) { + $loop[] = $k; + $loopByConstructor = $loopByConstructor && $pathByConstructor; + } elseif ($k === $first) { + $loop = []; + } + } + $this->addCircularReferences($first, $loop, true); + break; + } } } unset($path[$sourceId]); diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index b78fbd72ea5a8..dc462a0ee5853 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -1374,6 +1374,9 @@ public function testAlmostCircular($visibility) $container = include __DIR__.'/Fixtures/containers/container_almost_circular.php'; $container->compile(); + $pA = $container->get('pA'); + $this->assertEquals(new \stdClass(), $pA); + $logger = $container->get('monolog.logger'); $this->assertEquals(new \stdClass(), $logger->handler); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 663e3fe66dbaf..0e5e0f5a716b8 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -1054,6 +1054,9 @@ public function testAlmostCircular($visibility) $container = new $container(); + $pA = $container->get('pA'); + $this->assertEquals(new \stdClass(), $pA); + $logger = $container->get('monolog.logger'); $this->assertEquals(new \stdClass(), $logger->handler); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php index 96c714493e8f3..6a0b2da766cdd 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php @@ -9,6 +9,21 @@ $public = 'public' === $visibility; $container = new ContainerBuilder(); +// multiple path detection + +$container->register('pA', 'stdClass')->setPublic(true) + ->addArgument(new Reference('pB')) + ->addArgument(new Reference('pC')); + +$container->register('pB', 'stdClass')->setPublic($public) + ->setProperty('d', new Reference('pD')); +$container->register('pC', 'stdClass')->setPublic($public) + ->setLazy(true) + ->setProperty('d', new Reference('pD')); + +$container->register('pD', 'stdClass')->setPublic($public) + ->addArgument(new Reference('pA')); + // monolog-like + handler that require monolog $container->register('monolog.logger', 'stdClass')->setPublic(true) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php index 069878fff86d3..0ef3627e69eaf 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php @@ -40,6 +40,7 @@ public function __construct() 'manager2' => 'getManager2Service', 'manager3' => 'getManager3Service', 'monolog.logger' => 'getMonolog_LoggerService', + 'pA' => 'getPAService', 'root' => 'getRootService', 'subscriber' => 'getSubscriberService', ]; @@ -87,6 +88,9 @@ public function getRemovedIds(): array 'manager4' => true, 'monolog.logger_2' => true, 'multiuse1' => true, + 'pB' => true, + 'pC' => true, + 'pD' => true, 'subscriber2' => true, ]; } @@ -374,6 +378,28 @@ protected function getMonolog_LoggerService() return $instance; } + /** + * Gets the public 'pA' shared service. + * + * @return \stdClass + */ + protected function getPAService() + { + $a = new \stdClass(); + + $b = ($this->privates['pC'] ?? $this->getPCService()); + + if (isset($this->services['pA'])) { + return $this->services['pA']; + } + + $this->services['pA'] = $instance = new \stdClass($a, $b); + + $a->d = ($this->privates['pD'] ?? $this->getPDService()); + + return $instance; + } + /** * Gets the public 'root' shared service. * @@ -481,4 +507,34 @@ protected function getManager4Service($lazyLoad = true) return $instance; } + + /** + * Gets the private 'pC' shared service. + * + * @return \stdClass + */ + protected function getPCService($lazyLoad = true) + { + $this->privates['pC'] = $instance = new \stdClass(); + + $instance->d = ($this->privates['pD'] ?? $this->getPDService()); + + return $instance; + } + + /** + * Gets the private 'pD' shared service. + * + * @return \stdClass + */ + protected function getPDService() + { + $a = ($this->services['pA'] ?? $this->getPAService()); + + if (isset($this->privates['pD'])) { + return $this->privates['pD']; + } + + return $this->privates['pD'] = new \stdClass($a); + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php index e42560198ab4f..ddc1f59a269b9 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php @@ -53,6 +53,10 @@ public function __construct() 'manager3' => 'getManager3Service', 'monolog.logger' => 'getMonolog_LoggerService', 'monolog.logger_2' => 'getMonolog_Logger2Service', + 'pA' => 'getPAService', + 'pB' => 'getPBService', + 'pC' => 'getPCService', + 'pD' => 'getPDService', 'root' => 'getRootService', 'subscriber' => 'getSubscriberService', ]; @@ -558,6 +562,71 @@ protected function getMonolog_Logger2Service() return $instance; } + /** + * Gets the public 'pA' shared service. + * + * @return \stdClass + */ + protected function getPAService() + { + $a = ($this->services['pB'] ?? $this->getPBService()); + + if (isset($this->services['pA'])) { + return $this->services['pA']; + } + $b = ($this->services['pC'] ?? $this->getPCService()); + + if (isset($this->services['pA'])) { + return $this->services['pA']; + } + + return $this->services['pA'] = new \stdClass($a, $b); + } + + /** + * Gets the public 'pB' shared service. + * + * @return \stdClass + */ + protected function getPBService() + { + $this->services['pB'] = $instance = new \stdClass(); + + $instance->d = ($this->services['pD'] ?? $this->getPDService()); + + return $instance; + } + + /** + * Gets the public 'pC' shared service. + * + * @return \stdClass + */ + protected function getPCService($lazyLoad = true) + { + $this->services['pC'] = $instance = new \stdClass(); + + $instance->d = ($this->services['pD'] ?? $this->getPDService()); + + return $instance; + } + + /** + * Gets the public 'pD' shared service. + * + * @return \stdClass + */ + protected function getPDService() + { + $a = ($this->services['pA'] ?? $this->getPAService()); + + if (isset($this->services['pD'])) { + return $this->services['pD']; + } + + return $this->services['pD'] = new \stdClass($a); + } + /** * Gets the public 'root' shared service. * From 33fce73bdfee5be8c6ba9e789327b1679c93b2e7 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 11 Nov 2020 23:10:29 +0100 Subject: [PATCH 087/136] [Filesystem] fix cleaning up tmp files when dumpFile() fails --- src/Symfony/Component/Filesystem/Filesystem.php | 14 +++++++++----- .../Component/Filesystem/Tests/FilesystemTest.php | 12 ++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index 5d698e1da2a64..95e4a801071b8 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -686,13 +686,17 @@ public function dumpFile($filename, $content) // when the filesystem supports chmod. $tmpFile = $this->tempnam($dir, basename($filename)); - if (false === @file_put_contents($tmpFile, $content)) { - throw new IOException(sprintf('Failed to write file "%s".', $filename), 0, null, $filename); - } + try { + if (false === @file_put_contents($tmpFile, $content)) { + throw new IOException(sprintf('Failed to write file "%s".', $filename), 0, null, $filename); + } - @chmod($tmpFile, file_exists($filename) ? fileperms($filename) : 0666 & ~umask()); + @chmod($tmpFile, file_exists($filename) ? fileperms($filename) : 0666 & ~umask()); - $this->rename($tmpFile, $filename, true); + $this->rename($tmpFile, $filename, true); + } finally { + @unlink($tmpFile); + } } /** diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php index 0c012a6921746..b697d7f47898f 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php @@ -1710,6 +1710,18 @@ public function testAppendToFileCreateTheFileIfNotExists() $this->assertStringEqualsFile($filename, 'bar'); } + public function testDumpRemovesTmpFilesOnFailure() + { + $expected = scandir(__DIR__, \SCANDIR_SORT_ASCENDING); + + try { + $this->filesystem->dumpFile(__DIR__.'/Fixtures', 'bar'); + $this->fail('IOException expected.'); + } catch (IOException $e) { + $this->assertSame($expected, scandir(__DIR__, \SCANDIR_SORT_ASCENDING)); + } + } + public function testDumpKeepsExistingPermissionsWhenOverwritingAnExistingFile() { $this->markAsSkippedIfChmodIsMissing(); From 9645fa39ece71f41c583ab5153cfda209bec4c8c Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Fri, 14 Aug 2020 10:22:32 +0200 Subject: [PATCH 088/136] [Validator][RecursiveContextualValidator] Prevent validated hash collisions --- .../Validator/RecursiveValidatorTest.php | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php b/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php index 1af4c9acfa9bd..f9aa6831ce0c4 100644 --- a/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php @@ -13,11 +13,14 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Translation\IdentityTranslator; +use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Constraints\All; use Symfony\Component\Validator\Constraints\Callback; use Symfony\Component\Validator\Constraints\Collection; use Symfony\Component\Validator\Constraints\Expression; use Symfony\Component\Validator\Constraints\GroupSequence; +use Symfony\Component\Validator\Constraints\IsFalse; +use Symfony\Component\Validator\Constraints\IsNull; use Symfony\Component\Validator\Constraints\IsTrue; use Symfony\Component\Validator\Constraints\Length; use Symfony\Component\Validator\Constraints\NotBlank; @@ -26,6 +29,7 @@ use Symfony\Component\Validator\Constraints\Required; use Symfony\Component\Validator\Constraints\Traverse; use Symfony\Component\Validator\Constraints\Valid; +use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\ConstraintValidatorFactory; use Symfony\Component\Validator\ConstraintViolationInterface; use Symfony\Component\Validator\Context\ExecutionContextFactory; @@ -2135,4 +2139,47 @@ public function testOptionalConstraintIsIgnored() $this->assertCount(0, $violations); } + + public function testValidatedConstraintsHashesDoNotCollide() + { + $metadata = new ClassMetadata(Entity::class); + $metadata->addPropertyConstraint('initialized', new NotNull(['groups' => 'should_pass'])); + $metadata->addPropertyConstraint('initialized', new IsNull(['groups' => 'should_fail'])); + + $this->metadataFactory->addMetadata($metadata); + + $entity = new Entity(); + $entity->data = new \stdClass(); + + $this->assertCount(2, $this->validator->validate($entity, new TestConstraintHashesDoNotCollide())); + } +} + +final class TestConstraintHashesDoNotCollide extends Constraint +{ +} + +final class TestConstraintHashesDoNotCollideValidator extends ConstraintValidator +{ + /** + * {@inheritdoc} + */ + public function validate($value, Constraint $constraint) + { + if (!$value instanceof Entity) { + throw new \LogicException(); + } + + $this->context->getValidator() + ->inContext($this->context) + ->atPath('data') + ->validate($value, new NotNull()) + ->validate($value, new NotNull()) + ->validate($value, new IsFalse()); + + $this->context->getValidator() + ->inContext($this->context) + ->validate($value, null, new GroupSequence(['should_pass'])) + ->validate($value, null, new GroupSequence(['should_fail'])); + } } From 47041370c06591f4b4cca94839d3381bec1fe577 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 12 Nov 2020 13:55:13 +0100 Subject: [PATCH 089/136] [ProxyManagerBridge] relax fixture in tests --- .../Tests/LazyProxy/PhpDumper/Fixtures/proxy-implem.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-implem.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-implem.php index 3362aab9fb5eb..c8239fc37d29b 100644 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-implem.php +++ b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-implem.php @@ -76,7 +76,7 @@ public function & __get($name) $targetObject = $this->valueHolder%s; - $backtrace = debug_backtrace(false); + $backtrace = debug_backtrace(false%S); trigger_error( sprintf( 'Undefined property: %s::$%s in %s on line %s', @@ -114,8 +114,7 @@ public function __unset($name) $targetObject = $this->valueHolder%s; - unset($targetObject->$name); -return; + unset($targetObject->$name);%S } public function __clone() From ecf9859609697785af2172b0bdb15c9a79a72331 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 12 Nov 2020 14:19:35 +0100 Subject: [PATCH 090/136] [ProxyManagerBridge] fix tests --- .../Tests/LazyProxy/PhpDumper/Fixtures/proxy-implem.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-implem.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-implem.php index c8239fc37d29b..684ff36581776 100644 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-implem.php +++ b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-implem.php @@ -114,8 +114,8 @@ public function __unset($name) $targetObject = $this->valueHolder%s; - unset($targetObject->$name);%S - } + unset($targetObject->$name); +%a } public function __clone() { From 7b4310f045526186f19042bd4e34a52fed423fd1 Mon Sep 17 00:00:00 2001 From: Thomas P Date: Fri, 30 Oct 2020 15:19:28 +0100 Subject: [PATCH 091/136] Add tests on CacheDataCollector --- .../DataCollector/CacheDataCollectorTest.php | 98 +++++++++++++++++++ src/Symfony/Component/Cache/composer.json | 1 + 2 files changed, 99 insertions(+) create mode 100644 src/Symfony/Component/Cache/Tests/DataCollector/CacheDataCollectorTest.php diff --git a/src/Symfony/Component/Cache/Tests/DataCollector/CacheDataCollectorTest.php b/src/Symfony/Component/Cache/Tests/DataCollector/CacheDataCollectorTest.php new file mode 100644 index 0000000000000..f704bbfe0e49f --- /dev/null +++ b/src/Symfony/Component/Cache/Tests/DataCollector/CacheDataCollectorTest.php @@ -0,0 +1,98 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Marshaller; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Cache\Adapter\TraceableAdapter; +use Symfony\Component\Cache\DataCollector\CacheDataCollector; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +class CacheDataCollectorTest extends TestCase +{ + private const INSTANCE_NAME = 'test'; + + public function testEmptyDataCollector() + { + $statistics = $this->getCacheDataCollectorStatisticsFromEvents([]); + + $this->assertEquals($statistics[self::INSTANCE_NAME]['calls'], 0, 'calls'); + $this->assertEquals($statistics[self::INSTANCE_NAME]['reads'], 0, 'reads'); + $this->assertEquals($statistics[self::INSTANCE_NAME]['hits'], 0, 'hits'); + $this->assertEquals($statistics[self::INSTANCE_NAME]['misses'], 0, 'misses'); + $this->assertEquals($statistics[self::INSTANCE_NAME]['writes'], 0, 'writes'); + } + + public function testOneEventDataCollector() + { + $traceableAdapterEvent = new \stdClass(); + $traceableAdapterEvent->name = 'getItem'; + $traceableAdapterEvent->start = 0; + $traceableAdapterEvent->end = 0; + $traceableAdapterEvent->hits = 0; + + $statistics = $this->getCacheDataCollectorStatisticsFromEvents([$traceableAdapterEvent]); + + $this->assertEquals($statistics[self::INSTANCE_NAME]['calls'], 1, 'calls'); + $this->assertEquals($statistics[self::INSTANCE_NAME]['reads'], 1, 'reads'); + $this->assertEquals($statistics[self::INSTANCE_NAME]['hits'], 0, 'hits'); + $this->assertEquals($statistics[self::INSTANCE_NAME]['misses'], 1, 'misses'); + $this->assertEquals($statistics[self::INSTANCE_NAME]['writes'], 0, 'writes'); + } + + public function testHitedEventDataCollector() + { + $traceableAdapterEvent = new \stdClass(); + $traceableAdapterEvent->name = 'hasItem'; + $traceableAdapterEvent->start = 0; + $traceableAdapterEvent->end = 0; + $traceableAdapterEvent->hits = 1; + $traceableAdapterEvent->misses = 0; + $traceableAdapterEvent->result = ['foo' => false]; + + $statistics = $this->getCacheDataCollectorStatisticsFromEvents([$traceableAdapterEvent]); + + $this->assertEquals($statistics[self::INSTANCE_NAME]['calls'], 1, 'calls'); + $this->assertEquals($statistics[self::INSTANCE_NAME]['reads'], 1, 'reads'); + $this->assertEquals($statistics[self::INSTANCE_NAME]['hits'], 1, 'hits'); + $this->assertEquals($statistics[self::INSTANCE_NAME]['misses'], 0, 'misses'); + $this->assertEquals($statistics[self::INSTANCE_NAME]['writes'], 0, 'writes'); + } + + public function testSavedEventDataCollector() + { + $traceableAdapterEvent = new \stdClass(); + $traceableAdapterEvent->name = 'save'; + $traceableAdapterEvent->start = 0; + $traceableAdapterEvent->end = 0; + + $statistics = $this->getCacheDataCollectorStatisticsFromEvents([$traceableAdapterEvent]); + + $this->assertEquals($statistics[self::INSTANCE_NAME]['calls'], 1, 'calls'); + $this->assertEquals($statistics[self::INSTANCE_NAME]['reads'], 0, 'reads'); + $this->assertEquals($statistics[self::INSTANCE_NAME]['hits'], 0, 'hits'); + $this->assertEquals($statistics[self::INSTANCE_NAME]['misses'], 0, 'misses'); + $this->assertEquals($statistics[self::INSTANCE_NAME]['writes'], 1, 'writes'); + } + + private function getCacheDataCollectorStatisticsFromEvents(array $traceableAdapterEvents) + { + $traceableAdapterMock = $this->createMock(TraceableAdapter::class); + $traceableAdapterMock->method('getCalls')->willReturn($traceableAdapterEvents); + + $cacheDataCollector = new CacheDataCollector(); + $cacheDataCollector->addInstance(self::INSTANCE_NAME, $traceableAdapterMock); + $cacheDataCollector->collect(new Request(), new Response()); + + return $cacheDataCollector->getStatistics(); + } +} diff --git a/src/Symfony/Component/Cache/composer.json b/src/Symfony/Component/Cache/composer.json index 49f634b372959..44bcd6c9972f0 100644 --- a/src/Symfony/Component/Cache/composer.json +++ b/src/Symfony/Component/Cache/composer.json @@ -37,6 +37,7 @@ "symfony/config": "^4.2|^5.0", "symfony/dependency-injection": "^3.4|^4.1|^5.0", "symfony/filesystem": "^4.4|^5.0", + "symfony/http-kernel": "^4.4|^5.0", "symfony/var-dumper": "^4.4|^5.0" }, "conflict": { From 73a3b838b742f103033218a2758548b829d27061 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 5 Nov 2020 11:17:07 +0100 Subject: [PATCH 092/136] autoconfigure behavior describing tags on decorators --- .../FrameworkExtension.php | 8 +++ .../FrameworkExtensionTest.php | 14 +++++ .../ResolveInstanceofConditionalsPass.php | 22 +++++-- .../ResolveInstanceofConditionalsPassTest.php | 60 +++++++++++++++++++ 4 files changed, 98 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 5f0f6f5140487..fe2778fdc6c8b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -470,6 +470,14 @@ public function load(array $configs, ContainerBuilder $container) $container->registerForAutoconfiguration(RouteLoaderInterface::class) ->addTag('routing.route_loader'); + + $container->setParameter('container.behavior_describing_tags', [ + 'container.service_locator', + 'container.service_subscriber', + 'kernel.event_subscriber', + 'kernel.locale_aware', + 'kernel.reset', + ]); } /** diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index f28402eaadc1c..920fb8b1e2d73 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -1656,6 +1656,20 @@ public function testMailer(string $configFile, array $expectedTransports): void $this->assertSame(['redirected@example.org', 'redirected1@example.org'], $l->getArgument(1)); } + public function testRegisterParameterCollectingBehaviorDescribingTags() + { + $container = $this->createContainerFromFile('default_config'); + + $this->assertTrue($container->hasParameter('container.behavior_describing_tags')); + $this->assertEquals([ + 'container.service_locator', + 'container.service_subscriber', + 'kernel.event_subscriber', + 'kernel.locale_aware', + 'kernel.reset', + ], $container->getParameter('container.behavior_describing_tags')); + } + protected function createContainer(array $data = []) { return new ContainerBuilder(new EnvPlaceholderParameterBag(array_merge([ diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php index 96afb039c6642..92b48ed888946 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php @@ -35,16 +35,26 @@ public function process(ContainerBuilder $container) } } + $tagsToKeep = []; + + if ($container->hasParameter('container.behavior_describing_tags')) { + $tagsToKeep = $container->getParameter('container.behavior_describing_tags'); + } + foreach ($container->getDefinitions() as $id => $definition) { if ($definition instanceof ChildDefinition) { // don't apply "instanceof" to children: it will be applied to their parent continue; } - $container->setDefinition($id, $this->processDefinition($container, $id, $definition)); + $container->setDefinition($id, $this->processDefinition($container, $id, $definition, $tagsToKeep)); + } + + if ($container->hasParameter('container.behavior_describing_tags')) { + $container->getParameterBag()->remove('container.behavior_describing_tags'); } } - private function processDefinition(ContainerBuilder $container, string $id, Definition $definition): Definition + private function processDefinition(ContainerBuilder $container, string $id, Definition $definition, array $tagsToKeep): Definition { $instanceofConditionals = $definition->getInstanceofConditionals(); $autoconfiguredInstanceof = $definition->isAutoconfigured() ? $container->getAutoconfiguredInstanceof() : []; @@ -115,10 +125,10 @@ private function processDefinition(ContainerBuilder $container, string $id, Defi } // Don't add tags to service decorators - if (null === $definition->getDecoratedService()) { - $i = \count($instanceofTags); - while (0 <= --$i) { - foreach ($instanceofTags[$i] as $k => $v) { + $i = \count($instanceofTags); + while (0 <= --$i) { + foreach ($instanceofTags[$i] as $k => $v) { + if (null === $definition->getDecoratedService() || \in_array($k, $tagsToKeep, true)) { foreach ($v as $v) { if ($definition->hasTag($k) && \in_array($v, $definition->getTag($k))) { continue; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php index 3acfbed776f1f..99aa65b13869b 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php @@ -12,12 +12,16 @@ namespace Symfony\Component\DependencyInjection\Tests\Compiler; use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Resource\ResourceInterface; +use Symfony\Component\Config\ResourceCheckerInterface; use Symfony\Component\DependencyInjection\Argument\BoundArgument; use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass; use Symfony\Component\DependencyInjection\Compiler\ResolveInstanceofConditionalsPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; +use Symfony\Contracts\Service\ResetInterface; +use Symfony\Contracts\Service\ServiceSubscriberInterface; class ResolveInstanceofConditionalsPassTest extends TestCase { @@ -325,4 +329,60 @@ public function testDecoratorsAreNotAutomaticallyTagged() $this->assertSame(['manual' => [[]]], $container->getDefinition('decorator')->getTags()); } + + public function testDecoratorsKeepBehaviorDescribingTags() + { + $container = new ContainerBuilder(); + + $container->setParameter('container.behavior_describing_tags', [ + 'container.service_subscriber', + 'kernel.reset', + ]); + + $container->register('decorator', DecoratorWithBehavior::class) + ->setAutoconfigured(true) + ->setDecoratedService('decorated') + ; + + $container->registerForAutoconfiguration(ResourceCheckerInterface::class) + ->addTag('config_cache.resource_checker') + ; + $container->registerForAutoconfiguration(ServiceSubscriberInterface::class) + ->addTag('container.service_subscriber') + ; + $container->registerForAutoconfiguration(ResetInterface::class) + ->addTag('kernel.reset', ['method' => 'reset']) + ; + + (new ResolveInstanceofConditionalsPass())->process($container); + + $this->assertEquals([ + 'container.service_subscriber' => [0 => []], + 'kernel.reset' => [ + [ + 'method' => 'reset', + ], + ], + ], $container->getDefinition('decorator')->getTags()); + $this->assertFalse($container->hasParameter('container.behavior_describing_tags')); + } +} + +class DecoratorWithBehavior implements ResetInterface, ResourceCheckerInterface, ServiceSubscriberInterface +{ + public function reset() + { + } + + public function supports(ResourceInterface $metadata) + { + } + + public function isFresh(ResourceInterface $resource, $timestamp) + { + } + + public static function getSubscribedServices() + { + } } From 8dd1a6e545c399fb7876a5deb06d3bf39becf2e9 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 2 Oct 2020 14:16:41 +0200 Subject: [PATCH 093/136] prevent hash collisions caused by reused object hashes --- .../Validator/Constraints/FormValidator.php | 13 ++------ src/Symfony/Component/Form/composer.json | 2 +- .../Validator/Context/ExecutionContext.php | 18 +++++++++++ .../Validator/RecursiveValidatorTest.php | 19 ++++++++++++ .../RecursiveContextualValidator.php | 30 +++++++++++++++---- 5 files changed, 64 insertions(+), 18 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php index f0e10c1d483b2..72ce53a592364 100644 --- a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php +++ b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php @@ -25,7 +25,6 @@ class FormValidator extends ConstraintValidator { private $resolvedGroups; - private $fieldFormConstraints; /** * {@inheritdoc} @@ -68,7 +67,6 @@ public function validate($form, Constraint $formConstraint) if ($hasChildren && $form->isRoot()) { $this->resolvedGroups = new \SplObjectStorage(); - $this->fieldFormConstraints = []; } if ($groups instanceof GroupSequence) { @@ -93,7 +91,6 @@ public function validate($form, Constraint $formConstraint) $this->resolvedGroups[$field] = (array) $group; $fieldFormConstraint = new Form(); $fieldFormConstraint->groups = $group; - $this->fieldFormConstraints[] = $fieldFormConstraint; $this->context->setNode($this->context->getValue(), $field, $this->context->getMetadata(), $this->context->getPropertyPath()); $validator->atPath(sprintf('children[%s]', $field->getName()))->validate($field, $fieldFormConstraint, $group); } @@ -139,10 +136,8 @@ public function validate($form, Constraint $formConstraint) foreach ($form->all() as $field) { if ($field->isSubmitted()) { $this->resolvedGroups[$field] = $groups; - $fieldFormConstraint = new Form(); - $this->fieldFormConstraints[] = $fieldFormConstraint; $this->context->setNode($this->context->getValue(), $field, $this->context->getMetadata(), $this->context->getPropertyPath()); - $validator->atPath(sprintf('children[%s]', $field->getName()))->validate($field, $fieldFormConstraint); + $validator->atPath(sprintf('children[%s]', $field->getName()))->validate($field, $formConstraint); } } } @@ -150,7 +145,6 @@ public function validate($form, Constraint $formConstraint) if ($hasChildren && $form->isRoot()) { // destroy storage to avoid memory leaks $this->resolvedGroups = new \SplObjectStorage(); - $this->fieldFormConstraints = []; } } elseif (!$form->isSynchronized()) { $childrenSynchronized = true; @@ -159,11 +153,8 @@ public function validate($form, Constraint $formConstraint) foreach ($form as $child) { if (!$child->isSynchronized()) { $childrenSynchronized = false; - - $fieldFormConstraint = new Form(); - $this->fieldFormConstraints[] = $fieldFormConstraint; $this->context->setNode($this->context->getValue(), $child, $this->context->getMetadata(), $this->context->getPropertyPath()); - $validator->atPath(sprintf('children[%s]', $child->getName()))->validate($child, $fieldFormConstraint); + $validator->atPath(sprintf('children[%s]', $child->getName()))->validate($child, $formConstraint); } } diff --git a/src/Symfony/Component/Form/composer.json b/src/Symfony/Component/Form/composer.json index 2a44a9f68aaaf..b03b63f7c9729 100644 --- a/src/Symfony/Component/Form/composer.json +++ b/src/Symfony/Component/Form/composer.json @@ -27,7 +27,7 @@ }, "require-dev": { "doctrine/collections": "~1.0", - "symfony/validator": "^3.4.44|^4.3.4|^5.0", + "symfony/validator": "^4.4.17|^5.1.9", "symfony/dependency-injection": "^3.4|^4.0|^5.0", "symfony/expression-language": "^3.4|^4.0|^5.0", "symfony/config": "^3.4|^4.0|^5.0", diff --git a/src/Symfony/Component/Validator/Context/ExecutionContext.php b/src/Symfony/Component/Validator/Context/ExecutionContext.php index a197168bf72ab..6acecac1520da 100644 --- a/src/Symfony/Component/Validator/Context/ExecutionContext.php +++ b/src/Symfony/Component/Validator/Context/ExecutionContext.php @@ -129,6 +129,7 @@ class ExecutionContext implements ExecutionContextInterface * @var array */ private $initializedObjects; + private $cachedObjectsRefs; /** * Creates a new execution context. @@ -153,6 +154,7 @@ public function __construct(ValidatorInterface $validator, $root, $translator, s $this->translator = $translator; $this->translationDomain = $translationDomain; $this->violations = new ConstraintViolationList(); + $this->cachedObjectsRefs = new \SplObjectStorage(); } /** @@ -358,4 +360,20 @@ public function isObjectInitialized($cacheKey): bool { return isset($this->initializedObjects[$cacheKey]); } + + /** + * @internal + * + * @param object $object + * + * @return string + */ + public function generateCacheKey($object) + { + if (!isset($this->cachedObjectsRefs[$object])) { + $this->cachedObjectsRefs[$object] = spl_object_hash($object); + } + + return $this->cachedObjectsRefs[$object]; + } } diff --git a/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php b/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php index f9aa6831ce0c4..17a89143046ef 100644 --- a/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php @@ -2153,6 +2153,25 @@ public function testValidatedConstraintsHashesDoNotCollide() $this->assertCount(2, $this->validator->validate($entity, new TestConstraintHashesDoNotCollide())); } + + public function testValidatedConstraintsHashesDoNotCollideWithSameConstraintValidatingDifferentProperties() + { + $value = new \stdClass(); + + $entity = new Entity(); + $entity->firstName = $value; + $entity->setLastName($value); + + $validator = $this->validator->startContext($entity); + + $constraint = new IsNull(); + $validator->atPath('firstName') + ->validate($entity->firstName, $constraint); + $validator->atPath('lastName') + ->validate($entity->getLastName(), $constraint); + + $this->assertCount(2, $validator->getViolations()); + } } final class TestConstraintHashesDoNotCollide extends Constraint diff --git a/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php b/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php index fb321ff8388d6..9e743f44a7538 100644 --- a/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php +++ b/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php @@ -108,7 +108,7 @@ public function validate($value, $constraints = null, $groups = null) $this->validateGenericNode( $value, $previousObject, - \is_object($value) ? spl_object_hash($value) : null, + \is_object($value) ? $this->generateCacheKey($value) : null, $metadata, $this->defaultPropertyPath, $groups, @@ -176,7 +176,7 @@ public function validateProperty($object, $propertyName, $groups = null) $propertyMetadatas = $classMetadata->getPropertyMetadata($propertyName); $groups = $groups ? $this->normalizeGroups($groups) : $this->defaultGroups; - $cacheKey = spl_object_hash($object); + $cacheKey = $this->generateCacheKey($object); $propertyPath = PropertyPath::append($this->defaultPropertyPath, $propertyName); $previousValue = $this->context->getValue(); @@ -224,7 +224,7 @@ public function validatePropertyValue($objectOrClass, $propertyName, $value, $gr if (\is_object($objectOrClass)) { $object = $objectOrClass; $class = \get_class($object); - $cacheKey = spl_object_hash($objectOrClass); + $cacheKey = $this->generateCacheKey($objectOrClass); $propertyPath = PropertyPath::append($this->defaultPropertyPath, $propertyName); } else { // $objectOrClass contains a class name @@ -313,7 +313,7 @@ private function validateObject($object, string $propertyPath, array $groups, in $this->validateClassNode( $object, - spl_object_hash($object), + $this->generateCacheKey($object), $classMetadata, $propertyPath, $groups, @@ -429,7 +429,7 @@ private function validateClassNode($object, ?string $cacheKey, ClassMetadataInte $defaultOverridden = false; // Use the object hash for group sequences - $groupHash = \is_object($group) ? spl_object_hash($group) : $group; + $groupHash = \is_object($group) ? $this->generateCacheKey($group, true) : $group; if ($context->isGroupValidated($cacheKey, $groupHash)) { // Skip this group when validating the properties and when @@ -740,7 +740,7 @@ private function validateInGroup($value, ?string $cacheKey, MetadataInterface $m // Prevent duplicate validation of constraints, in the case // that constraints belong to multiple validated groups if (null !== $cacheKey) { - $constraintHash = spl_object_hash($constraint); + $constraintHash = $this->generateCacheKey($constraint, true); // instanceof Valid: In case of using a Valid constraint with many groups // it makes a reference object get validated by each group if ($constraint instanceof Composite || $constraint instanceof Valid) { @@ -772,4 +772,22 @@ private function validateInGroup($value, ?string $cacheKey, MetadataInterface $m } } } + + /** + * @param object $object + */ + private function generateCacheKey($object, bool $dependsOnPropertyPath = false): string + { + if ($this->context instanceof ExecutionContext) { + $cacheKey = $this->context->generateCacheKey($object); + } else { + $cacheKey = spl_object_hash($object); + } + + if ($dependsOnPropertyPath) { + $cacheKey .= $this->context->getPropertyPath(); + } + + return $cacheKey; + } } From 38145232ab98a1ce0834a6fc8bc2831b437439ab Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 13 Nov 2020 12:10:43 +0100 Subject: [PATCH 094/136] fix firebase transport factory DI tag type --- .../FrameworkBundle/Resources/config/notifier_transports.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.xml index 045eb52a1b96e..42a4f5183f618 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.xml @@ -35,7 +35,7 @@ - + From 4e45d2da3bd74d00d40697805b58c656d000fd85 Mon Sep 17 00:00:00 2001 From: Antoine Makdessi Date: Fri, 13 Nov 2020 13:20:22 +0100 Subject: [PATCH 095/136] Update ExceptionEvent.php --- src/Symfony/Component/HttpKernel/Event/ExceptionEvent.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/Event/ExceptionEvent.php b/src/Symfony/Component/HttpKernel/Event/ExceptionEvent.php index 3dae0d4ce69a2..313a3615b2df0 100644 --- a/src/Symfony/Component/HttpKernel/Event/ExceptionEvent.php +++ b/src/Symfony/Component/HttpKernel/Event/ExceptionEvent.php @@ -18,7 +18,7 @@ * current request. The propagation of this event is stopped as soon as a * response is set. * - * You can also call setException() to replace the thrown exception. This + * You can also call setThrowable() to replace the thrown exception. This * exception will be thrown if no response is set during processing of this * event. * From c5a107e4cce55057fbe335909ba95c4d46e47feb Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Fri, 13 Nov 2020 17:28:59 +0100 Subject: [PATCH 096/136] [PhpUnitBridge] Fix test fixture file name --- .../coverage/tests/{SutNotFindTest.php => SutNotFoundTest.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/Symfony/Bridge/PhpUnit/Tests/Fixtures/coverage/tests/{SutNotFindTest.php => SutNotFoundTest.php} (100%) diff --git a/src/Symfony/Bridge/PhpUnit/Tests/Fixtures/coverage/tests/SutNotFindTest.php b/src/Symfony/Bridge/PhpUnit/Tests/Fixtures/coverage/tests/SutNotFoundTest.php similarity index 100% rename from src/Symfony/Bridge/PhpUnit/Tests/Fixtures/coverage/tests/SutNotFindTest.php rename to src/Symfony/Bridge/PhpUnit/Tests/Fixtures/coverage/tests/SutNotFoundTest.php From 5907444e81113438a3e34567be2c9651f406d582 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 14 Nov 2020 15:49:24 +0100 Subject: [PATCH 097/136] remove unreachable code --- src/Symfony/Component/Yaml/Parser.php | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index 997de27965d93..e8f951a1eca4d 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -1181,27 +1181,6 @@ private function parseQuotedString(string $yaml): ?string } return $value; - - for ($i = 1; isset($yaml[$i]) && $quotation !== $yaml[$i]; ++$i) { - } - - // quoted single line string - if (isset($yaml[$i]) && $quotation === $yaml[$i]) { - return $yaml; - } - - $lines = [$yaml]; - - while ($this->moveToNextLine()) { - for ($i = 1; isset($this->currentLine[$i]) && $quotation !== $this->currentLine[$i]; ++$i) { - } - - $lines[] = trim($this->currentLine); - - if (isset($this->currentLine[$i]) && $quotation === $this->currentLine[$i]) { - break; - } - } } private function lexInlineMapping(string $yaml): string From bd72a5650541493ad856957e7c03a736fb70b2ce Mon Sep 17 00:00:00 2001 From: Chi-teck Date: Sat, 14 Nov 2020 17:10:20 +0000 Subject: [PATCH 098/136] Check if method inheritEnvironmentVariables exists --- src/Symfony/Component/Dotenv/Dotenv.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Dotenv/Dotenv.php b/src/Symfony/Component/Dotenv/Dotenv.php index 4096cc62d8b0e..5765e25b0d1f7 100644 --- a/src/Symfony/Component/Dotenv/Dotenv.php +++ b/src/Symfony/Component/Dotenv/Dotenv.php @@ -401,7 +401,7 @@ private function resolveCommands(string $value, array $loadedVars): string $process = method_exists(Process::class, 'fromShellCommandline') ? Process::fromShellCommandline('echo '.$matches[0]) : new Process('echo '.$matches[0]); - if (!method_exists(Process::class, 'fromShellCommandline')) { + if (!method_exists(Process::class, 'fromShellCommandline') && method_exists(Process::class, 'inheritEnvironmentVariables')) { // Symfony 3.4 does not inherit env vars by default: $process->inheritEnvironmentVariables(); } From d9534779cf838b3db2edaf3c81984808e7ff161d Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Mon, 16 Nov 2020 12:15:53 +0100 Subject: [PATCH 099/136] Reinitialize globBrace after unserialization --- .../Component/Config/Resource/GlobResource.php | 8 ++++++++ .../Config/Tests/Resource/GlobResourceTest.php | 13 +++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/Symfony/Component/Config/Resource/GlobResource.php b/src/Symfony/Component/Config/Resource/GlobResource.php index 041b663f3e8e1..f825a92911558 100644 --- a/src/Symfony/Component/Config/Resource/GlobResource.php +++ b/src/Symfony/Component/Config/Resource/GlobResource.php @@ -94,6 +94,14 @@ public function __sleep(): array return ['prefix', 'pattern', 'recursive', 'hash', 'forExclusion', 'excludedPrefixes']; } + /** + * @internal + */ + public function __wakeup(): void + { + $this->globBrace = \defined('GLOB_BRACE') ? \GLOB_BRACE : 0; + } + /** * @return \Traversable */ diff --git a/src/Symfony/Component/Config/Tests/Resource/GlobResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/GlobResourceTest.php index 2b6609d740c86..a30fbe8c4339b 100644 --- a/src/Symfony/Component/Config/Tests/Resource/GlobResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/GlobResourceTest.php @@ -194,4 +194,17 @@ public function testUnbalancedBraceFallback() $this->assertSame([], array_keys(iterator_to_array($resource))); } + + public function testSerializeUnserialize() + { + $dir = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Fixtures'; + $resource = new GlobResource($dir, '/Resource', true); + + $newResource = unserialize(serialize($resource)); + + $p = new \ReflectionProperty($resource, 'globBrace'); + $p->setAccessible(true); + + $this->assertEquals($p->getValue($resource), $p->getValue($newResource)); + } } From a2b74762a61b99700981590c80d50409971fea98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Mon, 16 Nov 2020 12:44:36 +0100 Subject: [PATCH 100/136] Fix critical extension when reseting paged control --- src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php b/src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php index 6bb798319c851..4fa933a319649 100644 --- a/src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php +++ b/src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php @@ -100,7 +100,7 @@ public function execute() $cookie = ''; do { if ($pageControl) { - $this->controlPagedResult($con, $pageSize, $cookie); + $this->controlPagedResult($con, $pageSize, true, $cookie); } $sizeLimit = $itemsLeft; if ($pageSize > 0 && $sizeLimit >= $pageSize) { @@ -174,7 +174,7 @@ public function getResources(): array private function resetPagination() { $con = $this->connection->getResource(); - $this->controlPagedResult($con, 0, ''); + $this->controlPagedResult($con, 0, false, ''); $this->serverctrls = []; // This is a workaround for a bit of a bug in the above invocation @@ -204,15 +204,15 @@ private function resetPagination() * * @param resource $con */ - private function controlPagedResult($con, int $pageSize, string $cookie): bool + private function controlPagedResult($con, int $pageSize, bool $critical, string $cookie): bool { if (\PHP_VERSION_ID < 70300) { - return ldap_control_paged_result($con, $pageSize, true, $cookie); + return ldap_control_paged_result($con, $pageSize, $critical, $cookie); } $this->serverctrls = [ [ 'oid' => \LDAP_CONTROL_PAGEDRESULTS, - 'isCritical' => true, + 'isCritical' => $critical, 'value' => [ 'size' => $pageSize, 'cookie' => $cookie, From af9562b12c1590fb546e9fc4272a022fff46e9f4 Mon Sep 17 00:00:00 2001 From: Luca Saba Date: Mon, 2 Nov 2020 20:20:43 +0100 Subject: [PATCH 101/136] Adds LDAP Adapter test in integration group Adds ext-ldap on github-actions --- .../actions/populate-ldap/Dockerfile | 9 +++++++ .../actions/populate-ldap/action.yml | 9 +++++++ .../actions/populate-ldap/fixtures.ldif | 26 +++++++++++++++++++ .github/workflows/tests.yml | 5 ++++ .travis.yml | 5 ---- phpunit.xml.dist | 2 +- .../Tests/Adapter/ExtLdap/AdapterTest.php | 10 ++----- .../Tests/Adapter/ExtLdap/LdapManagerTest.php | 19 ++++++++++---- .../Component/Ldap/Tests/LdapTestCase.php | 1 + 9 files changed, 67 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/actions/populate-ldap/Dockerfile create mode 100644 .github/workflows/actions/populate-ldap/action.yml create mode 100644 .github/workflows/actions/populate-ldap/fixtures.ldif diff --git a/.github/workflows/actions/populate-ldap/Dockerfile b/.github/workflows/actions/populate-ldap/Dockerfile new file mode 100644 index 0000000000000..c256b27bf69c0 --- /dev/null +++ b/.github/workflows/actions/populate-ldap/Dockerfile @@ -0,0 +1,9 @@ +FROM osixia/openldap +LABEL maintainer="wshihadeh.devx@gmail.com" +ENV LDAP_ORGANISATION="Symfony" +ENV LDAP_DOMAIN="symfony.com" +ENV LDAP_ADMIN_PASSWORD="symfony" +ENV LDAP_BASE_DN="dc=symfony,dc=com" +ENV LDAP_SEED_INTERNAL_LDIF_PATH="/ldif-data" +RUN mkdir /ldif-data +COPY ./fixtures.ldif /ldif-data/50-fixtures.ldif diff --git a/.github/workflows/actions/populate-ldap/action.yml b/.github/workflows/actions/populate-ldap/action.yml new file mode 100644 index 0000000000000..971d98a0fd6d0 --- /dev/null +++ b/.github/workflows/actions/populate-ldap/action.yml @@ -0,0 +1,9 @@ +name: 'LDAP Populate' +description: 'Create a pre-populated LDAP server with symfony test data' +branding: + icon: 'database' + color: 'blue' + +runs: + using: 'docker' + image: 'Dockerfile' diff --git a/.github/workflows/actions/populate-ldap/fixtures.ldif b/.github/workflows/actions/populate-ldap/fixtures.ldif new file mode 100644 index 0000000000000..43842146b2837 --- /dev/null +++ b/.github/workflows/actions/populate-ldap/fixtures.ldif @@ -0,0 +1,26 @@ +dn: cn=Fabien Potencier,dc=symfony,dc=com +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +cn: Fabien Potencier +sn: fabpot +mail: fabpot@symfony.com +mail: fabien@potencier.com +ou: People +ou: Maintainers +ou: Founder +givenName: Fabien Potencier +description: Founder and project lead @Symfony + +dn: ou=Components,dc=symfony,dc=com +objectclass: organizationalunit +ou: Components + +dn: ou=Ldap,ou=Components,dc=symfony,dc=com +objectclass: organizationalunit +ou: Ldap + +dn: ou=Ldap scoping,ou=Ldap,ou=Components,dc=symfony,dc=com +objectclass: organizationalunit +ou: Ldap scoping diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a5d6ea0e9a932..c12a7339bb63a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -45,6 +45,9 @@ jobs: - name: Checkout uses: actions/checkout@v2 + - name: Populate LDAP + uses: ./.github/actions/populate-ldap + - name: Setup PHP uses: shivammathur/setup-php@v2 with: @@ -87,6 +90,8 @@ jobs: MESSENGER_REDIS_DSN: redis://127.0.0.1:7006/messages MESSENGER_AMQP_DSN: amqp://localhost/%2f/messages MEMCACHED_HOST: localhost + LDAP_HOST: localhost + LDAP_PORT: 3389 - name: Run HTTP push tests if: matrix.php == '7.4' diff --git a/.travis.yml b/.travis.yml index b69c4567dd0d7..cbb8984c88961 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,11 +55,6 @@ before_install: # General configuration set -e stty cols 120 - mkdir /tmp/slapd - if [ ! -e /tmp/slapd-modules ]; then - [ -d /usr/lib/openldap ] && ln -s /usr/lib/openldap /tmp/slapd-modules || ln -s /usr/lib/ldap /tmp/slapd-modules - fi - slapd -f src/Symfony/Component/Ldap/Tests/Fixtures/conf/slapd.conf -h ldap://localhost:3389 & cp .github/composer-config.json "$(composer config home)/config.json" export PHPUNIT=$(readlink -f ./phpunit) export PHPUNIT_X="$PHPUNIT --exclude-group tty,benchmark,intl-data" diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 7313d16d25c70..d7f495fac7216 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -15,7 +15,7 @@ - + diff --git a/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/AdapterTest.php b/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/AdapterTest.php index 11ad46544e834..3447cdda96dba 100644 --- a/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/AdapterTest.php +++ b/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/AdapterTest.php @@ -25,12 +25,6 @@ */ class AdapterTest extends LdapTestCase { - private const PAGINATION_REQUIRED_CONFIG = [ - 'options' => [ - 'protocol_version' => 3, - ], - ]; - public function testLdapEscape() { $ldap = new Adapter(); @@ -122,7 +116,7 @@ public function testLdapQueryScopeOneLevel() public function testLdapPagination() { - $ldap = new Adapter(array_merge($this->getLdapConfig(), static::PAGINATION_REQUIRED_CONFIG)); + $ldap = new Adapter(array_merge($this->getLdapConfig())); $ldap->getConnection()->bind('cn=admin,dc=symfony,dc=com', 'symfony'); $entries = $this->setupTestUsers($ldap); @@ -205,7 +199,7 @@ private function destroyEntries($ldap, $entries) public function testLdapPaginationLimits() { - $ldap = new Adapter(array_merge($this->getLdapConfig(), static::PAGINATION_REQUIRED_CONFIG)); + $ldap = new Adapter(array_merge($this->getLdapConfig())); $ldap->getConnection()->bind('cn=admin,dc=symfony,dc=com', 'symfony'); $entries = $this->setupTestUsers($ldap); diff --git a/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/LdapManagerTest.php b/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/LdapManagerTest.php index e23e8018547bf..0fcbbfadec7ec 100644 --- a/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/LdapManagerTest.php +++ b/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/LdapManagerTest.php @@ -15,7 +15,6 @@ use Symfony\Component\Ldap\Adapter\ExtLdap\Collection; use Symfony\Component\Ldap\Adapter\ExtLdap\UpdateOperation; use Symfony\Component\Ldap\Entry; -use Symfony\Component\Ldap\Exception\AlreadyExistsException; use Symfony\Component\Ldap\Exception\LdapException; use Symfony\Component\Ldap\Exception\NotBoundException; use Symfony\Component\Ldap\Exception\UpdateOperationException; @@ -23,6 +22,7 @@ /** * @requires extension ldap + * @group integration */ class LdapManagerTest extends LdapTestCase { @@ -82,7 +82,7 @@ public function testLdapAddInvalidEntry() */ public function testLdapAddDouble() { - $this->expectException(AlreadyExistsException::class); + $this->expectException(LdapException::class); $this->executeSearchQuery(1); $entry = new Entry('cn=Elsa Amrouche,dc=symfony,dc=com', [ @@ -94,7 +94,12 @@ public function testLdapAddDouble() $em = $this->adapter->getEntryManager(); $em->add($entry); - $em->add($entry); + try { + $em->add($entry); + } catch (LdapException $e) { + $em->remove($entry); + throw $e; + } } /** @@ -210,7 +215,8 @@ public function testLdapRenameWithoutRemovingOldRdn() $newEntry = $result[0]; $originalCN = $entry->getAttribute('cn')[0]; - $this->assertStringContainsString($originalCN, $newEntry->getAttribute('cn')); + $this->assertContains($originalCN, $newEntry->getAttribute('cn')); + $this->assertContains('Kevin', $newEntry->getAttribute('cn')); $entryManager->rename($newEntry, 'cn='.$originalCN); @@ -372,7 +378,7 @@ public function testLdapMove() $result = $this->executeSearchQuery(1); $entry = $result[0]; - $this->assertNotContains('ou=Ldap', $entry->getDn()); + $this->assertStringNotContainsString('ou=Ldap', $entry->getDn()); $entryManager = $this->adapter->getEntryManager(); $entryManager->move($entry, 'ou=Ldap,ou=Components,dc=symfony,dc=com'); @@ -380,5 +386,8 @@ public function testLdapMove() $result = $this->executeSearchQuery(1); $movedEntry = $result[0]; $this->assertStringContainsString('ou=Ldap', $movedEntry->getDn()); + + // Move back entry + $entryManager->move($movedEntry, 'dc=symfony,dc=com'); } } diff --git a/src/Symfony/Component/Ldap/Tests/LdapTestCase.php b/src/Symfony/Component/Ldap/Tests/LdapTestCase.php index 9a1424a62e8f7..6caf659e097f6 100644 --- a/src/Symfony/Component/Ldap/Tests/LdapTestCase.php +++ b/src/Symfony/Component/Ldap/Tests/LdapTestCase.php @@ -9,6 +9,7 @@ class LdapTestCase extends TestCase protected function getLdapConfig() { $h = @ldap_connect(getenv('LDAP_HOST'), getenv('LDAP_PORT')); + ldap_set_option($h, LDAP_OPT_PROTOCOL_VERSION, 3); if (!$h || !@ldap_bind($h)) { $this->markTestSkipped('No server is listening on LDAP_HOST:LDAP_PORT'); From ea78f728b153fccc37f732c5f25c897b8dd3123c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Mon, 16 Nov 2020 09:41:36 +0100 Subject: [PATCH 102/136] Use GithubAction to run ldap tests --- .../actions/populate-ldap/Dockerfile | 9 ------- .../actions/populate-ldap/action.yml | 9 ------- .../actions/populate-ldap/fixtures.ldif | 26 ------------------- .github/workflows/tests.yml | 24 +++++++++++++---- .travis.yml | 9 ------- .../Tests/Adapter/ExtLdap/AdapterTest.php | 7 ++--- .../Tests/Adapter/ExtLdap/LdapManagerTest.php | 15 +++++------ .../Ldap/Tests/Fixtures/conf/slapd.conf | 18 ------------- .../Ldap/Tests/Fixtures/data/base.ldif | 4 --- .../Component/Ldap/Tests/LdapTestCase.php | 2 +- src/Symfony/Component/Ldap/phpunit.xml.dist | 2 +- 11 files changed, 32 insertions(+), 93 deletions(-) delete mode 100644 .github/workflows/actions/populate-ldap/Dockerfile delete mode 100644 .github/workflows/actions/populate-ldap/action.yml delete mode 100644 .github/workflows/actions/populate-ldap/fixtures.ldif delete mode 100644 src/Symfony/Component/Ldap/Tests/Fixtures/conf/slapd.conf delete mode 100644 src/Symfony/Component/Ldap/Tests/Fixtures/data/base.ldif diff --git a/.github/workflows/actions/populate-ldap/Dockerfile b/.github/workflows/actions/populate-ldap/Dockerfile deleted file mode 100644 index c256b27bf69c0..0000000000000 --- a/.github/workflows/actions/populate-ldap/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -FROM osixia/openldap -LABEL maintainer="wshihadeh.devx@gmail.com" -ENV LDAP_ORGANISATION="Symfony" -ENV LDAP_DOMAIN="symfony.com" -ENV LDAP_ADMIN_PASSWORD="symfony" -ENV LDAP_BASE_DN="dc=symfony,dc=com" -ENV LDAP_SEED_INTERNAL_LDIF_PATH="/ldif-data" -RUN mkdir /ldif-data -COPY ./fixtures.ldif /ldif-data/50-fixtures.ldif diff --git a/.github/workflows/actions/populate-ldap/action.yml b/.github/workflows/actions/populate-ldap/action.yml deleted file mode 100644 index 971d98a0fd6d0..0000000000000 --- a/.github/workflows/actions/populate-ldap/action.yml +++ /dev/null @@ -1,9 +0,0 @@ -name: 'LDAP Populate' -description: 'Create a pre-populated LDAP server with symfony test data' -branding: - icon: 'database' - color: 'blue' - -runs: - using: 'docker' - image: 'Dockerfile' diff --git a/.github/workflows/actions/populate-ldap/fixtures.ldif b/.github/workflows/actions/populate-ldap/fixtures.ldif deleted file mode 100644 index 43842146b2837..0000000000000 --- a/.github/workflows/actions/populate-ldap/fixtures.ldif +++ /dev/null @@ -1,26 +0,0 @@ -dn: cn=Fabien Potencier,dc=symfony,dc=com -objectClass: inetOrgPerson -objectClass: organizationalPerson -objectClass: person -objectClass: top -cn: Fabien Potencier -sn: fabpot -mail: fabpot@symfony.com -mail: fabien@potencier.com -ou: People -ou: Maintainers -ou: Founder -givenName: Fabien Potencier -description: Founder and project lead @Symfony - -dn: ou=Components,dc=symfony,dc=com -objectclass: organizationalunit -ou: Components - -dn: ou=Ldap,ou=Components,dc=symfony,dc=com -objectclass: organizationalunit -ou: Ldap - -dn: ou=Ldap scoping,ou=Ldap,ou=Components,dc=symfony,dc=com -objectclass: organizationalunit -ou: Ldap scoping diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c12a7339bb63a..efb905e996d4f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -15,6 +15,17 @@ jobs: php: ['7.1', '7.4'] services: + ldap: + image: bitnami/openldap + ports: + - 3389:3389 + env: + LDAP_ADMIN_USERNAME: admin + LDAP_ADMIN_PASSWORD: symfony + LDAP_ROOT: dc=symfony,dc=com + LDAP_PORT_NUMBER: 3389 + LDAP_USERS: a + LDAP_PASSWORDS: a redis: image: redis:6.0.0 ports: @@ -45,17 +56,20 @@ jobs: - name: Checkout uses: actions/checkout@v2 - - name: Populate LDAP - uses: ./.github/actions/populate-ldap - - name: Setup PHP uses: shivammathur/setup-php@v2 with: coverage: "none" - extensions: "memcached,redis,xsl" + extensions: "memcached,redis,xsl,ldap" ini-values: "memory_limit=-1" php-version: "${{ matrix.php }}" + - name: Load fixtures + uses: docker://bitnami/openldap + with: + entrypoint: /bin/bash + args: -c "(ldapwhoami -h localhost:3389 -D cn=admin,dc=symfony,dc=com -w symfony||sleep 5) && ldapadd -h ldap:3389 -D cn=admin,dc=symfony,dc=com -w symfony -f src/Symfony/Component/Ldap/Tests/Fixtures/data/fixtures.ldif && ldapdelete -h ldap:3389 -D cn=admin,dc=symfony,dc=com -w symfony cn=a,ou=users,dc=symfony,dc=com" + - name: Configure composer run: | COMPOSER_HOME="$(composer config home)" @@ -83,7 +97,7 @@ jobs: echo "::endgroup::" - name: Run tests - run: ./phpunit --group integration + run: ./phpunit --group integration -v env: REDIS_HOST: localhost REDIS_CLUSTER_HOSTS: 'localhost:7000 localhost:7001 localhost:7002 localhost:7003 localhost:7004 localhost:7005' diff --git a/.travis.yml b/.travis.yml index cbb8984c88961..582625f988533 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,8 +9,6 @@ addons: apt_packages: - parallel - language-pack-fr-base - - ldap-utils - - slapd - zookeeperd - libzookeeper-mt-dev @@ -164,13 +162,6 @@ before_install: tfold ext.redis tpecl redis-5.2.3 redis.so $INI "no" done - - | - # Load fixtures - if [[ ! $skip ]]; then - ldapadd -h localhost:3389 -D cn=admin,dc=symfony,dc=com -w symfony -f src/Symfony/Component/Ldap/Tests/Fixtures/data/base.ldif && - ldapadd -h localhost:3389 -D cn=admin,dc=symfony,dc=com -w symfony -f src/Symfony/Component/Ldap/Tests/Fixtures/data/fixtures.ldif - fi - install: - | # Install the phpunit-bridge from a PR if required diff --git a/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/AdapterTest.php b/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/AdapterTest.php index 3447cdda96dba..d7b06c6b35db6 100644 --- a/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/AdapterTest.php +++ b/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/AdapterTest.php @@ -22,6 +22,7 @@ /** * @requires extension ldap + * @group integration */ class AdapterTest extends LdapTestCase { @@ -116,7 +117,7 @@ public function testLdapQueryScopeOneLevel() public function testLdapPagination() { - $ldap = new Adapter(array_merge($this->getLdapConfig())); + $ldap = new Adapter($this->getLdapConfig()); $ldap->getConnection()->bind('cn=admin,dc=symfony,dc=com', 'symfony'); $entries = $this->setupTestUsers($ldap); @@ -147,7 +148,7 @@ public function testLdapPagination() $this->assertEquals(\count($fully_paged_query->getResources()), 1); $this->assertEquals(\count($paged_query->getResources()), 5); - if (\PHP_MAJOR_VERSION > 7 || (\PHP_MAJOR_VERSION == 7 && \PHP_MINOR_VERSION >= 2)) { + if (\PHP_VERSION_ID >= 70200) { // This last query is to ensure that we haven't botched the state of our connection // by not resetting pagination properly. extldap <= PHP 7.1 do not implement the necessary // bits to work around an implementation flaw, so we simply can't guarantee this to work there. @@ -199,7 +200,7 @@ private function destroyEntries($ldap, $entries) public function testLdapPaginationLimits() { - $ldap = new Adapter(array_merge($this->getLdapConfig())); + $ldap = new Adapter($this->getLdapConfig()); $ldap->getConnection()->bind('cn=admin,dc=symfony,dc=com', 'symfony'); $entries = $this->setupTestUsers($ldap); diff --git a/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/LdapManagerTest.php b/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/LdapManagerTest.php index 0fcbbfadec7ec..bfdd7d5342ff5 100644 --- a/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/LdapManagerTest.php +++ b/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/LdapManagerTest.php @@ -96,9 +96,8 @@ public function testLdapAddDouble() $em->add($entry); try { $em->add($entry); - } catch (LdapException $e) { + } finally { $em->remove($entry); - throw $e; } } @@ -215,12 +214,12 @@ public function testLdapRenameWithoutRemovingOldRdn() $newEntry = $result[0]; $originalCN = $entry->getAttribute('cn')[0]; - $this->assertContains($originalCN, $newEntry->getAttribute('cn')); - $this->assertContains('Kevin', $newEntry->getAttribute('cn')); - - $entryManager->rename($newEntry, 'cn='.$originalCN); - - $this->executeSearchQuery(1); + try { + $this->assertContains($originalCN, $newEntry->getAttribute('cn')); + $this->assertContains('Kevin', $newEntry->getAttribute('cn')); + } finally { + $entryManager->rename($newEntry, 'cn='.$originalCN); + } } public function testLdapAddRemoveAttributeValues() diff --git a/src/Symfony/Component/Ldap/Tests/Fixtures/conf/slapd.conf b/src/Symfony/Component/Ldap/Tests/Fixtures/conf/slapd.conf deleted file mode 100644 index 24eebcb2dbe33..0000000000000 --- a/src/Symfony/Component/Ldap/Tests/Fixtures/conf/slapd.conf +++ /dev/null @@ -1,18 +0,0 @@ -# See slapd.conf(5) for details on configuration options. -include /etc/ldap/schema/core.schema -include /etc/ldap/schema/cosine.schema -include /etc/ldap/schema/inetorgperson.schema -include /etc/ldap/schema/nis.schema - -pidfile /tmp/slapd/slapd.pid -argsfile /tmp/slapd/slapd.args - -modulepath /tmp/slapd-modules -moduleload back_hdb - -database hdb -directory /tmp/slapd - -suffix "dc=symfony,dc=com" -rootdn "cn=admin,dc=symfony,dc=com" -rootpw {SSHA}btWUi971ytYpVMbZLkaQ2A6ETh3VA0lL diff --git a/src/Symfony/Component/Ldap/Tests/Fixtures/data/base.ldif b/src/Symfony/Component/Ldap/Tests/Fixtures/data/base.ldif deleted file mode 100644 index 25abb296c9a6c..0000000000000 --- a/src/Symfony/Component/Ldap/Tests/Fixtures/data/base.ldif +++ /dev/null @@ -1,4 +0,0 @@ -dn: dc=symfony,dc=com -objectClass: dcObject -objectClass: organizationalUnit -ou: Organization diff --git a/src/Symfony/Component/Ldap/Tests/LdapTestCase.php b/src/Symfony/Component/Ldap/Tests/LdapTestCase.php index 6caf659e097f6..606065e491e36 100644 --- a/src/Symfony/Component/Ldap/Tests/LdapTestCase.php +++ b/src/Symfony/Component/Ldap/Tests/LdapTestCase.php @@ -9,7 +9,7 @@ class LdapTestCase extends TestCase protected function getLdapConfig() { $h = @ldap_connect(getenv('LDAP_HOST'), getenv('LDAP_PORT')); - ldap_set_option($h, LDAP_OPT_PROTOCOL_VERSION, 3); + @ldap_set_option($h, LDAP_OPT_PROTOCOL_VERSION, 3); if (!$h || !@ldap_bind($h)) { $this->markTestSkipped('No server is listening on LDAP_HOST:LDAP_PORT'); diff --git a/src/Symfony/Component/Ldap/phpunit.xml.dist b/src/Symfony/Component/Ldap/phpunit.xml.dist index e9861f822170b..a679848078856 100644 --- a/src/Symfony/Component/Ldap/phpunit.xml.dist +++ b/src/Symfony/Component/Ldap/phpunit.xml.dist @@ -10,7 +10,7 @@ > - + From 160cc6144cef25110330e7bce007dd348264d74e Mon Sep 17 00:00:00 2001 From: Bruno Baguette <1922257+Levure@users.noreply.github.com> Date: Mon, 16 Nov 2020 18:02:08 +0100 Subject: [PATCH 103/136] Minor : Removed typo (extra "the" term) --- src/Symfony/Component/Finder/Finder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Finder/Finder.php b/src/Symfony/Component/Finder/Finder.php index 3e8a9483ea0fe..186cb32298507 100644 --- a/src/Symfony/Component/Finder/Finder.php +++ b/src/Symfony/Component/Finder/Finder.php @@ -616,7 +616,7 @@ public function append($iterator) } /** - * Check if the any results were found. + * Check if any results were found. * * @return bool */ From 15da31686a5c095c0b06b876aec9a2a4bf55e2f8 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Mon, 16 Nov 2020 18:05:55 +0100 Subject: [PATCH 104/136] [Ldap] Fix undefined variable $con. --- src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php b/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php index f34a5597612bd..8ed1b7d668be9 100644 --- a/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php +++ b/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php @@ -151,8 +151,9 @@ public function applyOperations(string $dn, iterable $operations): void $operationsMapped[] = $modification->toArray(); } - if (!@ldap_modify_batch($this->getConnectionResource(), $dn, $operationsMapped)) { - throw new UpdateOperationException(sprintf('Error executing UpdateOperation on "%s": "%s".', $dn, ldap_error($this->getConnectionResource()))); + $con = $this->getConnectionResource(); + if (!@ldap_modify_batch($con, $dn, $operationsMapped)) { + throw new UpdateOperationException(sprintf('Error executing UpdateOperation on "%s": "%s".', $dn, ldap_error($con))); } } From bd84394dc5eb19399709caeac400cb243d776dd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Mon, 16 Nov 2020 16:43:27 +0100 Subject: [PATCH 105/136] Run Redis Sentinel tests in GithubAction --- .github/workflows/tests.yml | 13 +++++++++++-- .../Tests/Adapter/RedisAdapterSentinelTest.php | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a5d6ea0e9a932..5732b5340341d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,9 +29,16 @@ jobs: - 7004:7004 - 7005:7005 - 7006:7006 - - 7007:7007 env: - STANDALONE: true + STANDALONE: 1 + redis-sentinel: + image: bitnami/redis-sentinel:6.0 + ports: + - 26379:26379 + env: + REDIS_MASTER_HOST: redis + REDIS_MASTER_SET: redis_sentinel + REDIS_SENTINEL_QUORUM: 1 memcached: image: memcached:1.6.5 ports: @@ -84,6 +91,8 @@ jobs: env: REDIS_HOST: localhost REDIS_CLUSTER_HOSTS: 'localhost:7000 localhost:7001 localhost:7002 localhost:7003 localhost:7004 localhost:7005' + REDIS_SENTINEL_HOSTS: 'localhost:26379' + REDIS_SENTINEL_SERVICE: redis_sentinel MESSENGER_REDIS_DSN: redis://127.0.0.1:7006/messages MESSENGER_AMQP_DSN: amqp://localhost/%2f/messages MEMCACHED_HOST: localhost diff --git a/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php b/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php index 09f563036bc2f..82b9f08b65474 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php @@ -37,7 +37,7 @@ public static function setUpBeforeClass(): void public function testInvalidDSNHasBothClusterAndSentinel() { $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('Invalid Redis DSN: cannot use both redis_cluster and redis_sentinel at the same time'); + $this->expectExceptionMessage('Cannot use both "redis_cluster" and "redis_sentinel" at the same time:'); $dsn = 'redis:?host[redis1]&host[redis2]&host[redis3]&redis_cluster=1&redis_sentinel=mymaster'; RedisAdapter::createConnection($dsn); } From e7698e74349764615ad3799737dcfb13f40c6fea Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 17 Nov 2020 17:13:30 +0100 Subject: [PATCH 106/136] ignore the pattern attribute for textareas --- .../Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php | 2 +- src/Symfony/Bridge/Twig/composer.json | 2 +- src/Symfony/Component/Form/Extension/Core/Type/TextareaType.php | 1 + src/Symfony/Component/Form/Tests/AbstractLayoutTest.php | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php index 765e1592d1628..44cf60db3ac5c 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php @@ -2379,7 +2379,7 @@ public function testTextarea() $this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']], '/textarea [@name="name"] - [@pattern="foo"] + [not(@pattern)] [@class="my&class form-control"] [.="foo&bar"] ' diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index 75860d1ed465b..84045151c8ab7 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -26,7 +26,7 @@ "symfony/dependency-injection": "^3.4|^4.0|^5.0", "symfony/error-handler": "^4.4|^5.0", "symfony/finder": "^3.4|^4.0|^5.0", - "symfony/form": "^4.3.5", + "symfony/form": "^4.4.17", "symfony/http-foundation": "^4.3|^5.0", "symfony/http-kernel": "^4.4", "symfony/mime": "^4.3|^5.0", diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TextareaType.php b/src/Symfony/Component/Form/Extension/Core/Type/TextareaType.php index 7db19d8aedc65..173b7ef53c8a2 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TextareaType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TextareaType.php @@ -23,6 +23,7 @@ class TextareaType extends AbstractType public function buildView(FormView $view, FormInterface $form, array $options) { $view->vars['pattern'] = null; + unset($view->vars['attr']['pattern']); } /** diff --git a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php index e860557468024..38ba3bf53198c 100644 --- a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php @@ -2068,7 +2068,7 @@ public function testTextarea() $this->assertWidgetMatchesXpath($form->createView(), [], '/textarea [@name="name"] - [@pattern="foo"] + [not(@pattern)] [.="foo&bar"] ' ); From b7e5c7d67da2c4cf9df41afdfb846786d2d5e7be Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 17 Nov 2020 19:23:27 +0100 Subject: [PATCH 107/136] do not depend on the actual time to fix a transient test --- .../HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php index fd67af368b740..62179ba154fcd 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php @@ -239,6 +239,7 @@ public function testResponseIsExpirableButNotValidateableWhenMasterResponseCombi } /** + * @group time-sensitive * @dataProvider cacheControlMergingProvider */ public function testCacheControlMerging(array $expects, array $master, array $surrogates) From 4c15f80d8439ab12327e60f3432a231c8477c611 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 24 Sep 2019 00:08:17 +0200 Subject: [PATCH 108/136] fix lexing nested sequences/mappings --- src/Symfony/Component/Yaml/Parser.php | 187 +++++++++++------- .../Component/Yaml/Tests/ParserTest.php | 184 +++++++++++++++++ 2 files changed, 303 insertions(+), 68 deletions(-) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index e8f951a1eca4d..259e3e6b4946f 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -355,7 +355,7 @@ private function doParse(string $value, int $flags) } try { - return Inline::parse($this->parseQuotedString($this->currentLine), $flags, $this->refs); + return Inline::parse($this->lexInlineQuotedString(), $flags, $this->refs); } catch (ParseException $e) { $e->setParsedLine($this->getRealCurrentLineNb() + 1); $e->setSnippet($this->currentLine); @@ -368,7 +368,7 @@ private function doParse(string $value, int $flags) } try { - $parsedMapping = Inline::parse($this->lexInlineMapping($this->currentLine), $flags, $this->refs); + $parsedMapping = Inline::parse($this->lexInlineMapping(), $flags, $this->refs); while ($this->moveToNextLine()) { if (!$this->isCurrentLineEmpty()) { @@ -389,7 +389,7 @@ private function doParse(string $value, int $flags) } try { - $parsedSequence = Inline::parse($this->lexInlineSequence($this->currentLine), $flags, $this->refs); + $parsedSequence = Inline::parse($this->lexInlineSequence(), $flags, $this->refs); while ($this->moveToNextLine()) { if (!$this->isCurrentLineEmpty()) { @@ -659,6 +659,11 @@ private function getNextEmbedBlock(int $indentation = null, bool $inSequence = f return implode("\n", $data); } + private function hasMoreLines(): bool + { + return (\count($this->lines) - 1) > $this->currentLineNb; + } + /** * Moves the parser to the next line. */ @@ -736,9 +741,13 @@ private function parseValue(string $value, int $flags, string $context) try { if ('' !== $value && '{' === $value[0]) { - return Inline::parse($this->lexInlineMapping($value), $flags, $this->refs); + $cursor = \strlen($this->currentLine) - \strlen($value); + + return Inline::parse($this->lexInlineMapping($cursor), $flags, $this->refs); } elseif ('' !== $value && '[' === $value[0]) { - return Inline::parse($this->lexInlineSequence($value), $flags, $this->refs); + $cursor = \strlen($this->currentLine) - \strlen($value); + + return Inline::parse($this->lexInlineSequence($cursor), $flags, $this->refs); } $quotation = '' !== $value && ('"' === $value[0] || "'" === $value[0]) ? $value[0] : null; @@ -1137,106 +1146,148 @@ private function getLineTag(string $value, int $flags, bool $nextLineCheck = tru throw new ParseException(sprintf('Tags support is not enabled. You must use the flag "Yaml::PARSE_CUSTOM_TAGS" to use "%s".', $matches['tag']), $this->getRealCurrentLineNb() + 1, $value, $this->filename); } - private function parseQuotedString(string $yaml): ?string + private function lexInlineQuotedString(int &$cursor = 0): string { - if ('' === $yaml || ('"' !== $yaml[0] && "'" !== $yaml[0])) { - throw new \InvalidArgumentException(sprintf('"%s" is not a quoted string.', $yaml)); - } + $quotation = $this->currentLine[$cursor]; + $value = $quotation; + ++$cursor; - $lines = [$yaml]; - - while ($this->moveToNextLine()) { - $lines[] = $this->currentLine; + $previousLineWasNewline = true; + $previousLineWasTerminatedWithBackslash = false; - if (!$this->isCurrentLineEmpty() && $yaml[0] === $this->currentLine[-1]) { - break; - } - } - - $value = ''; - - for ($i = 0, $linesCount = \count($lines), $previousLineWasNewline = false, $previousLineWasTerminatedWithBackslash = false; $i < $linesCount; ++$i) { - if ('' === trim($lines[$i])) { + do { + if ($this->isCurrentLineBlank()) { $value .= "\n"; } elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) { $value .= ' '; } - if ('' !== trim($lines[$i]) && '\\' === substr($lines[$i], -1)) { - $value .= ltrim(substr($lines[$i], 0, -1)); - } elseif ('' !== trim($lines[$i])) { - $value .= trim($lines[$i]); + for (; \strlen($this->currentLine) > $cursor; ++$cursor) { + switch ($this->currentLine[$cursor]) { + case '\\': + if (isset($this->currentLine[++$cursor])) { + $value .= '\\'.$this->currentLine[$cursor]; + } + + break; + case $quotation: + ++$cursor; + + if ("'" === $quotation && isset($this->currentLine[$cursor]) && "'" === $this->currentLine[$cursor]) { + $value .= "''"; + break; + } + + return $value.$quotation; + default: + $value .= $this->currentLine[$cursor]; + } } - if ('' === trim($lines[$i])) { + if ($this->isCurrentLineBlank()) { $previousLineWasNewline = true; $previousLineWasTerminatedWithBackslash = false; - } elseif ('\\' === substr($lines[$i], -1)) { + } elseif ('\\' === $this->currentLine[-1]) { $previousLineWasNewline = false; $previousLineWasTerminatedWithBackslash = true; } else { $previousLineWasNewline = false; $previousLineWasTerminatedWithBackslash = false; } - } - return $value; + if ($this->hasMoreLines()) { + $cursor = 0; + } + } while ($this->moveToNextLine()); + + throw new ParseException('Malformed inline YAML string'); } - private function lexInlineMapping(string $yaml): string + private function lexUnquotedString(int &$cursor): string { - if ('' === $yaml || '{' !== $yaml[0]) { - throw new \InvalidArgumentException(sprintf('"%s" is not a sequence.', $yaml)); - } - - for ($i = 1; isset($yaml[$i]) && '}' !== $yaml[$i]; ++$i) { - } + $offset = $cursor; + $cursor += strcspn($this->currentLine, '[]{},: ', $cursor); - if (isset($yaml[$i]) && '}' === $yaml[$i]) { - return $yaml; - } - - $lines = [$yaml]; - - while ($this->moveToNextLine()) { - $lines[] = $this->currentLine; - } + return substr($this->currentLine, $offset, $cursor - $offset); + } - return implode("\n", $lines); + private function lexInlineMapping(int &$cursor = 0): string + { + return $this->lexInlineStructure($cursor, '}'); } - private function lexInlineSequence(string $yaml): string + private function lexInlineSequence(int &$cursor = 0): string { - if ('' === $yaml || '[' !== $yaml[0]) { - throw new \InvalidArgumentException(sprintf('"%s" is not a sequence.', $yaml)); - } + return $this->lexInlineStructure($cursor, ']'); + } - for ($i = 1; isset($yaml[$i]) && ']' !== $yaml[$i]; ++$i) { - } + private function lexInlineStructure(int &$cursor, string $closingTag): string + { + $value = $this->currentLine[$cursor]; + ++$cursor; - if (isset($yaml[$i]) && ']' === $yaml[$i]) { - return $yaml; - } + do { + $this->consumeWhitespaces($cursor); + + while (isset($this->currentLine[$cursor])) { + switch ($this->currentLine[$cursor]) { + case '"': + case "'": + $value .= $this->lexInlineQuotedString($cursor); + break; + case ':': + case ',': + $value .= $this->currentLine[$cursor]; + ++$cursor; + break; + case '{': + $value .= $this->lexInlineMapping($cursor); + break; + case '[': + $value .= $this->lexInlineSequence($cursor); + break; + case $closingTag: + $value .= $this->currentLine[$cursor]; + ++$cursor; + + return $value; + case '#': + break 2; + default: + $value .= $this->lexUnquotedString($cursor); + } - $value = $yaml; + if ($this->consumeWhitespaces($cursor)) { + $value .= ' '; + } + } - while ($this->moveToNextLine()) { - for ($i = 1; isset($this->currentLine[$i]) && ']' !== $this->currentLine[$i]; ++$i) { + if ($this->hasMoreLines()) { + $cursor = 0; } + } while ($this->moveToNextLine()); - $trimmedValue = trim($this->currentLine); + throw new ParseException('Malformed inline YAML string'); + } - if ('' !== $trimmedValue && '#' === $trimmedValue[0]) { - continue; - } + private function consumeWhitespaces(int &$cursor): bool + { + $whitespacesConsumed = 0; - $value .= $trimmedValue; + do { + $whitespaceOnlyTokenLength = strspn($this->currentLine, ' ', $cursor); + $whitespacesConsumed += $whitespaceOnlyTokenLength; + $cursor += $whitespaceOnlyTokenLength; - if (isset($this->currentLine[$i]) && ']' === $this->currentLine[$i]) { - break; + if (isset($this->currentLine[$cursor])) { + return 0 < $whitespacesConsumed; } - } - return $value; + if ($this->hasMoreLines()) { + $cursor = 0; + } + } while ($this->moveToNextLine()); + + return 0 < $whitespacesConsumed; } } diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index 5f3b8f311d060..f9e4765a5d2af 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -1660,6 +1660,16 @@ public function inlineNotationSpanningMultipleLinesProvider(): array 'foo': 'bar', 'bar': 'baz' } +YAML + , + ], + 'mapping with unquoted strings and values' => [ + ['foo' => 'bar', 'bar' => 'baz'], + << [ + ['foo', 'bar'], + << [ + [ + 'foo' => [ + 'bar' => 'foobar', + ], + ], + << [ + [ + 'foo', + [ + 'bar', + 'baz', + ], + ], + << [ + [ + ['entry1', []], + ['entry2'], + ], + << [ ['foo' => ['bar', 'foobar'], 'bar' => ['baz']], << [ + [ + 'foobar' => [ + 'foo', + 'bar', + ], + 'bar' => 'baz', + ], + << [ [ 'foo' => [ @@ -1824,6 +1897,110 @@ public function inlineNotationSpanningMultipleLinesProvider(): array foo: 'bar baz' +YAML + ], + 'mixed mapping with inline notation having separated lines' => [ + [ + 'map' => [ + 'key' => 'value', + 'a' => 'b', + ], + 'param' => 'some', + ], + << [ + [ + 'map' => [ + 'key' => 'value', + 'a' => 'b', + ], + 'param' => 'some', + ], + << [ + [ + 'map' => [ + 'key' => 'value', + 'a' => 'b', + ], + 'param' => 'some', + ], + << [ + [ + [']'], + ['}'], + ['ba[r'], + ['[ba]r'], + ['bar]'], + ['foo' => 'bar{'], + ['foo' => 'b{ar}'], + ['foo' => 'bar}'], + ], + << [ + [ + ['te"st'], + ['test'], + ["te'st"], + ['te"st]'], + ['te"st'], + ['test'], + ["te'st"], + ['te"st]'], + ], + <<assertEquals(new TaggedValue('foo', ['foo' => 'bar']), $this->parser->parse('!foo {foo: bar}', Yaml::PARSE_CUSTOM_TAGS)); } + public function testInvalidInlineSequenceContainingStringWithEscapedQuotationCharacter() + { + $this->expectException(ParseException::class); + + $this->parser->parse('["\\"]'); + } + /** * @dataProvider taggedValuesProvider */ From 0c92bc5a8324d5c0a0e247b5f4b8fa90551362b5 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 19 Nov 2020 01:16:02 +0100 Subject: [PATCH 109/136] [HttpClient] don't fallback to HTTP/1.1 when HTTP/2 streams break --- src/Symfony/Component/HttpClient/Response/CurlResponse.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpClient/Response/CurlResponse.php b/src/Symfony/Component/HttpClient/Response/CurlResponse.php index 435f6402c796d..9709a189f5926 100644 --- a/src/Symfony/Component/HttpClient/Response/CurlResponse.php +++ b/src/Symfony/Component/HttpClient/Response/CurlResponse.php @@ -283,10 +283,7 @@ private static function perform(ClientState $multi, array &$responses = null): v curl_multi_remove_handle($multi->handle, $ch); $waitFor[1] = (string) ((int) $waitFor[1] - 1); // decrement the retry counter curl_setopt($ch, \CURLOPT_PRIVATE, $waitFor); - - if ('1' === $waitFor[1]) { - curl_setopt($ch, \CURLOPT_HTTP_VERSION, \CURL_HTTP_VERSION_1_1); - } + curl_setopt($ch, \CURLOPT_FORBID_REUSE, true); if (0 === curl_multi_add_handle($multi->handle, $ch)) { continue; From fcbf0bf76ea165cb66c7a9d4b84bd4441994d8be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Fri, 20 Nov 2020 22:20:21 +0100 Subject: [PATCH 110/136] Display debug info --- .github/workflows/tests.yml | 12 ++++++------ .../Cache/Adapter/CouchbaseBucketAdapter.php | 6 +++--- .../Tests/Adapter/CouchbaseBucketAdapterTest.php | 7 ++++++- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1387e5ac9c130..b9f5438e2e061 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -93,17 +93,12 @@ jobs: - name: Install system dependencies run: | - echo "::group::add apt sources" - sudo wget -O - http://packages.couchbase.com/ubuntu/couchbase.key | sudo apt-key add - - echo "deb http://packages.couchbase.com/ubuntu bionic bionic/main" | sudo tee /etc/apt/sources.list.d/couchbase.list - echo "::endgroup::" - echo "::group::apt-get update" sudo apt-get update echo "::endgroup::" echo "::group::install tools & libraries" - sudo apt-get install libcouchbase-dev librdkafka-dev + sudo apt-get install librdkafka-dev echo "::endgroup::" - name: Configure Couchbase @@ -122,6 +117,11 @@ jobs: php-version: "${{ matrix.php }}" tools: pecl + - name: Display versions + run: | + php -r 'foreach (get_loaded_extensions() as $extension) echo $extension . " " . phpversion($extension) . PHP_EOL;' + php -i + - name: Load fixtures uses: docker://bitnami/openldap with: diff --git a/src/Symfony/Component/Cache/Adapter/CouchbaseBucketAdapter.php b/src/Symfony/Component/Cache/Adapter/CouchbaseBucketAdapter.php index a0e8f4027181c..36667f2a0dfb9 100644 --- a/src/Symfony/Component/Cache/Adapter/CouchbaseBucketAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/CouchbaseBucketAdapter.php @@ -42,7 +42,7 @@ class CouchbaseBucketAdapter extends AbstractAdapter public function __construct(\CouchbaseBucket $bucket, string $namespace = '', int $defaultLifetime = 0, MarshallerInterface $marshaller = null) { if (!static::isSupported()) { - throw new CacheException('Couchbase >= 2.6.0 is required.'); + throw new CacheException('Couchbase >= 2.6.0 < 3.0.0 is required.'); } $this->maxIdLength = static::MAX_KEY_LENGTH; @@ -66,7 +66,7 @@ public static function createConnection($servers, array $options = []): \Couchba } if (!static::isSupported()) { - throw new CacheException('Couchbase >= 2.6.0 is required.'); + throw new CacheException('Couchbase >= 2.6.0 < 3.0.0 is required.'); } set_error_handler(function ($type, $msg, $file, $line) { throw new \ErrorException($msg, 0, $type, $file, $line); }); @@ -125,7 +125,7 @@ public static function createConnection($servers, array $options = []): \Couchba public static function isSupported(): bool { - return \extension_loaded('couchbase') && version_compare(phpversion('couchbase'), '2.6.0', '>='); + return \extension_loaded('couchbase') && version_compare(phpversion('couchbase'), '2.6.0', '>=') && version_compare(phpversion('couchbase'), '3.0', '<'); } private static function getOptions(string $options): array diff --git a/src/Symfony/Component/Cache/Tests/Adapter/CouchbaseBucketAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/CouchbaseBucketAdapterTest.php index 120d0d94c0cc5..c72d6710f22e9 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/CouchbaseBucketAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/CouchbaseBucketAdapterTest.php @@ -16,7 +16,8 @@ use Symfony\Component\Cache\Adapter\CouchbaseBucketAdapter; /** - * @requires extension couchbase 2.6.0 + * @requires extension couchbase <3.0.0 + * @requires extension couchbase >=2.6.0 * @group integration * * @author Antonio Jose Cerezo Aranda @@ -32,6 +33,10 @@ class CouchbaseBucketAdapterTest extends AdapterTestCase public static function setupBeforeClass(): void { + if (!CouchbaseBucketAdapter::isSupported()) { + self::markTestSkipped('Couchbase >= 2.6.0 < 3.0.0 is required.'); + } + self::$client = AbstractAdapter::createConnection('couchbase://'.getenv('COUCHBASE_HOST').'/cache', ['username' => getenv('COUCHBASE_USER'), 'password' => getenv('COUCHBASE_PASS')] ); From fe6a2dd64fc7f703d7bcd6e3b9448dc881debf60 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 19 Nov 2020 19:56:09 +0100 Subject: [PATCH 111/136] prevent duplicated error message for file upload limits --- .../Form/Extension/Core/Type/FileType.php | 4 +- .../ViolationMapper/ViolationMapper.php | 19 ++++ .../Component/Form/FileUploadError.php | 19 ++++ .../ViolationMapper/ViolationMapperTest.php | 92 +++++++++++++++++++ 4 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Component/Form/FileUploadError.php diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php index 207944bf5ad6d..d8b93f6fc77b0 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php @@ -12,8 +12,8 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FileUploadError; use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormError; use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvents; use Symfony\Component\Form\FormInterface; @@ -171,7 +171,7 @@ private function getFileUploadError(int $errorCode) $message = strtr($messageTemplate, $messageParameters); } - return new FormError($message, $messageTemplate, $messageParameters); + return new FileUploadError($message, $messageTemplate, $messageParameters); } /** diff --git a/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php b/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php index 8799fc196cc95..4c19e9850a444 100644 --- a/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php +++ b/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php @@ -11,12 +11,14 @@ namespace Symfony\Component\Form\Extension\Validator\ViolationMapper; +use Symfony\Component\Form\FileUploadError; use Symfony\Component\Form\FormError; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\Util\InheritDataAwareIterator; use Symfony\Component\PropertyAccess\PropertyPathBuilder; use Symfony\Component\PropertyAccess\PropertyPathIterator; use Symfony\Component\PropertyAccess\PropertyPathIteratorInterface; +use Symfony\Component\Validator\Constraints\File; use Symfony\Component\Validator\ConstraintViolation; /** @@ -124,6 +126,23 @@ public function mapViolation(ConstraintViolation $violation, FormInterface $form // Only add the error if the form is synchronized if ($this->acceptsErrors($scope)) { + if ($violation->getConstraint() instanceof File && (string) \UPLOAD_ERR_INI_SIZE === $violation->getCode()) { + $errorsTarget = $scope; + + while (null !== $errorsTarget->getParent() && $errorsTarget->getConfig()->getErrorBubbling()) { + $errorsTarget = $errorsTarget->getParent(); + } + + $errors = $errorsTarget->getErrors(); + $errorsTarget->clearErrors(); + + foreach ($errors as $error) { + if (!$error instanceof FileUploadError) { + $errorsTarget->addError($error); + } + } + } + $scope->addError(new FormError( $violation->getMessage(), $violation->getMessageTemplate(), diff --git a/src/Symfony/Component/Form/FileUploadError.php b/src/Symfony/Component/Form/FileUploadError.php new file mode 100644 index 0000000000000..20142b20337ea --- /dev/null +++ b/src/Symfony/Component/Form/FileUploadError.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form; + +/** + * @internal + */ +class FileUploadError extends FormError +{ +} diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php index 822e36e6a1dcc..8c71b7bfacefa 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php @@ -18,12 +18,14 @@ use Symfony\Component\Form\Exception\TransformationFailedException; use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper; use Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationMapper; +use Symfony\Component\Form\FileUploadError; use Symfony\Component\Form\Form; use Symfony\Component\Form\FormConfigBuilder; use Symfony\Component\Form\FormError; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\Tests\Extension\Validator\ViolationMapper\Fixtures\Issue; use Symfony\Component\PropertyAccess\PropertyPath; +use Symfony\Component\Validator\Constraints\File; use Symfony\Component\Validator\ConstraintViolation; use Symfony\Component\Validator\ConstraintViolationInterface; @@ -81,6 +83,7 @@ protected function getForm($name = 'name', $propertyPath = null, $dataClass = nu $config->setPropertyPath($propertyPath); $config->setCompound(true); $config->setDataMapper(new PropertyPathMapper()); + $config->setErrorBubbling($options['error_bubbling'] ?? false); if (!$synchronized) { $config->addViewTransformer(new CallbackTransformer( @@ -1590,4 +1593,93 @@ public function testBacktrackIfSeveralSubFormsWithSamePropertyPath() $this->assertEquals([$this->getFormError($violation2, $grandChild2)], iterator_to_array($grandChild2->getErrors()), $grandChild2->getName().' should have an error, but has none'); $this->assertEquals([$this->getFormError($violation3, $grandChild3)], iterator_to_array($grandChild3->getErrors()), $grandChild3->getName().' should have an error, but has none'); } + + public function testFileUploadErrorIsNotRemovedIfNoFileSizeConstraintViolationWasRaised() + { + $form = $this->getForm('form'); + $form->addError(new FileUploadError( + 'The file is too large. Allowed maximum size is 2 MB.', + 'The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.', + [ + '{{ limit }}' => '2', + '{{ suffix }}' => 'MB', + ] + )); + + $this->mapper->mapViolation($this->getConstraintViolation('data'), $form); + + $this->assertCount(2, $form->getErrors()); + } + + public function testFileUploadErrorIsRemovedIfFileSizeConstraintViolationWasRaised() + { + $form = $this->getForm('form'); + $form->addError(new FileUploadError( + 'The file is too large. Allowed maximum size is 2 MB.', + 'The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.', + [ + '{{ limit }}' => '2', + '{{ suffix }}' => 'MB', + ] + )); + + $violation = new ConstraintViolation( + 'The file is too large (3 MB). Allowed maximum size is 2 MB.', + 'The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.', + [ + '{{ limit }}' => '2', + '{{ size }}' => '3', + '{{ suffix }}' => 'MB', + ], + '', + 'data', + null, + null, + (string) \UPLOAD_ERR_INI_SIZE, + new File() + ); + $this->mapper->mapViolation($this->getConstraintViolation('data'), $form); + $this->mapper->mapViolation($violation, $form); + + $this->assertCount(2, $form->getErrors()); + } + + public function testFileUploadErrorIsRemovedIfFileSizeConstraintViolationWasRaisedOnFieldWithErrorBubbling() + { + $parent = $this->getForm('parent'); + $child = $this->getForm('child', 'file', null, [], false, true, [ + 'error_bubbling' => true, + ]); + $parent->add($child); + $child->addError(new FileUploadError( + 'The file is too large. Allowed maximum size is 2 MB.', + 'The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.', + [ + '{{ limit }}' => '2', + '{{ suffix }}' => 'MB', + ] + )); + + $violation = new ConstraintViolation( + 'The file is too large (3 MB). Allowed maximum size is 2 MB.', + 'The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.', + [ + '{{ limit }}' => '2', + '{{ size }}' => '3', + '{{ suffix }}' => 'MB', + ], + null, + 'data.file', + null, + null, + (string) \UPLOAD_ERR_INI_SIZE, + new File() + ); + $this->mapper->mapViolation($this->getConstraintViolation('data'), $parent); + $this->mapper->mapViolation($this->getConstraintViolation('data.file'), $parent); + $this->mapper->mapViolation($violation, $parent); + + $this->assertCount(3, $parent->getErrors()); + $this->assertCount(0, $child->getErrors()); + } } From 76a077d947d4c4d52c230d1395badc2a08ed7f74 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 24 Nov 2020 10:55:37 +0100 Subject: [PATCH 112/136] [VarDumper] fix casting resources turned into objects on PHP 8 --- src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php b/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php index 9d50da90577a7..178237905e37d 100644 --- a/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php +++ b/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php @@ -149,7 +149,10 @@ abstract class AbstractCloner implements ClonerInterface ':dba' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castDba'], ':dba persistent' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castDba'], + + 'GdImage' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castGd'], ':gd' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castGd'], + ':mysql link' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castMysqlLink'], ':pgsql large object' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castLargeObject'], ':pgsql link' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castLink'], @@ -157,9 +160,14 @@ abstract class AbstractCloner implements ClonerInterface ':pgsql result' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castResult'], ':process' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castProcess'], ':stream' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castStream'], + + 'OpenSSLCertificate' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castOpensslX509'], ':OpenSSL X.509' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castOpensslX509'], + ':persistent stream' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castStream'], ':stream-context' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castStreamContext'], + + 'XmlParser' => ['Symfony\Component\VarDumper\Caster\XmlResourceCaster', 'castXml'], ':xml' => ['Symfony\Component\VarDumper\Caster\XmlResourceCaster', 'castXml'], ]; From 673b8e941a11344ad95037fa7b01600ae8e0ca86 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 17 Nov 2020 17:51:58 +0100 Subject: [PATCH 113/136] fix lexing strings containing escaped quotation characters --- src/Symfony/Component/Yaml/Parser.php | 81 ++++++++++--------- .../Component/Yaml/Tests/ParserTest.php | 48 +++++++++++ 2 files changed, 91 insertions(+), 38 deletions(-) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index 259e3e6b4946f..0c4a76e2b189e 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -750,54 +750,54 @@ private function parseValue(string $value, int $flags, string $context) return Inline::parse($this->lexInlineSequence($cursor), $flags, $this->refs); } - $quotation = '' !== $value && ('"' === $value[0] || "'" === $value[0]) ? $value[0] : null; - - // do not take following lines into account when the current line is a quoted single line value - if (null !== $quotation && self::preg_match('/^'.$quotation.'.*'.$quotation.'(\s*#.*)?$/', $value)) { - return Inline::parse($value, $flags, $this->refs); - } + switch ($value[0] ?? '') { + case '"': + case "'": + $cursor = \strlen($this->currentLine) - \strlen($value); + $parsedValue = Inline::parse($this->lexInlineQuotedString($cursor), $flags, $this->refs); + + if (isset($this->currentLine[$cursor]) && preg_replace('/\s*#.*$/A', '', substr($this->currentLine, $cursor))) { + throw new ParseException(sprintf('Unexpected characters near "%s".', substr($this->currentLine, $cursor))); + } - $lines = []; + return $parsedValue; + default: + $lines = []; - while ($this->moveToNextLine()) { - // unquoted strings end before the first unindented line - if (null === $quotation && 0 === $this->getCurrentLineIndentation()) { - $this->moveToPreviousLine(); + while ($this->moveToNextLine()) { + // unquoted strings end before the first unindented line + if (0 === $this->getCurrentLineIndentation()) { + $this->moveToPreviousLine(); - break; - } + break; + } - $lines[] = trim($this->currentLine); + $lines[] = trim($this->currentLine); + } - // quoted string values end with a line that is terminated with the quotation character - $escapedLine = str_replace(['\\\\', '\\"'], '', $this->currentLine); - if ('' !== $escapedLine && substr($escapedLine, -1) === $quotation) { - break; - } - } + for ($i = 0, $linesCount = \count($lines), $previousLineBlank = false; $i < $linesCount; ++$i) { + if ('' === $lines[$i]) { + $value .= "\n"; + $previousLineBlank = true; + } elseif ($previousLineBlank) { + $value .= $lines[$i]; + $previousLineBlank = false; + } else { + $value .= ' '.$lines[$i]; + $previousLineBlank = false; + } + } - for ($i = 0, $linesCount = \count($lines), $previousLineBlank = false; $i < $linesCount; ++$i) { - if ('' === $lines[$i]) { - $value .= "\n"; - $previousLineBlank = true; - } elseif ($previousLineBlank) { - $value .= $lines[$i]; - $previousLineBlank = false; - } else { - $value .= ' '.$lines[$i]; - $previousLineBlank = false; - } - } + Inline::$parsedLineNumber = $this->getRealCurrentLineNb(); - Inline::$parsedLineNumber = $this->getRealCurrentLineNb(); + $parsedValue = Inline::parse($value, $flags, $this->refs); - $parsedValue = Inline::parse($value, $flags, $this->refs); + if ('mapping' === $context && \is_string($parsedValue) && '"' !== $value[0] && "'" !== $value[0] && '[' !== $value[0] && '{' !== $value[0] && '!' !== $value[0] && false !== strpos($parsedValue, ': ')) { + throw new ParseException('A colon cannot be used in an unquoted mapping value.', $this->getRealCurrentLineNb() + 1, $value, $this->filename); + } - if ('mapping' === $context && \is_string($parsedValue) && '"' !== $value[0] && "'" !== $value[0] && '[' !== $value[0] && '{' !== $value[0] && '!' !== $value[0] && false !== strpos($parsedValue, ': ')) { - throw new ParseException('A colon cannot be used in an unquoted mapping value.', $this->getRealCurrentLineNb() + 1, $value, $this->filename); + return $parsedValue; } - - return $parsedValue; } catch (ParseException $e) { $e->setParsedLine($this->getRealCurrentLineNb() + 1); $e->setSnippet($this->currentLine); @@ -1154,8 +1154,13 @@ private function lexInlineQuotedString(int &$cursor = 0): string $previousLineWasNewline = true; $previousLineWasTerminatedWithBackslash = false; + $lineNumber = 0; do { + if (++$lineNumber > 1) { + $cursor += strspn($this->currentLine, ' ', $cursor); + } + if ($this->isCurrentLineBlank()) { $value .= "\n"; } elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) { diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index f9e4765a5d2af..a9715151f1b03 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -1570,6 +1570,54 @@ public function testParseMultiLineUnquotedString() $this->assertSame(['foo' => 'bar baz foobar foo', 'bar' => 'baz'], $this->parser->parse($yaml)); } + /** + * @dataProvider escapedQuotationCharactersInQuotedStrings + */ + public function testParseQuotedStringContainingEscapedQuotationCharacters(string $yaml, array $expected) + { + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function escapedQuotationCharactersInQuotedStrings() + { + return [ + 'single quoted string' => [ + << [ + [ + 'message' => 'No emails received before timeout - Address: \'test@testemail.company.com\' Keyword: \'Your Order confirmation\' ttl: 50', + 'outcome' => 'failed', + ], + ], + ], + ], + 'double quoted string' => [ + << [ + [ + 'message' => 'No emails received before timeout - Address: "test@testemail.company.com" Keyword: "Your Order confirmation" ttl: 50', + 'outcome' => 'failed', + ], + ], + ], + ], + ]; + } + public function testParseMultiLineString() { $this->assertEquals("foo bar\nbaz", $this->parser->parse("foo\nbar\n\nbaz")); From ca93ae5b1affaa15d120f11c045d901a3946414f Mon Sep 17 00:00:00 2001 From: Ikko Ashimine Date: Tue, 24 Nov 2020 21:09:17 +0900 Subject: [PATCH 114/136] Fix typo in comment possibe -> possible --- .../Routing/Matcher/Dumper/CompiledUrlMatcherDumper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Routing/Matcher/Dumper/CompiledUrlMatcherDumper.php b/src/Symfony/Component/Routing/Matcher/Dumper/CompiledUrlMatcherDumper.php index e77d24aecf9c1..402ac51351d55 100644 --- a/src/Symfony/Component/Routing/Matcher/Dumper/CompiledUrlMatcherDumper.php +++ b/src/Symfony/Component/Routing/Matcher/Dumper/CompiledUrlMatcherDumper.php @@ -242,7 +242,7 @@ private function compileStaticRoutes(array $staticRoutes, array &$conditions): a * Paths that can match two or more routes, or have user-specified conditions are put in separate switch's cases. * * Last but not least: - * - Because it is not possibe to mix unicode/non-unicode patterns in a single regexp, several of them can be generated. + * - Because it is not possible to mix unicode/non-unicode patterns in a single regexp, several of them can be generated. * - The same regexp can be used several times when the logic in the switch rejects the match. When this happens, the * matching-but-failing subpattern is excluded by replacing its name by "(*F)", which forces a failure-to-match. * To ease this backlisting operation, the name of subpatterns is also the string offset where the replacement should occur. From 2834c279d7f26e2ef45739f7468cdd23654c7adb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Wed, 25 Nov 2020 01:21:23 +0100 Subject: [PATCH 115/136] Fix console closing tag --- .../Component/Console/Formatter/OutputFormatter.php | 8 ++++++++ .../Style/SymfonyStyle/command/command_20.php | 13 +++++++++++++ .../Style/SymfonyStyle/output/output_20.txt | 1 + 3 files changed, 22 insertions(+) create mode 100644 src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/command_20.php create mode 100644 src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/output/output_20.txt diff --git a/src/Symfony/Component/Console/Formatter/OutputFormatter.php b/src/Symfony/Component/Console/Formatter/OutputFormatter.php index 5d52896ac995c..26288ce62f473 100644 --- a/src/Symfony/Component/Console/Formatter/OutputFormatter.php +++ b/src/Symfony/Component/Console/Formatter/OutputFormatter.php @@ -25,6 +25,14 @@ class OutputFormatter implements WrappableOutputFormatterInterface private $styles = []; private $styleStack; + public function __clone() + { + $this->styleStack = clone $this->styleStack; + foreach ($this->styles as $key => $value) { + $this->styles[$key] = clone $value; + } + } + /** * Escapes "<" special char in given text. * diff --git a/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/command_20.php b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/command_20.php new file mode 100644 index 0000000000000..6b47969eeeba6 --- /dev/null +++ b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/command_20.php @@ -0,0 +1,13 @@ +setDecorated(true); + $output = new SymfonyStyle($input, $output); + $output->write('do you want something'); + $output->writeln('?'); +}; diff --git a/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/output/output_20.txt b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/output/output_20.txt new file mode 100644 index 0000000000000..c082985309229 --- /dev/null +++ b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/output/output_20.txt @@ -0,0 +1 @@ +do you want something? From 18fca2984d97f90b291c5e3a9cd163a524d716ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Tue, 24 Nov 2020 13:45:24 +0100 Subject: [PATCH 116/136] Use a partial buffer in SymfonyStyle --- .../Console/Output/TrimmedBufferOutput.php | 67 +++++++++++++++++++ .../Component/Console/Style/SymfonyStyle.php | 9 ++- .../Console/Tests/Style/SymfonyStyleTest.php | 15 +++++ 3 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 src/Symfony/Component/Console/Output/TrimmedBufferOutput.php diff --git a/src/Symfony/Component/Console/Output/TrimmedBufferOutput.php b/src/Symfony/Component/Console/Output/TrimmedBufferOutput.php new file mode 100644 index 0000000000000..c014d43633cf8 --- /dev/null +++ b/src/Symfony/Component/Console/Output/TrimmedBufferOutput.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Output; + +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Formatter\OutputFormatterInterface; + +/** + * A BufferedOutput that keeps only the last N chars. + * + * @author Jérémy Derussé + */ +class TrimmedBufferOutput extends Output +{ + private $maxLength; + private $buffer = ''; + + public function __construct( + ?int $verbosity = self::VERBOSITY_NORMAL, + bool $decorated = false, + OutputFormatterInterface $formatter = null, + int $maxLength + ) { + if ($maxLength <= 0) { + throw new InvalidArgumentException(sprintf('"%s()" expects a strictly positive maxLength. Got %d.', __METHOD__, $maxLength)); + } + + parent::__construct($verbosity, $decorated, $formatter); + $this->maxLength = $maxLength; + } + + /** + * Empties buffer and returns its content. + * + * @return string + */ + public function fetch() + { + $content = $this->buffer; + $this->buffer = ''; + + return $content; + } + + /** + * {@inheritdoc} + */ + protected function doWrite($message, $newline) + { + $this->buffer .= $message; + + if ($newline) { + $this->buffer .= \PHP_EOL; + } + + $this->buffer = substr($this->buffer, 0 - $this->maxLength); + } +} diff --git a/src/Symfony/Component/Console/Style/SymfonyStyle.php b/src/Symfony/Component/Console/Style/SymfonyStyle.php index b40c16e99d005..a5edac3c4a1f1 100644 --- a/src/Symfony/Component/Console/Style/SymfonyStyle.php +++ b/src/Symfony/Component/Console/Style/SymfonyStyle.php @@ -21,8 +21,8 @@ use Symfony\Component\Console\Helper\TableCell; use Symfony\Component\Console\Helper\TableSeparator; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\BufferedOutput; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Output\TrimmedBufferOutput; use Symfony\Component\Console\Question\ChoiceQuestion; use Symfony\Component\Console\Question\ConfirmationQuestion; use Symfony\Component\Console\Question\Question; @@ -46,7 +46,7 @@ class SymfonyStyle extends OutputStyle public function __construct(InputInterface $input, OutputInterface $output) { $this->input = $input; - $this->bufferedOutput = new BufferedOutput($output->getVerbosity(), false, clone $output->getFormatter()); + $this->bufferedOutput = new TrimmedBufferOutput($output->getVerbosity(), false, clone $output->getFormatter(), \DIRECTORY_SEPARATOR === '\\' ? 4 : 2); // Windows cmd wraps lines as soon as the terminal width is reached, whether there are following chars or not. $width = (new Terminal())->getWidth() ?: self::MAX_LINE_LENGTH; $this->lineLength = min($width - (int) (\DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH); @@ -449,9 +449,8 @@ private function autoPrependText(): void private function writeBuffer(string $message, bool $newLine, int $type): void { - // We need to know if the two last chars are PHP_EOL - // Preserve the last 4 chars inserted (PHP_EOL on windows is two chars) in the history buffer - $this->bufferedOutput->write(substr($message, -4), $newLine, $type); + // We need to know if the last chars are PHP_EOL + $this->bufferedOutput->write($message, $newLine, $type); } private function createBlock(iterable $messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = false): array diff --git a/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php b/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php index 943b94172a609..2444d89ba001a 100644 --- a/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php +++ b/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php @@ -14,8 +14,10 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Formatter\OutputFormatter; +use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\ConsoleOutputInterface; +use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Console\Tester\CommandTester; @@ -115,4 +117,17 @@ public function testGetErrorStyleUsesTheCurrentOutputIfNoErrorOutputIsAvailable( $this->assertInstanceOf(SymfonyStyle::class, $style->getErrorStyle()); } + + public function testMemoryConsumption() + { + $io = new SymfonyStyle(new ArrayInput([]), new NullOutput()); + $str = 'teststr'; + $io->writeln($str, SymfonyStyle::VERBOSITY_QUIET); + $start = memory_get_usage(); + for ($i = 0; $i < 100; ++$i) { + $io->writeln($str, SymfonyStyle::VERBOSITY_QUIET); + } + + $this->assertSame(0, memory_get_usage() - $start); + } } From f2713d6580e2e3451da8ffb5b3b7706eeb414bca Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Wed, 25 Nov 2020 12:55:08 +0100 Subject: [PATCH 117/136] Improve return phpdoc for Normalizer --- .../Component/Serializer/Normalizer/ArrayDenormalizer.php | 2 ++ .../Normalizer/ConstraintViolationListNormalizer.php | 2 ++ .../Component/Serializer/Normalizer/DataUriNormalizer.php | 4 ++++ .../Serializer/Normalizer/DateIntervalNormalizer.php | 4 ++++ .../Component/Serializer/Normalizer/DateTimeNormalizer.php | 4 ++++ .../Serializer/Normalizer/DateTimeZoneNormalizer.php | 4 ++++ .../Component/Serializer/Normalizer/ProblemNormalizer.php | 2 ++ 7 files changed, 22 insertions(+) diff --git a/src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php b/src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php index 759dbcd889ce7..65b1c2e82175b 100644 --- a/src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php @@ -35,6 +35,8 @@ class ArrayDenormalizer implements ContextAwareDenormalizerInterface, Serializer * {@inheritdoc} * * @throws NotNormalizableValueException + * + * @return array */ public function denormalize($data, $type, $format = null, array $context = []) { diff --git a/src/Symfony/Component/Serializer/Normalizer/ConstraintViolationListNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/ConstraintViolationListNormalizer.php index 36373d9f5c32b..81a5416ff0633 100644 --- a/src/Symfony/Component/Serializer/Normalizer/ConstraintViolationListNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/ConstraintViolationListNormalizer.php @@ -40,6 +40,8 @@ public function __construct($defaultContext = [], NameConverterInterface $nameCo /** * {@inheritdoc} + * + * @return array */ public function normalize($object, $format = null, array $context = []) { diff --git a/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php index 87bb96aad81bb..4646d6ce0d249 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php @@ -61,6 +61,8 @@ public function __construct($mimeTypeGuesser = null) /** * {@inheritdoc} + * + * @return string */ public function normalize($object, $format = null, array $context = []) { @@ -102,6 +104,8 @@ public function supportsNormalization($data, $format = null) * * @throws InvalidArgumentException * @throws NotNormalizableValueException + * + * @return \SplFileInfo */ public function denormalize($data, $type, $format = null, array $context = []) { diff --git a/src/Symfony/Component/Serializer/Normalizer/DateIntervalNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DateIntervalNormalizer.php index c4b7c55ab170c..31cadaa88beeb 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DateIntervalNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/DateIntervalNormalizer.php @@ -46,6 +46,8 @@ public function __construct($defaultContext = []) * {@inheritdoc} * * @throws InvalidArgumentException + * + * @return string */ public function normalize($object, $format = null, array $context = []) { @@ -77,6 +79,8 @@ public function hasCacheableSupportsMethod(): bool * * @throws InvalidArgumentException * @throws UnexpectedValueException + * + * @return \DateInterval */ public function denormalize($data, $type, $format = null, array $context = []) { diff --git a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php index 34e1083bc7e08..996700cf1406d 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php @@ -57,6 +57,8 @@ public function __construct($defaultContext = [], \DateTimeZone $timezone = null * {@inheritdoc} * * @throws InvalidArgumentException + * + * @return string */ public function normalize($object, $format = null, array $context = []) { @@ -87,6 +89,8 @@ public function supportsNormalization($data, $format = null) * {@inheritdoc} * * @throws NotNormalizableValueException + * + * @return \DateTimeInterface */ public function denormalize($data, $type, $format = null, array $context = []) { diff --git a/src/Symfony/Component/Serializer/Normalizer/DateTimeZoneNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DateTimeZoneNormalizer.php index 519381b22388a..1080393240a4d 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DateTimeZoneNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/DateTimeZoneNormalizer.php @@ -25,6 +25,8 @@ class DateTimeZoneNormalizer implements NormalizerInterface, DenormalizerInterfa * {@inheritdoc} * * @throws InvalidArgumentException + * + * @return string */ public function normalize($object, $format = null, array $context = []) { @@ -47,6 +49,8 @@ public function supportsNormalization($data, $format = null) * {@inheritdoc} * * @throws NotNormalizableValueException + * + * @return \DateTimeZone */ public function denormalize($data, $type, $format = null, array $context = []) { diff --git a/src/Symfony/Component/Serializer/Normalizer/ProblemNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/ProblemNormalizer.php index 17f4500f26fda..ca7b78b5c68ee 100644 --- a/src/Symfony/Component/Serializer/Normalizer/ProblemNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/ProblemNormalizer.php @@ -37,6 +37,8 @@ public function __construct(bool $debug = false, array $defaultContext = []) /** * {@inheritdoc} + * + * @return array */ public function normalize($exception, $format = null, array $context = []) { From 98cf389fb9651fc5e087bfd5c716aeb173fc18dc Mon Sep 17 00:00:00 2001 From: Camille Dejoye Date: Thu, 26 Nov 2020 14:01:08 +0100 Subject: [PATCH 118/136] fix denormalizing scalar with UnwrappingDenormalizer --- src/Symfony/Component/Serializer/Serializer.php | 7 +++++-- src/Symfony/Component/Serializer/Tests/SerializerTest.php | 7 +++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Serializer/Serializer.php b/src/Symfony/Component/Serializer/Serializer.php index b8c33a2fe56c5..6414caf900472 100644 --- a/src/Symfony/Component/Serializer/Serializer.php +++ b/src/Symfony/Component/Serializer/Serializer.php @@ -189,7 +189,10 @@ public function normalize($data, string $format = null, array $context = []) */ public function denormalize($data, string $type, string $format = null, array $context = []) { - if (isset(self::SCALAR_TYPES[$type])) { + $normalizer = $this->getDenormalizer($data, $type, $format, $context); + + // Check for a denormalizer first, e.g. the data is wrapped + if (!$normalizer && isset(self::SCALAR_TYPES[$type])) { if (!('is_'.$type)($data)) { throw new NotNormalizableValueException(sprintf('Data expected to be of type "%s" ("%s" given).', $type, get_debug_type($data))); } @@ -201,7 +204,7 @@ public function denormalize($data, string $type, string $format = null, array $c throw new LogicException('You must register at least one normalizer to be able to denormalize objects.'); } - if ($normalizer = $this->getDenormalizer($data, $type, $format, $context)) { + if ($normalizer) { return $normalizer->denormalize($data, $type, $format, $context); } diff --git a/src/Symfony/Component/Serializer/Tests/SerializerTest.php b/src/Symfony/Component/Serializer/Tests/SerializerTest.php index 80c430a7d4323..b72d9030d2155 100644 --- a/src/Symfony/Component/Serializer/Tests/SerializerTest.php +++ b/src/Symfony/Component/Serializer/Tests/SerializerTest.php @@ -613,6 +613,13 @@ public function testDeserializeInconsistentScalarArray() $serializer->deserialize('["42"]', 'int[]', 'json'); } + public function testDeserializeWrappedScalar() + { + $serializer = new Serializer([new UnwrappingDenormalizer()], ['json' => new JsonEncoder()]); + + $this->assertSame(42, $serializer->deserialize('{"wrapper": 42}', 'int', 'json', [UnwrappingDenormalizer::UNWRAP_PATH => '[wrapper]'])); + } + private function serializerWithClassDiscriminator() { $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); From dff539434e2f553fc5d73298870b995d8e7fb51a Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Fri, 16 Oct 2020 10:44:52 +0200 Subject: [PATCH 119/136] [PhpUnitBridge] Fix qualification of deprecations triggered by the debug class loader --- src/Symfony/Bridge/PhpUnit/.gitignore | 1 + .../DeprecationErrorHandler/Deprecation.php | 14 +++++ .../debug_class_loader_autoload.phpt | 51 +++++++++++++++++++ .../fake_app/BarService.php | 13 +++++ .../ExtendsDeprecatedClassFromOtherVendor.php | 10 ++++ .../fake_vendor/composer/autoload_real.php | 16 ++++-- .../fake_vendor/fcy/lib/DeprecatedClass.php | 10 ++++ .../symfony/error-handler/.gitkeep | 0 src/Symfony/Bridge/PhpUnit/composer.json | 3 ++ 9 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/debug_class_loader_autoload.phpt create mode 100644 src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_app/BarService.php create mode 100644 src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/lib/ExtendsDeprecatedClassFromOtherVendor.php create mode 100644 src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/fcy/lib/DeprecatedClass.php create mode 100644 src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/symfony/error-handler/.gitkeep diff --git a/src/Symfony/Bridge/PhpUnit/.gitignore b/src/Symfony/Bridge/PhpUnit/.gitignore index c49a5d8df5c65..9d8c4aadaf9f5 100644 --- a/src/Symfony/Bridge/PhpUnit/.gitignore +++ b/src/Symfony/Bridge/PhpUnit/.gitignore @@ -1,3 +1,4 @@ vendor/ composer.lock phpunit.xml +Tests/DeprecationErrorHandler/fake_vendor/symfony/error-handler/DebugClassLoader.php diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php index 911d37495e15a..9eded1a14e124 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php @@ -13,6 +13,8 @@ use PHPUnit\Util\Test; use Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerFor; +use Symfony\Component\Debug\DebugClassLoader as LegacyDebugClassLoader; +use Symfony\Component\ErrorHandler\DebugClassLoader; /** * @internal @@ -53,6 +55,18 @@ class Deprecation public function __construct($message, array $trace, $file) { $this->trace = $trace; + + if ('trigger_error' === ($trace[1]['function'] ?? null) + && (DebugClassLoader::class === ($class = $trace[2]['class'] ?? null) || LegacyDebugClassLoader::class === $class) + && 'checkClass' === ($trace[2]['function'] ?? null) + && null !== ($extraFile = $trace[2]['args'][1] ?? null) + && '' !== $extraFile + && false !== $extraFile = realpath($extraFile) + ) { + $this->getOriginalFilesStack(); + array_splice($this->originalFilesStack, 2, 1, $extraFile); + } + $this->message = $message; $i = \count($trace); while (1 < $i && $this->lineShouldBeSkipped($trace[--$i])) { diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/debug_class_loader_autoload.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/debug_class_loader_autoload.phpt new file mode 100644 index 0000000000000..781027e84fe66 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/debug_class_loader_autoload.phpt @@ -0,0 +1,51 @@ +--TEST-- +Test that a deprecation from the DebugClassLoader on a vendor class autoload triggered by an app class is considered indirect. +--FILE-- + +--EXPECTF-- +Remaining indirect deprecation notices (1) + + 1x: The "acme\lib\ExtendsDeprecatedClassFromOtherVendor" class extends "fcy\lib\DeprecatedClass" that is deprecated. + 1x in BarService::__construct from App\Services diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_app/BarService.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_app/BarService.php new file mode 100644 index 0000000000000..868de5bd443db --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_app/BarService.php @@ -0,0 +1,13 @@ + [__DIR__.'/../../fake_app/'], 'acme\\lib\\' => [__DIR__.'/../acme/lib/'], + 'fcy\\lib\\' => [__DIR__.'/../fcy/lib/'], ]; } public function loadClass($className) + { + if ($file = $this->findFile($className)) { + require $file; + } + } + + public function findFile($class) { foreach ($this->getPrefixesPsr4() as $prefix => $baseDirs) { - if (strpos($className, $prefix) !== 0) { + if (strpos($class, $prefix) !== 0) { continue; } foreach ($baseDirs as $baseDir) { - $file = str_replace([$prefix, '\\'], [$baseDir, '/'], $className.'.php'); + $file = str_replace([$prefix, '\\'], [$baseDir, '/'], $class.'.php'); if (file_exists($file)) { - require $file; + return $file; } } } + + return false; } } diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/fcy/lib/DeprecatedClass.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/fcy/lib/DeprecatedClass.php new file mode 100644 index 0000000000000..f6672cea20400 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/fcy/lib/DeprecatedClass.php @@ -0,0 +1,10 @@ +=5.5.9" }, + "require-dev": { + "symfony/error-handler": "^4.4|^5.0" + }, "suggest": { "symfony/error-handler": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" }, From b047064842c534d5d417d22294b89825c1753967 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Fri, 27 Nov 2020 01:30:48 +0100 Subject: [PATCH 120/136] Fix test. --- src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php b/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php index 2444d89ba001a..16bb2baec4ac7 100644 --- a/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php +++ b/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php @@ -123,6 +123,7 @@ public function testMemoryConsumption() $io = new SymfonyStyle(new ArrayInput([]), new NullOutput()); $str = 'teststr'; $io->writeln($str, SymfonyStyle::VERBOSITY_QUIET); + $io->writeln($str, SymfonyStyle::VERBOSITY_QUIET); $start = memory_get_usage(); for ($i = 0; $i < 100; ++$i) { $io->writeln($str, SymfonyStyle::VERBOSITY_QUIET); From 114b7a543a7bd7ff77a8fe2f0668d517f565eb46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Thu, 12 Nov 2020 21:59:34 +0100 Subject: [PATCH 121/136] [DependencyInjection][Translator] Silent deprecation triggered by libxml_disable_entity_loader --- .../Loader/XmlFileLoader.php | 33 ++++++++++++- .../Tests/Resources/TranslationFilesTest.php | 15 ++++++ .../Tests/Resources/TranslationFilesTest.php | 14 ++++++ .../Component/Translation/Util/XliffUtils.php | 49 ++++++++++++++----- .../Tests/Resources/TranslationFilesTest.php | 14 ++++++ 5 files changed, 112 insertions(+), 13 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php index 19566e9aa7050..2ebdbda090e31 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php @@ -634,14 +634,13 @@ public function validateSchema(\DOMDocument $dom) EOF ; - if (\LIBXML_VERSION < 20900) { + if ($this->shouldEnableEntityLoader()) { $disableEntities = libxml_disable_entity_loader(false); $valid = @$dom->schemaValidateSource($source); libxml_disable_entity_loader($disableEntities); } else { $valid = @$dom->schemaValidateSource($source); } - foreach ($tmpfiles as $tmpfile) { @unlink($tmpfile); } @@ -649,6 +648,36 @@ public function validateSchema(\DOMDocument $dom) return $valid; } + private function shouldEnableEntityLoader(): bool + { + // Version prior to 8.0 can be enabled without deprecation + if (\PHP_VERSION_ID < 80000) { + return true; + } + + static $dom, $schema; + if (null === $dom) { + $dom = new \DOMDocument(); + $dom->loadXML(''); + + $tmpfile = tempnam(sys_get_temp_dir(), 'symfony'); + register_shutdown_function(static function () use ($tmpfile) { + @unlink($tmpfile); + }); + $schema = ' + + +'; + file_put_contents($tmpfile, ' + + + +'); + } + + return !@$dom->schemaValidateSource($schema); + } + private function validateAlias(\DOMElement $alias, string $file) { foreach ($alias->attributes as $name => $node) { diff --git a/src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php b/src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php index 53b2cee448805..5a9669e92b424 100644 --- a/src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php +++ b/src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php @@ -29,6 +29,21 @@ public function testTranslationFileIsValid($filePath) $this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message')))); } + /** + * @dataProvider provideTranslationFiles + * @group Legacy + */ + public function testTranslationFileIsValidWithoutEntityLoader($filePath) + { + $document = new \DOMDocument(); + $document->loadXML(file_get_contents($filePath)); + libxml_disable_entity_loader(true); + + $errors = XliffUtils::validateSchema($document); + + $this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message')))); + } + public function provideTranslationFiles() { return array_map( diff --git a/src/Symfony/Component/Security/Core/Tests/Resources/TranslationFilesTest.php b/src/Symfony/Component/Security/Core/Tests/Resources/TranslationFilesTest.php index 2402b0199824f..4255e91d926b8 100644 --- a/src/Symfony/Component/Security/Core/Tests/Resources/TranslationFilesTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Resources/TranslationFilesTest.php @@ -29,6 +29,20 @@ public function testTranslationFileIsValid($filePath) $this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message')))); } + /** + * @dataProvider provideTranslationFiles + */ + public function testTranslationFileIsValidWithoutEntityLoader($filePath) + { + $document = new \DOMDocument(); + $document->loadXML(file_get_contents($filePath)); + libxml_disable_entity_loader(true); + + $errors = XliffUtils::validateSchema($document); + + $this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message')))); + } + public function provideTranslationFiles() { return array_map( diff --git a/src/Symfony/Component/Translation/Util/XliffUtils.php b/src/Symfony/Component/Translation/Util/XliffUtils.php index a8c05c2244d47..e4373a7d5ba1b 100644 --- a/src/Symfony/Component/Translation/Util/XliffUtils.php +++ b/src/Symfony/Component/Translation/Util/XliffUtils.php @@ -61,21 +61,18 @@ public static function validateSchema(\DOMDocument $dom): array { $xliffVersion = static::getVersionNumber($dom); $internalErrors = libxml_use_internal_errors(true); - if (\LIBXML_VERSION < 20900) { + if ($shouldEnable = self::shouldEnableEntityLoader()) { $disableEntities = libxml_disable_entity_loader(false); } - - $isValid = @$dom->schemaValidateSource(self::getSchema($xliffVersion)); - if (!$isValid) { - if (\LIBXML_VERSION < 20900) { + try { + $isValid = @$dom->schemaValidateSource(self::getSchema($xliffVersion)); + if (!$isValid) { + return self::getXmlErrors($internalErrors); + } + } finally { + if ($shouldEnable) { libxml_disable_entity_loader($disableEntities); } - - return self::getXmlErrors($internalErrors); - } - - if (\LIBXML_VERSION < 20900) { - libxml_disable_entity_loader($disableEntities); } $dom->normalizeDocument(); @@ -86,6 +83,36 @@ public static function validateSchema(\DOMDocument $dom): array return []; } + private static function shouldEnableEntityLoader(): bool + { + // Version prior to 8.0 can be enabled without deprecation + if (\PHP_VERSION_ID < 80000) { + return true; + } + + static $dom, $schema; + if (null === $dom) { + $dom = new \DOMDocument(); + $dom->loadXML(''); + + $tmpfile = tempnam(sys_get_temp_dir(), 'symfony'); + register_shutdown_function(static function () use ($tmpfile) { + @unlink($tmpfile); + }); + $schema = ' + + +'; + file_put_contents($tmpfile, ' + + + +'); + } + + return !@$dom->schemaValidateSource($schema); + } + public static function getErrorsAsString(array $xmlErrors): string { $errorsAsString = ''; diff --git a/src/Symfony/Component/Validator/Tests/Resources/TranslationFilesTest.php b/src/Symfony/Component/Validator/Tests/Resources/TranslationFilesTest.php index 894ae55f10567..6e0620b517563 100644 --- a/src/Symfony/Component/Validator/Tests/Resources/TranslationFilesTest.php +++ b/src/Symfony/Component/Validator/Tests/Resources/TranslationFilesTest.php @@ -29,6 +29,20 @@ public function testTranslationFileIsValid($filePath) $this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message')))); } + /** + * @dataProvider provideTranslationFiles + */ + public function testTranslationFileIsValidWithoutEntityLoader($filePath) + { + $document = new \DOMDocument(); + $document->loadXML(file_get_contents($filePath)); + libxml_disable_entity_loader(true); + + $errors = XliffUtils::validateSchema($document); + + $this->assertCount(0, $errors, sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message')))); + } + public function provideTranslationFiles() { return array_map( From 6aa31a13c72fd98d0bc06e109e90bc80eb262a0f Mon Sep 17 00:00:00 2001 From: Gabi Udrescu Date: Sun, 8 Nov 2020 17:07:20 +0200 Subject: [PATCH 122/136] Add Romanian missing translations --- .../Resources/translations/validators.ro.xlf | 126 +++++++++++++++++- .../Resources/translations/security.ro.xlf | 8 ++ 2 files changed, 131 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Form/Resources/translations/validators.ro.xlf b/src/Symfony/Component/Form/Resources/translations/validators.ro.xlf index 25abab3b6f148..a7dc62b579c6b 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.ro.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.ro.xlf @@ -4,7 +4,7 @@ This form should not contain extra fields. - Aceast formular nu ar trebui să conțină câmpuri suplimentare. + Acest formular nu ar trebui să conțină câmpuri suplimentare. The uploaded file was too large. Please try to upload a smaller file. @@ -12,8 +12,128 @@ The CSRF token is invalid. Please try to resubmit the form. - Token-ul CSRF este invalid. Vă rugăm să trimiteți formularul incă o dată. + Token-ul CSRF este invalid. Vă rugăm să retrimiteți formularul. + + + This value is not a valid HTML5 color. + Această valoare nu este un cod de culoare HTML5 valid. + + + Please enter a valid birthdate. + Vă rugăm să introduceți o dată de naștere validă. + + + The selected choice is invalid. + Valoarea selectată este invalidă. + + + The collection is invalid. + Colecția nu este validă. + + + Please select a valid color. + Vă rugăm să selectați o culoare validă. + + + Please select a valid country. + Vă rugăm să selectați o țară validă. + + + Please select a valid currency. + Vă rugăm să selectați o monedă validă. + + + Please choose a valid date interval. + Vă rugăm să selectați un interval de zile valid. + + + Please enter a valid date and time. + Vă rugăm să introduceți o dată și o oră validă. + + + Please enter a valid date. + Vă rugăm să introduceți o dată validă. + + + Please select a valid file. + Vă rugăm să selectați un fișier valid. + + + The hidden field is invalid. + Câmpul ascuns este invalid. + + + Please enter an integer. + Vă rugăm să introduceți un număr întreg. + + + Please select a valid language. + Vă rugăm să selectați o limbă validă. + + + Please select a valid locale. + Vă rugăm să selectați o setare locală validă. + + + Please enter a valid money amount. + Vă rugăm să introduceți o valoare monetară corectă. + + + Please enter a number. + Vă rugăm să introduceți un număr. + + + The password is invalid. + Parola nu este validă. + + + Please enter a percentage value. + Vă rugăm să introduceți o valoare procentuală. + + + The values do not match. + Valorile nu coincid. + + + Please enter a valid time. + Vă rugăm să introduceți o oră validă. + + + Please select a valid timezone. + Vă rugăm să selectați un fus orar valid. + + + Please enter a valid URL. + Vă rugăm să introduceți un URL valid. + + + Please enter a valid search term. + Vă rugăm să introduceți un termen de căutare valid. + + + Please provide a valid phone number. + Vă rugăm să introduceți un număr de telefon valid. + + + The checkbox has an invalid value. + Bifa nu are o valoare validă. + + + Please enter a valid email address. + Vă rugăm să introduceți o adresă de email validă. + + + Please select a valid option. + Vă rugăm să selectați o opțiune validă. + + + Please select a valid range. + Vă rugăm să selectați un interval valid. + + + Please enter a valid week. + Vă rugăm să introduceți o săptămână validă. - \ No newline at end of file + diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.ro.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.ro.xlf index f35a2bb815878..1462e650e9c4b 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.ro.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.ro.xlf @@ -62,6 +62,14 @@ Account is locked. Contul este blocat. + + Too many failed login attempts, please try again later. + Prea multe încercări de autentificare eșuate, vă rugăm să încercați mai târziu. + + + Invalid or expired login link. + Link de autentificare invalid sau expirat. + From 0153c44975f89859a6f764384089eb0eb1685aa4 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 27 Nov 2020 09:41:25 +0100 Subject: [PATCH 123/136] Update CHANGELOG for 3.4.47 --- CHANGELOG-3.4.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG-3.4.md b/CHANGELOG-3.4.md index 95a2107528b52..23e1671360b2c 100644 --- a/CHANGELOG-3.4.md +++ b/CHANGELOG-3.4.md @@ -7,6 +7,10 @@ in 3.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/v3.4.0...v3.4.1 +* 3.4.47 (2020-11-27) + + * bug #38628 [DoctrineBridge] indexBy could reference to association columns (juanmiguelbesada) + * 3.4.46 (2020-10-28) * bug #38669 [Serializer] fix decoding float XML attributes starting with 0 (Marcin Kruk) From f93df0ef1d6b9206c9ffe2f64ded2bfab982ee65 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 27 Nov 2020 09:41:54 +0100 Subject: [PATCH 124/136] Update CONTRIBUTORS for 3.4.47 --- CONTRIBUTORS.md | 84 +++++++++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 30 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 5d3ae522834d7..3bed011d06243 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -12,9 +12,10 @@ Symfony is the result of the work of many people who made the code better - Robin Chalas (chalas_r) - Christophe Coevoet (stof) - Kévin Dunglas (dunglas) - - Jordi Boggiano (seldaek) - Maxime Steinhausser (ogizanagi) + - Jordi Boggiano (seldaek) - Victor Berchet (victor) + - Alexander M. Turek (derrabus) - Grégoire Pineau (lyrixx) - Ryan Weaver (weaverryan) - Javier Eguiluz (javier.eguiluz) @@ -22,33 +23,32 @@ Symfony is the result of the work of many people who made the code better - Jakub Zalas (jakubzalas) - Johannes S (johannes) - Kris Wallsmith (kriswallsmith) - - Alexander M. Turek (derrabus) - Wouter de Jong (wouterj) - Yonel Ceruto (yonelceruto) - Thomas Calvet (fancyweb) - Hugo Hamon (hhamon) + - Jérémy DERUSSÉ (jderusse) - Abdellatif Ait boudad (aitboudad) - Samuel ROZE (sroze) - Romain Neutron (romain) - Pascal Borreli (pborreli) - - Jérémy DERUSSÉ (jderusse) - Joseph Bielawski (stloyd) - Karma Dordrak (drak) - Jules Pietri (heah) - Lukas Kahwe Smith (lsmith) - Martin Hasoň (hason) - Hamza Amrouche (simperfit) + - Tobias Nyholm (tobias) - Jeremy Mikola (jmikola) - Jean-François Simon (jfsimon) - Benjamin Eberlei (beberlei) - Igor Wiedler (igorw) - - Tobias Nyholm (tobias) - Eriksen Costa (eriksencosta) - Guilhem Niot (energetick) - Sarah Khalil (saro0h) - Jonathan Wage (jwage) - - Lynn van der Berg (kjarli) - Jan Schädlich (jschaedl) + - Lynn van der Berg (kjarli) - Matthias Pigulla (mpdude) - Diego Saint Esteben (dosten) - Pierre du Plessis (pierredup) @@ -56,13 +56,13 @@ Symfony is the result of the work of many people who made the code better - William Durand (couac) - Valentin Udaltsov (vudaltsov) - ornicar + - Grégoire Paris (greg0ire) - Dany Maillard (maidmaid) - Francis Besset (francisbesset) - stealth35 ‏ (stealth35) - Alexander Mols (asm89) - Kevin Bond (kbond) - Konstantin Myakshin (koc) - - Grégoire Paris (greg0ire) - Bulat Shakirzyanov (avalanche123) - Saša Stamenković (umpirsky) - Peter Rehm (rpet) @@ -116,17 +116,17 @@ Symfony is the result of the work of many people who made the code better - Tim Nagel (merk) - Chris Wilkinson (thewilkybarkid) - Brice BERNARD (brikou) + - Alexander Schranz (alexander-schranz) - marc.weistroff - Tomáš Votruba (tomas_votruba) - Peter Kokot (maastermedia) - Lars Strojny (lstrojny) - lenar - Alexander Schwenn (xelaris) + - Massimiliano Arione (garak) - Włodzimierz Gajda (gajdaw) - - Alexander Schranz (alexander-schranz) - Oskar Stark (oskarstark) - Adrien Brault (adrienbrault) - - Massimiliano Arione (garak) - Jacob Dreesen (jdreesen) - Florian Voutzinos (florianv) - Teoh Han Hui (teohhanhui) @@ -139,11 +139,11 @@ Symfony is the result of the work of many people who made the code better - excelwebzone - Gordon Franke (gimler) - Joel Wurtz (brouznouf) + - Antoine Makdessi (amakdessi) - Fabien Pennequin (fabienpennequin) - Julien Falque (julienfalque) - Théo FIDRY (theofidry) - Eric GELOEN (gelo) - - Antoine Makdessi (amakdessi) - Jannik Zschiesche (apfelbox) - jeremyFreeAgent (jeremyfreeagent) - Robert Schönthal (digitalkaoz) @@ -166,6 +166,7 @@ Symfony is the result of the work of many people who made the code better - Guilherme Blanco (guilhermeblanco) - SpacePossum - Pablo Godel (pgodel) + - Andreas Braun - Matthieu Napoli (mnapoli) - Richard van Laak (rvanlaak) - Jérémie Augustin (jaugustin) @@ -175,7 +176,6 @@ Symfony is the result of the work of many people who made the code better - Rafael Dohms (rdohms) - jwdeitch - Ahmed TAILOULOUTE (ahmedtai) - - Andreas Braun - Mikael Pajunen - Arman Hosseini (arman) - Niels Keurentjes (curry684) @@ -295,7 +295,9 @@ Symfony is the result of the work of many people who made the code better - Lorenz Schori - Sébastien Lavoie (lavoiesl) - Dariusz + - Farhad Safarov (safarov) - Michael Babker (mbabker) + - Thomas Lallement (raziel057) - Francois Zaninotto - Colin O'Dell (colinodell) - Alexander Kotynia (olden) @@ -307,21 +309,25 @@ Symfony is the result of the work of many people who made the code better - Danny Berger (dpb587) - zairig imad (zairigimad) - Antonio J. García Lagar (ajgarlag) + - Alessandro Lai (jean85) - Adam Prager (padam87) - Benoît Burnichon (bburnichon) - Maciej Malarz (malarzm) - Roman Marintšenko (inori) - Xavier Montaña Carreras (xmontana) + - Timothée Barray (tyx) - Mickaël Andrieu (mickaelandrieu) - Xavier Perez - Arjen Brouwer (arjenjb) - Katsuhiro OGAWA - Patrick McDougle (patrick-mcdougle) + - Rokas Mikalkėnas (rokasm) - Marc Weistroff (futurecat) - Alif Rachmawadi - Anton Chernikov (anton_ch1989) - Kristen Gilden (kgilden) - Pierre-Yves LEBECQ (pylebecq) + - Benjamin Leveque (benji07) - Jordan Samouh (jordansamouh) - Jakub Kucharovic (jkucharovic) - Loick Piera (pyrech) @@ -337,6 +343,7 @@ Symfony is the result of the work of many people who made the code better - Ray - Chekote - Thomas Adam + - Chi-teck - Jhonny Lidfors (jhonne) - Diego Agulló (aeoris) - jdhoek @@ -348,7 +355,6 @@ Symfony is the result of the work of many people who made the code better - Wodor Wodorski - Timo Bakx (timobakx) - Joe Bennett (kralos) - - Thomas Lallement (raziel057) - soyuka - Giorgio Premi - renanbr @@ -362,7 +368,6 @@ Symfony is the result of the work of many people who made the code better - Alexander Menshchikov (zmey_kk) - Emanuele Panzeri (thepanz) - Kim Hemsø Rasmussen (kimhemsoe) - - Alessandro Lai (jean85) - Langlet Vincent (deviling) - Pascal Luna (skalpa) - Wouter Van Hecke @@ -375,6 +380,7 @@ Symfony is the result of the work of many people who made the code better - Christian Schmidt - Patrick Landolt (scube) - MatTheCat + - Denis Brumann (dbrumann) - Bohan Yang (brentybh) - Vilius Grigaliūnas - David Badura (davidbadura) @@ -383,8 +389,6 @@ Symfony is the result of the work of many people who made the code better - Chris Smith (cs278) - Thomas Bisignani (toma) - Florian Klein (docteurklein) - - Timothée Barray (tyx) - - Benjamin Leveque (benji07) - Manuel Kiessling (manuelkiessling) - Alexey Kopytko (sanmai) - Atsuhiro KUBO (iteman) @@ -404,7 +408,6 @@ Symfony is the result of the work of many people who made the code better - Emmanuel BORGES (eborges78) - Aurelijus Valeiša (aurelijus) - Jan Decavele (jandc) - - Chi-teck - Gustavo Piltcher - Jesse Rushlow (geeshoe) - Stepan Tanasiychuk (stfalcon) @@ -459,19 +462,22 @@ Symfony is the result of the work of many people who made the code better - Thomas Perez (scullwm) - Felix Labrecque - Yaroslav Kiliba + - Ben Hakim - Terje Bråten - Gonzalo Vilaseca (gonzalovilaseca) + - Marco Petersen (ocrampete16) - Markus Fasselt (digilist) - Daniel STANCU - Robbert Klarenbeek (robbertkl) - Eric Masoero (eric-masoero) - Ion Bazan (ionbazan) - - Denis Brumann (dbrumann) + - Vitalii Ekert (comrade42) - JhonnyL - Clara van Miert - Haralan Dobrev (hkdobrev) - hossein zolfi (ocean) - Clément Gautier (clementgautier) + - Jeroen Noten (jeroennoten) - Bastien Jaillot (bastnic) - Dāvis Zālītis (k0d3r1s) - Sanpi @@ -485,7 +491,6 @@ Symfony is the result of the work of many people who made the code better - Dimitri Gritsajuk (ottaviano) - Kirill chEbba Chebunin (chebba) - - - Rokas Mikalkėnas (rokasm) - Greg Thornton (xdissent) - Alex Bowers - Philipp Cordes @@ -551,7 +556,6 @@ Symfony is the result of the work of many people who made the code better - Nate Wiebe (natewiebe13) - Marcin Szepczynski (czepol) - Mohammad Emran Hasan (phpfour) - - Farhad Safarov - Dmitriy Mamontov (mamontovdmitriy) - Jan Schumann - Niklas Fiekas @@ -600,18 +604,20 @@ Symfony is the result of the work of many people who made the code better - Arkadius Stefanski (arkadius) - Tim Goudriaan (codedmonkey) - Jonas Flodén (flojon) + - AnneKir - Soner Sayakci - Tobias Weichart + - Miro Michalicka - Tarmo Leppänen (tarlepp) - Marcin Sikoń (marphi) - M. Vondano - Dominik Zogg (dominik.zogg) - Marek Pietrzak + - Tavo Nieves J - Luc Vieillescazes (iamluc) - Lukáš Holeczy (holicz) - franek (franek) - Raulnet - - Marco Petersen (ocrampete16) - Christian Wahler - Giso Stallenberg (gisostallenberg) - Gintautas Miselis @@ -660,6 +666,7 @@ Symfony is the result of the work of many people who made the code better - Roy Van Ginneken (rvanginneken) - ondrowan - Barry vd. Heuvel (barryvdh) + - Michael Voříšek - Evan S Kaufman (evanskaufman) - mcben - Jérôme Vieilledent (lolautruche) @@ -758,6 +765,7 @@ Symfony is the result of the work of many people who made the code better - Fred Cox - vitaliytv - Philippe Segatori + - fd6130 (fdtvui) - Dalibor Karlović (dkarlovi) - Andrey Sevastianov - Sebastian Blum @@ -803,8 +811,10 @@ Symfony is the result of the work of many people who made the code better - Jérôme Tamarelle (jtamarelle-prismamedia) - Geoffrey Brier (geoffrey-brier) - Alexandre Parent + - Roger Guasch (rogerguasch) - Vladimir Tsykun - Dustin Dobervich (dustin10) + - Luis Tacón (lutacon) - dantleech - Philipp Kolesnikov - Anne-Sophie Bachelard (annesophie) @@ -828,6 +838,7 @@ Symfony is the result of the work of many people who made the code better - Stefan Warman - Tristan Maindron (tmaindron) - Behnoush Norouzali (behnoush) + - Marko H. Tamminen (gzumba) - Wesley Lancel - Xavier Briand (xavierbriand) - Ke WANG (yktd26) @@ -853,8 +864,10 @@ Symfony is the result of the work of many people who made the code better - Michael Devery (mickadoo) - Antoine Corcy - Ahmed Ashraf (ahmedash95) + - Luca Saba (lucasaba) - Sascha Grossenbacher - Szijarto Tamas + - Thomas P - Robin Lehrmann (robinlehrmann) - Catalin Dan - Jaroslav Kuba @@ -918,6 +931,7 @@ Symfony is the result of the work of many people who made the code better - Peter Ward - Davide Borsatto (davide.borsatto) - Julien DIDIER (juliendidier) + - Randy Geraads - Dominik Ritter (dritter) - Andreas Leathley (iquito) - Sebastian Grodzicki (sgrodzicki) @@ -927,7 +941,6 @@ Symfony is the result of the work of many people who made the code better - Baldur Rensch (brensch) - Pierre Rineau - Fritz Michael Gschwantner - - Jeroen Noten (jeroennoten) - Vladyslav Petrovych - Alex Xandra Albert Sim - Carson Full @@ -1045,12 +1058,10 @@ Symfony is the result of the work of many people who made the code better - Daniel Gorgan - Tony Malzhacker - Mathieu MARCHOIS - - Tavo Nieves J - Cyril Quintin (cyqui) - Gerard van Helden (drm) - flack (flack) - Johnny Peck (johnnypeck) - - Michael Voříšek - Stefan Kruppa - Ivan Menshykov - David Romaní @@ -1058,6 +1069,7 @@ Symfony is the result of the work of many people who made the code better - Gustavo Falco (gfalco) - Matt Robinson (inanimatt) - Kristof Van Cauwenbergh (kristofvc) + - Marco Lipparini (liarco) - Peter Bowyer (pbowyer) - Aleksey Podskrebyshev - Calin Mihai Pristavu @@ -1095,6 +1107,7 @@ Symfony is the result of the work of many people who made the code better - Don Pinkster - Maksim Muruev - Emil Einarsson + - Anderson Müller - 243083df - Thibault Duplessis - Rimas Kudelis @@ -1195,7 +1208,9 @@ Symfony is the result of the work of many people who made the code better - Pieter - Michael Tibben - Hallison Boaventura (hallisonboaventura) + - Mas Iting - Billie Thompson + - Albion Bame (abame) - Ganesh Chandrasekaran - Sander Marechal - Franz Wilding (killerpoke) @@ -1216,11 +1231,15 @@ Symfony is the result of the work of many people who made the code better - Nicolas Martin (cocorambo) - Tom Panier (neemzy) - Fred Cox + - luffy1727 - Luciano Mammino (loige) - fabios - Sander Coolen (scoolen) + - Amirreza Shafaat (amirrezashafaat) - Laurent Clouet + - Adoni Pavlakis (adoni) - Nicolas Le Goff (nlegoff) + - Ahmed EBEN HASSINE (famas23) - Ben Oman - Chris de Kok - Eduard Bulava (nonanerz) @@ -1229,6 +1248,7 @@ Symfony is the result of the work of many people who made the code better - Guillaume (guill) - Igor Timoshenko (igor.timoshenko) - Manuele Menozzi + - “teerasak” - Anton Babenko (antonbabenko) - Irmantas Šiupšinskas (irmantas) - Benoit Mallo @@ -1238,6 +1258,7 @@ Symfony is the result of the work of many people who made the code better - pizzaminded - Arnaud PETITPAS (apetitpa) - Ken Stanley + - ivan - Zachary Tong (polyfractal) - linh - Guilherme Augusto Henschel @@ -1279,8 +1300,10 @@ Symfony is the result of the work of many people who made the code better - Danijel Obradović - Pablo Borowicz - Arjan Keeman + - Bruno Rodrigues de Araujo (brunosinister) - Máximo Cuadros (mcuadros) - Lukas Mencl + - Jacek Wilczyński (jacekwilczynski) - tamirvs - gauss - julien.galenski @@ -1342,7 +1365,6 @@ Symfony is the result of the work of many people who made the code better - Martijn Evers - Philipp Fritsche - tarlepp - - Luca Saba (lucasaba) - Benjamin Paap (benjaminpaap) - Claus Due (namelesscoder) - Christian @@ -1449,6 +1471,7 @@ Symfony is the result of the work of many people who made the code better - Makdessi Alex - James Gilliland - fduch (fduch) + - Juan Miguel Besada Vidal (soutlink) - Stuart Fyfe - David de Boer (ddeboer) - Eno Mullaraj (emullaraj) @@ -1677,7 +1700,6 @@ Symfony is the result of the work of many people who made the code better - WedgeSama - Hugo Sales - Felds Liscia - - Randy Geraads - Chihiro Adachi (chihiro-adachi) - Raphaëll Roussel - Tadcka @@ -1693,7 +1715,6 @@ Symfony is the result of the work of many people who made the code better - Emmanuel Vella (emmanuel.vella) - Guillaume BRETOU (guiguiboy) - Carsten Nielsen (phreaknerd) - - Roger Guasch (rogerguasch) - Jay Severson - Benny Born - Emirald Mateli @@ -1727,6 +1748,7 @@ Symfony is the result of the work of many people who made the code better - Michael Dowling (mtdowling) - Karlos Presumido (oneko) - Tony Vermeiren (tony) + - Bart Wach - Jos Elstgeest - Thomas Counsell - BilgeXA @@ -1772,7 +1794,6 @@ Symfony is the result of the work of many people who made the code better - Pablo Ogando Ferreira - Thomas Ploch - Simon Neidhold - - Ben Hakim - Valentin VALCIU - Jeremiah VALERIE - Julien Menth @@ -1826,8 +1847,8 @@ Symfony is the result of the work of many people who made the code better - Antonio Peric-Mazar (antonioperic) - César Suárez (csuarez) - Bjorn Twachtmann (dotbjorn) + - Marek Víger (freezy) - Tobias Genberg (lorceroth) - - Luis Tacón (lutacon) - Nicolas Badey (nico-b) - Shane Preece (shane) - Johannes Goslar @@ -1996,6 +2017,7 @@ Symfony is the result of the work of many people who made the code better - Felix Marezki - Normunds - Luiz “Felds” Liscia + - Johan - Thomas Rothe - Adrien Wilmet - Martin @@ -2095,6 +2117,8 @@ Symfony is the result of the work of many people who made the code better - Ali Tavafi - Trevor Suarez - gedrox + - hugovms + - Viet Pham - Alan Bondarchuk - Pchol - dropfen @@ -2200,7 +2224,6 @@ Symfony is the result of the work of many people who made the code better - Marin Nicolae - Alessandro Loffredo - Ian Phillips - - Marco Lipparini - Haritz - Matthieu Prat - Grummfy @@ -2246,7 +2269,6 @@ Symfony is the result of the work of many people who made the code better - Gyula Szucs - Tomas Liubinas - Alex - - Thomas P - Jan Hort - Klaas Naaijkens - Daniel González Cerviño @@ -2410,8 +2432,10 @@ Symfony is the result of the work of many people who made the code better - Daniel Bannert - Karim Miladi - Michael Genereux + - Wojciech Kania - patrick-mcdougle - Dariusz Czech + - Bruno Baguette - Jack Wright - MrNicodemuz - Anonymous User @@ -2430,7 +2454,6 @@ Symfony is the result of the work of many people who made the code better - n-aleha - Talha Zekeriya Durmuş - Anatol Belski - - Anderson Müller - Şəhriyar İmanov - Alexis BOYER - Kaipi Yann @@ -2485,6 +2508,7 @@ Symfony is the result of the work of many people who made the code better - Alex Nostadt - Michael Squires - Egor Gorbachev + - Fabien Villepinte - Derek Stephen McLean - Norman Soetbeer - zorn From 67f1f1e159e7f83f6b3497847462aae263c6b100 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 27 Nov 2020 09:42:42 +0100 Subject: [PATCH 125/136] Update VERSION for 3.4.47 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 815359e13201b..280401e919033 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -67,12 +67,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private $requestStackSize = 0; private $resetServices = false; - const VERSION = '3.4.47-DEV'; + const VERSION = '3.4.47'; const VERSION_ID = 30447; const MAJOR_VERSION = 3; const MINOR_VERSION = 4; const RELEASE_VERSION = 47; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2020'; const END_OF_LIFE = '11/2021'; From 4857be89d37ef628ce8b7e8b7e42a7fa1cd64aed Mon Sep 17 00:00:00 2001 From: Guilherme Augusto Henschel Date: Fri, 27 Nov 2020 09:41:21 -0300 Subject: [PATCH 126/136] fix: resolving pt translation issues --- .../Resources/translations/validators.pt.xlf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.pt.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.pt.xlf index f140e1a45c00e..0244ee4f398ba 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.pt.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.pt.xlf @@ -128,7 +128,7 @@ This value should be a valid number. - Este valor deveria de ser um número válido. + Este valor deveria ser um número válido. This file is not a valid image. @@ -176,15 +176,15 @@ This value should be the user's current password. - Este valor deveria de ser a senha atual do usuário. + Este valor deveria ser a senha atual do usuário. This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. - Este valor deve possuir exatamente {{ limit }} carateres. + Este valor deve possuir exatamente {{ limit }} caracteres. The file was only partially uploaded. - Só foi enviado uma parte do arquivo. + Só foi enviada uma parte do arquivo. No file was uploaded. @@ -192,7 +192,7 @@ No temporary folder was configured in php.ini. - Não existe nenhuma pasta temporária configurada no arquivo do php.ini. + Não existe uma pasta temporária configurada no arquivo php.ini. Cannot write temporary file to disk. @@ -292,11 +292,11 @@ The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. - A imagem está em orientação de paisagem com ({{ width }}x{{ height }}px). Imagens orientadas em paisagem não são permitidas. + A imagem está em orientação de paisagem ({{ width }}x{{ height }}px). Imagens orientadas em paisagem não são permitidas. The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. - A imagem está em orientação de retrato com ({{ width }}x{{ height }}px). Imagens orientadas em retrato não são permitidas. + A imagem está em orientação de retrato ({{ width }}x{{ height }}px). Imagens orientadas em retrato não são permitidas. An empty file is not allowed. From ce046fd120dc40efacfad5845b7f9c769667c0a8 Mon Sep 17 00:00:00 2001 From: Kevin Bond Date: Fri, 27 Nov 2020 08:48:41 -0500 Subject: [PATCH 127/136] adjust KernelBrowser::getProfile() typehint --- src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php index 6e44657cf8181..40381e34aa310 100644 --- a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php +++ b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php @@ -65,7 +65,7 @@ public function getKernel() /** * Gets the profile associated with the current Response. * - * @return HttpProfile|false A Profile instance + * @return HttpProfile|false|null A Profile instance */ public function getProfile() { From 5f2bb905e7730cc3bc765a7cd3254e943294f25d Mon Sep 17 00:00:00 2001 From: Kevin Bond Date: Fri, 27 Nov 2020 09:11:20 -0500 Subject: [PATCH 128/136] adjust Client::getProfile() typehint --- src/Symfony/Bundle/FrameworkBundle/Client.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Client.php b/src/Symfony/Bundle/FrameworkBundle/Client.php index 6450a4ec0022a..ee95a9ae7b793 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Client.php +++ b/src/Symfony/Bundle/FrameworkBundle/Client.php @@ -62,7 +62,7 @@ public function getKernel() /** * Gets the profile associated with the current Response. * - * @return HttpProfile|false A Profile instance + * @return HttpProfile|false|null A Profile instance */ public function getProfile() { From 54af139a4ea2eb5ac0792fc0a355e5ecc9047642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Fri, 20 Nov 2020 19:00:05 +0100 Subject: [PATCH 129/136] [DependencyInjection] Fix circular in DI with lazy + byContruct loop --- .../Compiler/AnalyzeServiceReferencesPass.php | 9 +- .../DependencyInjection/Dumper/PhpDumper.php | 2 +- .../Tests/ContainerBuilderTest.php | 6 + .../Tests/Dumper/PhpDumperTest.php | 6 + .../containers/container_almost_circular.php | 36 ++++++ .../Tests/Fixtures/includes/classes.php | 12 ++ .../php/services_almost_circular_private.php | 77 ++++++++++- .../php/services_almost_circular_public.php | 120 ++++++++++++++++-- 8 files changed, 252 insertions(+), 16 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php index 1cd5ab93eebd2..92e4acacfba2f 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php @@ -12,6 +12,7 @@ namespace Symfony\Component\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Definition; @@ -35,6 +36,7 @@ class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements Repe private $hasProxyDumper; private $lazy; private $byConstructor; + private $byFactory; private $definitions; private $aliases; @@ -66,6 +68,7 @@ public function process(ContainerBuilder $container) $this->graph->clear(); $this->lazy = false; $this->byConstructor = false; + $this->byFactory = false; $this->definitions = $container->getDefinitions(); $this->aliases = $container->getAliases(); @@ -87,7 +90,7 @@ protected function processValue($value, $isRoot = false) $inExpression = $this->inExpression(); if ($value instanceof ArgumentInterface) { - $this->lazy = true; + $this->lazy = !$this->byFactory || !$value instanceof IteratorArgument; parent::processValue($value->getValues()); $this->lazy = $lazy; @@ -137,7 +140,11 @@ protected function processValue($value, $isRoot = false) $byConstructor = $this->byConstructor; $this->byConstructor = $isRoot || $byConstructor; + + $byFactory = $this->byFactory; + $this->byFactory = true; $this->processValue($value->getFactory()); + $this->byFactory = $byFactory; $this->processValue($value->getArguments()); $properties = $value->getProperties(); diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index a9c46edd66efe..a57ce41c59744 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -420,7 +420,7 @@ private function collectCircularReferences(string $sourceId, array $edges, array foreach ($edges as $edge) { $node = $edge->getDestNode(); $id = $node->getId(); - if (!($definition = $node->getValue()) instanceof Definition || $sourceId === $id || ($edge->isLazy() && ($this->proxyDumper ?? $this->getProxyDumper())->isProxyCandidate($definition)) || $edge->isWeak()) { + if ($sourceId === $id || !$node->getValue() instanceof Definition || $edge->isLazy() || $edge->isWeak()) { continue; } diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index dc462a0ee5853..b69e875a7e452 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -1374,12 +1374,18 @@ public function testAlmostCircular($visibility) $container = include __DIR__.'/Fixtures/containers/container_almost_circular.php'; $container->compile(); + $entityManager = $container->get('doctrine.entity_manager'); + $this->assertEquals(new \stdClass(), $entityManager); + $pA = $container->get('pA'); $this->assertEquals(new \stdClass(), $pA); $logger = $container->get('monolog.logger'); $this->assertEquals(new \stdClass(), $logger->handler); + $logger_inline = $container->get('monolog_inline.logger'); + $this->assertEquals(new \stdClass(), $logger_inline->handler); + $foo = $container->get('foo'); $this->assertSame($foo, $foo->bar->foobar->foo); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 0e5e0f5a716b8..9f17269846cf8 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -1054,12 +1054,18 @@ public function testAlmostCircular($visibility) $container = new $container(); + $entityManager = $container->get('doctrine.entity_manager'); + $this->assertEquals(new \stdClass(), $entityManager); + $pA = $container->get('pA'); $this->assertEquals(new \stdClass(), $pA); $logger = $container->get('monolog.logger'); $this->assertEquals(new \stdClass(), $logger->handler); + $logger_inline = $container->get('monolog_inline.logger'); + $this->assertEquals(new \stdClass(), $logger_inline->handler); + $foo = $container->get('foo'); $this->assertSame($foo, $foo->bar->foobar->foo); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php index 6a0b2da766cdd..8dd05316969f2 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php @@ -1,5 +1,6 @@ register('doctrine.config', 'stdClass')->setPublic(false) + ->setProperty('resolver', new Reference('doctrine.entity_listener_resolver')) + ->setProperty('flag', 'ok'); + +$container->register('doctrine.entity_manager', 'stdClass')->setPublic(true) + ->setFactory([FactoryChecker::class, 'create']) + ->addArgument(new Reference('doctrine.config')); +$container->register('doctrine.entity_listener_resolver', 'stdClass')->setPublic($public) + ->addArgument(new IteratorArgument([new Reference('doctrine.listener')])); +$container->register('doctrine.listener', 'stdClass')->setPublic($public) + ->addArgument(new Reference('doctrine.entity_manager')); + // multiple path detection $container->register('pA', 'stdClass')->setPublic(true) @@ -42,6 +57,27 @@ $container->register('monolog.logger_2', 'stdClass')->setPublic($public) ->setProperty('handler', new Reference('mailer.transport')); +// monolog-like + handler that require monolog with inlined factory + +$container->register('monolog_inline.logger', 'stdClass')->setPublic(true) + ->setProperty('handler', new Reference('mailer_inline.mailer')); + +$container->register('mailer_inline.mailer', 'stdClass')->setPublic(false) + ->addArgument( + (new Definition('stdClass')) + ->setFactory([new Reference('mailer_inline.transport_factory'), 'create']) + ); + +$container->register('mailer_inline.transport_factory', FactoryCircular::class)->setPublic($public) + ->addArgument(new TaggedIteratorArgument('mailer_inline.transport')); + +$container->register('mailer_inline.transport_factory.amazon', 'stdClass')->setPublic($public) + ->addArgument(new Reference('monolog_inline.logger_2')) + ->addTag('mailer.transport'); + +$container->register('monolog_inline.logger_2', 'stdClass')->setPublic($public) + ->setProperty('handler', new Reference('mailer_inline.mailer')); + // same visibility for deps $container->register('foo', FooCircular::class)->setPublic(true) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php index 46efa450acfff..dcac28effc4ee 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php @@ -128,6 +128,18 @@ public function create() } } +class FactoryChecker +{ + public static function create($config) + { + if (!isset($config->flag)) { + throw new \LogicException('The injected config must contain a "flag" property.'); + } + + return new stdClass(); + } +} + class FoobarCircular { public function __construct(FooCircular $foo) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php index 0ef3627e69eaf..40c86fb88fb6a 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php @@ -28,6 +28,7 @@ public function __construct() 'baz6' => 'getBaz6Service', 'connection' => 'getConnectionService', 'connection2' => 'getConnection2Service', + 'doctrine.entity_manager' => 'getDoctrine_EntityManagerService', 'foo' => 'getFooService', 'foo2' => 'getFoo2Service', 'foo5' => 'getFoo5Service', @@ -40,6 +41,7 @@ public function __construct() 'manager2' => 'getManager2Service', 'manager3' => 'getManager3Service', 'monolog.logger' => 'getMonolog_LoggerService', + 'monolog_inline.logger' => 'getMonologInline_LoggerService', 'pA' => 'getPAService', 'root' => 'getRootService', 'subscriber' => 'getSubscriberService', @@ -72,6 +74,9 @@ public function getRemovedIds(): array 'connection4' => true, 'dispatcher' => true, 'dispatcher2' => true, + 'doctrine.config' => true, + 'doctrine.entity_listener_resolver' => true, + 'doctrine.listener' => true, 'foo4' => true, 'foobar' => true, 'foobar2' => true, @@ -85,8 +90,12 @@ public function getRemovedIds(): array 'mailer.transport' => true, 'mailer.transport_factory' => true, 'mailer.transport_factory.amazon' => true, + 'mailer_inline.mailer' => true, + 'mailer_inline.transport_factory' => true, + 'mailer_inline.transport_factory.amazon' => true, 'manager4' => true, 'monolog.logger_2' => true, + 'monolog_inline.logger_2' => true, 'multiuse1' => true, 'pB' => true, 'pC' => true, @@ -185,6 +194,22 @@ protected function getConnection2Service() return $instance; } + /** + * Gets the public 'doctrine.entity_manager' shared service. + * + * @return \stdClass + */ + protected function getDoctrine_EntityManagerService() + { + $a = new \stdClass(); + $a->resolver = new \stdClass(new RewindableGenerator(function () { + yield 0 => ($this->privates['doctrine.listener'] ?? $this->getDoctrine_ListenerService()); + }, 1)); + $a->flag = 'ok'; + + return $this->services['doctrine.entity_manager'] = \FactoryChecker::create($a); + } + /** * Gets the public 'foo' shared service. * @@ -378,6 +403,20 @@ protected function getMonolog_LoggerService() return $instance; } + /** + * Gets the public 'monolog_inline.logger' shared service. + * + * @return \stdClass + */ + protected function getMonologInline_LoggerService() + { + $this->services['monolog_inline.logger'] = $instance = new \stdClass(); + + $instance->handler = ($this->privates['mailer_inline.mailer'] ?? $this->getMailerInline_MailerService()); + + return $instance; + } + /** * Gets the public 'pA' shared service. * @@ -448,6 +487,16 @@ protected function getBar6Service() return $this->privates['bar6'] = new \stdClass($a); } + /** + * Gets the private 'doctrine.listener' shared service. + * + * @return \stdClass + */ + protected function getDoctrine_ListenerService() + { + return $this->privates['doctrine.listener'] = new \stdClass(($this->services['doctrine.entity_manager'] ?? $this->getDoctrine_EntityManagerService())); + } + /** * Gets the private 'level5' shared service. * @@ -473,7 +522,8 @@ protected function getMailer_TransportService() { return $this->privates['mailer.transport'] = (new \FactoryCircular(new RewindableGenerator(function () { yield 0 => ($this->privates['mailer.transport_factory.amazon'] ?? $this->getMailer_TransportFactory_AmazonService()); - }, 1)))->create(); + yield 1 => $this->getMailerInline_TransportFactory_AmazonService(); + }, 2)))->create(); } /** @@ -492,6 +542,31 @@ protected function getMailer_TransportFactory_AmazonService() return $instance; } + /** + * Gets the private 'mailer_inline.mailer' shared service. + * + * @return \stdClass + */ + protected function getMailerInline_MailerService() + { + return $this->privates['mailer_inline.mailer'] = new \stdClass((new \FactoryCircular(new RewindableGenerator(function () { + return new \EmptyIterator(); + }, 0)))->create()); + } + + /** + * Gets the private 'mailer_inline.transport_factory.amazon' shared service. + * + * @return \stdClass + */ + protected function getMailerInline_TransportFactory_AmazonService() + { + $a = new \stdClass(); + $a->handler = ($this->privates['mailer_inline.mailer'] ?? $this->getMailerInline_MailerService()); + + return new \stdClass($a); + } + /** * Gets the private 'manager4' shared service. * diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php index ddc1f59a269b9..86efcab216516 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php @@ -33,6 +33,9 @@ public function __construct() 'connection4' => 'getConnection4Service', 'dispatcher' => 'getDispatcherService', 'dispatcher2' => 'getDispatcher2Service', + 'doctrine.entity_listener_resolver' => 'getDoctrine_EntityListenerResolverService', + 'doctrine.entity_manager' => 'getDoctrine_EntityManagerService', + 'doctrine.listener' => 'getDoctrine_ListenerService', 'foo' => 'getFooService', 'foo2' => 'getFoo2Service', 'foo4' => 'getFoo4Service', @@ -48,11 +51,15 @@ public function __construct() 'mailer.transport' => 'getMailer_TransportService', 'mailer.transport_factory' => 'getMailer_TransportFactoryService', 'mailer.transport_factory.amazon' => 'getMailer_TransportFactory_AmazonService', + 'mailer_inline.transport_factory' => 'getMailerInline_TransportFactoryService', + 'mailer_inline.transport_factory.amazon' => 'getMailerInline_TransportFactory_AmazonService', 'manager' => 'getManagerService', 'manager2' => 'getManager2Service', 'manager3' => 'getManager3Service', 'monolog.logger' => 'getMonolog_LoggerService', 'monolog.logger_2' => 'getMonolog_Logger2Service', + 'monolog_inline.logger' => 'getMonologInline_LoggerService', + 'monolog_inline.logger_2' => 'getMonologInline_Logger2Service', 'pA' => 'getPAService', 'pB' => 'getPBService', 'pC' => 'getPCService', @@ -83,12 +90,14 @@ public function getRemovedIds(): array 'bar6' => true, 'config' => true, 'config2' => true, + 'doctrine.config' => true, 'level2' => true, 'level3' => true, 'level4' => true, 'level5' => true, 'level6' => true, 'logger2' => true, + 'mailer_inline.mailer' => true, 'manager4' => true, 'multiuse1' => true, 'subscriber2' => true, @@ -260,6 +269,42 @@ protected function getDispatcher2Service($lazyLoad = true) return $instance; } + /** + * Gets the public 'doctrine.entity_listener_resolver' shared service. + * + * @return \stdClass + */ + protected function getDoctrine_EntityListenerResolverService() + { + return $this->services['doctrine.entity_listener_resolver'] = new \stdClass(new RewindableGenerator(function () { + yield 0 => ($this->services['doctrine.listener'] ?? $this->getDoctrine_ListenerService()); + }, 1)); + } + + /** + * Gets the public 'doctrine.entity_manager' shared service. + * + * @return \stdClass + */ + protected function getDoctrine_EntityManagerService() + { + $a = new \stdClass(); + $a->resolver = ($this->services['doctrine.entity_listener_resolver'] ?? $this->getDoctrine_EntityListenerResolverService()); + $a->flag = 'ok'; + + return $this->services['doctrine.entity_manager'] = \FactoryChecker::create($a); + } + + /** + * Gets the public 'doctrine.listener' shared service. + * + * @return \stdClass + */ + protected function getDoctrine_ListenerService() + { + return $this->services['doctrine.listener'] = new \stdClass(($this->services['doctrine.entity_manager'] ?? $this->getDoctrine_EntityManagerService())); + } + /** * Gets the public 'foo' shared service. * @@ -449,13 +494,7 @@ protected function getLoggerService() */ protected function getMailer_TransportService() { - $a = ($this->services['mailer.transport_factory'] ?? $this->getMailer_TransportFactoryService()); - - if (isset($this->services['mailer.transport'])) { - return $this->services['mailer.transport']; - } - - return $this->services['mailer.transport'] = $a->create(); + return $this->services['mailer.transport'] = ($this->services['mailer.transport_factory'] ?? $this->getMailer_TransportFactoryService())->create(); } /** @@ -467,7 +506,8 @@ protected function getMailer_TransportFactoryService() { return $this->services['mailer.transport_factory'] = new \FactoryCircular(new RewindableGenerator(function () { yield 0 => ($this->services['mailer.transport_factory.amazon'] ?? $this->getMailer_TransportFactory_AmazonService()); - }, 1)); + yield 1 => ($this->services['mailer_inline.transport_factory.amazon'] ?? $this->getMailerInline_TransportFactory_AmazonService()); + }, 2)); } /** @@ -477,13 +517,29 @@ protected function getMailer_TransportFactoryService() */ protected function getMailer_TransportFactory_AmazonService() { - $a = ($this->services['monolog.logger_2'] ?? $this->getMonolog_Logger2Service()); + return $this->services['mailer.transport_factory.amazon'] = new \stdClass(($this->services['monolog.logger_2'] ?? $this->getMonolog_Logger2Service())); + } - if (isset($this->services['mailer.transport_factory.amazon'])) { - return $this->services['mailer.transport_factory.amazon']; - } + /** + * Gets the public 'mailer_inline.transport_factory' shared service. + * + * @return \FactoryCircular + */ + protected function getMailerInline_TransportFactoryService() + { + return $this->services['mailer_inline.transport_factory'] = new \FactoryCircular(new RewindableGenerator(function () { + return new \EmptyIterator(); + }, 0)); + } - return $this->services['mailer.transport_factory.amazon'] = new \stdClass($a); + /** + * Gets the public 'mailer_inline.transport_factory.amazon' shared service. + * + * @return \stdClass + */ + protected function getMailerInline_TransportFactory_AmazonService() + { + return $this->services['mailer_inline.transport_factory.amazon'] = new \stdClass(($this->services['monolog_inline.logger_2'] ?? $this->getMonologInline_Logger2Service())); } /** @@ -562,6 +618,34 @@ protected function getMonolog_Logger2Service() return $instance; } + /** + * Gets the public 'monolog_inline.logger' shared service. + * + * @return \stdClass + */ + protected function getMonologInline_LoggerService() + { + $this->services['monolog_inline.logger'] = $instance = new \stdClass(); + + $instance->handler = ($this->privates['mailer_inline.mailer'] ?? $this->getMailerInline_MailerService()); + + return $instance; + } + + /** + * Gets the public 'monolog_inline.logger_2' shared service. + * + * @return \stdClass + */ + protected function getMonologInline_Logger2Service() + { + $this->services['monolog_inline.logger_2'] = $instance = new \stdClass(); + + $instance->handler = ($this->privates['mailer_inline.mailer'] ?? $this->getMailerInline_MailerService()); + + return $instance; + } + /** * Gets the public 'pA' shared service. * @@ -691,6 +775,16 @@ protected function getLevel5Service() return $instance; } + /** + * Gets the private 'mailer_inline.mailer' shared service. + * + * @return \stdClass + */ + protected function getMailerInline_MailerService() + { + return $this->privates['mailer_inline.mailer'] = new \stdClass(($this->services['mailer_inline.transport_factory'] ?? $this->getMailerInline_TransportFactoryService())->create()); + } + /** * Gets the private 'manager4' shared service. * From 726f3616a816e0b36cb96cdd8045cbe6b08314c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Sat, 28 Nov 2020 11:15:42 +0100 Subject: [PATCH 130/136] Fix parameter order --- src/Symfony/Component/Console/Output/TrimmedBufferOutput.php | 4 ++-- src/Symfony/Component/Console/Style/SymfonyStyle.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Console/Output/TrimmedBufferOutput.php b/src/Symfony/Component/Console/Output/TrimmedBufferOutput.php index c014d43633cf8..a03aa835f0086 100644 --- a/src/Symfony/Component/Console/Output/TrimmedBufferOutput.php +++ b/src/Symfony/Component/Console/Output/TrimmedBufferOutput.php @@ -25,10 +25,10 @@ class TrimmedBufferOutput extends Output private $buffer = ''; public function __construct( + int $maxLength, ?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = false, - OutputFormatterInterface $formatter = null, - int $maxLength + OutputFormatterInterface $formatter = null ) { if ($maxLength <= 0) { throw new InvalidArgumentException(sprintf('"%s()" expects a strictly positive maxLength. Got %d.', __METHOD__, $maxLength)); diff --git a/src/Symfony/Component/Console/Style/SymfonyStyle.php b/src/Symfony/Component/Console/Style/SymfonyStyle.php index a5edac3c4a1f1..0400a26cf2f0d 100644 --- a/src/Symfony/Component/Console/Style/SymfonyStyle.php +++ b/src/Symfony/Component/Console/Style/SymfonyStyle.php @@ -46,7 +46,7 @@ class SymfonyStyle extends OutputStyle public function __construct(InputInterface $input, OutputInterface $output) { $this->input = $input; - $this->bufferedOutput = new TrimmedBufferOutput($output->getVerbosity(), false, clone $output->getFormatter(), \DIRECTORY_SEPARATOR === '\\' ? 4 : 2); + $this->bufferedOutput = new TrimmedBufferOutput(\DIRECTORY_SEPARATOR === '\\' ? 4 : 2, $output->getVerbosity(), false, clone $output->getFormatter()); // Windows cmd wraps lines as soon as the terminal width is reached, whether there are following chars or not. $width = (new Terminal())->getWidth() ?: self::MAX_LINE_LENGTH; $this->lineLength = min($width - (int) (\DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH); From faa1fd32f9bb1bdd64e2e7172f28477c8d617654 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 28 Nov 2020 14:14:15 +0100 Subject: [PATCH 131/136] [HttpClient] fix binding to network interfaces --- src/Symfony/Component/HttpClient/CurlHttpClient.php | 2 +- .../Component/HttpClient/NativeHttpClient.php | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/HttpClient/CurlHttpClient.php b/src/Symfony/Component/HttpClient/CurlHttpClient.php index bbcaf69e3bda1..e69761b392ffa 100644 --- a/src/Symfony/Component/HttpClient/CurlHttpClient.php +++ b/src/Symfony/Component/HttpClient/CurlHttpClient.php @@ -269,7 +269,7 @@ public function request(string $method, string $url, array $options = []): Respo if ($options['bindto']) { if (file_exists($options['bindto'])) { $curlopts[\CURLOPT_UNIX_SOCKET_PATH] = $options['bindto']; - } elseif (preg_match('/^(.*):(\d+)$/', $options['bindto'], $matches)) { + } elseif (0 !== strpos($options['bindto'], 'if!') && preg_match('/^(.*):(\d+)$/', $options['bindto'], $matches)) { $curlopts[\CURLOPT_INTERFACE] = $matches[1]; $curlopts[\CURLOPT_LOCALPORT] = $matches[2]; } else { diff --git a/src/Symfony/Component/HttpClient/NativeHttpClient.php b/src/Symfony/Component/HttpClient/NativeHttpClient.php index 0710b7a72bba2..18bf8f569bbbf 100644 --- a/src/Symfony/Component/HttpClient/NativeHttpClient.php +++ b/src/Symfony/Component/HttpClient/NativeHttpClient.php @@ -67,8 +67,16 @@ public function request(string $method, string $url, array $options = []): Respo { [$url, $options] = self::prepareRequest($method, $url, $options, $this->defaultOptions); - if ($options['bindto'] && file_exists($options['bindto'])) { - throw new TransportException(__CLASS__.' cannot bind to local Unix sockets, use e.g. CurlHttpClient instead.'); + if ($options['bindto']) { + if (file_exists($options['bindto'])) { + throw new TransportException(__CLASS__.' cannot bind to local Unix sockets, use e.g. CurlHttpClient instead.'); + } + if (0 === strpos($options['bindto'], 'if!')) { + throw new TransportException(__CLASS__.' cannot bind to network interfaces, use e.g. CurlHttpClient instead.'); + } + if (0 === strpos($options['bindto'], 'host!')) { + $options['bindto'] = substr($options['bindto'], 5); + } } $options['body'] = self::getBodyAsString($options['body']); From 02d16324a5df65aa4c045815ebf1cb3c1bf58851 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 28 Nov 2020 14:29:03 +0100 Subject: [PATCH 132/136] [HttpClient] fix binding to network interfaces --- src/Symfony/Component/HttpClient/AmpHttpClient.php | 11 ++++++++++- .../Component/HttpClient/Internal/AmpClientState.php | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpClient/AmpHttpClient.php b/src/Symfony/Component/HttpClient/AmpHttpClient.php index 0877b8883bef7..b53d636b9cf2f 100644 --- a/src/Symfony/Component/HttpClient/AmpHttpClient.php +++ b/src/Symfony/Component/HttpClient/AmpHttpClient.php @@ -82,6 +82,15 @@ public function request(string $method, string $url, array $options = []): Respo throw new \LogicException('You cannot use the "proxy" option as the "amphp/http-tunnel" package is not installed. Try running "composer require amphp/http-tunnel".'); } + if ($options['bindto']) { + if (0 === strpos($options['bindto'], 'if!')) { + throw new TransportException(__CLASS__.' cannot bind to network interfaces, use e.g. CurlHttpClient instead.'); + } + if (0 === strpos($options['bindto'], 'host!')) { + $options['bindto'] = substr($options['bindto'], 5); + } + } + if ('' !== $options['body'] && 'POST' === $method && !isset($options['normalized_headers']['content-type'])) { $options['headers'][] = 'Content-Type: application/x-www-form-urlencoded'; } @@ -141,7 +150,7 @@ public function stream($responses, float $timeout = null): ResponseStreamInterfa if ($responses instanceof AmpResponse) { $responses = [$responses]; } elseif (!is_iterable($responses)) { - throw new \TypeError(sprintf('%s() expects parameter 1 to be an iterable of AmpResponse objects, %s given.', __METHOD__, get_debug_type($responses))); + throw new \TypeError(sprintf('"%s()" expects parameter 1 to be an iterable of AmpResponse objects, "%s" given.', __METHOD__, get_debug_type($responses))); } return new ResponseStream(AmpResponse::stream($responses, $timeout)); diff --git a/src/Symfony/Component/HttpClient/Internal/AmpClientState.php b/src/Symfony/Component/HttpClient/Internal/AmpClientState.php index 61a0c004acfb9..71cb6e9cc3393 100644 --- a/src/Symfony/Component/HttpClient/Internal/AmpClientState.php +++ b/src/Symfony/Component/HttpClient/Internal/AmpClientState.php @@ -119,7 +119,7 @@ public function request(array $options, Request $request, CancellationToken $can private function getClient(array $options): array { $options = [ - 'bindto' => $options['bindto'] ?: '0', + 'bindto' => $options['bindto'] ?: '0:0', 'verify_peer' => $options['verify_peer'], 'capath' => $options['capath'], 'cafile' => $options['cafile'], From 8d512d98196d3cba001313b3dff7746e02c5dcc9 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 28 Nov 2020 14:45:11 +0100 Subject: [PATCH 133/136] [HttpClient] partial revert of previous commit --- src/Symfony/Component/HttpClient/Internal/AmpClientState.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpClient/Internal/AmpClientState.php b/src/Symfony/Component/HttpClient/Internal/AmpClientState.php index 71cb6e9cc3393..61a0c004acfb9 100644 --- a/src/Symfony/Component/HttpClient/Internal/AmpClientState.php +++ b/src/Symfony/Component/HttpClient/Internal/AmpClientState.php @@ -119,7 +119,7 @@ public function request(array $options, Request $request, CancellationToken $can private function getClient(array $options): array { $options = [ - 'bindto' => $options['bindto'] ?: '0:0', + 'bindto' => $options['bindto'] ?: '0', 'verify_peer' => $options['verify_peer'], 'capath' => $options['capath'], 'cafile' => $options['cafile'], From 37be09499201804c28a799ad2206b913f857559a Mon Sep 17 00:00:00 2001 From: bill moll Date: Tue, 24 Nov 2020 14:13:56 -0600 Subject: [PATCH 134/136] [Messenger] Fix mssql compatibility for doctrine transport. Add logic for locking row for update when the doctrine dbal connection is sqlsrv. This is a quick and dirty solution, but it prevents the need to rewrite the logic due to doctrine dbal limitations. See issue https://github.com/symfony/symfony/issues/39117 --- .../Messenger/Transport/Doctrine/Connection.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php b/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php index 637c7a57ac194..ef41dc5f02fe5 100644 --- a/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php +++ b/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php @@ -16,6 +16,7 @@ use Doctrine\DBAL\Driver\Result as DriverResult; use Doctrine\DBAL\Exception; use Doctrine\DBAL\Exception\TableNotFoundException; +use Doctrine\DBAL\LockMode; use Doctrine\DBAL\Query\QueryBuilder; use Doctrine\DBAL\Result; use Doctrine\DBAL\Schema\Comparator; @@ -161,9 +162,23 @@ public function get(): ?array ->orderBy('available_at', 'ASC') ->setMaxResults(1); + // Append pessimistic write lock to FROM clause if db platform supports it + $sql = $query->getSQL(); + if (($fromPart = $query->getQueryPart('from')) && + ($table = $fromPart[0]['table'] ?? null) && + ($alias = $fromPart[0]['alias'] ?? null) + ) { + $fromClause = sprintf('%s %s', $table, $alias); + $sql = str_replace( + sprintf('FROM %s WHERE', $fromClause), + sprintf('FROM %s WHERE', $this->driverConnection->getDatabasePlatform()->appendLockHint($fromClause, LockMode::PESSIMISTIC_WRITE)), + $sql + ); + } + // use SELECT ... FOR UPDATE to lock table $stmt = $this->executeQuery( - $query->getSQL().' '.$this->driverConnection->getDatabasePlatform()->getWriteLockSQL(), + $sql.' '.$this->driverConnection->getDatabasePlatform()->getWriteLockSQL(), $query->getParameters(), $query->getParameterTypes() ); From 915e787d0f1c02a2cfd57358b1f1987e8c718680 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 29 Nov 2020 10:27:43 +0100 Subject: [PATCH 135/136] Update CHANGELOG for 5.1.9 --- CHANGELOG-5.1.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/CHANGELOG-5.1.md b/CHANGELOG-5.1.md index 0f8e3a5c324dd..3d530f59a41d1 100644 --- a/CHANGELOG-5.1.md +++ b/CHANGELOG-5.1.md @@ -7,6 +7,54 @@ in 5.1 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v5.1.0...v5.1.1 +* 5.1.9 (2020-11-29) + + * bug #39166 [Messenger] Fix mssql compatibility for doctrine transport. (bill moll) + * bug #39211 [HttpClient] fix binding to network interfaces (nicolas-grekas) + * bug #39129 [DependencyInjection] Fix circular in DI with lazy + byContruct loop (jderusse) + * bug #39068 [DependencyInjection][Translator] Silent deprecation triggered by libxml_disable_entity_loader (jderusse) + * bug #39119 [Form] prevent duplicated error message for file upload limits (xabbuh) + * bug #39099 [Form] ignore the pattern attribute for textareas (xabbuh) + * bug #39154 [Yaml] fix lexing strings containing escaped quotation characters (xabbuh) + * bug #39180 [Serializer] Fix denormalizing scalar with UnwrappingDenormalizer (camilledejoye) + * bug #38597 [PhpUnitBridge] Fix qualification of deprecations triggered by the debug class loader (fancyweb) + * bug #39160 [Console] Use a partial buffer in SymfonyStyle (jderusse) + * bug #39168 [Console] Fix console closing tag (jderusse) + * bug #39155 [VarDumper] fix casting resources turned into objects on PHP 8 (nicolas-grekas) + * bug #39131 [Cache] Fix CI because of Couchbase version (jderusse) + * bug #39115 [HttpClient] don't fallback to HTTP/1.1 when HTTP/2 streams break (nicolas-grekas) + * bug #33763 [Yaml] fix lexing nested sequences/mappings (xabbuh) + * bug #39083 [Dotenv] Check if method inheritEnvironmentVariables exists (Chi-teck) + * bug #39094 [Ldap] Fix undefined variable $con (derrabus) + * bug #39091 [Config] Recheck glob brace support after GlobResource was serialized (wouterj) + * bug #39092 Fix critical extension when reseting paged control (jderusse) + * bug #38614 [HttpFoundation] Fix for virtualhosts based on URL path (mvorisek) + * bug #39072 [FrameworkBundle] [Notifier] fix firebase transport factory DI tag type (xabbuh) + * bug #38387 [Validator] prevent hash collisions caused by reused object hashes (fancyweb, xabbuh) + * bug #38999 [DependencyInjection] autoconfigure behavior describing tags on decorators (xabbuh) + * bug #39058 [DependencyInjection] Fix circular detection with multiple paths (jderusse) + * bug #39059 [Filesystem] fix cleaning up tmp files when dumpFile() fails (nicolas-grekas) + * bug #38628 [DoctrineBridge] indexBy could reference to association columns (juanmiguelbesada) + * bug #39021 [DependencyInjection] Optimize circular collection by removing flattening (jderusse) + * bug #39031 [Ldap] Fix pagination (jderusse) + * bug #39038 [DoctrineBridge] also reset id readers (xabbuh) + * bug #39026 [Messenger] Fix DBAL deprecations in PostgreSqlConnection (chalasr) + * bug #39025 [DoctrineBridge] Fix DBAL deprecations in middlewares (derrabus) + * bug #38991 [Console] Fix ANSI when stdErr is not a tty (jderusse) + * bug #38980 [DependencyInjection] Fix circular reference with Factory + Lazy Iterrator (jderusse) + * bug #38977 [HttpClient] Check status code before decoding content in TraceableResponse (chalasr) + * bug #38971 [PhpUnitBridge] fix replaying skipped tests (nicolas-grekas) + * bug #38910 [HttpKernel] Fix session initialized several times (jderusse) + * bug #38882 [DependencyInjection] Improve performances in CircualReference detection (jderusse) + * bug #38950 [Process] Dont test TTY if there is no TTY support (Nyholm) + * bug #38921 [PHPUnitBridge] Fixed crash on Windows with PHP 8 (villfa) + * bug #38869 [SecurityBundle] inject only compatible token storage implementations for usage tracking (xabbuh) + * bug #38894 [HttpKernel] Remove Symfony 3 compatibility code (derrabus) + * bug #38895 [PhpUnitBridge] Fix wrong check for exporter in ConstraintTrait (alcaeus) + * bug #38879 [Cache] Fixed expiry could be int in ChainAdapter due to race conditions (phamviet) + * bug #38867 [FrameworkBundle] Fixing TranslationUpdateCommand failure when using "--no-backup" (liarco) + * bug #38856 [Cache] Add missing use statement (fabpot) + * 5.1.8 (2020-10-28) * bug #38713 [DI] Fix Preloader exception when preloading a class with an unknown parent/interface (rgeraads) From a2efa61d2db36c852ca259b285778388f08161eb Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 29 Nov 2020 10:27:52 +0100 Subject: [PATCH 136/136] Update VERSION for 5.1.9 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 55e50173badc2..4134ff870e331 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -73,12 +73,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private static $freshCache = []; - const VERSION = '5.1.9-DEV'; + const VERSION = '5.1.9'; const VERSION_ID = 50109; const MAJOR_VERSION = 5; const MINOR_VERSION = 1; const RELEASE_VERSION = 9; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '01/2021'; const END_OF_LIFE = '01/2021';