diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 415464c40b9a8..0bef18db33536 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -25,3 +25,5 @@ /src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ValidateWorkflowsPass.php @lyrixx /src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/WorkflowGuardListenerPass.php @lyrixx /src/Symfony/Component/Workflow/* @lyrixx +# Yaml +/src/Symfony/Component/Yaml/* @xabbuh diff --git a/.travis.yml b/.travis.yml index c9b85c3e6d194..f3f3660ef8dfe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -157,7 +157,7 @@ before_install: tfold ext.apcu tpecl apcu-5.1.6 apcu.so $INI tfold ext.libsodium tpecl libsodium sodium.so $INI - tfold ext.mongodb tpecl mongodb-1.4.0RC1 mongodb.so $INI + tfold ext.mongodb tpecl mongodb-1.5.0 mongodb.so $INI fi - | diff --git a/CHANGELOG-3.4.md b/CHANGELOG-3.4.md index 3c612a6ebd595..94bbcf155cd1a 100644 --- a/CHANGELOG-3.4.md +++ b/CHANGELOG-3.4.md @@ -7,6 +7,39 @@ 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.13 (2018-07-23) + + * bug #28005 [HttpKernel] Fixed templateExists on parse error of the template name (yceruto) + * bug #27997 Serbo-Croatian has Serbian plural rule (kylekatarnls) + * bug #26193 Fix false-positive deprecation notices for TranslationLoader and WriteCheckSessionHandler (iquito) + * bug #27941 [WebProfilerBundle] Fixed icon alignment issue using Bootstrap 4.1.2 (jmsche) + * bug #27937 [HttpFoundation] reset callback on StreamedResponse when setNotModified() is called (rubencm) + * bug #27927 [HttpFoundation] Suppress side effects in 'get' and 'has' methods of NamespacedAttributeBag (webnet-fr) + * bug #27923 [Form/Profiler] Massively reducing memory footprint of form profiling pages... (VincentChalnot) + * bug #27918 [Console] correctly return parameter's default value on "--" (seschwar) + * bug #27904 [Filesystem] fix lock file permissions (fritzmg) + * bug #27903 [Lock] fix lock file permissions (fritzmg) + * bug #27889 [Form] Replace .initialism with .text-uppercase. (vudaltsov) + * bug #27902 Fix the detection of the Process new argument (stof) + * bug #27885 [HttpFoundation] don't encode cookie name for BC (nicolas-grekas) + * bug #27782 [DI] Fix dumping ignore-on-uninitialized references to synthetic services (nicolas-grekas) + * bug #27435 [OptionResolver] resolve arrays (Doctrs) + * bug #27728 [TwigBridge] Fix missing path and separators in loader paths list on debug:twig output (yceruto) + * bug #27837 [PropertyInfo] Fix dock block lookup fallback loop (DerManoMann) + * bug #27758 [WebProfilerBundle] Prevent toolbar links color override by css (alcalyn) + * bug #27834 [DI] Don't show internal service id on binding errors (nicolas-grekas) + * bug #27831 Check for Hyper terminal on all operating systems. (azjezz) + * bug #27794 Add color support for Hyper terminal . (azjezz) + * bug #27809 [HttpFoundation] Fix tests: new message for status 425 (dunglas) + * bug #27618 [PropertyInfo] added handling of nullable types in PhpDoc (oxan) + * bug #27659 [HttpKernel] Make AbstractTestSessionListener compatible with CookieClearingLogoutHandler (thewilkybarkid) + * bug #27752 [Cache] provider does not respect option maxIdLength with versioning enabled (Constantine Shtompel) + * bug #27776 [ProxyManagerBridge] Fix support of private services (bis) (nicolas-grekas) + * bug #27714 [HttpFoundation] fix session tracking counter (nicolas-grekas, dmaicher) + * bug #27747 [HttpFoundation] fix registration of session proxies (nicolas-grekas) + * bug #27722 Redesign the Debug error page in prod (javiereguiluz) + * bug #27716 [DI] fix dumping deprecated service in yaml (nicolas-grekas) + * 3.4.12 (2018-06-25) * bug #27626 [TwigBundle][DX] Only add the Twig WebLinkExtension if the WebLink component is enabled (thewilkybarkid) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 672246e7f9da8..b6eef0b63198c 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -16,8 +16,8 @@ Symfony is the result of the work of many people who made the code better - Robin Chalas (chalas_r) - Johannes S (johannes) - Jakub Zalas (jakubzalas) - - Kris Wallsmith (kriswallsmith) - Maxime Steinhausser (ogizanagi) + - Kris Wallsmith (kriswallsmith) - Ryan Weaver (weaverryan) - Javier Eguiluz (javier.eguiluz) - Grégoire Pineau (lyrixx) @@ -25,8 +25,8 @@ Symfony is the result of the work of many people who made the code better - Abdellatif Ait boudad (aitboudad) - Romain Neutron (romain) - Pascal Borreli (pborreli) - - Wouter De Jong (wouterj) - Roland Franssen (ro0) + - Wouter De Jong (wouterj) - Joseph Bielawski (stloyd) - Karma Dordrak (drak) - Lukas Kahwe Smith (lsmith) @@ -39,8 +39,8 @@ Symfony is the result of the work of many people who made the code better - Jules Pietri (heah) - Eriksen Costa (eriksencosta) - Guilhem Niot (energetick) - - Sarah Khalil (saro0h) - Yonel Ceruto (yonelceruto) + - Sarah Khalil (saro0h) - Jonathan Wage (jwage) - Hamza Amrouche (simperfit) - Diego Saint Esteben (dosten) @@ -54,36 +54,37 @@ Symfony is the result of the work of many people who made the code better - Bulat Shakirzyanov (avalanche123) - Peter Rehm (rpet) - Matthias Pigulla (mpdude) + - Dany Maillard (maidmaid) - Saša Stamenković (umpirsky) + - Kevin Bond (kbond) + - Tobias Nyholm (tobias) - Pierre du Plessis (pierredup) - Henrik Bjørnskov (henrikbjorn) - - Dany Maillard (maidmaid) - Miha Vrhovnik - - Kevin Bond (kbond) - - Tobias Nyholm (tobias) - Diego Saint Esteben (dii3g0) - - Konstantin Kudryashov (everzet) - Alexander M. Turek (derrabus) + - Konstantin Kudryashov (everzet) - Bilal Amarni (bamarni) - Jérémy DERUSSÉ (jderusse) - Florin Patan (florinpatan) - Mathieu Piot (mpiot) - Gábor Egyed (1ed) - Michel Weimerskirch (mweimerskirch) + - Titouan Galopin (tgalopin) - Andrej Hudec (pulzarraider) - Eric Clemmons (ericclemmons) - Jáchym Toušek (enumag) - Charles Sarrazin (csarrazi) - - Titouan Galopin (tgalopin) - Konstantin Myakshin (koc) - Christian Raue + - David Maicher (dmaicher) - Arnout Boks (aboks) - Deni - Henrik Westphal (snc) - Dariusz Górecki (canni) - Issei Murasawa (issei_m) - Douglas Greenshields (shieldo) - - David Maicher (dmaicher) + - Vladimir Reznichenko (kalessil) - Lee McDermott - Brandon Turner - Luis Cordova (cordoval) @@ -96,7 +97,6 @@ Symfony is the result of the work of many people who made the code better - Jérôme Tamarelle (gromnan) - John Wards (johnwards) - Fran Moreno (franmomu) - - Vladimir Reznichenko (kalessil) - Antoine Hérault (herzult) - Paráda József (paradajozsef) - Arnaud Le Blanc (arnaud-lb) @@ -105,18 +105,20 @@ Symfony is the result of the work of many people who made the code better - Tim Nagel (merk) - Grégoire Paris (greg0ire) - Brice BERNARD (brikou) + - Valentin Udaltsov (vudaltsov) + - gadelat (gadelat) - Baptiste Clavié (talus) - marc.weistroff - lenar - Alexander Schwenn (xelaris) - Włodzimierz Gajda (gajdaw) + - Peter Kokot (maastermedia) - Jacob Dreesen (jdreesen) - Florian Voutzinos (florianv) - Colin Frei - Adrien Brault (adrienbrault) - Tomáš Votruba (tomas_votruba) - Joshua Thijssen - - Peter Kokot (maastermedia) - David Buchmann (dbu) - excelwebzone - Fabien Pennequin (fabienpennequin) @@ -131,6 +133,7 @@ Symfony is the result of the work of many people who made the code better - Florian Lonqueu-Brochard (florianlb) - Sebastiaan Stok (sstok) - Stefano Sala (stefano.sala) + - Jérôme Vasseur (jvasseur) - Evgeniy (ewgraf) - Alex Pott - Vincent AUBERT (vincent) @@ -139,9 +142,8 @@ Symfony is the result of the work of many people who made the code better - Sebastian Hörl (blogsh) - Daniel Gomes (danielcsgomes) - Hidenori Goto (hidenorigoto) - - Jérôme Vasseur (jvasseur) - - Valentin Udaltsov (vudaltsov) - - gadelat (gadelat) + - Chris Wilkinson (thewilkybarkid) + - Arnaud Kleinpeter (nanocom) - Guilherme Blanco (guilhermeblanco) - Pablo Godel (pgodel) - Jérémie Augustin (jaugustin) @@ -149,12 +151,10 @@ Symfony is the result of the work of many people who made the code better - Philipp Wahala (hifi) - Julien Falque (julienfalque) - Rafael Dohms (rdohms) - - Arnaud Kleinpeter (nanocom) - jwdeitch - Teoh Han Hui (teohhanhui) - Mikael Pajunen - Joel Wurtz (brouznouf) - - Chris Wilkinson (thewilkybarkid) - Oleg Voronkovich - Vyacheslav Pavlov - Richard van Laak (rvanlaak) @@ -170,6 +170,7 @@ Symfony is the result of the work of many people who made the code better - Amal Raghav (kertz) - Jonathan Ingram (jonathaningram) - Artur Kotyrba + - Jannik Zschiesche (apfelbox) - GDIBass - jeremyFreeAgent (Jérémy Romey) (jeremyfreeagent) - James Halsall (jaitsu) @@ -178,6 +179,7 @@ Symfony is the result of the work of many people who made the code better - Warnar Boekkooi (boekkooi) - Dmitrii Chekaliuk (lazyhammer) - Clément JOBEILI (dator) + - Niels Keurentjes (curry684) - Daniel Espendiller - Possum - Dorian Villet (gnutix) @@ -203,7 +205,6 @@ Symfony is the result of the work of many people who made the code better - Matthieu Bontemps (mbontemps) - apetitpa - Pierre Minnieur (pminnieur) - - Jannik Zschiesche (apfelbox) - fivestar - Dominique Bongiraud - Jeremy Livingston (jeremylivingston) @@ -219,22 +220,26 @@ Symfony is the result of the work of many people who made the code better - Michele Orselli (orso) - Tom Van Looy (tvlooy) - Sven Paulus (subsven) + - Yanick Witschi (toflar) - Thomas Calvet (fancyweb) - Rui Marinho (ruimarinho) - - Niels Keurentjes (curry684) + - Alessandro Chitolina - Eugene Wissner + - Pascal Montoya - Julien Brochet (mewt) - Leo Feyer - Tristan Darricau (nicofuma) - Nikolay Labinskiy (e-moe) - Michaël Perrin (michael.perrin) - Marcel Beerta (mazen) + - Albert Casademont (acasademont) - Loïc Faugeron - Hidde Wieringa (hiddewie) - Marco Pivetta (ocramius) - Rob Frawley 2nd (robfrawley) - julien pauli (jpauli) - Lorenz Schori + - Oskar Stark (oskarstark) - Sébastien Lavoie (lavoiesl) - Gregor Harlan (gharlan) - Dariusz @@ -255,14 +260,13 @@ Symfony is the result of the work of many people who made the code better - Arjen Brouwer (arjenjb) - Katsuhiro OGAWA - Patrick McDougle (patrick-mcdougle) - - Yanick Witschi (toflar) - Alif Rachmawadi - - Alessandro Chitolina - Kristen Gilden (kgilden) - Pierre-Yves LEBECQ (pylebecq) - Jordan Samouh (jordansamouh) - Baptiste Lafontaine (magnetik) - Jakub Kucharovic (jkucharovic) + - Edi Modrić (emodric) - Uwe Jäger (uwej711) - Eugene Leonovich (rybakit) - Filippo Tessarotto @@ -274,7 +278,6 @@ Symfony is the result of the work of many people who made the code better - Tyson Andre - Chekote - Thomas Adam - - Albert Casademont (acasademont) - Viktor Bocharskyi (bocharsky_bw) - Jhonny Lidfors (jhonne) - Diego Agulló (aeoris) @@ -284,7 +287,6 @@ Symfony is the result of the work of many people who made the code better - Bob den Otter (bopp) - Nikita Konstantinov - Wodor Wodorski - - Oskar Stark (oskarstark) - Thomas Lallement (raziel057) - Giorgio Premi - Christian Schmidt @@ -303,7 +305,7 @@ Symfony is the result of the work of many people who made the code better - Marc Weistroff (futurecat) - Christian Schmidt - Maxime Veber (nek-) - - Edi Modrić (emodric) + - MatTheCat - Chad Sikorra (chadsikorra) - Chris Smith (cs278) - Florian Klein (docteurklein) @@ -347,6 +349,7 @@ Symfony is the result of the work of many people who made the code better - Artur Melo (restless) - Matthew Lewinski (lewinski) - Magnus Nordlander (magnusnordlander) + - Thomas Royer (cydonia7) - alquerci - Francesco Levorato - Vitaliy Zakharov (zakharovvi) @@ -358,11 +361,11 @@ Symfony is the result of the work of many people who made the code better - Artur Eshenbrener - François-Xavier de Guillebon (de-gui_f) - Damien Alexandre (damienalexandre) + - Thomas Perez (scullwm) - Felix Labrecque - Yaroslav Kiliba - Terje Bråten - Mathieu Lechat - - MatTheCat - Robbert Klarenbeek (robbertkl) - JhonnyL - David Badura (davidbadura) @@ -374,6 +377,7 @@ Symfony is the result of the work of many people who made the code better - ShinDarth - Stéphane PY (steph_py) - Philipp Kräutli (pkraeutli) + - Grzegorz (Greg) Zdanowski (kiler129) - Kirill chEbba Chebunin (chebba) - Greg Thornton (xdissent) - Gary PEGEOT (gary-p) @@ -427,13 +431,13 @@ Symfony is the result of the work of many people who made the code better - Christopher Davis (chrisguitarguy) - Jan Schumann - Niklas Fiekas + - Colin O'Dell (colinodell) - Markus Bachmann (baachi) - lancergr - Zan Baldwin - Mihai Stancu - Olivier Dolbeau (odolbeau) - Jan Rosier (rosier) - - Thomas Royer (cydonia7) - Arturs Vonda - Josip Kruslin - Asmir Mustafic (goetas) @@ -453,7 +457,6 @@ Symfony is the result of the work of many people who made the code better - Dirk Pahl (dirkaholic) - cedric lombardot (cedriclombardot) - Jonas Flodén (flojon) - - Thomas Perez (scullwm) - Marcin Sikoń (marphi) - Dominik Zogg (dominik.zogg) - Marek Pietrzak @@ -511,6 +514,7 @@ Symfony is the result of the work of many people who made the code better - Andrew Udvare (audvare) - alexpods - Arjen van der Meijden + - Adam Szaraniec (mimol) - Dariusz Ruminski - Erik Trapman (eriktrapman) - De Cock Xavier (xdecock) @@ -550,6 +554,7 @@ Symfony is the result of the work of many people who made the code better - Ned Schwartz - Ziumin - Jeremy Benoist + - fritzmg - Lenar Lõhmus - Sander Toonen (xatoo) - Benjamin Laugueux (yzalis) @@ -588,9 +593,11 @@ Symfony is the result of the work of many people who made the code better - Nahuel Cuesta (ncuesta) - Chris Boden (cboden) - Christophe Villeger (seragan) + - Bob van de Vijver (bobvandevijver) - Stefan Gehrig (sgehrig) - Hany el-Kerdany - Wang Jingyu + - Webnet team (webnet) - Åsmund Garfors - Gunnstein Lye (glye) - Maxime Douailin @@ -609,6 +616,7 @@ Symfony is the result of the work of many people who made the code better - David Fuhr - Kamil Kokot (pamil) - Max Grigorian (maxakawizard) + - DerManoMann - mcfedr (mcfedr) - Rostyslav Kinash - Maciej Malarz (malarzm) @@ -637,6 +645,7 @@ Symfony is the result of the work of many people who made the code better - Richard Bradley - Ulumuddin Yunus (joenoez) - Johann Saunier (prophet777) + - Sergey (upyx) - Michael Devery (mickadoo) - Antoine Corcy - Sascha Grossenbacher @@ -666,31 +675,40 @@ Symfony is the result of the work of many people who made the code better - Thomas Ploch - Benjamin Grandfond (benjamin) - Tiago Brito (blackmx) + - - Richard van den Brand (ricbra) - develop + - flip111 - Greg Anderson - VJ - Delf Tonder (leberknecht) - Mark Sonnabaum + - Massimiliano Braglia (massimilianobraglia) - Richard Quadling - jochenvdv - Arturas Smorgun (asarturas) - Alexander Volochnev (exelenz) - Michael Piecko - yclian + - Aleksey Prilipko - twifty - Indra Gunawan (guind) - Peter Ward + - Davide Borsatto (davide.borsatto) + - Rhodri Pugh (rodnaph) - Julien DIDIER (juliendidier) - Dominik Ritter (dritter) - Sebastian Grodzicki (sgrodzicki) - Jeroen van den Enden (stoefke) - Pascal Helfenstein + - Anthony GRASSIOT (antograssiot) - Baldur Rensch (brensch) + - Pierre Rineau - Vladyslav Petrovych - Alex Xandra Albert Sim - Craig Duncan (duncan3dc) - Carson Full + - Sergey Yastrebov - Trent Steel (trsteel88) - Yuen-Chi Lian - Besnik Br @@ -717,11 +735,13 @@ Symfony is the result of the work of many people who made the code better - Joschi Kuphal - John Bohn (jbohn) - Marc Morera (mmoreram) + - Saif Eddin Gmati (azjezz) + - Smaine Milianni (ismail1432) + - Michael Moravec - Andrew Hilobok (hilobok) - Noah Heck (myesain) - Christian Soronellas (theunic) - Johann Pardanaud - - Adam Szaraniec (mimol) - Yosmany Garcia (yosmanyga) - Wouter de Wild - Antoine M (amakdessi) @@ -734,6 +754,7 @@ Symfony is the result of the work of many people who made the code better - Xavier Lacot (xavier) - possum - Denis Zunke (donalberto) + - Ahmadou Waly Ndiaye (waly) - Philipp Cordes - Ahmed TAILOULOUTE (ahmedtai) - Olivier Maisonneuve (olineuve) @@ -770,6 +791,7 @@ Symfony is the result of the work of many people who made the code better - Abhoryo - Fabian Vogler (fabian) - Korvin Szanto + - Stéphan Kochen - Arjan Keeman - Alaattin Kahramanlar (alaattin) - Sergey Zolotov (enleur) @@ -777,6 +799,7 @@ Symfony is the result of the work of many people who made the code better - Neil Ferreira - Nathanael Noblet (gnat) - Indra Gunawan (indragunawan) + - Julie Hourcade (juliehde) - Dmitry Parnas (parnas) - Paul LE CORRE - Emanuele Iannone @@ -853,6 +876,7 @@ Symfony is the result of the work of many people who made the code better - LOUARDI Abdeltif (ouardisoft) - Robert Gruendler (pulse00) - Simon Terrien (sterrien) + - Tarmo Leppänen (tarlepp) - Benoît Merlet (trompette) - Koen Kuipers - datibbaw @@ -863,6 +887,7 @@ Symfony is the result of the work of many people who made the code better - Sebastien Morel (plopix) - Patrick Kaufmann - Piotr Stankowski + - Anton Dyshkant - Reece Fowell (reecefowell) - Mátyás Somfai (smatyas) - stefan.r @@ -880,17 +905,18 @@ Symfony is the result of the work of many people who made the code better - Sam Malone - Phan Thanh Ha (haphan) - Chris Jones (leek) - - Colin O'Dell (colinodell) - xaav - Mahmoud Mostafa (mahmoud) - Pieter - Michael Tibben - Billie Thompson - Sander Marechal + - Oleg Golovakhin (doc_tr) - Icode4Food (icode4food) - Radosław Benkel - jean pasqualini (darkilliant) - Ross Motley (rossmotley) + - Julien Fredon - ttomor - Mei Gwilym (meigwilym) - Michael H. Arieli (excelwebzone) @@ -916,6 +942,7 @@ Symfony is the result of the work of many people who made the code better - dantleech - Bastien DURAND (deamon) - Xavier Leune + - Rudy Onfroy - Tero Alén (tero) - DerManoMann - Guillaume Royer @@ -934,7 +961,6 @@ Symfony is the result of the work of many people who made the code better - Máximo Cuadros (mcuadros) - tamirvs - julien.galenski - - Bob van de Vijver - Christian Neff - Oliver Hoff - Ole Rößner (basster) @@ -952,8 +978,10 @@ Symfony is the result of the work of many people who made the code better - ilyes kooli - gr1ev0us - mlazovla + - Behnoush norouzali (behnoush) - Max Beutel - Antanas Arvasevicius + - Pierre Dudoret - Thomas - Maximilian Berghoff (electricmaxxx) - nacho @@ -962,6 +990,7 @@ Symfony is the result of the work of many people who made the code better - Sergey Novikov (s12v) - Marcos Quesada (marcos_quesada) - Matthew Vickery (mattvick) + - Viktor Novikov (panzer_commander) - Paul Mitchum (paul-m) - Angel Koilov (po_taka) - Dan Finnie @@ -996,7 +1025,6 @@ Symfony is the result of the work of many people who made the code better - Thanos Polymeneas (thanos) - Benoit Garret - Jakub Sacha - - DerManoMann - Olaf Klischat - orlovv - Jonathan Hedstrom @@ -1017,13 +1045,13 @@ Symfony is the result of the work of many people who made the code better - Alex Bowers - Jeremy Bush - wizhippo + - Thomason, James - Viacheslav Sychov - Helmut Hummel (helhum) - Matt Brunt - Carlos Ortega Huetos - rpg600 - Péter Buri (burci) - - Davide Borsatto (davide.borsatto) - kaiwa - RJ Garcia - Charles Sanquer (csanquer) @@ -1033,7 +1061,6 @@ Symfony is the result of the work of many people who made the code better - Will Donohoe - peter - Jaroslav Kuba - - flip111 - Jérémy Jourdin (jjk801) - BRAMILLE Sébastien (oktapodia) - Artem Kolesnikov (tyomo4ka) @@ -1043,11 +1070,9 @@ Symfony is the result of the work of many people who made the code better - rchoquet - gitlost - Taras Girnyk - - Anthony GRASSIOT (antograssiot) - Eduardo García Sanz (coma) - James Gilliland - fduch (fduch) - - Rhodri Pugh (rodnaph) - David de Boer (ddeboer) - Ryan Rogers - Klaus Purer @@ -1061,6 +1086,7 @@ Symfony is the result of the work of many people who made the code better - Roger Webb - Dmitriy Simushev - Pawel Smolinski + - Oxan van Leeuwen - pkowalczyk - Max Voloshin (maxvoloshin) - Nicolas Fabre (nfabre) @@ -1111,6 +1137,7 @@ Symfony is the result of the work of many people who made the code better - ConneXNL - Aharon Perkel - matze + - Rubén Calvo (rubencm) - Abdul.Mohsen B. A. A - Benoît Burnichon - pthompson @@ -1121,10 +1148,10 @@ Symfony is the result of the work of many people who made the code better - Lars Ambrosius Wallenborn (larsborn) - Oriol Mangas Abellan (oriolman) - Sebastian Göttschkes (sgoettschkes) - - Sergey (upyx) - Tatsuya Tsuruoka - Ross Tuck - Kévin Gomez (kevin) + - Andrei Igna - azine - Dawid Sajdak - Ludek Stepan @@ -1134,6 +1161,7 @@ Symfony is the result of the work of many people who made the code better - Erika Heidi Reinaldo (erikaheidi) - Pierre Tachoire (krichprollsch) - Marc J. Schmidt (marcjs) + - Sebastian Schwarz - Marco Jantke - Saem Ghani - Clément LEFEBVRE @@ -1142,7 +1170,6 @@ Symfony is the result of the work of many people who made the code better - Adrien Gallou (agallou) - Maks Rafalko (bornfree) - Karol Sójko (karolsojko) - - Grzegorz Zdanowski (kiler129) - sl_toto (sl_toto) - Walter Dal Mut (wdalmut) - abluchet @@ -1155,16 +1182,17 @@ Symfony is the result of the work of many people who made the code better - Keri Henare (kerihenare) - Cédric Lahouste (rapotor) - Samuel Vogel (samuelvogel) + - Alexey Kopytko (sanmai) - Berat Doğan - Guillaume LECERF - Juanmi Rodriguez Cerón - - Sergey Yastrebov - Andy Raines - Anthony Ferrara - Klaas Cuvelier (kcuvelier) - Mathieu TUDISCO (mathieutu) - markusu49 - Steve Frécinaux + - Constantine Shtompel - Jules Lamur - Renato Mendes Figueiredo - ShiraNai7 @@ -1187,6 +1215,7 @@ Symfony is the result of the work of many people who made the code better - Lance McNearney - Gonzalo Vilaseca (gonzalovilaseca) - Giorgio Premi + - Andrew Berry - ncou - Ian Carroll - caponica @@ -1205,10 +1234,10 @@ Symfony is the result of the work of many people who made the code better - Tadcka - Beth Binkovitz - Gonzalo Míguez - - Pierre Rineau - Romain Geissler - Adrien Moiruad - Tomaz Ahlin + - Philip Ardery - Marcus Stöhr (dafish) - Emmanuel Vella (emmanuel.vella) - Jonathan Johnson (jrjohnson) @@ -1217,7 +1246,6 @@ Symfony is the result of the work of many people who made the code better - Jay Severson - René Kerner - Nathaniel Catchpole - - - Adrien Samson (adriensamson) - Samuel Gordalina (gordalina) - Max Romanovsky (maxromanovsky) @@ -1254,7 +1282,6 @@ Symfony is the result of the work of many people who made the code better - Ergie Gonzaga - Matthew J Mucklo - AnrDaemon - - Smaine Milianni (ismail1432) - fdgdfg (psampaz) - Stéphane Seng - Maxwell Vandervelde @@ -1275,18 +1302,22 @@ Symfony is the result of the work of many people who made the code better - Jonathan Gough - Benjamin Bender - Jared Farrish + - karl.rixon - Konrad Mohrfeldt - Lance Chen + - Ciaran McNulty (ciaranmcnulty) - Andrew (drew) - kor3k kor3k (kor3k) - Stelian Mocanita (stelian) - Flavian (2much) + - Gautier Deuette - mike - Kirk Madera - Keith Maika - Mephistofeles - Hoffmann András - Olivier + - Cyril PASCAL - pscheit - Wybren Koelmans - Zdeněk Drahoš @@ -1313,6 +1344,7 @@ Symfony is the result of the work of many people who made the code better - Artiom - Jakub Simon - Bouke Haarsma + - Evert Harmeling - Martin Eckhardt - natechicago - Jonathan Poston @@ -1339,6 +1371,7 @@ Symfony is the result of the work of many people who made the code better - Harold Iedema - Arnau González (arnaugm) - Simon Bouland (bouland) + - Ivan Nikolaev (destillat) - Matthew Foster (mfoster) - Paul Seiffert (seiffert) - Vasily Khayrulin (sirian) @@ -1372,10 +1405,12 @@ Symfony is the result of the work of many people who made the code better - Manatsawin Hanmongkolchai - Gunther Konig - Maciej Schmidt + - Greg ORIOL - Dennis Væversted - nuncanada - flack - František Bereň + - Kamil Madejski - Jeremiah VALERIE - Mike Francis - Christoph Nissle (derstoffel) @@ -1468,7 +1503,6 @@ Symfony is the result of the work of many people who made the code better - Sam Ward - Walther Lalk - Adam - - Stéphan Kochen - devel - taiiiraaa - Trevor Suarez @@ -1482,6 +1516,7 @@ Symfony is the result of the work of many people who made the code better - Chansig - Tischoi - J Bruni + - Fritz Michael Gschwantner - Alexey Prilipko - Dmitriy Fedorenko - vlakoff @@ -1509,10 +1544,12 @@ Symfony is the result of the work of many people who made the code better - Joel Marcey - David Christmann - root + - Vincent Chalnot - James Hudson - Tom Maguire - Richard Quadling - David Zuelke + - Adrian - Oleg Andreyev - Pierre Rineau - Maxim Lovchikov @@ -1535,6 +1572,7 @@ Symfony is the result of the work of many people who made the code better - Hein Zaw Htet™ - Ruben Kruiswijk - Cosmin-Romeo TANASE + - Julien Maulny - Michael J - Joseph Maarek - Alexander Menk @@ -1580,6 +1618,7 @@ Symfony is the result of the work of many people who made the code better - Kuba Werłos - Tomas Liubinas - Alex + - Jan Hort - Klaas Naaijkens - Daniel González Cerviño - Rafał @@ -1686,7 +1725,6 @@ Symfony is the result of the work of many people who made the code better - Christian Eikermann - Kai Eichinger - Antonio Angelino - - Pascal Montoya - Matt Fields - Niklas Keller - Vladimir Sazhin @@ -1753,6 +1791,7 @@ Symfony is the result of the work of many people who made the code better - Adam Klvač - Yevgen Kovalienia - Lebnik + - nsbx - Shude - Ondřej Führer - Sema @@ -1765,11 +1804,13 @@ Symfony is the result of the work of many people who made the code better - Norman Soetbeer - zorn - Yuriy Potemkin + - Emilie Lorenzo - Benjamin Long - Matt Janssen - Ben Miller - Peter Gribanov - kwiateusz + - jspee - David Soria Parra - Sergiy Sokolenko - dinitrol @@ -1827,6 +1868,7 @@ Symfony is the result of the work of many people who made the code better - Damon Jones (damon__jones) - Łukasz Giza (destroyer) - Daniel Londero (dlondero) + - Samuele Lilli (doncallisto) - Sebastian Landwehr (dword123) - Adel ELHAIBA (eadel) - Damián Nohales (eagleoneraptor) @@ -1889,6 +1931,7 @@ Symfony is the result of the work of many people who made the code better - scourgen hung (scourgen) - Sébastien Alfaiate (seb33300) - Sebastian Busch (sebu) + - Sepehr Lajevardi (sepehr) - André Filipe Gonçalves Neves (seven) - Bruno Ziegler (sfcoder) - Andrea Giuliano (shark) @@ -1898,12 +1941,13 @@ Symfony is the result of the work of many people who made the code better - Julien Sanchez (sumbobyboys) - Guillermo Gisinger (t3chn0r) - Markus Tacker (tacker) - - Tarmo Leppänen (tarlepp) + - Andrew Clark (tqt_andrew_clark) - Tyler Stroud (tystr) - Moritz Kraft (userfriendly) - Víctor Mateo (victormateo) - Vincent (vincent1870) - Vincent CHALAMON (vincentchalamon) + - David Herrmann (vworldat) - Eugene Babushkin (warl) - Wouter Sioen (wouter_sioen) - Xavier Amado (xamado) @@ -1929,6 +1973,7 @@ Symfony is the result of the work of many people who made the code better - fh-github@fholzhauer.de - AbdElKader Bouadjadja - DSeemiller + - Kyle - Jan Emrich - Mark Topper - Xavier REN @@ -1939,10 +1984,12 @@ Symfony is the result of the work of many people who made the code better - Mohamed Karnichi (amiral) - Andrew Carter (andrewcarteruk) - Adam Elsodaney (archfizz) + - Gregório Bonfante Borba (bonfante) - Daniel Kolvik (dkvk) - Marc Lemay (flug) - Henne Van Och (hennevo) - Jeroen De Dauw (jeroendedauw) + - Jonathan Scheiber (jmsche) - Daniel Alejandro Castro Arellano (lexcast) - Maxime COLIN (maximecolin) - Muharrem Demirci (mdemirci) diff --git a/composer.json b/composer.json index 8c7d87c73c2a9..e0a1c53c4f158 100644 --- a/composer.json +++ b/composer.json @@ -92,7 +92,7 @@ "doctrine/cache": "~1.6", "doctrine/data-fixtures": "1.0.*", "doctrine/dbal": "~2.4", - "doctrine/orm": "~2.4,>=2.4.5", + "doctrine/orm": "~2.4,>=2.4.5,<=2.7.0", "doctrine/doctrine-bundle": "~1.4", "monolog/monolog": "~1.11", "ocramius/proxy-manager": "~0.4|~1.0|~2.0", @@ -104,7 +104,7 @@ }, "conflict": { "phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.2", - "phpdocumentor/type-resolver": "<0.2.1", + "phpdocumentor/type-resolver": "<0.3.0", "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" }, "provide": { diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php index 3ffd924e519e3..f1c4d5c014a9f 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php @@ -68,7 +68,7 @@ private function addTaggedSubscribers(ContainerBuilder $container) $connections = isset($tag['connection']) ? array($tag['connection']) : array_keys($this->connections); foreach ($connections as $con) { if (!isset($this->connections[$con])) { - throw new RuntimeException(sprintf('The Doctrine connection "%s" referenced in service "%s" does not exist. Available connections names: %s', $con, $taggedSubscriber, implode(', ', array_keys($this->connections)))); + throw new RuntimeException(sprintf('The Doctrine connection "%s" referenced in service "%s" does not exist. Available connections names: %s', $con, $id, implode(', ', array_keys($this->connections)))); } $this->getEventManagerDef($container, $con)->addMethodCall('addEventSubscriber', array(new Reference($id))); diff --git a/src/Symfony/Bridge/Monolog/Handler/FirePHPHandler.php b/src/Symfony/Bridge/Monolog/Handler/FirePHPHandler.php index 056496ae1325a..966a7baf83079 100644 --- a/src/Symfony/Bridge/Monolog/Handler/FirePHPHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/FirePHPHandler.php @@ -38,9 +38,10 @@ public function onKernelResponse(FilterResponseEvent $event) return; } - if (!preg_match('{\bFirePHP/\d+\.\d+\b}', $event->getRequest()->headers->get('User-Agent')) - && !$event->getRequest()->headers->has('X-FirePHP-Version')) { - $this->sendHeaders = false; + $request = $event->getRequest(); + if (!preg_match('{\bFirePHP/\d+\.\d+\b}', $request->headers->get('User-Agent')) + && !$request->headers->has('X-FirePHP-Version')) { + self::$sendHeaders = false; $this->headers = array(); return; @@ -58,7 +59,7 @@ public function onKernelResponse(FilterResponseEvent $event) */ protected function sendHeader($header, $content) { - if (!$this->sendHeaders) { + if (!self::$sendHeaders) { return; } diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index 29b1960798b8c..a2528db303fbb 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -311,6 +311,10 @@ private static function hasColorSupport() return false; } + if ('Hyper' === getenv('TERM_PROGRAM')) { + return true; + } + if (DIRECTORY_SEPARATOR === '\\') { return (function_exists('sapi_windows_vt100_support') && sapi_windows_vt100_support(STDOUT)) diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php index 4a54cc7658e6b..1e47f4424b66b 100644 --- a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php +++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php @@ -15,6 +15,7 @@ use ProxyManager\GeneratorStrategy\BaseGeneratorStrategy; use ProxyManager\Version; use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface; @@ -57,7 +58,7 @@ public function getProxyFactoryCode(Definition $definition, $id, $factoryCode = $instantiation = 'return'; if ($definition->isShared()) { - $instantiation .= sprintf(' $this->%s[\'%s\'] =', $definition->isPublic() && !$definition->isPrivate() ? 'services' : 'privates', $id); + $instantiation .= sprintf(' $this->%s[\'%s\'] =', \method_exists(ContainerBuilder::class, 'addClassResource') || ($definition->isPublic() && !$definition->isPrivate()) ? 'services' : 'privates', $id); } if (null === $factoryCode) { diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php index 357b26844c364..8bdc63146605d 100644 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php +++ b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php @@ -13,6 +13,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; /** @@ -101,7 +102,7 @@ public function getPrivatePublicDefinitions() array( (new Definition(__CLASS__)) ->setPublic(false), - 'privates', + \method_exists(ContainerBuilder::class, 'addClassResource') ? 'services' : 'privates', ), array( (new Definition(__CLASS__)) diff --git a/src/Symfony/Bridge/Twig/Command/DebugCommand.php b/src/Symfony/Bridge/Twig/Command/DebugCommand.php index 1e45cf4d285af..e7741aa3f6b8f 100644 --- a/src/Symfony/Bridge/Twig/Command/DebugCommand.php +++ b/src/Symfony/Bridge/Twig/Command/DebugCommand.php @@ -39,7 +39,7 @@ class DebugCommand extends Command public function __construct($twig = null, $projectDir = null) { if (!$twig instanceof Environment) { - @trigger_error(sprintf('Passing a command name as the first argument of "%s" is deprecated since Symfony 3.4 and will be removed in 4.0. If the command was registered by convention, make it a service instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('Passing a command name as the first argument of "%s()" is deprecated since Symfony 3.4 and support for it will be removed in 4.0. If the command was registered by convention, make it a service instead.', __METHOD__), E_USER_DEPRECATED); parent::__construct($twig); @@ -54,7 +54,7 @@ public function __construct($twig = null, $projectDir = null) public function setTwigEnvironment(Environment $twig) { - @trigger_error(sprintf('Method "%s" is deprecated since Symfony 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED); $this->twig = $twig; } @@ -64,7 +64,7 @@ public function setTwigEnvironment(Environment $twig) */ protected function getTwigEnvironment() { - @trigger_error(sprintf('Method "%s" is deprecated since Symfony 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED); return $this->twig; } @@ -151,19 +151,27 @@ protected function execute(InputInterface $input, OutputInterface $output) } $rows = array(); + $firstNamespace = true; + $prevHasSeparator = false; foreach ($this->getLoaderPaths() as $namespace => $paths) { - if (count($paths) > 1) { + if (!$firstNamespace && !$prevHasSeparator && count($paths) > 1) { $rows[] = array('', ''); } + $firstNamespace = false; foreach ($paths as $path) { - $rows[] = array($namespace, '- '.$path); + $rows[] = array($namespace, $path.DIRECTORY_SEPARATOR); $namespace = ''; } if (count($paths) > 1) { $rows[] = array('', ''); + $prevHasSeparator = true; + } else { + $prevHasSeparator = false; } } - array_pop($rows); + if ($prevHasSeparator) { + array_pop($rows); + } $io->section('Loader Paths'); $io->table(array('Namespace', 'Paths'), $rows); diff --git a/src/Symfony/Bridge/Twig/Command/LintCommand.php b/src/Symfony/Bridge/Twig/Command/LintCommand.php index 24630012188b1..a9d81c990423c 100644 --- a/src/Symfony/Bridge/Twig/Command/LintCommand.php +++ b/src/Symfony/Bridge/Twig/Command/LintCommand.php @@ -43,7 +43,7 @@ class LintCommand extends Command public function __construct($twig = null) { if (!$twig instanceof Environment) { - @trigger_error(sprintf('Passing a command name as the first argument of "%s" is deprecated since Symfony 3.4 and will be removed in 4.0. If the command was registered by convention, make it a service instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('Passing a command name as the first argument of "%s()" is deprecated since Symfony 3.4 and support for it will be removed in 4.0. If the command was registered by convention, make it a service instead.', __METHOD__), E_USER_DEPRECATED); parent::__construct($twig); @@ -57,7 +57,7 @@ public function __construct($twig = null) public function setTwigEnvironment(Environment $twig) { - @trigger_error(sprintf('Method "%s" is deprecated since Symfony 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED); $this->twig = $twig; } @@ -67,7 +67,7 @@ public function setTwigEnvironment(Environment $twig) */ protected function getTwigEnvironment() { - @trigger_error(sprintf('Method "%s" is deprecated since Symfony 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED); return $this->twig; } diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig index 43c031b933366..b4e5b0120eebf 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig @@ -187,7 +187,7 @@ {%- set element = 'legend' -%} {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' col-form-label')|trim}) -%} {%- else -%} - {%- set label_attr = label_attr|merge({for: id, class: (label_attr.class|default('') ~ ' form-control-label')|trim}) -%} + {%- set label_attr = label_attr|merge({for: id}) -%} {%- endif -%} {% if required -%} {% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) %} @@ -268,8 +268,8 @@ {%- if errors|length > 0 -%} {%- for error in errors -%} - - {{ 'Error'|trans({}, 'validators') }} {{ error.message }} + + {{ 'Error'|trans({}, 'validators') }} {{ error.message }} {%- endfor -%} diff --git a/src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php b/src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php new file mode 100644 index 0000000000000..77d522f5230aa --- /dev/null +++ b/src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Twig\Tests\Command; + +use PHPUnit\Framework\TestCase; +use Symfony\Bridge\Twig\Command\DebugCommand; +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Tester\CommandTester; +use Twig\Loader\FilesystemLoader; +use Twig\Environment; + +class DebugCommandTest extends TestCase +{ + public function testDebugCommand() + { + $tester = $this->createCommandTester(); + $ret = $tester->execute(array(), array('decorated' => false)); + + $this->assertEquals(0, $ret, 'Returns 0 in case of success'); + $this->assertContains('Functions', trim($tester->getDisplay())); + } + + public function testLineSeparatorInLoaderPaths() + { + // these paths aren't realistic, + // they're configured to force the line separator + $tester = $this->createCommandTester(array( + 'Acme' => array('extractor', 'extractor'), + '!Acme' => array('extractor', 'extractor'), + FilesystemLoader::MAIN_NAMESPACE => array('extractor', 'extractor'), + )); + $ret = $tester->execute(array(), array('decorated' => false)); + $ds = DIRECTORY_SEPARATOR; + $loaderPaths = <<assertEquals(0, $ret, 'Returns 0 in case of success'); + $this->assertContains($loaderPaths, trim($tester->getDisplay(true))); + } + + private function createCommandTester(array $paths = array()) + { + $filesystemLoader = new FilesystemLoader(array(), dirname(__DIR__).'/Fixtures'); + foreach ($paths as $namespace => $relDirs) { + foreach ($relDirs as $relDir) { + $filesystemLoader->addPath($relDir, $namespace); + } + } + $command = new DebugCommand(new Environment($filesystemLoader)); + + $application = new Application(); + $application->add($command); + $command = $application->find('debug:twig'); + + return new CommandTester($command); + } +} diff --git a/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php b/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php index 9ef18640684f9..c761a1a3d6dc2 100644 --- a/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php @@ -70,7 +70,7 @@ public function testLintFileCompileTimeException() /** * @group legacy - * @expectedDeprecation Passing a command name as the first argument of "Symfony\Bridge\Twig\Command\LintCommand::__construct" is deprecated since Symfony 3.4 and will be removed in 4.0. If the command was registered by convention, make it a service instead. + * @expectedDeprecation Passing a command name as the first argument of "Symfony\Bridge\Twig\Command\LintCommand::__construct()" is deprecated since Symfony 3.4 and support for it will be removed in 4.0. If the command was registered by convention, make it a service instead. * @expectedException \RuntimeException * @expectedExceptionMessage The Twig environment needs to be set. */ diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap3HorizontalLayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3HorizontalLayoutTest.php similarity index 99% rename from src/Symfony/Component/Form/Tests/AbstractBootstrap3HorizontalLayoutTest.php rename to src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3HorizontalLayoutTest.php index 04b5b5836c650..97311b38a93f9 100644 --- a/src/Symfony/Component/Form/Tests/AbstractBootstrap3HorizontalLayoutTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3HorizontalLayoutTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\Form\Tests; +namespace Symfony\Bridge\Twig\Tests\Extension; abstract class AbstractBootstrap3HorizontalLayoutTest extends AbstractBootstrap3LayoutTest { diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap3LayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php similarity index 99% rename from src/Symfony/Component/Form/Tests/AbstractBootstrap3LayoutTest.php rename to src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php index 33de7b638fd68..5800e6fef19a8 100644 --- a/src/Symfony/Component/Form/Tests/AbstractBootstrap3LayoutTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php @@ -9,9 +9,10 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\Form\Tests; +namespace Symfony\Bridge\Twig\Tests\Extension; use Symfony\Component\Form\FormError; +use Symfony\Component\Form\Tests\AbstractLayoutTest; abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest { diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4HorizontalLayoutTest.php similarity index 94% rename from src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php rename to src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4HorizontalLayoutTest.php index 016792e0edaf6..9d216e38194f2 100644 --- a/src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4HorizontalLayoutTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\Form\Tests; +namespace Symfony\Bridge\Twig\Tests\Extension; use Symfony\Component\Form\FormError; @@ -33,7 +33,7 @@ public function testRow() ./label[@for="name"] [ ./span[@class="alert alert-danger d-block"] - [./span[@class="mb-0 d-block"] + [./span[@class="d-block"] [./span[.="[trans]Error[/trans]"]] [./span[.="[trans]Error![/trans]"]] ] @@ -72,7 +72,7 @@ public function testLabelDoesNotRenderFieldAttributes() $this->assertMatchesXpath($html, '/label [@for="name"] - [@class="col-form-label col-sm-2 form-control-label required"] + [@class="col-form-label col-sm-2 required"] ' ); } @@ -89,7 +89,7 @@ public function testLabelWithCustomAttributesPassedDirectly() $this->assertMatchesXpath($html, '/label [@for="name"] - [@class="my&class col-form-label col-sm-2 form-control-label required"] + [@class="my&class col-form-label col-sm-2 required"] ' ); } @@ -106,7 +106,7 @@ public function testLabelWithCustomTextAndCustomAttributesPassedDirectly() $this->assertMatchesXpath($html, '/label [@for="name"] - [@class="my&class col-form-label col-sm-2 form-control-label required"] + [@class="my&class col-form-label col-sm-2 required"] [.="[trans]Custom label[/trans]"] ' ); @@ -126,7 +126,7 @@ public function testLabelWithCustomTextAsOptionAndCustomAttributesPassedDirectly $this->assertMatchesXpath($html, '/label [@for="name"] - [@class="my&class col-form-label col-sm-2 form-control-label required"] + [@class="my&class col-form-label col-sm-2 required"] [.="[trans]Custom label[/trans]"] ' ); diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4LayoutTest.php similarity index 98% rename from src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php rename to src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4LayoutTest.php index f9c4613e591c7..1d8c597920ce5 100644 --- a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4LayoutTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\Form\Tests; +namespace Symfony\Bridge\Twig\Tests\Extension; use Symfony\Component\Form\Extension\Core\Type\ButtonType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; @@ -42,7 +42,7 @@ public function testRow() ./label[@for="name"] [ ./span[@class="alert alert-danger d-block"] - [./span[@class="mb-0 d-block"] + [./span[@class="d-block"] [./span[.="[trans]Error[/trans]"]] [./span[.="[trans]Error![/trans]"]] ] @@ -81,7 +81,7 @@ public function testLabelDoesNotRenderFieldAttributes() $this->assertMatchesXpath($html, '/label [@for="name"] - [@class="form-control-label required"] + [@class="required"] ' ); } @@ -98,7 +98,7 @@ public function testLabelWithCustomAttributesPassedDirectly() $this->assertMatchesXpath($html, '/label [@for="name"] - [@class="my&class form-control-label required"] + [@class="my&class required"] ' ); } @@ -115,7 +115,7 @@ public function testLabelWithCustomTextAndCustomAttributesPassedDirectly() $this->assertMatchesXpath($html, '/label [@for="name"] - [@class="my&class form-control-label required"] + [@class="my&class required"] [.="[trans]Custom label[/trans]"] ' ); @@ -135,7 +135,7 @@ public function testLabelWithCustomTextAsOptionAndCustomAttributesPassedDirectly $this->assertMatchesXpath($html, '/label [@for="name"] - [@class="my&class form-control-label required"] + [@class="my&class required"] [.="[trans]Custom label[/trans]"] ' ); @@ -172,11 +172,11 @@ public function testErrors() '/span [@class="alert alert-danger d-block"] [ - ./span[@class="mb-0 d-block"] + ./span[@class="d-block"] [./span[.="[trans]Error[/trans]"]] [./span[.="[trans]Error 1[/trans]"]] - /following-sibling::span[@class="mb-0 d-block"] + /following-sibling::span[@class="d-block"] [./span[.="[trans]Error[/trans]"]] [./span[.="[trans]Error 2[/trans]"]] ] diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap3HorizontalLayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap3HorizontalLayoutTest.php index e5ee8903efe4a..309b2df80b16c 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap3HorizontalLayoutTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap3HorizontalLayoutTest.php @@ -18,7 +18,6 @@ use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubFilesystemLoader; use Symfony\Component\Form\FormRenderer; use Symfony\Component\Form\FormView; -use Symfony\Component\Form\Tests\AbstractBootstrap3HorizontalLayoutTest; use Twig\Environment; class FormExtensionBootstrap3HorizontalLayoutTest extends AbstractBootstrap3HorizontalLayoutTest diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap3LayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap3LayoutTest.php index d45ac367b1808..99002c6f1bbb8 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap3LayoutTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap3LayoutTest.php @@ -18,7 +18,6 @@ use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubFilesystemLoader; use Symfony\Component\Form\FormRenderer; use Symfony\Component\Form\FormView; -use Symfony\Component\Form\Tests\AbstractBootstrap3LayoutTest; use Twig\Environment; class FormExtensionBootstrap3LayoutTest extends AbstractBootstrap3LayoutTest diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap4HorizontalLayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap4HorizontalLayoutTest.php index 551d145acf4e5..1a563d76a26cc 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap4HorizontalLayoutTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap4HorizontalLayoutTest.php @@ -18,7 +18,6 @@ use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubFilesystemLoader; use Symfony\Component\Form\FormRenderer; use Symfony\Component\Form\FormView; -use Symfony\Component\Form\Tests\AbstractBootstrap4HorizontalLayoutTest; use Twig\Environment; /** diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap4LayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap4LayoutTest.php index fdc4f3ebda5c0..d93bd3925feb2 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap4LayoutTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap4LayoutTest.php @@ -18,7 +18,6 @@ use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubFilesystemLoader; use Symfony\Component\Form\FormRenderer; use Symfony\Component\Form\FormView; -use Symfony\Component\Form\Tests\AbstractBootstrap4LayoutTest; use Twig\Environment; /** diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index f3be0e624cd17..2b48bab11c382 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -23,7 +23,7 @@ "symfony/asset": "~2.8|~3.0|~4.0", "symfony/dependency-injection": "~2.8|~3.0|~4.0", "symfony/finder": "~2.8|~3.0|~4.0", - "symfony/form": "^3.4.9|^4.0.9", + "symfony/form": "^3.4.13|~4.0.13|^4.1.2", "symfony/http-foundation": "^3.3.11|~4.0", "symfony/http-kernel": "~3.2|~4.0", "symfony/polyfill-intl-icu": "~1.0", @@ -41,7 +41,7 @@ "symfony/workflow": "~3.3|~4.0" }, "conflict": { - "symfony/form": "<3.4.9|<4.0.9,>=4.0", + "symfony/form": "<3.4.13|>=4.0,<4.0.13|>=4.1,<4.1.2", "symfony/console": "<3.4" }, "suggest": { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/CacheWarmupCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/CacheWarmupCommand.php index a5874df234674..593b93475564e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/CacheWarmupCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/CacheWarmupCommand.php @@ -36,7 +36,7 @@ class CacheWarmupCommand extends ContainerAwareCommand public function __construct($cacheWarmer = null) { if (!$cacheWarmer instanceof CacheWarmerAggregate) { - @trigger_error(sprintf('Passing a command name as the first argument of "%s" is deprecated since Symfony 3.4 and will be removed in 4.0. If the command was registered by convention, make it a service instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('Passing a command name as the first argument of "%s()" is deprecated since Symfony 3.4 and support for it will be removed in 4.0. If the command was registered by convention, make it a service instead.', __METHOD__), E_USER_DEPRECATED); parent::__construct($cacheWarmer); diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/XliffLintCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/XliffLintCommand.php index 534ab36c34a6f..bad4284e2d8c6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/XliffLintCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/XliffLintCommand.php @@ -29,7 +29,7 @@ class XliffLintCommand extends BaseLintCommand public function __construct($name = null, $directoryIteratorProvider = null, $isReadableProvider = null) { if (func_num_args()) { - @trigger_error(sprintf('Passing a constructor argument in "%s" is deprecated since Symfony 3.4 and will be removed in 4.0. If the command was registered by convention, make it a service instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('Passing a constructor argument in "%s()" is deprecated since Symfony 3.4 and will be removed in 4.0. If the command was registered by convention, make it a service instead.', __METHOD__), E_USER_DEPRECATED); } if (null === $directoryIteratorProvider) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/YamlLintCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/YamlLintCommand.php index 2ca60ca0673c8..2df4c165378a4 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/YamlLintCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/YamlLintCommand.php @@ -28,7 +28,7 @@ class YamlLintCommand extends BaseLintCommand public function __construct($name = null, $directoryIteratorProvider = null, $isReadableProvider = null) { if (func_num_args()) { - @trigger_error(sprintf('Passing a constructor argument in "%s" is deprecated since Symfony 3.4 and will be removed in 4.0. If the command was registered by convention, make it a service instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('Passing a constructor argument in "%s()" is deprecated since Symfony 3.4 and will be removed in 4.0. If the command was registered by convention, make it a service instead.', __METHOD__), E_USER_DEPRECATED); } if (null === $directoryIteratorProvider) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 3a81958b1158c..11b0c959593ec 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -191,8 +191,8 @@ public function testWorkflows() { $container = $this->createContainerFromFile('workflows'); - $this->assertTrue($container->hasDefinition('workflow.article', 'Workflow is registered as a service')); - $this->assertTrue($container->hasDefinition('workflow.article.definition', 'Workflow definition is registered as a service')); + $this->assertTrue($container->hasDefinition('workflow.article'), 'Workflow is registered as a service'); + $this->assertTrue($container->hasDefinition('workflow.article.definition'), 'Workflow definition is registered as a service'); $workflowDefinition = $container->getDefinition('workflow.article.definition'); @@ -210,8 +210,8 @@ public function testWorkflows() ); $this->assertSame(array('workflow.definition' => array(array('name' => 'article', 'type' => 'workflow', 'marking_store' => 'multiple_state'))), $workflowDefinition->getTags()); - $this->assertTrue($container->hasDefinition('state_machine.pull_request', 'State machine is registered as a service')); - $this->assertTrue($container->hasDefinition('state_machine.pull_request.definition', 'State machine definition is registered as a service')); + $this->assertTrue($container->hasDefinition('state_machine.pull_request'), 'State machine is registered as a service'); + $this->assertTrue($container->hasDefinition('state_machine.pull_request.definition'), 'State machine definition is registered as a service'); $this->assertCount(4, $workflowDefinition->getArgument(1)); $this->assertSame('draft', $workflowDefinition->getArgument(2)); @@ -293,8 +293,8 @@ public function testWorkflowMultipleTransitionsWithSameName() { $container = $this->createContainerFromFile('workflow_with_multiple_transitions_with_same_name'); - $this->assertTrue($container->hasDefinition('workflow.article', 'Workflow is registered as a service')); - $this->assertTrue($container->hasDefinition('workflow.article.definition', 'Workflow definition is registered as a service')); + $this->assertTrue($container->hasDefinition('workflow.article'), 'Workflow is registered as a service'); + $this->assertTrue($container->hasDefinition('workflow.article.definition'), 'Workflow definition is registered as a service'); $workflowDefinition = $container->getDefinition('workflow.article.definition'); 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 a1d91e7929d65..0c82d8cc73eb2 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 @@ -43,6 +43,14 @@ public function welcomeAction(Request $request, $name = null) return new Response(sprintf('Welcome back %s, nice to meet you.', $name)); } + public function cacheableAction() + { + $response = new Response('all good'); + $response->setSharedMaxAge(100); + + return $response; + } + public function logoutAction(Request $request) { $request->getSession()->invalidate(); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml index 11b85a86d3299..923204ab0f427 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml @@ -2,6 +2,10 @@ session_welcome: path: /session defaults: { _controller: TestBundle:Session:welcome } +session_cacheable: + path: /cacheable + defaults: { _controller: Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\SessionController::cacheableAction } + session_welcome_name: path: /session/{name} defaults: { _controller: TestBundle:Session:welcome } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SessionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SessionTest.php index 166d8a33919df..2e1634220c3a5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SessionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SessionTest.php @@ -126,6 +126,22 @@ public function testTwoClients($config, $insulate) $this->assertContains('Welcome back client2, nice to meet you.', $crawler2->text()); } + /** + * @dataProvider getConfigs + */ + public function testCorrectCacheControlHeadersForCacheableAction($config, $insulate) + { + $client = $this->createClient(array('test_case' => 'Session', 'root_config' => $config)); + if ($insulate) { + $client->insulate(); + } + + $client->request('GET', '/cacheable'); + + $response = $client->getResponse(); + $this->assertSame('public, s-maxage=100', $response->headers->get('cache-control')); + } + public function getConfigs() { return array( diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php index c2c2364d7097c..63ecc5171ca5d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php @@ -45,7 +45,7 @@ protected function deleteTmpDir() /** * @group legacy - * @expectedDeprecation Method Symfony\Bundle\FrameworkBundle\Translation\Translator::__construct() takes the default locale as 3rd argument since Symfony 3.3. Not passing it is deprecated and will trigger an error in 4.0. + * @expectedDeprecation The "Symfony\Bundle\FrameworkBundle\Translation\Translator::__construct()" method takes the default locale as the 3rd argument since Symfony 3.3. Not passing it is deprecated and will trigger an error in 4.0. */ public function testTransWithoutCachingOmittingLocale() { @@ -66,7 +66,7 @@ public function testTransWithoutCachingOmittingLocale() /** * @group legacy - * @expectedDeprecation Method Symfony\Bundle\FrameworkBundle\Translation\Translator::__construct() takes the default locale as 3rd argument since Symfony 3.3. Not passing it is deprecated and will trigger an error in 4.0. + * @expectedDeprecation The "Symfony\Bundle\FrameworkBundle\Translation\Translator::__construct()" method takes the default locale as the 3rd argument since Symfony 3.3. Not passing it is deprecated and will trigger an error in 4.0. */ public function testTransWithCachingOmittingLocale() { @@ -106,7 +106,7 @@ public function testTransWithCachingOmittingLocale() /** * @group legacy - * @expectedDeprecation Method Symfony\Bundle\FrameworkBundle\Translation\Translator::__construct() takes the default locale as 3rd argument since Symfony 3.3. Not passing it is deprecated and will trigger an error in 4.0. + * @expectedDeprecation The "Symfony\Bundle\FrameworkBundle\Translation\Translator::__construct()" method takes the default locale as the 3rd argument since Symfony 3.3. Not passing it is deprecated and will trigger an error in 4.0. * @expectedException \InvalidArgumentException */ public function testTransWithCachingWithInvalidLocaleOmittingLocale() @@ -119,7 +119,7 @@ public function testTransWithCachingWithInvalidLocaleOmittingLocale() /** * @group legacy - * @expectedDeprecation Method Symfony\Bundle\FrameworkBundle\Translation\Translator::__construct() takes the default locale as 3rd argument since Symfony 3.3. Not passing it is deprecated and will trigger an error in 4.0. + * @expectedDeprecation The "Symfony\Bundle\FrameworkBundle\Translation\Translator::__construct()" method takes the default locale as the 3rd argument since Symfony 3.3. Not passing it is deprecated and will trigger an error in 4.0. */ public function testLoadResourcesWithoutCachingOmittingLocale() { @@ -138,7 +138,7 @@ public function testLoadResourcesWithoutCachingOmittingLocale() /** * @group legacy - * @expectedDeprecation Method Symfony\Bundle\FrameworkBundle\Translation\Translator::__construct() takes the default locale as 3rd argument since Symfony 3.3. Not passing it is deprecated and will trigger an error in 4.0. + * @expectedDeprecation The "Symfony\Bundle\FrameworkBundle\Translation\Translator::__construct()" method takes the default locale as the 3rd argument since Symfony 3.3. Not passing it is deprecated and will trigger an error in 4.0. */ public function testGetDefaultLocaleOmittingLocale() { @@ -167,7 +167,7 @@ public function testGetDefaultLocaleOmittingLocaleWithPsrContainer() /** * @group legacy - * @expectedDeprecation Method Symfony\Bundle\FrameworkBundle\Translation\Translator::__construct() takes the default locale as 3rd argument since Symfony 3.3. Not passing it is deprecated and will trigger an error in 4.0. + * @expectedDeprecation The "Symfony\Bundle\FrameworkBundle\Translation\Translator::__construct()" method takes the default locale as the 3rd argument since Symfony 3.3. Not passing it is deprecated and will trigger an error in 4.0. */ public function testWarmupOmittingLocale() { diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/TranslationLoader.php b/src/Symfony/Bundle/FrameworkBundle/Translation/TranslationLoader.php index 2431e79ff238e..2466d1f2952da 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/TranslationLoader.php +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/TranslationLoader.php @@ -14,13 +14,16 @@ use Symfony\Component\Translation\Reader\TranslationReader; use Symfony\Component\Translation\MessageCatalogue; -@trigger_error(sprintf('The class "%s" is deprecated since Symfony 3.4 and will be removed in 4.0. Use "%s" instead. ', TranslationLoader::class, TranslationReader::class), E_USER_DEPRECATED); - /** * @deprecated since version 3.4 and will be removed in 4.0. Use Symfony\Component\Translation\Reader\TranslationReader instead */ class TranslationLoader extends TranslationReader { + public function __construct() + { + @trigger_error(sprintf('The class "%s" is deprecated since Symfony 3.4 and will be removed in 4.0. Use "%s" instead. ', self::class, TranslationReader::class), E_USER_DEPRECATED); + } + /** * Loads translation messages from a directory to the catalogue. * diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php index 631d14e91b600..119adccba1d2d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php @@ -75,7 +75,7 @@ public function __construct(ContainerInterface $container, $formatter, $defaultL $options = $loaderIds; $loaderIds = $defaultLocale; $defaultLocale = $container->getParameter('kernel.default_locale'); - @trigger_error(sprintf('Method %s() takes the default locale as 3rd argument since Symfony 3.3. Not passing it is deprecated and will trigger an error in 4.0.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method takes the default locale as the 3rd argument since Symfony 3.3. Not passing it is deprecated and will trigger an error in 4.0.', __METHOD__), E_USER_DEPRECATED); } $this->container = $container; diff --git a/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php b/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php index cea8bd2e1541d..aff7074c51e79 100644 --- a/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php +++ b/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php @@ -42,7 +42,7 @@ class UserPasswordEncoderCommand extends ContainerAwareCommand public function __construct(EncoderFactoryInterface $encoderFactory = null, array $userClasses = array()) { if (null === $encoderFactory) { - @trigger_error(sprintf('Passing null as the first argument of "%s" is deprecated since Symfony 3.3 and will be removed in 4.0. If the command was registered by convention, make it a service instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('Passing null as the first argument of "%s()" is deprecated since Symfony 3.3 and support for it will be removed in 4.0. If the command was registered by convention, make it a service instead.', __METHOD__), E_USER_DEPRECATED); } $this->encoderFactory = $encoderFactory; @@ -75,7 +75,7 @@ protected function configure() security: encoders: Symfony\Component\Security\Core\User\User: plaintext - AppBundle\Entity\User: bcrypt + App\Entity\User: bcrypt If you execute the command non-interactively, the first available configured @@ -87,16 +87,16 @@ protected function configure() Pass the full user class path as the second argument to encode passwords for your own entities: - php %command.full_name% --no-interaction [password] AppBundle\Entity\User + php %command.full_name% --no-interaction [password] App\Entity\User Executing the command interactively allows you to generate a random salt for encoding the password: - php %command.full_name% [password] AppBundle\Entity\User + php %command.full_name% [password] App\Entity\User In case your encoder doesn't require a salt, add the empty-salt option: - php %command.full_name% --empty-salt [password] AppBundle\Entity\User + php %command.full_name% --empty-salt [password] App\Entity\User EOF ) diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php index a514ab04a8327..0948b63442bfb 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php @@ -410,8 +410,8 @@ private function addEncodersSection(ArrayNodeDefinition $rootNode) ->children() ->arrayNode('encoders') ->example(array( - 'AppBundle\Entity\User1' => 'bcrypt', - 'AppBundle\Entity\User2' => array( + 'App\Entity\User1' => 'bcrypt', + 'App\Entity\User2' => array( 'algorithm' => 'bcrypt', 'cost' => 13, ), diff --git a/src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php b/src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php index 7fafc1a35ba21..e68e5529dc13d 100644 --- a/src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php +++ b/src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php @@ -55,7 +55,7 @@ public function getConfig() */ public function getContext() { - @trigger_error(sprintf('Method %s() is deprecated since Symfony 3.3 and will be removed in 4.0. Use %s::getListeners/getExceptionListener() instead.', __METHOD__, __CLASS__), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 3.3 and will be removed in 4.0. Use %s::getListeners/getExceptionListener() instead.', __METHOD__, __CLASS__), E_USER_DEPRECATED); return array($this->getListeners(), $this->getExceptionListener(), $this->getLogoutListener()); } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php index 1c6f5c280f2ed..7a4a1f3907e9c 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php @@ -231,7 +231,7 @@ public function testThrowsExceptionOnNoConfiguredEncoders() /** * @group legacy - * @expectedDeprecation Passing null as the first argument of "Symfony\Bundle\SecurityBundle\Command\UserPasswordEncoderCommand::__construct" is deprecated since Symfony 3.3 and will be removed in 4.0. If the command was registered by convention, make it a service instead. + * @expectedDeprecation Passing null as the first argument of "Symfony\Bundle\SecurityBundle\Command\UserPasswordEncoderCommand::__construct()" is deprecated since Symfony 3.3 and support for it will be removed in 4.0. If the command was registered by convention, make it a service instead. */ public function testLegacy() { diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallContextTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallContextTest.php index 69c8ce308f53b..8466d9f06f702 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallContextTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallContextTest.php @@ -41,7 +41,7 @@ public function testGetters() } /** - * @expectedDeprecation Method Symfony\Bundle\SecurityBundle\Security\FirewallContext::getContext() is deprecated since Symfony 3.3 and will be removed in 4.0. Use Symfony\Bundle\SecurityBundle\Security\FirewallContext::getListeners/getExceptionListener() instead. + * @expectedDeprecation The "Symfony\Bundle\SecurityBundle\Security\FirewallContext::getContext()" method is deprecated since Symfony 3.3 and will be removed in 4.0. Use Symfony\Bundle\SecurityBundle\Security\FirewallContext::getListeners/getExceptionListener() instead. * @group legacy */ public function testGetContext() diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig index e3a0d8454f5c8..9c76e0ad8f33d 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig @@ -70,6 +70,7 @@ .sf-toolbarreset svg, .sf-toolbarreset img { height: 20px; + width: 20px; display: inline-block; } @@ -160,11 +161,11 @@ margin-bottom: 0; } -.sf-toolbar-block .sf-toolbar-info-piece a { +div.sf-toolbar .sf-toolbar-block .sf-toolbar-info-piece a { color: #99CDD8; text-decoration: underline; } -.sf-toolbar-block .sf-toolbar-info-piece a:hover { +div.sf-toolbar .sf-toolbar-block a:hover { text-decoration: none; } @@ -292,6 +293,7 @@ border-width: 0; position: relative; top: 8px; + vertical-align: baseline; } .sf-toolbar-block .sf-toolbar-icon img + span, diff --git a/src/Symfony/Component/Cache/Tests/Adapter/MaxIdLengthAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/MaxIdLengthAdapterTest.php index cf2384c5f37e6..266e1f850c953 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/MaxIdLengthAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/MaxIdLengthAdapterTest.php @@ -34,6 +34,34 @@ public function testLongKey() $cache->hasItem(str_repeat('-', 39)); } + public function testLongKeyVersioning() + { + $cache = $this->getMockBuilder(MaxIdLengthAdapter::class) + ->setConstructorArgs(array(str_repeat('-', 26))) + ->getMock(); + + $reflectionClass = new \ReflectionClass(AbstractAdapter::class); + + $reflectionMethod = $reflectionClass->getMethod('getId'); + $reflectionMethod->setAccessible(true); + + // No versioning enabled + $this->assertEquals('--------------------------:------------', $reflectionMethod->invokeArgs($cache, array(str_repeat('-', 12)))); + $this->assertLessThanOrEqual(50, strlen($reflectionMethod->invokeArgs($cache, array(str_repeat('-', 12))))); + $this->assertLessThanOrEqual(50, strlen($reflectionMethod->invokeArgs($cache, array(str_repeat('-', 23))))); + $this->assertLessThanOrEqual(50, strlen($reflectionMethod->invokeArgs($cache, array(str_repeat('-', 40))))); + + $reflectionProperty = $reflectionClass->getProperty('versioningIsEnabled'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($cache, true); + + // Versioning enabled + $this->assertEquals('--------------------------:1:------------', $reflectionMethod->invokeArgs($cache, array(str_repeat('-', 12)))); + $this->assertLessThanOrEqual(50, strlen($reflectionMethod->invokeArgs($cache, array(str_repeat('-', 12))))); + $this->assertLessThanOrEqual(50, strlen($reflectionMethod->invokeArgs($cache, array(str_repeat('-', 23))))); + $this->assertLessThanOrEqual(50, strlen($reflectionMethod->invokeArgs($cache, array(str_repeat('-', 40))))); + } + /** * @expectedException \Symfony\Component\Cache\Exception\InvalidArgumentException * @expectedExceptionMessage Namespace must be 26 chars max, 40 given ("----------------------------------------") diff --git a/src/Symfony/Component/Cache/Traits/AbstractTrait.php b/src/Symfony/Component/Cache/Traits/AbstractTrait.php index 7953ae6e8beee..ec60fe79c4a6b 100644 --- a/src/Symfony/Component/Cache/Traits/AbstractTrait.php +++ b/src/Symfony/Component/Cache/Traits/AbstractTrait.php @@ -255,7 +255,7 @@ private function getId($key) return $this->namespace.$this->namespaceVersion.$key; } if (\strlen($id = $this->namespace.$this->namespaceVersion.$key) > $this->maxIdLength) { - $id = $this->namespace.$this->namespaceVersion.substr_replace(base64_encode(hash('sha256', $key, true)), ':', -22); + $id = $this->namespace.$this->namespaceVersion.substr_replace(base64_encode(hash('sha256', $key, true)), ':', -(\strlen($this->namespaceVersion) + 22)); } return $id; diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index 107c1ed6caaa9..65dc90ccec2ef 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -807,7 +807,7 @@ protected function doRenderException(\Exception $e, OutputInterface $output) */ protected function getTerminalWidth() { - @trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Create a Terminal instance instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method is deprecated as of 3.2 and will be removed in 4.0. Create a Terminal instance instead.', __METHOD__), E_USER_DEPRECATED); return $this->terminal->getWidth(); } @@ -821,7 +821,7 @@ protected function getTerminalWidth() */ protected function getTerminalHeight() { - @trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Create a Terminal instance instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method is deprecated as of 3.2 and will be removed in 4.0. Create a Terminal instance instead.', __METHOD__), E_USER_DEPRECATED); return $this->terminal->getHeight(); } @@ -835,7 +835,7 @@ protected function getTerminalHeight() */ public function getTerminalDimensions() { - @trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Create a Terminal instance instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method is deprecated as of 3.2 and will be removed in 4.0. Create a Terminal instance instead.', __METHOD__), E_USER_DEPRECATED); return array($this->terminal->getWidth(), $this->terminal->getHeight()); } @@ -854,7 +854,7 @@ public function getTerminalDimensions() */ public function setTerminalDimensions($width, $height) { - @trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Set the COLUMNS and LINES env vars instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method is deprecated as of 3.2 and will be removed in 4.0. Set the COLUMNS and LINES env vars instead.', __METHOD__), E_USER_DEPRECATED); putenv('COLUMNS='.$width); putenv('LINES='.$height); diff --git a/src/Symfony/Component/Console/Command/Command.php b/src/Symfony/Component/Console/Command/Command.php index 627da5ec8b487..45c26d2a04a84 100644 --- a/src/Symfony/Component/Console/Command/Command.php +++ b/src/Symfony/Component/Console/Command/Command.php @@ -220,7 +220,7 @@ public function run(InputInterface $input, OutputInterface $output) if (function_exists('cli_set_process_title')) { if (!@cli_set_process_title($this->processTitle)) { if ('Darwin' === PHP_OS) { - $output->writeln('Running "cli_get_process_title" as an unprivileged user is not supported on MacOS.'); + $output->writeln('Running "cli_set_process_title" as an unprivileged user is not supported on MacOS.', OutputInterface::VERBOSITY_VERY_VERBOSE); } else { cli_set_process_title($this->processTitle); } diff --git a/src/Symfony/Component/Console/Input/ArgvInput.php b/src/Symfony/Component/Console/Input/ArgvInput.php index fd81981070f47..087974ab7336f 100644 --- a/src/Symfony/Component/Console/Input/ArgvInput.php +++ b/src/Symfony/Component/Console/Input/ArgvInput.php @@ -306,7 +306,7 @@ public function getParameterOption($values, $default = false, $onlyParams = fals while (0 < count($tokens)) { $token = array_shift($tokens); if ($onlyParams && '--' === $token) { - return false; + return $default; } foreach ($values as $value) { diff --git a/src/Symfony/Component/Console/Input/ArrayInput.php b/src/Symfony/Component/Console/Input/ArrayInput.php index 4d9797ba1af0c..595a8a0e8cbc1 100644 --- a/src/Symfony/Component/Console/Input/ArrayInput.php +++ b/src/Symfony/Component/Console/Input/ArrayInput.php @@ -81,7 +81,7 @@ public function getParameterOption($values, $default = false, $onlyParams = fals foreach ($this->parameters as $k => $v) { if ($onlyParams && ('--' === $k || (is_int($k) && '--' === $v))) { - return false; + return $default; } if (is_int($k)) { diff --git a/src/Symfony/Component/Console/Output/OutputInterface.php b/src/Symfony/Component/Console/Output/OutputInterface.php index cddfbb49e075f..ad785a4ce3e09 100644 --- a/src/Symfony/Component/Console/Output/OutputInterface.php +++ b/src/Symfony/Component/Console/Output/OutputInterface.php @@ -33,7 +33,7 @@ interface OutputInterface /** * Writes a message to the output. * - * @param string|array $messages The message as an array of lines or a single string + * @param string|array $messages The message as an array of strings or a single string * @param bool $newline Whether to add a newline * @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL */ @@ -42,7 +42,7 @@ public function write($messages, $newline = false, $options = 0); /** * Writes a message to the output and adds a newline at the end. * - * @param string|array $messages The message as an array of lines of a single string + * @param string|array $messages The message as an array of strings or a single string * @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL */ public function writeln($messages, $options = 0); diff --git a/src/Symfony/Component/Console/Output/StreamOutput.php b/src/Symfony/Component/Console/Output/StreamOutput.php index 5fc5d01e14718..6eb300ea322ed 100644 --- a/src/Symfony/Component/Console/Output/StreamOutput.php +++ b/src/Symfony/Component/Console/Output/StreamOutput.php @@ -93,6 +93,10 @@ protected function doWrite($message, $newline) */ protected function hasColorSupport() { + if ('Hyper' === getenv('TERM_PROGRAM')) { + return true; + } + if (DIRECTORY_SEPARATOR === '\\') { return (function_exists('sapi_windows_vt100_support') && @sapi_windows_vt100_support($this->stream)) diff --git a/src/Symfony/Component/Console/Style/SymfonyStyle.php b/src/Symfony/Component/Console/Style/SymfonyStyle.php index 6cf53cd924255..12cc4fe1e9381 100644 --- a/src/Symfony/Component/Console/Style/SymfonyStyle.php +++ b/src/Symfony/Component/Console/Style/SymfonyStyle.php @@ -269,7 +269,7 @@ public function createProgressBar($max = 0) { $progressBar = parent::createProgressBar($max); - if ('\\' !== DIRECTORY_SEPARATOR) { + if ('\\' !== DIRECTORY_SEPARATOR || 'Hyper' === getenv('TERM_PROGRAM')) { $progressBar->setEmptyBarCharacter('░'); // light shade character \u2591 $progressBar->setProgressCharacter(''); $progressBar->setBarCharacter('▓'); // dark shade character \u2593 diff --git a/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php b/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php index 61d1723e0842e..4cd7ab478f3a4 100644 --- a/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php +++ b/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php @@ -395,25 +395,26 @@ public function testToString() /** * @dataProvider provideGetParameterOptionValues */ - public function testGetParameterOptionEqualSign($argv, $key, $onlyParams, $expected) + public function testGetParameterOptionEqualSign($argv, $key, $default, $onlyParams, $expected) { $input = new ArgvInput($argv); - $this->assertEquals($expected, $input->getParameterOption($key, false, $onlyParams), '->getParameterOption() returns the expected value'); + $this->assertEquals($expected, $input->getParameterOption($key, $default, $onlyParams), '->getParameterOption() returns the expected value'); } public function provideGetParameterOptionValues() { return array( - array(array('app/console', 'foo:bar', '-e', 'dev'), '-e', false, 'dev'), - array(array('app/console', 'foo:bar', '--env=dev'), '--env', false, 'dev'), - array(array('app/console', 'foo:bar', '-e', 'dev'), array('-e', '--env'), false, 'dev'), - array(array('app/console', 'foo:bar', '--env=dev'), array('-e', '--env'), false, 'dev'), - array(array('app/console', 'foo:bar', '--env=dev', '--en=1'), array('--en'), false, '1'), - array(array('app/console', 'foo:bar', '--env=dev', '', '--en=1'), array('--en'), false, '1'), - array(array('app/console', 'foo:bar', '--env', 'val'), '--env', false, 'val'), - array(array('app/console', 'foo:bar', '--env', 'val', '--dummy'), '--env', false, 'val'), - array(array('app/console', 'foo:bar', '--', '--env=dev'), '--env', false, 'dev'), - array(array('app/console', 'foo:bar', '--', '--env=dev'), '--env', true, false), + array(array('app/console', 'foo:bar'), '-e', 'default', false, 'default'), + array(array('app/console', 'foo:bar', '-e', 'dev'), '-e', 'default', false, 'dev'), + array(array('app/console', 'foo:bar', '--env=dev'), '--env', 'default', false, 'dev'), + array(array('app/console', 'foo:bar', '-e', 'dev'), array('-e', '--env'), 'default', false, 'dev'), + array(array('app/console', 'foo:bar', '--env=dev'), array('-e', '--env'), 'default', false, 'dev'), + array(array('app/console', 'foo:bar', '--env=dev', '--en=1'), array('--en'), 'default', false, '1'), + array(array('app/console', 'foo:bar', '--env=dev', '', '--en=1'), array('--en'), 'default', false, '1'), + array(array('app/console', 'foo:bar', '--env', 'val'), '--env', 'default', false, 'val'), + array(array('app/console', 'foo:bar', '--env', 'val', '--dummy'), '--env', 'default', false, 'val'), + array(array('app/console', 'foo:bar', '--', '--env=dev'), '--env', 'default', false, 'dev'), + array(array('app/console', 'foo:bar', '--', '--env=dev'), '--env', 'default', true, 'default'), ); } diff --git a/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php b/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php index 6b443e0b2abae..34b67ac7f5235 100644 --- a/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php +++ b/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php @@ -47,14 +47,14 @@ public function testGetParameterOption() { $input = new ArrayInput(array('name' => 'Fabien', '--foo' => 'bar')); $this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name'); - $this->assertFalse($input->getParameterOption('--bar'), '->getParameterOption() returns the default if an option is not present in the passed parameters'); + $this->assertEquals('default', $input->getParameterOption('--bar', 'default'), '->getParameterOption() returns the default value if an option is not present in the passed parameters'); $input = new ArrayInput(array('Fabien', '--foo' => 'bar')); $this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name'); $input = new ArrayInput(array('--foo', '--', '--bar' => 'woop')); $this->assertEquals('woop', $input->getParameterOption('--bar'), '->getParameterOption() returns the correct value if an option is present in the passed parameters'); - $this->assertFalse($input->getParameterOption('--bar', false, true), '->getParameterOption() returns false if an option is present in the passed parameters after an end of options signal'); + $this->assertEquals('default', $input->getParameterOption('--bar', 'default', true), '->getParameterOption() returns the default value if an option is present in the passed parameters after an end of options signal'); } public function testParseArguments() diff --git a/src/Symfony/Component/Debug/ExceptionHandler.php b/src/Symfony/Component/Debug/ExceptionHandler.php index f22b70f6e8c6f..4a324d6fe5b22 100644 --- a/src/Symfony/Component/Debug/ExceptionHandler.php +++ b/src/Symfony/Component/Debug/ExceptionHandler.php @@ -208,48 +208,54 @@ public function getContent(FlattenException $exception) $title = 'Whoops, looks like something went wrong.'; } + if (!$this->debug) { + return << +

$title

+ +EOF; + } + $content = ''; - if ($this->debug) { - try { - $count = count($exception->getAllPrevious()); - $total = $count + 1; - foreach ($exception->toArray() as $position => $e) { - $ind = $count - $position + 1; - $class = $this->formatClass($e['class']); - $message = nl2br($this->escapeHtml($e['message'])); - $content .= sprintf(<<<'EOF' -
- - - + try { + $count = count($exception->getAllPrevious()); + $total = $count + 1; + foreach ($exception->toArray() as $position => $e) { + $ind = $count - $position + 1; + $class = $this->formatClass($e['class']); + $message = nl2br($this->escapeHtml($e['message'])); + $content .= sprintf(<<<'EOF' +
+
-

- (%d/%d) - %s -

-

%s

-
+ + EOF - , $ind, $total, $class, $message); - foreach ($e['trace'] as $trace) { - $content .= '\n"; + , $ind, $total, $class, $message); + foreach ($e['trace'] as $trace) { + $content .= '\n
+

+ (%d/%d) + %s +

+

%s

+
'; - if ($trace['function']) { - $content .= sprintf('at %s%s%s(%s)', $this->formatClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args'])); - } - if (isset($trace['file']) && isset($trace['line'])) { - $content .= $this->formatPath($trace['file'], $trace['line']); - } - $content .= "
'; + if ($trace['function']) { + $content .= sprintf('at %s%s%s(%s)', $this->formatClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args'])); } - - $content .= "
\n
\n"; - } - } catch (\Exception $e) { - // something nasty happened and we cannot throw an exception anymore - if ($this->debug) { - $title = sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $this->escapeHtml($e->getMessage())); - } else { - $title = 'Whoops, looks like something went wrong.'; + if (isset($trace['file']) && isset($trace['line'])) { + $content .= $this->formatPath($trace['file'], $trace['line']); + } + $content .= "\n"; } + + $content .= "\n\n\n"; + } + } catch (\Exception $e) { + // something nasty happened and we cannot throw an exception anymore + if ($this->debug) { + $title = sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $this->escapeHtml($e->getMessage())); + } else { + $title = 'Whoops, looks like something went wrong.'; } } @@ -278,6 +284,14 @@ public function getContent(FlattenException $exception) */ public function getStylesheet(FlattenException $exception) { + if (!$this->debug) { + return <<<'EOF' + body { background-color: #fff; color: #222; font: 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; margin: 0; } + .container { margin: 30px; max-width: 600px; } + h1 { color: #dc3545; font-size: 24px; } +EOF; + } + return <<<'EOF' body { background-color: #F9F9F9; color: #222; font: 14px/1.4 Helvetica, Arial, sans-serif; margin: 0; padding-bottom: 45px; } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php index 15110261a2252..e02f61a8f4ecc 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php @@ -117,9 +117,11 @@ private function processDefinition(ContainerBuilder $container, $id, Definition } } + $definition->setBindings($bindings); + // reset fields with "merge" behavior $abstract - ->setBindings($bindings) + ->setBindings(array()) ->setArguments(array()) ->setMethodCalls(array()) ->setDecoratedService(null) diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index dc2d36053ee0d..8d556805c78f9 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -637,10 +637,10 @@ private function doGet($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_ * the parameters passed to the container constructor to have precedence * over the loaded ones. * - * $container = new ContainerBuilder(array('foo' => 'bar')); + * $container = new ContainerBuilder(new ParameterBag(array('foo' => 'bar'))); * $loader = new LoaderXXX($container); * $loader->load('resource_name'); - * $container->register('foo', new stdClass()); + * $container->register('foo', 'stdClass'); * * In the above example, even if the loaded resource defines a foo * parameter, the value will still be 'bar' as defined in the ContainerBuilder diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 7c493f62e365c..d7a345bd113a0 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -1898,8 +1898,10 @@ private function getServiceCall($id, Reference $reference = null) return '$this'; } - if ($this->container->hasDefinition($id) && ($definition = $this->container->getDefinition($id)) && !$definition->isSynthetic()) { - if (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) { + if ($this->container->hasDefinition($id) && $definition = $this->container->getDefinition($id)) { + if ($definition->isSynthetic()) { + $code = sprintf('$this->get(\'%s\'%s)', $id, null !== $reference ? ', '.$reference->getInvalidBehavior() : ''); + } elseif (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) { $code = 'null'; if (!$definition->isShared()) { return $code; diff --git a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php index f76857224a444..0478af3107cbb 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php @@ -102,7 +102,7 @@ private function addService($id, Definition $definition) } if ($definition->isDeprecated()) { - $code .= sprintf(" deprecated: %s\n", $definition->getDeprecationMessage('%service_id%')); + $code .= sprintf(" deprecated: %s\n", $this->dumper->dump($definition->getDeprecationMessage('%service_id%'))); } if ($definition->isAutowired()) { diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php index 21a2810578e97..39078dbaf6576 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\DependencyInjection\Tests\Compiler; use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Argument\BoundArgument; use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\Compiler\ResolveInstanceofConditionalsPass; use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass; @@ -250,4 +251,18 @@ public function testMergeReset() $this->assertEmpty($abstract->getTags()); $this->assertTrue($abstract->isAbstract()); } + + public function testBindings() + { + $container = new ContainerBuilder(); + $def = $container->register('foo', self::class)->setBindings(array('$toto' => 123)); + $def->setInstanceofConditionals(array(parent::class => new ChildDefinition(''))); + + (new ResolveInstanceofConditionalsPass())->process($container); + + $bindings = $container->getDefinition('foo')->getBindings(); + $this->assertSame(array('$toto'), array_keys($bindings)); + $this->assertInstanceOf(BoundArgument::class, $bindings['$toto']); + $this->assertSame(123, $bindings['$toto']->getValues()[0]); + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index f2e8368455f66..d8e7203028b0a 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -1434,6 +1434,21 @@ public function testArgumentsHaveHigherPriorityThanBindings() $this->assertSame('via-argument', $container->get('foo')->class1->identifier); $this->assertSame('via-bindings', $container->get('foo')->class2->identifier); } + + public function testUninitializedSyntheticReference() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->setPublic(true)->setSynthetic(true); + $container->register('bar', 'stdClass')->setPublic(true)->setShared(false) + ->setProperty('foo', new Reference('foo', ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)); + + $container->compile(); + + $this->assertEquals((object) array('foo' => null), $container->get('bar')); + + $container->set('foo', (object) array(123)); + $this->assertEquals((object) array('foo' => (object) array(123)), $container->get('bar')); + } } class FooClass diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 319561cf38941..161bf18aaf2e5 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -913,6 +913,29 @@ public function testDumpHandlesObjectClassNames() $this->assertInstanceOf('stdClass', $container->get('bar')); } + public function testUninitializedSyntheticReference() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->setPublic(true)->setSynthetic(true); + $container->register('bar', 'stdClass')->setPublic(true)->setShared(false) + ->setProperty('foo', new Reference('foo', ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE)); + + $container->compile(); + + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump(array( + 'class' => 'Symfony_DI_PhpDumper_Test_UninitializedSyntheticReference', + 'inline_class_loader_parameter' => 'inline_requires', + ))); + + $container = new \Symfony_DI_PhpDumper_Test_UninitializedSyntheticReference(); + + $this->assertEquals((object) array('foo' => null), $container->get('bar')); + + $container->set('foo', (object) array(123)); + $this->assertEquals((object) array('foo' => (object) array(123)), $container->get('bar')); + } + /** * @group legacy * @expectedDeprecation The "private" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead. diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/prototype.expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/prototype.expected.yml index 5394535caf1d8..ebfe087d779cf 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/prototype.expected.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/prototype.expected.yml @@ -10,7 +10,7 @@ services: tags: - { name: foo } - { name: baz } - deprecated: %service_id% + deprecated: '%service_id%' arguments: [1] factory: f Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar: @@ -19,7 +19,7 @@ services: tags: - { name: foo } - { name: baz } - deprecated: %service_id% + deprecated: '%service_id%' lazy: true arguments: [1] factory: f diff --git a/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php b/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php index a3539bc1b421e..8562181a2915c 100644 --- a/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php +++ b/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php @@ -75,7 +75,7 @@ public function isDisabled() /** * Sets the value of the field. * - * @param string $value The value of the field + * @param string|array $value The value of the field */ public function select($value) { diff --git a/src/Symfony/Component/Filesystem/LockHandler.php b/src/Symfony/Component/Filesystem/LockHandler.php index 81c4ce64c72ad..8e0eb741213b2 100644 --- a/src/Symfony/Component/Filesystem/LockHandler.php +++ b/src/Symfony/Component/Filesystem/LockHandler.php @@ -83,7 +83,7 @@ public function lock($blocking = false) if (!$this->handle = fopen($this->file, 'r+') ?: fopen($this->file, 'r')) { if ($this->handle = fopen($this->file, 'x')) { - chmod($this->file, 0444); + chmod($this->file, 0666); } elseif (!$this->handle = fopen($this->file, 'r+') ?: fopen($this->file, 'r')) { usleep(100); // Give some time for chmod() to complete $this->handle = fopen($this->file, 'r+') ?: fopen($this->file, 'r'); diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php b/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php index a1c214c8bcd29..c562da0bf618f 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php @@ -95,7 +95,7 @@ public function getBlockPrefix() */ public function loadChoiceList($value = null) { - @trigger_error(sprintf('Method "%s" is deprecated since Symfony 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED); if (null !== $this->choiceList) { return $this->choiceList; @@ -111,7 +111,7 @@ public function loadChoiceList($value = null) */ public function loadChoicesForValues(array $values, $value = null) { - @trigger_error(sprintf('Method "%s" is deprecated since Symfony 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED); // Optimize $values = array_filter($values); @@ -134,7 +134,7 @@ public function loadChoicesForValues(array $values, $value = null) */ public function loadValuesForChoices(array $choices, $value = null) { - @trigger_error(sprintf('Method "%s" is deprecated since Symfony 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED); // Optimize $choices = array_filter($choices); diff --git a/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php b/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php index 448f7cb815dca..cd09530b1d03b 100644 --- a/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php +++ b/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php @@ -19,6 +19,7 @@ use Symfony\Component\Validator\ConstraintViolationInterface; use Symfony\Component\VarDumper\Caster\Caster; use Symfony\Component\VarDumper\Caster\ClassStub; +use Symfony\Component\VarDumper\Caster\StubCaster; use Symfony\Component\VarDumper\Cloner\Stub; /** @@ -262,6 +263,7 @@ protected function getCasters() Caster::PREFIX_VIRTUAL.'type_class' => new ClassStub(get_class($f->getConfig()->getType()->getInnerType())), ); }, + FormView::class => array(StubCaster::class, 'cutInternals'), ConstraintViolationInterface::class => function (ConstraintViolationInterface $v, array $a) { return array( Caster::PREFIX_VIRTUAL.'root' => $v->getRoot(), diff --git a/src/Symfony/Component/Form/FormConfigBuilder.php b/src/Symfony/Component/Form/FormConfigBuilder.php index f6cdff5310494..9e08e31a54181 100644 --- a/src/Symfony/Component/Form/FormConfigBuilder.php +++ b/src/Symfony/Component/Form/FormConfigBuilder.php @@ -138,7 +138,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface private $data; /** - * @var string + * @var string|null */ private $dataClass; @@ -181,7 +181,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface * Creates an empty form configuration. * * @param string|int $name The form name - * @param string $dataClass The class of the form's data + * @param string|null $dataClass The class of the form's data * @param EventDispatcherInterface $dispatcher The event dispatcher * @param array $options The form options * diff --git a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/default_option_with_normalizer.txt b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/default_option_with_normalizer.txt index c622057cdbdfd..391c3e694d974 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/default_option_with_normalizer.txt +++ b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/default_option_with_normalizer.txt @@ -15,9 +15,9 @@ Symfony\Component\Form\Extension\Core\Type\ChoiceType (choice_translation_domain ---------------- --------------------%s Allowed values - %s ---------------- --------------------%s - Normalizer Closure { %s + Normalizer Closure%s{%w parameters: 2 %s - file: "%s%eExtension%eCore%eType%eChoiceType.php" + file: "%s%eExtension%eCore%eType%eChoiceType.php"%w line: "%s to %s" %s } %s ---------------- --------------------%s diff --git a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/overridden_option_with_default_closures.txt b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/overridden_option_with_default_closures.txt index 231d1319bbeff..846d6f384684c 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/overridden_option_with_default_closures.txt +++ b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/overridden_option_with_default_closures.txt @@ -8,14 +8,14 @@ Symfony\Component\Form\Tests\Console\Descriptor\FooType (empty_data) Default Value: null %s %s Closure(s): [ %s - Closure { %s + Closure%s{%w parameters: 1 %s - file: "%s%eExtension%eCore%eType%eFormType.php" + file: "%s%eExtension%eCore%eType%eFormType.php"%w line: "%s to %s" %s }, %s - Closure { %s + Closure%s{%w parameters: 2 %s - file: "%s%eTests%eConsole%eDescriptor%eAbstractDescriptorTest.php" + file: "%s%eTests%eConsole%eDescriptor%eAbstractDescriptorTest.php"%w line: "%s to %s" %s } %s ] %s diff --git a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/required_option_with_allowed_values.txt b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/required_option_with_allowed_values.txt index da3e6c82d8b1a..8cc88a550ab70 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/required_option_with_allowed_values.txt +++ b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/required_option_with_allowed_values.txt @@ -16,9 +16,9 @@ Symfony\Component\Form\Tests\Console\Descriptor\FooType (foo) "baz" %s ] %s ---------------- --------------------%s - Normalizer Closure { %s + Normalizer Closure%s{%w parameters: 2 %s - file: "%s%eTests%eConsole%eDescriptor%eAbstractDescriptorTest.php" + file: "%s%eTests%eConsole%eDescriptor%eAbstractDescriptorTest.php"%w line: "%s to %s" %s } %s ---------------- --------------------%s diff --git a/src/Symfony/Component/HttpFoundation/HeaderBag.php b/src/Symfony/Component/HttpFoundation/HeaderBag.php index 7aaa52ae56c11..d811b52758269 100644 --- a/src/Symfony/Component/HttpFoundation/HeaderBag.php +++ b/src/Symfony/Component/HttpFoundation/HeaderBag.php @@ -101,11 +101,11 @@ public function add(array $headers) /** * Returns a header value by name. * - * @param string $key The header name - * @param string|string[] $default The default value - * @param bool $first Whether to return the first value or all header values + * @param string $key The header name + * @param string|string[]|null $default The default value + * @param bool $first Whether to return the first value or all header values * - * @return string|string[] The first header value or default value if $first is true, an array of values otherwise + * @return string|string[]|null The first header value or default value if $first is true, an array of values otherwise */ public function get($key, $default = null, $first = true) { diff --git a/src/Symfony/Component/HttpFoundation/Response.php b/src/Symfony/Component/HttpFoundation/Response.php index e05194b01818a..7c1edd5a5ed48 100644 --- a/src/Symfony/Component/HttpFoundation/Response.php +++ b/src/Symfony/Component/HttpFoundation/Response.php @@ -64,7 +64,12 @@ class Response const HTTP_UNPROCESSABLE_ENTITY = 422; // RFC4918 const HTTP_LOCKED = 423; // RFC4918 const HTTP_FAILED_DEPENDENCY = 424; // RFC4918 + + /** + * @deprecated + */ const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425; // RFC2817 + const HTTP_TOO_EARLY = 425; // RFC-ietf-httpbis-replay-04 const HTTP_UPGRADE_REQUIRED = 426; // RFC2817 const HTTP_PRECONDITION_REQUIRED = 428; // RFC6585 const HTTP_TOO_MANY_REQUESTS = 429; // RFC6585 @@ -169,7 +174,7 @@ class Response 422 => 'Unprocessable Entity', // RFC4918 423 => 'Locked', // RFC4918 424 => 'Failed Dependency', // RFC4918 - 425 => 'Reserved for WebDAV advanced collections expired proposal', // RFC2817 + 425 => 'Too Early', // RFC-ietf-httpbis-replay-04 426 => 'Upgrade Required', // RFC2817 428 => 'Precondition Required', // RFC6585 429 => 'Too Many Requests', // RFC6585 @@ -328,12 +333,17 @@ public function sendHeaders() } // headers - foreach ($this->headers->allPreserveCase() as $name => $values) { + foreach ($this->headers->allPreserveCaseWithoutCookies() as $name => $values) { foreach ($values as $value) { header($name.': '.$value, false, $this->statusCode); } } + // cookies + foreach ($this->headers->getCookies() as $cookie) { + header('Set-Cookie: '.$cookie->getName().strstr($cookie, '='), false, $this->statusCode); + } + // status header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText), true, $this->statusCode); diff --git a/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php b/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php index abbf37ee7c33c..f9df69e90782f 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php +++ b/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php @@ -124,7 +124,13 @@ protected function &resolveAttributePath($name, $writeContext = false) foreach ($parts as $part) { if (null !== $array && !array_key_exists($part, $array)) { - $array[$part] = $writeContext ? array() : null; + if (!$writeContext) { + $null = null; + + return $null; + } + + $array[$part] = array(); } $array = &$array[$part]; diff --git a/src/Symfony/Component/HttpFoundation/Session/Flash/FlashBagInterface.php b/src/Symfony/Component/HttpFoundation/Session/Flash/FlashBagInterface.php index 80e97f17cdff3..f53c9dae6c0aa 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Flash/FlashBagInterface.php +++ b/src/Symfony/Component/HttpFoundation/Session/Flash/FlashBagInterface.php @@ -24,7 +24,7 @@ interface FlashBagInterface extends SessionBagInterface * Adds a flash message for type. * * @param string $type - * @param string $message + * @param mixed $message */ public function add($type, $message); diff --git a/src/Symfony/Component/HttpFoundation/Session/Session.php b/src/Symfony/Component/HttpFoundation/Session/Session.php index f0379c1697b82..c0978d552f197 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Session.php +++ b/src/Symfony/Component/HttpFoundation/Session/Session.php @@ -54,8 +54,6 @@ public function __construct(SessionStorageInterface $storage = null, AttributeBa */ public function start() { - ++$this->usageIndex; - return $this->storage->start(); } @@ -160,7 +158,9 @@ public function getUsageIndex() */ public function isEmpty() { - ++$this->usageIndex; + if ($this->isStarted()) { + ++$this->usageIndex; + } foreach ($this->data as &$data) { if (!empty($data)) { return false; @@ -185,8 +185,6 @@ public function invalidate($lifetime = null) */ public function migrate($destroy = false, $lifetime = null) { - ++$this->usageIndex; - return $this->storage->regenerate($destroy, $lifetime); } @@ -195,8 +193,6 @@ public function migrate($destroy = false, $lifetime = null) */ public function save() { - ++$this->usageIndex; - $this->storage->save(); } diff --git a/src/Symfony/Component/HttpFoundation/Session/SessionBagProxy.php b/src/Symfony/Component/HttpFoundation/Session/SessionBagProxy.php index 88005ee092e2a..3504bdfe7b4a6 100644 --- a/src/Symfony/Component/HttpFoundation/Session/SessionBagProxy.php +++ b/src/Symfony/Component/HttpFoundation/Session/SessionBagProxy.php @@ -44,6 +44,9 @@ public function getBag() */ public function isEmpty() { + if (!isset($this->data[$this->bag->getStorageKey()])) { + return true; + } ++$this->usageIndex; return empty($this->data[$this->bag->getStorageKey()]); @@ -81,8 +84,6 @@ public function getStorageKey() */ public function clear() { - ++$this->usageIndex; - return $this->bag->clear(); } } diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/WriteCheckSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/WriteCheckSessionHandler.php index 1541ec4e0aa49..127e47f2107a3 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/WriteCheckSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/WriteCheckSessionHandler.php @@ -11,8 +11,6 @@ namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; -@trigger_error(sprintf('The %s class is deprecated since Symfony 3.4 and will be removed in 4.0. Implement `SessionUpdateTimestampHandlerInterface` or extend `AbstractSessionHandler` instead.', WriteCheckSessionHandler::class), E_USER_DEPRECATED); - /** * Wraps another SessionHandlerInterface to only write the session when it has been modified. * @@ -31,6 +29,8 @@ class WriteCheckSessionHandler implements \SessionHandlerInterface public function __construct(\SessionHandlerInterface $wrappedSessionHandler) { + @trigger_error(sprintf('The %s class is deprecated since Symfony 3.4 and will be removed in 4.0. Implement `SessionUpdateTimestampHandlerInterface` or extend `AbstractSessionHandler` instead.', self::class), E_USER_DEPRECATED); + $this->wrappedSessionHandler = $wrappedSessionHandler; } diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php index 6416a03fdf4b5..41410bd323d8f 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php @@ -411,8 +411,6 @@ public function setSaveHandler($saveHandler = null) } if ($this->saveHandler instanceof SessionHandlerProxy) { - session_set_save_handler($this->saveHandler->getHandler(), false); - } elseif ($this->saveHandler instanceof \SessionHandlerInterface) { session_set_save_handler($this->saveHandler, false); } } diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Proxy/SessionHandlerProxy.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Proxy/SessionHandlerProxy.php index 53c1209a1c07d..b11cc397a0973 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Proxy/SessionHandlerProxy.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Proxy/SessionHandlerProxy.php @@ -14,7 +14,7 @@ /** * @author Drak */ -class SessionHandlerProxy extends AbstractProxy implements \SessionHandlerInterface +class SessionHandlerProxy extends AbstractProxy implements \SessionHandlerInterface, \SessionUpdateTimestampHandlerInterface { protected $handler; @@ -82,4 +82,20 @@ public function gc($maxlifetime) { return (bool) $this->handler->gc($maxlifetime); } + + /** + * {@inheritdoc} + */ + public function validateId($sessionId) + { + return !$this->handler instanceof \SessionUpdateTimestampHandlerInterface || $this->handler->validateId($sessionId); + } + + /** + * {@inheritdoc} + */ + public function updateTimestamp($sessionId, $data) + { + return $this->handler instanceof \SessionUpdateTimestampHandlerInterface ? $this->handler->updateTimestamp($sessionId, $data) : $this->write($sessionId, $data); + } } diff --git a/src/Symfony/Component/HttpFoundation/StreamedResponse.php b/src/Symfony/Component/HttpFoundation/StreamedResponse.php index 92868d33e4814..1fb2b46af895d 100644 --- a/src/Symfony/Component/HttpFoundation/StreamedResponse.php +++ b/src/Symfony/Component/HttpFoundation/StreamedResponse.php @@ -141,4 +141,16 @@ public function getContent() { return false; } + + /** + * {@inheritdoc} + * + * @return $this + */ + public function setNotModified() + { + $this->setCallback(function () {}); + + return parent::setNotModified(); + } } diff --git a/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_urlencode.expected b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_urlencode.expected index 4e9c4c075f5ed..14e44a398af66 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_urlencode.expected +++ b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_urlencode.expected @@ -4,7 +4,7 @@ Array [0] => Content-Type: text/plain; charset=utf-8 [1] => Cache-Control: no-cache, private [2] => Date: Sat, 12 Nov 1955 20:04:00 GMT - [3] => Set-Cookie: %3F%2A%28%29%3A%40%26%2B%24%2F%25%23%5B%5D=%3F%2A%28%29%3A%40%26%2B%24%2F%25%23%5B%5D; path=/ + [3] => Set-Cookie: ?*():@&+$/%#[]=%3F%2A%28%29%3A%40%26%2B%24%2F%25%23%5B%5D; path=/ [4] => Set-Cookie: ?*():@&+$/%#[]=%3F%2A%28%29%3A%40%26%2B%24%2F%25%23%5B%5D; path=/ ) shutdown diff --git a/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php index 350d972a94588..03a9811ec38dc 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php @@ -126,7 +126,7 @@ public function testMustRevalidateWithProxyRevalidateCacheControlHeader() public function testSetNotModified() { - $response = new Response(); + $response = new Response('foo'); $modified = $response->setNotModified(); $this->assertObjectHasAttribute('headers', $modified); $this->assertObjectHasAttribute('content', $modified); @@ -135,6 +135,11 @@ public function testSetNotModified() $this->assertObjectHasAttribute('statusText', $modified); $this->assertObjectHasAttribute('charset', $modified); $this->assertEquals(304, $modified->getStatusCode()); + + ob_start(); + $modified->sendContent(); + $string = ob_get_clean(); + $this->assertEmpty($string); } public function testIsSuccessful() diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php index f074ce1b26261..ec4cd5ad1a146 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php @@ -82,6 +82,17 @@ public function testHas($key, $value, $exists) $this->assertEquals($exists, $this->bag->has($key)); } + /** + * @dataProvider attributesProvider + */ + public function testHasNoSideEffect($key, $value, $expected) + { + $expected = json_encode($this->bag->all()); + $this->bag->has($key); + + $this->assertEquals($expected, json_encode($this->bag->all())); + } + /** * @dataProvider attributesProvider */ @@ -96,6 +107,17 @@ public function testGetDefaults() $this->assertEquals('default', $this->bag->get('user2.login', 'default')); } + /** + * @dataProvider attributesProvider + */ + public function testGetNoSideEffect($key, $value, $expected) + { + $expected = json_encode($this->bag->all()); + $this->bag->get($key); + + $this->assertEquals($expected, json_encode($this->bag->all())); + } + /** * @dataProvider attributesProvider */ diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Flash/FlashBagTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Flash/FlashBagTest.php index c4e75b1b18b40..905a1f7517306 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Flash/FlashBagTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Flash/FlashBagTest.php @@ -74,6 +74,18 @@ public function testPeek() $this->assertEquals(array('A previous flash message'), $this->bag->peek('notice')); } + public function testAdd() + { + $tab = array('bar' => 'baz'); + $this->bag->add('string_message', 'lorem'); + $this->bag->add('object_message', new \stdClass()); + $this->bag->add('array_message', $tab); + + $this->assertEquals(array('lorem'), $this->bag->get('string_message')); + $this->assertEquals(array(new \stdClass()), $this->bag->get('object_message')); + $this->assertEquals(array($tab), $this->bag->get('array_message')); + } + public function testGet() { $this->assertEquals(array(), $this->bag->get('non_existing')); @@ -112,6 +124,19 @@ public function testKeys() $this->assertEquals(array('notice'), $this->bag->keys()); } + public function testSetAll() + { + $this->bag->add('one_flash', 'Foo'); + $this->bag->add('another_flash', 'Bar'); + $this->assertTrue($this->bag->has('one_flash')); + $this->assertTrue($this->bag->has('another_flash')); + $this->bag->setAll(array('unique_flash' => 'FooBar')); + $this->assertFalse($this->bag->has('one_flash')); + $this->assertFalse($this->bag->has('another_flash')); + $this->assertSame(array('unique_flash' => 'FooBar'), $this->bag->all()); + $this->assertSame(array(), $this->bag->all()); + } + public function testPeekAll() { $this->bag->set('notice', 'Foo'); diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php index 682825356a724..0b48250e01010 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php @@ -121,4 +121,37 @@ public function testGc() $this->proxy->gc(86400); } + + /** + * @requires PHPUnit 5.1 + */ + public function testValidateId() + { + $mock = $this->getMockBuilder(array('SessionHandlerInterface', 'SessionUpdateTimestampHandlerInterface'))->getMock(); + $mock->expects($this->once()) + ->method('validateId'); + + $proxy = new SessionHandlerProxy($mock); + $proxy->validateId('id'); + + $this->assertTrue($this->proxy->validateId('id')); + } + + /** + * @requires PHPUnit 5.1 + */ + public function testUpdateTimestamp() + { + $mock = $this->getMockBuilder(array('SessionHandlerInterface', 'SessionUpdateTimestampHandlerInterface'))->getMock(); + $mock->expects($this->once()) + ->method('updateTimestamp'); + + $proxy = new SessionHandlerProxy($mock); + $proxy->updateTimestamp('id', 'data'); + + $this->mock->expects($this->once()) + ->method('write'); + + $this->proxy->updateTimestamp('id', 'data'); + } } diff --git a/src/Symfony/Component/HttpFoundation/Tests/StreamedResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/StreamedResponseTest.php index c2ded996fab4f..699222e37916e 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/StreamedResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/StreamedResponseTest.php @@ -123,4 +123,22 @@ public function testReturnThis() $this->assertInstanceOf('Symfony\Component\HttpFoundation\StreamedResponse', $response->sendHeaders()); $this->assertInstanceOf('Symfony\Component\HttpFoundation\StreamedResponse', $response->sendHeaders()); } + + public function testSetNotModified() + { + $response = new StreamedResponse(function () { echo 'foo'; }); + $modified = $response->setNotModified(); + $this->assertObjectHasAttribute('headers', $modified); + $this->assertObjectHasAttribute('content', $modified); + $this->assertObjectHasAttribute('version', $modified); + $this->assertObjectHasAttribute('statusCode', $modified); + $this->assertObjectHasAttribute('statusText', $modified); + $this->assertObjectHasAttribute('charset', $modified); + $this->assertEquals(304, $modified->getStatusCode()); + + ob_start(); + $modified->sendContent(); + $string = ob_get_clean(); + $this->assertEmpty($string); + } } diff --git a/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php b/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php index b9d9f9fa254d9..0811fdf772a6b 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php @@ -101,7 +101,7 @@ public function getController(Request $request) */ public function getArguments(Request $request, $controller) { - @trigger_error(sprintf('%s is deprecated as of 3.1 and will be removed in 4.0. Implement the %s and inject it in the HttpKernel instead.', __METHOD__, ArgumentResolverInterface::class), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method is deprecated as of 3.1 and will be removed in 4.0. Implement the %s and inject it in the HttpKernel instead.', __METHOD__, ArgumentResolverInterface::class), E_USER_DEPRECATED); if (is_array($controller)) { $r = new \ReflectionMethod($controller[0], $controller[1]); @@ -126,7 +126,7 @@ public function getArguments(Request $request, $controller) */ protected function doGetArguments(Request $request, $controller, array $parameters) { - @trigger_error(sprintf('%s is deprecated as of 3.1 and will be removed in 4.0. Implement the %s and inject it in the HttpKernel instead.', __METHOD__, ArgumentResolverInterface::class), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method is deprecated as of 3.1 and will be removed in 4.0. Implement the %s and inject it in the HttpKernel instead.', __METHOD__, ArgumentResolverInterface::class), E_USER_DEPRECATED); $attributes = $request->attributes->all(); $arguments = array(); diff --git a/src/Symfony/Component/HttpKernel/Controller/TraceableControllerResolver.php b/src/Symfony/Component/HttpKernel/Controller/TraceableControllerResolver.php index 750107714026d..bfb770a0d039e 100644 --- a/src/Symfony/Component/HttpKernel/Controller/TraceableControllerResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/TraceableControllerResolver.php @@ -60,7 +60,7 @@ public function getController(Request $request) */ public function getArguments(Request $request, $controller) { - @trigger_error(sprintf('The %s method is deprecated as of 3.1 and will be removed in 4.0. Please use the %s instead.', __METHOD__, TraceableArgumentResolver::class), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method is deprecated as of 3.1 and will be removed in 4.0. Please use the %s instead.', __METHOD__, TraceableArgumentResolver::class), E_USER_DEPRECATED); $ret = $this->argumentResolver->getArguments($request, $controller); diff --git a/src/Symfony/Component/HttpKernel/Event/GetResponseEvent.php b/src/Symfony/Component/HttpKernel/Event/GetResponseEvent.php index f7745ea3dc160..c25a0f1cf1a1a 100644 --- a/src/Symfony/Component/HttpKernel/Event/GetResponseEvent.php +++ b/src/Symfony/Component/HttpKernel/Event/GetResponseEvent.php @@ -29,7 +29,7 @@ class GetResponseEvent extends KernelEvent /** * Returns the response object. * - * @return Response + * @return Response|null */ public function getResponse() { diff --git a/src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php b/src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php index 82061fd6ea0fc..75f810e988345 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php @@ -71,6 +71,13 @@ public function onKernelResponse(FilterResponseEvent $event) if ($session instanceof Session ? !$session->isEmpty() || (null !== $this->sessionId && $session->getId() !== $this->sessionId) : $wasStarted) { $params = session_get_cookie_params(); + + foreach ($event->getResponse()->headers->getCookies() as $cookie) { + if ($session->getName() === $cookie->getName() && $params['path'] === $cookie->getPath() && $params['domain'] == $cookie->getDomain()) { + return; + } + } + $event->getResponse()->headers->setCookie(new Cookie($session->getName(), $session->getId(), 0 === $params['lifetime'] ? 0 : time() + $params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly'])); $this->sessionId = $session->getId(); } diff --git a/src/Symfony/Component/HttpKernel/Fragment/HIncludeFragmentRenderer.php b/src/Symfony/Component/HttpKernel/Fragment/HIncludeFragmentRenderer.php index 7e957d4c95f71..ab7a83fa573a7 100644 --- a/src/Symfony/Component/HttpKernel/Fragment/HIncludeFragmentRenderer.php +++ b/src/Symfony/Component/HttpKernel/Fragment/HIncludeFragmentRenderer.php @@ -131,7 +131,7 @@ private function templateExists($template) if ($this->templating instanceof EngineInterface) { try { return $this->templating->exists($template); - } catch (\InvalidArgumentException $e) { + } catch (\Exception $e) { return false; } } diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 3c740e45ef5c1..be20edd8ad3e1 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -67,11 +67,11 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private $requestStackSize = 0; private $resetServices = false; - const VERSION = '3.4.12'; - const VERSION_ID = 30412; + const VERSION = '3.4.13'; + const VERSION_ID = 30413; const MAJOR_VERSION = 3; const MINOR_VERSION = 4; - const RELEASE_VERSION = 12; + const RELEASE_VERSION = 13; const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2020'; @@ -232,7 +232,7 @@ public function getBundle($name, $first = true/*, $noDeprecation = false */) } if (!$first && !$noDeprecation) { - @trigger_error(sprintf('Passing "false" as the second argument to %s() is deprecated as of 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('Passing "false" as the second argument to "%s()" is deprecated as of 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED); } if (!isset($this->bundleMap[$name])) { @@ -734,7 +734,7 @@ protected function getKernelParameters() protected function getEnvParameters() { if (0 === func_num_args() || func_get_arg(0)) { - @trigger_error(sprintf('The %s() method is deprecated as of 3.3 and will be removed in 4.0. Use the %%env()%% syntax to get the value of any environment variable from configuration files instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method is deprecated as of 3.3 and will be removed in 4.0. Use the %%env()%% syntax to get the value of any environment variable from configuration files instead.', __METHOD__), E_USER_DEPRECATED); } $parameters = array(); diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php index 22a2b71239874..01f0a3b8641a2 100644 --- a/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php @@ -106,6 +106,36 @@ public function testEmptySessionWithNewSessionIdDoesSendCookie() $this->assertNotEmpty($response->headers->getCookies()); } + /** + * @dataProvider anotherCookieProvider + */ + public function testSessionWithNewSessionIdAndNewCookieDoesNotSendAnotherCookie($existing, array $expected) + { + $this->sessionHasBeenStarted(); + $this->sessionIsEmpty(); + $this->fixSessionId('456'); + + $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(); + $request = Request::create('/', 'GET', array(), array('MOCKSESSID' => '123')); + $event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST); + $this->listener->onKernelRequest($event); + + $response = new Response('', 200, array('Set-Cookie' => $existing)); + + $response = $this->filterResponse(new Request(), HttpKernelInterface::MASTER_REQUEST, $response); + + $this->assertSame($expected, $response->headers->get('Set-Cookie', null, false)); + } + + public function anotherCookieProvider() + { + return array( + 'same' => array('MOCKSESSID=789; path=/', array('MOCKSESSID=789; path=/')), + 'different domain' => array('MOCKSESSID=789; path=/; domain=example.com', array('MOCKSESSID=789; path=/; domain=example.com', 'MOCKSESSID=456; path=/')), + 'different path' => array('MOCKSESSID=789; path=/foo', array('MOCKSESSID=789; path=/foo', 'MOCKSESSID=456; path=/')), + ); + } + public function testUnstartedSessionIsNotSave() { $this->sessionHasNotBeenStarted(); @@ -123,10 +153,10 @@ public function testDoesNotImplementServiceSubscriberInterface() $this->assertFalse(is_subclass_of(TestSessionListener::class, ServiceSubscriberInterface::class, 'Implementing ServiceSubscriberInterface would create a dep on the DI component, which eg Silex cannot afford')); } - private function filterResponse(Request $request, $type = HttpKernelInterface::MASTER_REQUEST) + private function filterResponse(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, Response $response = null) { $request->setSession($this->session); - $response = new Response(); + $response = $response ?: new Response(); $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(); $event = new FilterResponseEvent($kernel, $request, $type, $response); diff --git a/src/Symfony/Component/HttpKernel/Tests/Fragment/HIncludeFragmentRendererTest.php b/src/Symfony/Component/HttpKernel/Tests/Fragment/HIncludeFragmentRendererTest.php index 1be052e5e62fd..7171c71bc3af4 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Fragment/HIncludeFragmentRendererTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Fragment/HIncludeFragmentRendererTest.php @@ -86,4 +86,17 @@ public function testRenderWithDefaultText() $strategy = new HIncludeFragmentRenderer($engine); $this->assertEquals('default', $strategy->render('/foo', Request::create('/'), array('default' => 'default'))->getContent()); } + + public function testRenderWithEngineAndDefaultText() + { + $engine = $this->getMockBuilder('Symfony\\Component\\Templating\\EngineInterface')->getMock(); + $engine->expects($this->once()) + ->method('exists') + ->with('loading...') + ->will($this->throwException(new \RuntimeException())); + + // only default + $strategy = new HIncludeFragmentRenderer($engine); + $this->assertEquals('loading...', $strategy->render('/foo', Request::create('/'), array('default' => 'loading...'))->getContent()); + } } diff --git a/src/Symfony/Component/HttpKernel/Tests/KernelTest.php b/src/Symfony/Component/HttpKernel/Tests/KernelTest.php index 7cde2ac5e2ef9..916cf8d24d06a 100644 --- a/src/Symfony/Component/HttpKernel/Tests/KernelTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/KernelTest.php @@ -809,7 +809,7 @@ public function testKernelRootDirNameStartingWithANumber() /** * @group legacy - * @expectedDeprecation The Symfony\Component\HttpKernel\Kernel::getEnvParameters() method is deprecated as of 3.3 and will be removed in 4.0. Use the %cenv()%c syntax to get the value of any environment variable from configuration files instead. + * @expectedDeprecation The "Symfony\Component\HttpKernel\Kernel::getEnvParameters()" method is deprecated as of 3.3 and will be removed in 4.0. Use the %cenv()%c syntax to get the value of any environment variable from configuration files instead. * @expectedDeprecation The support of special environment variables that start with SYMFONY__ (such as "SYMFONY__FOO__BAR") is deprecated as of 3.3 and will be removed in 4.0. Use the %cenv()%c syntax instead to get the value of environment variables in configuration files. */ public function testSymfonyEnvironmentVariables() diff --git a/src/Symfony/Component/Lock/Store/FlockStore.php b/src/Symfony/Component/Lock/Store/FlockStore.php index 5c5baee29a91d..4d55b539e3632 100644 --- a/src/Symfony/Component/Lock/Store/FlockStore.php +++ b/src/Symfony/Component/Lock/Store/FlockStore.php @@ -81,7 +81,7 @@ private function lock(Key $key, $blocking) set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; }); if (!$handle = fopen($fileName, 'r+') ?: fopen($fileName, 'r')) { if ($handle = fopen($fileName, 'x')) { - chmod($fileName, 0444); + chmod($fileName, 0666); } elseif (!$handle = fopen($fileName, 'r+') ?: fopen($fileName, 'r')) { usleep(100); // Give some time for chmod() to complete $handle = fopen($fileName, 'r+') ?: fopen($fileName, 'r'); diff --git a/src/Symfony/Component/Lock/Tests/Store/SemaphoreStoreTest.php b/src/Symfony/Component/Lock/Tests/Store/SemaphoreStoreTest.php index 23b90360bea77..38babded2854e 100644 --- a/src/Symfony/Component/Lock/Tests/Store/SemaphoreStoreTest.php +++ b/src/Symfony/Component/Lock/Tests/Store/SemaphoreStoreTest.php @@ -50,13 +50,22 @@ public function testResourceRemoval() private function getOpenedSemaphores() { - $lines = explode(PHP_EOL, trim(`ipcs -su`)); + if ('Darwin' === PHP_OS) { + $lines = explode(PHP_EOL, trim(`ipcs -s`)); + if (-1 === $start = array_search('Semaphores:', $lines)) { + throw new \Exception('Failed to extract list of opened semaphores. Expected a Semaphore list, got '.implode(PHP_EOL, $lines)); + } + + return \count(\array_slice($lines, ++$start)); + } + + $lines = explode(PHP_EOL, trim(`LC_ALL=C ipcs -su`)); if ('------ Semaphore Status --------' !== $lines[0]) { - throw new \Exception('Failed to extract list of opend semaphores. Expect a Semaphore status, got '.implode(PHP_EOL, $lines)); + 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]); if ('used arrays' !== $key) { - throw new \Exception('Failed to extract list of opend semaphores. Expect a used arrays key, got '.implode(PHP_EOL, $lines)); + throw new \Exception('Failed to extract list of opened semaphores. Expected a "used arrays" key, got '.implode(PHP_EOL, $lines)); } return (int) $value; diff --git a/src/Symfony/Component/OptionsResolver/OptionsResolver.php b/src/Symfony/Component/OptionsResolver/OptionsResolver.php index 95a492de94bb8..a58f45c0a6588 100644 --- a/src/Symfony/Component/OptionsResolver/OptionsResolver.php +++ b/src/Symfony/Component/OptionsResolver/OptionsResolver.php @@ -433,7 +433,7 @@ public function setAllowedValues($option, $allowedValues) )); } - $this->allowedValues[$option] = is_array($allowedValues) ? $allowedValues : array($allowedValues); + $this->allowedValues[$option] = \is_array($allowedValues) ? $allowedValues : array($allowedValues); // Make sure the option is processed unset($this->resolved[$option]); @@ -785,14 +785,13 @@ public function offsetGet($option) } if (!$valid) { - throw new InvalidOptionsException(sprintf( - 'The option "%s" with value %s is expected to be of type '. - '"%s", but is of type "%s".', - $option, - $this->formatValue($value), - implode('" or "', $this->allowedTypes[$option]), - implode('|', array_keys($invalidTypes)) - )); + $keys = array_keys($invalidTypes); + + if (1 === \count($keys) && '[]' === substr($keys[0], -2)) { + throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but one of the elements is of type "%s".', $option, $this->formatValue($value), implode('" or "', $this->allowedTypes[$option]), $keys[0])); + } + + throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but is of type "%s".', $option, $this->formatValue($value), implode('" or "', $this->allowedTypes[$option]), implode('|', array_keys($invalidTypes)))); } } @@ -877,23 +876,8 @@ public function offsetGet($option) */ private function verifyTypes($type, $value, array &$invalidTypes) { - if ('[]' === substr($type, -2) && is_array($value)) { - $originalType = $type; - $type = substr($type, 0, -2); - $invalidValues = array_filter( // Filter out valid values, keeping invalid values in the resulting array - $value, - function ($value) use ($type) { - return !self::isValueValidType($type, $value); - } - ); - - if (!$invalidValues) { - return true; - } - - $invalidTypes[$this->formatTypeOf($value, $originalType)] = true; - - return false; + if (\is_array($value) && '[]' === substr($type, -2)) { + return $this->verifyArrayType($type, $value, $invalidTypes); } if (self::isValueValidType($type, $value)) { @@ -907,6 +891,46 @@ function ($value) use ($type) { return false; } + /** + * @return bool + */ + private function verifyArrayType($type, array $value, array &$invalidTypes, $level = 0) + { + $type = substr($type, 0, -2); + + $suffix = '[]'; + while (\strlen($suffix) <= $level * 2) { + $suffix .= '[]'; + } + + if ('[]' === substr($type, -2)) { + $success = true; + foreach ($value as $item) { + if (!\is_array($item)) { + $invalidTypes[$this->formatTypeOf($item, null).$suffix] = true; + + return false; + } + + if (!$this->verifyArrayType($type, $item, $invalidTypes, $level + 1)) { + $success = false; + } + } + + return $success; + } + + foreach ($value as $item) { + if (!self::isValueValidType($type, $item)) { + $invalidTypes[$this->formatTypeOf($item, $type).$suffix] = $value; + + return false; + } + } + + return true; + } + /** * Returns whether a resolved option with the given name exists. * @@ -990,13 +1014,13 @@ private function formatTypeOf($value, $type) while ('[]' === substr($type, -2)) { $type = substr($type, 0, -2); $value = array_shift($value); - if (!is_array($value)) { + if (!\is_array($value)) { break; } $suffix .= '[]'; } - if (is_array($value)) { + if (\is_array($value)) { $subTypes = array(); foreach ($value as $val) { $subTypes[$this->formatTypeOf($val, null)] = true; @@ -1006,7 +1030,7 @@ private function formatTypeOf($value, $type) } } - return (is_object($value) ? get_class($value) : gettype($value)).$suffix; + return (\is_object($value) ? get_class($value) : gettype($value)).$suffix; } /** @@ -1022,19 +1046,19 @@ private function formatTypeOf($value, $type) */ private function formatValue($value) { - if (is_object($value)) { + if (\is_object($value)) { return get_class($value); } - if (is_array($value)) { + if (\is_array($value)) { return 'array'; } - if (is_string($value)) { + if (\is_string($value)) { return '"'.$value.'"'; } - if (is_resource($value)) { + if (\is_resource($value)) { return 'resource'; } @@ -1078,4 +1102,20 @@ private static function isValueValidType($type, $value) { return (function_exists($isFunction = 'is_'.$type) && $isFunction($value)) || $value instanceof $type; } + + /** + * @return array + */ + private function getInvalidValues(array $arrayValues, $type) + { + $invalidValues = array(); + + foreach ($arrayValues as $key => $value) { + if (!self::isValueValidType($type, $value)) { + $invalidValues[$key] = $value; + } + } + + return $invalidValues; + } } diff --git a/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php b/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php index 12dc77b3c6b1c..ac12984447604 100644 --- a/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php +++ b/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php @@ -483,7 +483,7 @@ public function testFailIfSetAllowedTypesFromLazyOption() /** * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - * @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[]", but is of type "DateTime[]". + * @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "DateTime[]". */ public function testResolveFailsIfInvalidTypedArray() { @@ -507,7 +507,7 @@ public function testResolveFailsWithNonArray() /** * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - * @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[]", but is of type "integer|stdClass|array|DateTime[]". + * @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "stdClass[]". */ public function testResolveFailsIfTypedArrayContainsInvalidTypes() { @@ -524,7 +524,7 @@ public function testResolveFailsIfTypedArrayContainsInvalidTypes() /** * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - * @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[][]", but is of type "double[][]". + * @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "double[][]". */ public function testResolveFailsWithCorrectLevelsButWrongScalar() { @@ -1586,4 +1586,151 @@ public function testCountFailsOutsideResolve() count($this->resolver); } + + public function testNestedArrays() + { + $this->resolver->setDefined('foo'); + $this->resolver->setAllowedTypes('foo', 'int[][]'); + + $this->assertEquals(array( + 'foo' => array( + array( + 1, 2, + ), + ), + ), $this->resolver->resolve( + array( + 'foo' => array( + array(1, 2), + ), + ) + )); + } + + public function testNested2Arrays() + { + $this->resolver->setDefined('foo'); + $this->resolver->setAllowedTypes('foo', 'int[][][][]'); + + $this->assertEquals(array( + 'foo' => array( + array( + array( + array( + 1, 2, + ), + ), + ), + ), + ), $this->resolver->resolve( + array( + 'foo' => array( + array( + array( + array(1, 2), + ), + ), + ), + ) + )); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + * @expectedExceptionMessage The option "foo" with value array is expected to be of type "float[][][][]", but one of the elements is of type "integer[][][][]". + */ + public function testNestedArraysException() + { + $this->resolver->setDefined('foo'); + $this->resolver->setAllowedTypes('foo', 'float[][][][]'); + + $this->resolver->resolve( + array( + 'foo' => array( + array( + array( + array(1, 2), + ), + ), + ), + ) + ); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + * @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean[][]". + */ + public function testNestedArrayException1() + { + $this->resolver->setDefined('foo'); + $this->resolver->setAllowedTypes('foo', 'int[][]'); + $this->resolver->resolve(array( + 'foo' => array( + array(1, true, 'str', array(2, 3)), + ), + )); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + * @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean[][]". + */ + public function testNestedArrayException2() + { + $this->resolver->setDefined('foo'); + $this->resolver->setAllowedTypes('foo', 'int[][]'); + $this->resolver->resolve(array( + 'foo' => array( + array(true, 'str', array(2, 3)), + ), + )); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + * @expectedExceptionMessage The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "string[][]". + */ + public function testNestedArrayException3() + { + $this->resolver->setDefined('foo'); + $this->resolver->setAllowedTypes('foo', 'string[][][]'); + $this->resolver->resolve(array( + 'foo' => array( + array('str', array(1, 2)), + ), + )); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + * @expectedExceptionMessage The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "integer[][][]". + */ + public function testNestedArrayException4() + { + $this->resolver->setDefined('foo'); + $this->resolver->setAllowedTypes('foo', 'string[][][]'); + $this->resolver->resolve(array( + 'foo' => array( + array( + array('str'), array(1, 2), ), + ), + )); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + * @expectedExceptionMessage The option "foo" with value array is expected to be of type "string[]", but one of the elements is of type "array[]". + */ + public function testNestedArrayException5() + { + $this->resolver->setDefined('foo'); + $this->resolver->setAllowedTypes('foo', 'string[]'); + $this->resolver->resolve(array( + 'foo' => array( + array( + array('str'), array(1, 2), ), + ), + )); + } } diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index 830c623e0dc3b..dc386aa526937 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -272,7 +272,7 @@ public function start(callable $callback = null/*, array $env = array()*/) } else { if (__CLASS__ !== static::class) { $r = new \ReflectionMethod($this, __FUNCTION__); - if (__CLASS__ !== $r->getDeclaringClass()->getName() && (2 > $r->getNumberOfParameters() || 'env' !== $r->getParameters()[0]->name)) { + if (__CLASS__ !== $r->getDeclaringClass()->getName() && (2 > $r->getNumberOfParameters() || 'env' !== $r->getParameters()[1]->name)) { @trigger_error(sprintf('The %s::start() method expects a second "$env" argument since Symfony 3.3. It will be made mandatory in 4.0.', static::class), E_USER_DEPRECATED); } } diff --git a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php index 5c3475ed0e525..c500d5fea8ebe 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php @@ -169,25 +169,21 @@ private function getDocBlock($class, $property) $ucFirstProperty = ucfirst($property); - try { - switch (true) { - case $docBlock = $this->getDocBlockFromProperty($class, $property): - $data = array($docBlock, self::PROPERTY, null); - break; + switch (true) { + case $docBlock = $this->getDocBlockFromProperty($class, $property): + $data = array($docBlock, self::PROPERTY, null); + break; - case list($docBlock) = $this->getDocBlockFromMethod($class, $ucFirstProperty, self::ACCESSOR): - $data = array($docBlock, self::ACCESSOR, null); - break; + case list($docBlock) = $this->getDocBlockFromMethod($class, $ucFirstProperty, self::ACCESSOR): + $data = array($docBlock, self::ACCESSOR, null); + break; - case list($docBlock, $prefix) = $this->getDocBlockFromMethod($class, $ucFirstProperty, self::MUTATOR): - $data = array($docBlock, self::MUTATOR, $prefix); - break; + case list($docBlock, $prefix) = $this->getDocBlockFromMethod($class, $ucFirstProperty, self::MUTATOR): + $data = array($docBlock, self::MUTATOR, $prefix); + break; - default: - $data = array(null, null, null); - } - } catch (\InvalidArgumentException $e) { - $data = array(null, null, null); + default: + $data = array(null, null, null); } return $this->docBlocks[$propertyHash] = $data; @@ -210,7 +206,11 @@ private function getDocBlockFromProperty($class, $property) return; } - return $this->docBlockFactory->create($reflectionProperty, $this->contextFactory->createFromReflector($reflectionProperty->getDeclaringClass())); + try { + return $this->docBlockFactory->create($reflectionProperty, $this->contextFactory->createFromReflector($reflectionProperty->getDeclaringClass())); + } catch (\InvalidArgumentException $e) { + return null; + } } /** @@ -251,6 +251,10 @@ private function getDocBlockFromMethod($class, $ucFirstProperty, $type) return; } - return array($this->docBlockFactory->create($reflectionMethod, $this->contextFactory->createFromReflector($reflectionMethod)), $prefix); + try { + return array($this->docBlockFactory->create($reflectionMethod, $this->contextFactory->createFromReflector($reflectionMethod)), $prefix); + } catch (\InvalidArgumentException $e) { + return null; + } } } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php index 647d4c1072e64..080df2893a877 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php @@ -94,6 +94,9 @@ public function typesProvider() array('e', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_RESOURCE))), null, null), array('f', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_OBJECT, false, 'DateTime'))), null, null), array('g', array(new Type(Type::BUILTIN_TYPE_ARRAY, true, null, true)), 'Nullable array.', null), + array('h', array(new Type(Type::BUILTIN_TYPE_STRING, true)), null, null), + array('i', array(new Type(Type::BUILTIN_TYPE_STRING, true), new Type(Type::BUILTIN_TYPE_INT, true)), null, null), + array('j', array(new Type(Type::BUILTIN_TYPE_OBJECT, true, 'DateTime')), null, null), array('donotexist', null, null, null), array('staticGetter', null, null, null), array('staticSetter', null, null, null), @@ -130,6 +133,9 @@ public function typesWithCustomPrefixesProvider() array('e', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_RESOURCE))), null, null), array('f', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_OBJECT, false, 'DateTime'))), null, null), array('g', array(new Type(Type::BUILTIN_TYPE_ARRAY, true, null, true)), 'Nullable array.', null), + array('h', array(new Type(Type::BUILTIN_TYPE_STRING, true)), null, null), + array('i', array(new Type(Type::BUILTIN_TYPE_STRING, true), new Type(Type::BUILTIN_TYPE_INT, true)), null, null), + array('j', array(new Type(Type::BUILTIN_TYPE_OBJECT, true, 'DateTime')), null, null), array('donotexist', null, null, null), array('staticGetter', null, null, null), array('staticSetter', null, null, null), @@ -165,6 +171,9 @@ public function typesWithNoPrefixesProvider() array('e', null, null, null), array('f', null, null, null), array('g', array(new Type(Type::BUILTIN_TYPE_ARRAY, true, null, true)), 'Nullable array.', null), + array('h', array(new Type(Type::BUILTIN_TYPE_STRING, true)), null, null), + array('i', array(new Type(Type::BUILTIN_TYPE_STRING, true), new Type(Type::BUILTIN_TYPE_INT, true)), null, null), + array('j', array(new Type(Type::BUILTIN_TYPE_OBJECT, true, 'DateTime')), null, null), array('donotexist', null, null, null), array('staticGetter', null, null, null), array('staticSetter', null, null, null), @@ -175,6 +184,29 @@ public function testReturnNullOnEmptyDocBlock() { $this->assertNull($this->extractor->getShortDescription(EmptyDocBlock::class, 'foo')); } + + public function dockBlockFallbackTypesProvider() + { + return array( + 'pub' => array( + 'pub', array(new Type(Type::BUILTIN_TYPE_STRING)), + ), + 'protAcc' => array( + 'protAcc', array(new Type(Type::BUILTIN_TYPE_INT)), + ), + 'protMut' => array( + 'protMut', array(new Type(Type::BUILTIN_TYPE_BOOL)), + ), + ); + } + + /** + * @dataProvider dockBlockFallbackTypesProvider + */ + public function testDocBlockFallback($property, $types) + { + $this->assertEquals($types, $this->extractor->getTypes('Symfony\Component\PropertyInfo\Tests\Fixtures\DockBlockFallback', $property)); + } } class EmptyDocBlock diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php index f8c61dd48aa36..e7fddf473f37b 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php @@ -41,6 +41,9 @@ public function testGetProperties() 'B', 'Guid', 'g', + 'h', + 'i', + 'j', 'emptyVar', 'foo', 'foo2', @@ -77,6 +80,9 @@ public function testGetPropertiesWithCustomPrefixes() 'B', 'Guid', 'g', + 'h', + 'i', + 'j', 'emptyVar', 'foo', 'foo2', @@ -105,6 +111,9 @@ public function testGetPropertiesWithNoPrefixes() 'B', 'Guid', 'g', + 'h', + 'i', + 'j', 'emptyVar', 'foo', 'foo2', diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/DockBlockFallback.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/DockBlockFallback.php new file mode 100644 index 0000000000000..3f9c303b59137 --- /dev/null +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/DockBlockFallback.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\PropertyInfo\Tests\Fixtures; + +/** + * PhpDocExtractor should fallback from property -> accessor -> mutator when looking up dockblocks. + * + * @author Martin Rademacher + */ +class DockBlockFallback +{ + /** @var string $pub */ + public $pub = 'pub'; + + protected $protAcc; + protected $protMut; + + public function getPub() + { + return $this->pub; + } + + public function setPub($pub) + { + $this->pub = $pub; + } + + /** + * @return int + */ + public function getProtAcc() + { + return $this->protAcc; + } + + public function setProt($protAcc) + { + $this->protAcc = $protAcc; + } + + public function getProtMut() + { + return $this->protMut; + } + + /** + * @param bool $protMut + */ + public function setProtMut($protMut) + { + $this->protMut = $protMut; + } +} diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php index 5993d6e1d47e8..76c2e1042c604 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php @@ -68,6 +68,21 @@ class Dummy extends ParentDummy */ public $g; + /** + * @var ?string + */ + public $h; + + /** + * @var ?string|int + */ + public $i; + + /** + * @var ?\DateTime + */ + public $j; + /** * This should not be removed. * diff --git a/src/Symfony/Component/PropertyInfo/Util/PhpDocTypeHelper.php b/src/Symfony/Component/PropertyInfo/Util/PhpDocTypeHelper.php index bc14cd8b69b1b..e526c62348797 100644 --- a/src/Symfony/Component/PropertyInfo/Util/PhpDocTypeHelper.php +++ b/src/Symfony/Component/PropertyInfo/Util/PhpDocTypeHelper.php @@ -14,6 +14,7 @@ use phpDocumentor\Reflection\Type as DocType; use phpDocumentor\Reflection\Types\Compound; use phpDocumentor\Reflection\Types\Null_; +use phpDocumentor\Reflection\Types\Nullable; use Symfony\Component\PropertyInfo\Type; /** @@ -27,13 +28,18 @@ final class PhpDocTypeHelper /** * Creates a {@see Type} from a PHPDoc type. * - * @return Type + * @return Type[] */ public function getTypes(DocType $varType) { $types = array(); $nullable = false; + if ($varType instanceof Nullable) { + $nullable = true; + $varType = $varType->getActualType(); + } + if (!$varType instanceof Compound) { if ($varType instanceof Null_) { $nullable = true; @@ -54,10 +60,10 @@ public function getTypes(DocType $varType) // If null is present, all types are nullable $nullKey = array_search(Type::BUILTIN_TYPE_NULL, $varTypes); - $nullable = false !== $nullKey; + $nullable = $nullable || false !== $nullKey; // Remove the null type from the type if other types are defined - if ($nullable && count($varTypes) > 1) { + if ($nullable && false !== $nullKey && count($varTypes) > 1) { unset($varTypes[$nullKey]); } diff --git a/src/Symfony/Component/PropertyInfo/composer.json b/src/Symfony/Component/PropertyInfo/composer.json index ce41fabd09365..bf02fe0f980c5 100644 --- a/src/Symfony/Component/PropertyInfo/composer.json +++ b/src/Symfony/Component/PropertyInfo/composer.json @@ -35,7 +35,7 @@ }, "conflict": { "phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.2", - "phpdocumentor/type-resolver": "<0.2.1", + "phpdocumentor/type-resolver": "<0.3.0", "symfony/dependency-injection": "<3.3" }, "suggest": { diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php index ca55943ebbdf4..8acdccd4943b6 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php @@ -77,14 +77,7 @@ public function getUser() } /** - * Sets the user in the token. - * - * The user can be a UserInterface instance, or an object implementing - * a __toString method or the username as a regular string. - * - * @param string|object $user The user - * - * @throws \InvalidArgumentException + * {@inheritdoc} */ public function setUser($user) { diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php b/src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php index 4e1dd7b2fc46b..583700c178a71 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php @@ -47,17 +47,22 @@ public function getCredentials(); /** * Returns a user representation. * - * @return mixed Can be a UserInterface instance, an object implementing a __toString method, - * or the username as a regular string + * @return string|object Can be a UserInterface instance, an object implementing a __toString method, + * or the username as a regular string * * @see AbstractToken::setUser() */ public function getUser(); /** - * Sets a user. + * Sets the user in the token. * - * @param mixed $user + * The user can be a UserInterface instance, or an object implementing + * a __toString method or the username as a regular string. + * + * @param string|object $user The user + * + * @throws \InvalidArgumentException */ public function setUser($user); diff --git a/src/Symfony/Component/Security/Http/Logout/LogoutUrlGenerator.php b/src/Symfony/Component/Security/Http/Logout/LogoutUrlGenerator.php index 788f6470f9e50..3600ca6d73012 100644 --- a/src/Symfony/Component/Security/Http/Logout/LogoutUrlGenerator.php +++ b/src/Symfony/Component/Security/Http/Logout/LogoutUrlGenerator.php @@ -56,7 +56,7 @@ public function registerListener($key, $logoutPath, $csrfTokenId, $csrfParameter if (__CLASS__ !== get_class($this)) { $r = new \ReflectionMethod($this, __FUNCTION__); if (__CLASS__ !== $r->getDeclaringClass()->getName()) { - @trigger_error(sprintf('Method %s() will have a sixth `string $context = null` argument in version 4.0. Not defining it is deprecated since Symfony 3.3.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method will have a 6th `string $context = null` argument in version 4.0. Not defining it is deprecated since Symfony 3.3.', __METHOD__), E_USER_DEPRECATED); } } diff --git a/src/Symfony/Component/Serializer/Serializer.php b/src/Symfony/Component/Serializer/Serializer.php index 1eafaa96e52bb..60c603bb73df1 100644 --- a/src/Symfony/Component/Serializer/Serializer.php +++ b/src/Symfony/Component/Serializer/Serializer.php @@ -196,7 +196,7 @@ public function supportsNormalization($data, $format = null/*, array $context = if (__CLASS__ !== \get_class($this)) { $r = new \ReflectionMethod($this, __FUNCTION__); if (__CLASS__ !== $r->getDeclaringClass()->getName()) { - @trigger_error(sprintf('Method %s() will have a third `$context = array()` argument in version 4.0. Not defining it is deprecated since Symfony 3.3.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method will have a third `$context = array()` argument in version 4.0. Not defining it is deprecated since Symfony 3.3.', __METHOD__), E_USER_DEPRECATED); } } @@ -217,7 +217,7 @@ public function supportsDenormalization($data, $type, $format = null/*, array $c if (__CLASS__ !== \get_class($this)) { $r = new \ReflectionMethod($this, __FUNCTION__); if (__CLASS__ !== $r->getDeclaringClass()->getName()) { - @trigger_error(sprintf('Method %s() will have a fourth `$context = array()` argument in version 4.0. Not defining it is deprecated since Symfony 3.3.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method will have a fourth `$context = array()` argument in version 4.0. Not defining it is deprecated since Symfony 3.3.', __METHOD__), E_USER_DEPRECATED); } } @@ -291,7 +291,7 @@ public function supportsEncoding($format/*, array $context = array()*/) if (__CLASS__ !== \get_class($this)) { $r = new \ReflectionMethod($this, __FUNCTION__); if (__CLASS__ !== $r->getDeclaringClass()->getName()) { - @trigger_error(sprintf('Method %s() will have a second `$context = array()` argument in version 4.0. Not defining it is deprecated since Symfony 3.3.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method will have a second `$context = array()` argument in version 4.0. Not defining it is deprecated since Symfony 3.3.', __METHOD__), E_USER_DEPRECATED); } } @@ -312,7 +312,7 @@ public function supportsDecoding($format/*, array $context = array()*/) if (__CLASS__ !== \get_class($this)) { $r = new \ReflectionMethod($this, __FUNCTION__); if (__CLASS__ !== $r->getDeclaringClass()->getName()) { - @trigger_error(sprintf('Method %s() will have a second `$context = array()` argument in version 4.0. Not defining it is deprecated since Symfony 3.3.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method will have a second `$context = array()` argument in version 4.0. Not defining it is deprecated since Symfony 3.3.', __METHOD__), E_USER_DEPRECATED); } } diff --git a/src/Symfony/Component/Translation/DependencyInjection/TranslatorPass.php b/src/Symfony/Component/Translation/DependencyInjection/TranslatorPass.php index db2a2a1ecc46b..e60a4242976f3 100644 --- a/src/Symfony/Component/Translation/DependencyInjection/TranslatorPass.php +++ b/src/Symfony/Component/Translation/DependencyInjection/TranslatorPass.php @@ -27,7 +27,7 @@ class TranslatorPass implements CompilerPassInterface public function __construct($translatorServiceId = 'translator.default', $readerServiceId = 'translation.loader', $loaderTag = 'translation.loader', $debugCommandServiceId = 'console.command.translation_debug', $updateCommandServiceId = 'console.command.translation_update') { if ('translation.loader' === $readerServiceId && 2 > func_num_args()) { - @trigger_error('The default value for $readerServiceId will change in 4.0 to "translation.reader".', E_USER_DEPRECATED); + @trigger_error(sprintf('The default value for $readerServiceId in "%s()" will change in 4.0 to "translation.reader".', __METHOD__), E_USER_DEPRECATED); } $this->translatorServiceId = $translatorServiceId; diff --git a/src/Symfony/Component/Translation/PluralizationRules.php b/src/Symfony/Component/Translation/PluralizationRules.php index 48a6c608cbfe2..94d9e4350c3c2 100644 --- a/src/Symfony/Component/Translation/PluralizationRules.php +++ b/src/Symfony/Component/Translation/PluralizationRules.php @@ -144,6 +144,7 @@ public static function get($number, $locale) case 'bs': case 'hr': case 'ru': + case 'sh': case 'sr': case 'uk': return ((1 == $number % 10) && (11 != $number % 100)) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2); diff --git a/src/Symfony/Component/Translation/Tests/DependencyInjection/TranslationPassTest.php b/src/Symfony/Component/Translation/Tests/DependencyInjection/TranslationPassTest.php index c0274738d0f0d..4c03aaca57003 100644 --- a/src/Symfony/Component/Translation/Tests/DependencyInjection/TranslationPassTest.php +++ b/src/Symfony/Component/Translation/Tests/DependencyInjection/TranslationPassTest.php @@ -57,7 +57,7 @@ public function testValidCollector() /** * @group legacy - * @expectedDeprecation The default value for $readerServiceId will change in 4.0 to "translation.reader". + * @expectedDeprecation The default value for $readerServiceId in "Symfony\Component\Translation\DependencyInjection\TranslatorPass::__construct()" will change in 4.0 to "translation.reader". * * A test that verifies the deprecated "translation.loader" gets the LoaderInterfaces added. * diff --git a/src/Symfony/Component/Translation/Tests/Writer/TranslationWriterTest.php b/src/Symfony/Component/Translation/Tests/Writer/TranslationWriterTest.php index 8837553d56808..26a846ea90d94 100644 --- a/src/Symfony/Component/Translation/Tests/Writer/TranslationWriterTest.php +++ b/src/Symfony/Component/Translation/Tests/Writer/TranslationWriterTest.php @@ -20,7 +20,7 @@ class TranslationWriterTest extends TestCase { /** * @group legacy - * @expectedDeprecation Method Symfony\Component\Translation\Writer\TranslationWriter::writeTranslations() is deprecated since Symfony 3.4 and will be removed in 4.0. Use write() instead. + * @expectedDeprecation The "Symfony\Component\Translation\Writer\TranslationWriter::writeTranslations()" method is deprecated since Symfony 3.4 and will be removed in 4.0. Use write() instead. */ public function testWriteTranslations() { diff --git a/src/Symfony/Component/Translation/Translator.php b/src/Symfony/Component/Translation/Translator.php index 411eec7167ff9..6594ea2aec480 100644 --- a/src/Symfony/Component/Translation/Translator.php +++ b/src/Symfony/Component/Translation/Translator.php @@ -87,7 +87,7 @@ public function __construct($locale, $formatter = null, $cacheDir = null, $debug if ($formatter instanceof MessageSelector) { $formatter = new MessageFormatter($formatter); - @trigger_error(sprintf('Passing a "%s" instance into the "%s" as a second argument is deprecated since Symfony 3.4 and will be removed in 4.0. Inject a "%s" implementation instead.', MessageSelector::class, __METHOD__, MessageFormatterInterface::class), E_USER_DEPRECATED); + @trigger_error(sprintf('Passing a "%s" instance into the "%s()" method as a second argument is deprecated since Symfony 3.4 and will be removed in 4.0. Inject a "%s" implementation instead.', MessageSelector::class, __METHOD__, MessageFormatterInterface::class), E_USER_DEPRECATED); } elseif (null === $formatter) { $formatter = new MessageFormatter(); } diff --git a/src/Symfony/Component/Translation/Writer/TranslationWriter.php b/src/Symfony/Component/Translation/Writer/TranslationWriter.php index 5ff5cd855dfa4..66784c2a4d569 100644 --- a/src/Symfony/Component/Translation/Writer/TranslationWriter.php +++ b/src/Symfony/Component/Translation/Writer/TranslationWriter.php @@ -97,7 +97,7 @@ public function write(MessageCatalogue $catalogue, $format, $options = array()) */ public function writeTranslations(MessageCatalogue $catalogue, $format, $options = array()) { - @trigger_error(sprintf('Method %s() is deprecated since Symfony 3.4 and will be removed in 4.0. Use write() instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 3.4 and will be removed in 4.0. Use write() instead.', __METHOD__), E_USER_DEPRECATED); $this->write($catalogue, $format, $options); } } diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.ca.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.ca.xlf index 85b6970fc31cf..078a25d052d10 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.ca.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.ca.xlf @@ -302,6 +302,10 @@ An empty file is not allowed. No està permès un fixter buit. + + This is not a valid UUID. + Aquest valor no és un UUID vàlid. + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.de.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.de.xlf index 6e89e17ec3f1f..3e44e1e284b8c 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.de.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.de.xlf @@ -318,6 +318,10 @@ Error Fehler + + This is not a valid UUID. + Dies ist keine gültige UUID. + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf index 7e0e9614de50a..3d173846a54f1 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf @@ -318,6 +318,10 @@ Error Error + + This is not a valid UUID. + This is not a valid UUID. + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.es.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.es.xlf index 948594d03e91b..25d5b8a5d33a7 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.es.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.es.xlf @@ -318,6 +318,10 @@ Error Error + + This is not a valid UUID. + Este valor no es un UUID válido. + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.eu.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.eu.xlf index d4125fdb0fbed..d311dedb5e62e 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.eu.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.eu.xlf @@ -282,6 +282,10 @@ Error Errore + + This is not a valid UUID. + Balio hau ez da onartutako UUID bat. + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.fr.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.fr.xlf index 6c1b4030f3b0d..382acb975ce66 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.fr.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.fr.xlf @@ -318,6 +318,10 @@ Error Erreur + + This is not a valid UUID. + Ceci n'est pas un UUID valide. + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.hu.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.hu.xlf index 3a8a1db6eebd0..1011d5481829b 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.hu.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.hu.xlf @@ -318,6 +318,10 @@ Error Hiba + + This is not a valid UUID. + Érvénytelen egyedi azonosító (UUID). + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.it.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.it.xlf index bd71ece6aea49..f19544701d637 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.it.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.it.xlf @@ -318,6 +318,10 @@ Error Errore + + This is not a valid UUID. + Questo non è un UUID valido. + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.nl.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.nl.xlf index 70ec678ec9a6f..413a97eb17c6f 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.nl.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.nl.xlf @@ -314,6 +314,10 @@ Error Fout + + This is not a valid UUID. + Deze waarde is geen geldige UUID waarde. + diff --git a/src/Symfony/Component/Validator/Tests/Constraints/RegexTest.php b/src/Symfony/Component/Validator/Tests/Constraints/RegexTest.php index 3291c77356f23..26ef1b27361ad 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/RegexTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/RegexTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Constraints; +namespace Symfony\Component\Validator\Tests\Constraints; use PHPUnit\Framework\TestCase; use Symfony\Component\Validator\Constraints\Regex; diff --git a/src/Symfony/Component/VarDumper/Caster/Caster.php b/src/Symfony/Component/VarDumper/Caster/Caster.php index 2676fb78bf0b3..0caa4f1f923b0 100644 --- a/src/Symfony/Component/VarDumper/Caster/Caster.php +++ b/src/Symfony/Component/VarDumper/Caster/Caster.php @@ -49,7 +49,7 @@ class Caster public static function castObject($obj, $class, $hasDebugInfo = false) { if ($class instanceof \ReflectionClass) { - @trigger_error(sprintf('Passing a ReflectionClass to %s() is deprecated since Symfony 3.3 and will be unsupported in 4.0. Pass the class name as string instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('Passing a ReflectionClass to "%s()" is deprecated since Symfony 3.3 and will be unsupported in 4.0. Pass the class name as string instead.', __METHOD__), E_USER_DEPRECATED); $hasDebugInfo = $class->hasMethod('__debugInfo'); $class = $class->name; } diff --git a/src/Symfony/Component/VarDumper/Cloner/Data.php b/src/Symfony/Component/VarDumper/Cloner/Data.php index 75ded2912126f..0b6802169b272 100644 --- a/src/Symfony/Component/VarDumper/Cloner/Data.php +++ b/src/Symfony/Component/VarDumper/Cloner/Data.php @@ -172,7 +172,7 @@ public function __toString() */ public function getRawData() { - @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the array or object access instead.', __METHOD__)); + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the array or object access instead.', __METHOD__)); return $this->data; } diff --git a/src/Symfony/Component/VarDumper/Dumper/CliDumper.php b/src/Symfony/Component/VarDumper/Dumper/CliDumper.php index f1de350d28489..ff6d088202a9b 100644 --- a/src/Symfony/Component/VarDumper/Dumper/CliDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/CliDumper.php @@ -541,6 +541,10 @@ private function hasColorSupport($stream) return false; } + if ('Hyper' === getenv('TERM_PROGRAM')) { + return true; + } + if (DIRECTORY_SEPARATOR === '\\') { return (function_exists('sapi_windows_vt100_support') && @sapi_windows_vt100_support($stream)) @@ -575,7 +579,8 @@ private function isWindowsTrueColor() { $result = 183 <= getenv('ANSICON_VER') || 'ON' === getenv('ConEmuANSI') - || 'xterm' === getenv('TERM'); + || 'xterm' === getenv('TERM') + || 'Hyper' === getenv('TERM_PROGRAM'); if (!$result && PHP_VERSION_ID >= 70200) { $version = sprintf( diff --git a/src/Symfony/Component/VarDumper/Test/VarDumperTestTrait.php b/src/Symfony/Component/VarDumper/Test/VarDumperTestTrait.php index 0fffd55122218..4ca7b780cf3dc 100644 --- a/src/Symfony/Component/VarDumper/Test/VarDumperTestTrait.php +++ b/src/Symfony/Component/VarDumper/Test/VarDumperTestTrait.php @@ -22,7 +22,7 @@ trait VarDumperTestTrait public function assertDumpEquals($dump, $data, $filter = 0, $message = '') { if (is_string($filter)) { - @trigger_error(sprintf('The $message argument of the "%s()" method at 3rd position is deprecated since Symfony 3.4 and will be moved at 4th position in 4.0.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The $message argument of the "%s()" method at the 3rd position is deprecated since Symfony 3.4 and will be moved at the 4th position in 4.0.', __METHOD__), E_USER_DEPRECATED); $message = $filter; $filter = 0; } @@ -33,7 +33,7 @@ public function assertDumpEquals($dump, $data, $filter = 0, $message = '') public function assertDumpMatchesFormat($dump, $data, $filter = 0, $message = '') { if (is_string($filter)) { - @trigger_error(sprintf('The $message argument of the "%s()" method at 3rd position is deprecated since Symfony 3.4 and will be moved at 4th position in 4.0.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('The $message argument of the "%s()" method at the 3rd position is deprecated since Symfony 3.4 and will be moved at the 4th position in 4.0.', __METHOD__), E_USER_DEPRECATED); $message = $filter; $filter = 0; }