diff --git a/.travis.yml b/.travis.yml index 12cb463404..18d21e04cd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -162,7 +162,7 @@ before_install: fi tfold ext.apcu tpecl apcu-5.1.6 apcu.so $INI - tfold ext.mongodb tpecl mongodb-1.5.0 mongodb.so $INI + tfold ext.mongodb tpecl mongodb-1.5.2 mongodb.so $INI tfold ext.amqp tpecl amqp-1.9.3 amqp.so $INI tfold ext.igbinary tpecl igbinary-2.0.6 igbinary.so $INI tfold ext.zookeeper tpecl zookeeper-0.5.0 zookeeper.so $INI @@ -227,7 +227,7 @@ install: break fi phpenv global $PHP - ([[ $deps ]] && cd src/Symfony/Component/HttpFoundation; composer require --dev --no-update mongodb/mongodb) + ([[ $deps ]] && cd src/Symfony/Component/HttpFoundation; composer config platform.ext-mongodb 1.5.2; composer require --dev --no-update mongodb/mongodb) tfold 'composer update' $COMPOSER_UP tfold 'phpunit install' ./phpunit install if [[ $deps = high ]]; then diff --git a/CHANGELOG-4.1.md b/CHANGELOG-4.1.md index 0bff86ba3e..60b848a532 100644 --- a/CHANGELOG-4.1.md +++ b/CHANGELOG-4.1.md @@ -7,6 +7,32 @@ in 4.1 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v4.1.0...v4.1.1 +* 4.1.7 (2018-11-03) + + * bug #28820 [DependencyInjection] Fix tags on multiple decorated service (Soner Sayakci) + * bug #29020 Fix ini_get() for boolean values (deguif) + * bug #28955 [Messenger] send using the routing_key for AMQP transport (nicolas-grekas) + * bug #28960 also clean away the NO_AUTO_CACHE_CONTROL_HEADER if we have no session (dbu) + * feature #28893 [TwigBundle] Fix usage of TwigBundle without FrameworkBundle (tgalopin) + * bug #28889 [Serializer] Reduce class discriminator overhead (fbourigault) + * bug #28861 [DependencyInjection] Skip empty proxy code (olvlvl) + * bug #28801 Convert InsufficientAuthenticationException to HttpException with 401 status code (vincentchalamon) + * bug #28840 add missing double-quotes to extra_fields output message (danielkay) + * bug #28838 [DI] Default undefined env to empty string during compile (ro0NL) + * bug #28863 [Process] Allow to pass non-string arguments to Process (vudaltsov) + * bug #28712 [Form] reverse transform RFC 3339 formatted dates (xabbuh) + * bug #28813 Fix for race condition in console output stream write (rudolfratusinski) + * bug #27772 [Console] Fixes multiselect choice question defaults in non-interactive mode (veewee) + * bug #28835 [FrameworkBundle] Setting missing default paths under BC layer (yceruto) + * bug #28760 [DI] fix dumping inline services again (nicolas-grekas) + * bug #28689 [Process] fix locking of pipe files on Windows (nicolas-grekas) + * bug #28704 [Form] fix multi-digit seconds fraction handling (xabbuh) + * bug #28793 [SecurityBundle] do not override custom access decision configs (xabbuh) + * bug #28783 [FrameworkBundle] add missing cache prefix seed attribute to XSD (xabbuh) + * bug #28072 [Security] Do not deauthenticate user when the first refreshed user has changed (gpekz) + * bug #28735 [FWBundle] Automatically enable PropertyInfo when using Flex (dunglas) + * bug #28751 [FrameworkBundle] Register messenger before the profiler (sroze) + * 4.1.6 (2018-10-03) * bug #28604 [Finder] fixed root directory access for ftp/sftp wrapper (DerDu) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 66d9da5983..969c6a424c 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -14,23 +14,23 @@ Symfony is the result of the work of many people who made the code better - Victor Berchet (victor) - Robin Chalas (chalas_r) - Kévin Dunglas (dunglas) - - Johannes S (johannes) - Jakub Zalas (jakubzalas) + - Johannes S (johannes) - Maxime Steinhausser (ogizanagi) - Kris Wallsmith (kriswallsmith) - Ryan Weaver (weaverryan) - Javier Eguiluz (javier.eguiluz) - Grégoire Pineau (lyrixx) - Hugo Hamon (hhamon) - - Abdellatif Ait boudad (aitboudad) - Roland Franssen (ro0) + - Abdellatif Ait boudad (aitboudad) - Romain Neutron (romain) - Pascal Borreli (pborreli) - Wouter De Jong (wouterj) - Joseph Bielawski (stloyd) - Karma Dordrak (drak) - - Lukas Kahwe Smith (lsmith) - Samuel ROZE (sroze) + - Lukas Kahwe Smith (lsmith) - Martin Hasoň (hason) - Jeremy Mikola (jmikola) - Jean-François Simon (jfsimon) @@ -43,9 +43,9 @@ Symfony is the result of the work of many people who made the code better - Sarah Khalil (saro0h) - Jonathan Wage (jwage) - Hamza Amrouche (simperfit) + - Tobias Nyholm (tobias) - Diego Saint Esteben (dosten) - Iltar van der Berg (kjarli) - - Tobias Nyholm (tobias) - Alexandre Salomé (alexandresalome) - William Durand (couac) - ornicar @@ -72,11 +72,12 @@ Symfony is the result of the work of many people who made the code better - Titouan Galopin (tgalopin) - Michel Weimerskirch (mweimerskirch) - Andrej Hudec (pulzarraider) + - Konstantin Myakshin (koc) - Eric Clemmons (ericclemmons) - Jáchym Toušek (enumag) - Charles Sarrazin (csarrazi) - David Maicher (dmaicher) - - Konstantin Myakshin (koc) + - Vladimir Reznichenko (kalessil) - Christian Raue - Issei Murasawa (issei_m) - Arnout Boks (aboks) @@ -84,13 +85,12 @@ Symfony is the result of the work of many people who made the code better - Henrik Westphal (snc) - Dariusz Górecki (canni) - Douglas Greenshields (shieldo) - - Vladimir Reznichenko (kalessil) + - Dariusz Ruminski - Lee McDermott - Brandon Turner - Luis Cordova (cordoval) - Graham Campbell (graham) - Daniel Holmes (dholmes) - - Dariusz Ruminski - Toni Uebernickel (havvg) - Grégoire Paris (greg0ire) - Bart van den Burg (burgov) @@ -98,6 +98,7 @@ 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) + - Valentin Udaltsov (vudaltsov) - Antoine Hérault (herzult) - Paráda József (paradajozsef) - Arnaud Le Blanc (arnaud-lb) @@ -106,9 +107,9 @@ Symfony is the result of the work of many people who made the code better - gadelat (gadelat) - Tim Nagel (merk) - Brice BERNARD (brikou) - - Valentin Udaltsov (vudaltsov) - Baptiste Clavié (talus) - marc.weistroff + - David Buchmann (dbu) - lenar - Alexander Schwenn (xelaris) - Włodzimierz Gajda (gajdaw) @@ -119,12 +120,12 @@ Symfony is the result of the work of many people who made the code better - Adrien Brault (adrienbrault) - Tomáš Votruba (tomas_votruba) - Joshua Thijssen - - David Buchmann (dbu) - excelwebzone - Gordon Franke (gimler) - Fabien Pennequin (fabienpennequin) - Eric GELOEN (gelo) - Sebastiaan Stok (sstok) + - Jérôme Vasseur (jvasseur) - Lars Strojny (lstrojny) - Daniel Wehner (dawehner) - Tugdual Saunier (tucksaun) @@ -134,7 +135,6 @@ Symfony is the result of the work of many people who made the code better - Florian Lonqueu-Brochard (florianlb) - Chris Wilkinson (thewilkybarkid) - Stefano Sala (stefano.sala) - - Jérôme Vasseur (jvasseur) - Evgeniy (ewgraf) - Alex Pott - Vincent AUBERT (vincent) @@ -142,6 +142,7 @@ Symfony is the result of the work of many people who made the code better - Tigran Azatyan (tigranazatyan) - Sebastian Hörl (blogsh) - Daniel Gomes (danielcsgomes) + - Gabriel Caruso - Hidenori Goto (hidenorigoto) - Arnaud Kleinpeter (nanocom) - Jannik Zschiesche (apfelbox) @@ -165,6 +166,7 @@ Symfony is the result of the work of many people who made the code better - Clemens Tolboom - Helmer Aaviksoo - Hiromi Hishida (77web) + - Niels Keurentjes (curry684) - Matthieu Ouellette-Vachon (maoueh) - Michał Pipa (michal.pipa) - Dawid Nowak @@ -177,16 +179,16 @@ Symfony is the result of the work of many people who made the code better - jeremyFreeAgent (Jérémy Romey) (jeremyfreeagent) - James Halsall (jaitsu) - Matthieu Napoli (mnapoli) - - Gabriel Caruso - Warnar Boekkooi (boekkooi) + - Alessandro Chitolina (alekitto) - Dmitrii Chekaliuk (lazyhammer) - Clément JOBEILI (dator) - - Niels Keurentjes (curry684) - Daniel Espendiller - Possum - Dorian Villet (gnutix) - Sergey Linnik (linniksa) - Richard Miller (mr_r_miller) + - Albert Casademont (acasademont) - Mario A. Alvarez Garcia (nomack84) - Dennis Benkert (denderello) - DQNEO @@ -204,6 +206,7 @@ Symfony is the result of the work of many people who made the code better - sun (sun) - Larry Garfield (crell) - Michaël Perrin (michael.perrin) + - Nikolay Labinskiy (e-moe) - Martin Schuhfuß (usefulthink) - apetitpa - Matthieu Bontemps (mbontemps) @@ -225,15 +228,12 @@ Symfony is the result of the work of many people who made the code better - Tom Van Looy (tvlooy) - Sven Paulus (subsven) - Rui Marinho (ruimarinho) - - Alessandro Chitolina - Eugene Wissner - Pascal Montoya - Julien Brochet (mewt) - Leo Feyer - Tristan Darricau (nicofuma) - - Nikolay Labinskiy (e-moe) - Marcel Beerta (mazen) - - Albert Casademont (acasademont) - Pavel Batanov (scaytrase) - Loïc Faugeron - Hidde Wieringa (hiddewie) @@ -248,6 +248,7 @@ Symfony is the result of the work of many people who made the code better - Francois Zaninotto - Alexander Kotynia (olden) - Daniel Tschinder + - Christian Schmidt - Marcos Sánchez - Elnur Abdurrakhimov (elnur) - Manuel Reinhard (sprain) @@ -258,6 +259,7 @@ Symfony is the result of the work of many people who made the code better - Roman Marintšenko (inori) - Xavier Montaña Carreras (xmontana) - Mickaël Andrieu (mickaelandrieu) + - Maxime Veber (nek-) - Xavier Perez - Arjen Brouwer (arjenjb) - Katsuhiro OGAWA @@ -291,8 +293,8 @@ Symfony is the result of the work of many people who made the code better - Wodor Wodorski - Thomas Lallement (raziel057) - mcfedr (mcfedr) + - Colin O'Dell (colinodell) - Giorgio Premi - - Christian Schmidt - Beau Simensen (simensen) - Michael Hirschler (mvhirsch) - Robert Kiss (kepten) @@ -303,10 +305,10 @@ Symfony is the result of the work of many people who made the code better - Jérôme Parmentier (lctrs) - Michael Babker (mbabker) - Peter Kruithof (pkruithof) + - François-Xavier de Guillebon (de-gui_f) - Michael Holm (hollo) - Marc Weistroff (futurecat) - Christian Schmidt - - Maxime Veber (nek-) - MatTheCat - Chad Sikorra (chadsikorra) - Chris Smith (cs278) @@ -317,6 +319,7 @@ Symfony is the result of the work of many people who made the code better - rudy onfroy (ronfroy) - Andrew Moore (finewolf) - Bertrand Zuchuat (garfield-fr) + - Sullivan SENECHAL (soullivaneuh) - Gabor Toth (tgabi333) - realmfoo - Thomas Tourlourat (armetiz) @@ -346,8 +349,9 @@ Symfony is the result of the work of many people who made the code better - Thierry Thuon (lepiaf) - Ricard Clau (ricardclau) - Mark Challoner (markchalloner) - - Colin O'Dell (colinodell) - Gennady Telegin (gtelegin) + - Jan Schädlich (jschaedl) + - Fabien Bourigault (fbourigault) - Ben Davies (bendavies) - Erin Millard - Artur Melo (restless) @@ -363,7 +367,6 @@ Symfony is the result of the work of many people who made the code better - Christian Gärtner (dagardner) - Tomasz Kowalczyk (thunderer) - Artur Eshenbrener - - François-Xavier de Guillebon (de-gui_f) - Damien Alexandre (damienalexandre) - Thomas Perez (scullwm) - Felix Labrecque @@ -384,7 +387,6 @@ Symfony is the result of the work of many people who made the code better - Grzegorz (Greg) Zdanowski (kiler129) - Kirill chEbba Chebunin (chebba) - Greg Thornton (xdissent) - - Sullivan SENECHAL (soullivaneuh) - Costin Bereveanu (schniper) - Loïc Chardonnet (gnusat) - Marek Kalnik (marekkalnik) @@ -393,16 +395,19 @@ Symfony is the result of the work of many people who made the code better - Tamas Szijarto - Michele Locati - Pavel Volokitin (pvolok) + - Smaine Milianni (ismail1432) - Arthur de Moulins (4rthem) - Nicolas Dewez (nicolas_dewez) - Endre Fejes - Tobias Naumann (tna) + - George Mponos (gmponos) - Daniel Beyer - Shein Alexey - Alex Rock Ancelet (pierstoval) - Romain Gautier (mykiwi) - Joe Lencioni - Daniel Tschinder + - vladimir.reznichenko - Kai - Lee Rowlands - Krzysztof Piasecki (krzysztek) @@ -437,13 +442,13 @@ Symfony is the result of the work of many people who made the code better - Jan Schumann - Niklas Fiekas - Markus Bachmann (baachi) - - Jan Schädlich - lancergr - Zan Baldwin - Mihai Stancu - Olivier Dolbeau (odolbeau) - Jan Rosier (rosier) - Alessandro Lai (jean85) + - Pascal Luna (skalpa) - Arturs Vonda - Josip Kruslin - Asmir Mustafic (goetas) @@ -457,6 +462,7 @@ Symfony is the result of the work of many people who made the code better - Chris Sedlmayr (catchamonkey) - Mateusz Sip (mateusz_sip) - Remon van de Kamp + - Kamil Kokot (pamil) - Seb Koelen - Christoph Mewes (xrstf) - Vitaliy Tverdokhlib (vitaliytv) @@ -506,6 +512,7 @@ Symfony is the result of the work of many people who made the code better - Roy Van Ginneken (rvanginneken) - ondrowan - Barry vd. Heuvel (barryvdh) + - Craig Duncan (duncan3dc) - Sébastien Alfaiate (seb33300) - Evan S Kaufman (evanskaufman) - mcben @@ -513,7 +520,6 @@ Symfony is the result of the work of many people who made the code better - Maks Slesarenko - Filip Procházka (fprochazka) - mmoreram - - Smaine Milianni (ismail1432) - Markus Lanthaler (lanthaler) - Remi Collet - Vicent Soria Durá (vicentgodella) @@ -529,7 +535,6 @@ Symfony is the result of the work of many people who made the code better - Erik Trapman (eriktrapman) - De Cock Xavier (xdecock) - Almog Baku (almogbaku) - - George Mponos (gmponos) - Scott Arciszewski - Xavier HAUSHERR - Norbert Orzechowicz (norzechowicz) @@ -543,6 +548,7 @@ Symfony is the result of the work of many people who made the code better - Nate (frickenate) - Timothée Barray (tyx) - jhonnyL + - Grenier Kévin (mcsky_biig) - sasezaki - Dawid Pakuła (zulusx) - Florian Rey (nervo) @@ -579,6 +585,7 @@ Symfony is the result of the work of many people who made the code better - Jan Behrens - Mantas Var (mvar) - Sebastian Krebs + - Laurent VOULLEMIER (lvo) - Jean-Christophe Cuvelier [Artack] - Simon DELICATA - alcaeus @@ -625,12 +632,10 @@ Symfony is the result of the work of many people who made the code better - Erkhembayar Gantulga (erheme318) - Michal Trojanowski - David Fuhr - - Kamil Kokot (pamil) - Max Grigorian (maxakawizard) - DerManoMann - Rostyslav Kinash - Maciej Malarz (malarzm) - - Pascal Luna (skalpa) - Daisuke Ohata - Vincent Simonin - Alex Bogomazov (alebo) @@ -638,6 +643,7 @@ Symfony is the result of the work of many people who made the code better - adev - Stefan Warman - Arkadius Stefanski (arkadius) + - Gonzalo Vilaseca (gonzalovilaseca) - Tristan Maindron (tmaindron) - Wesley Lancel - Ke WANG (yktd26) @@ -645,6 +651,7 @@ Symfony is the result of the work of many people who made the code better - Strate - Anton A. Sumin - Israel J. Carberry + - Tim Goudriaan (codedmonkey) - Miquel Rodríguez Telep (mrtorrent) - Sergey Kolodyazhnyy (skolodyazhnyy) - umpirski @@ -665,6 +672,7 @@ Symfony is the result of the work of many people who made the code better - Jaroslav Kuba - Stephan Vock - Benjamin Zikarsky (bzikarsky) + - Roberto Espinoza (respinoza) - Simon Schick (simonsimcity) - redstar504 - Tristan Roussel @@ -716,7 +724,7 @@ Symfony is the result of the work of many people who made the code better - Pierre Rineau - Vladyslav Petrovych - Alex Xandra Albert Sim - - Craig Duncan (duncan3dc) + - Alexander Schranz (alexander-schranz) - Carson Full - Sergey Yastrebov - Trent Steel (trsteel88) @@ -787,14 +795,17 @@ Symfony is the result of the work of many people who made the code better - Patrick Dawkins (pjcdawkins) - Paul Kamer (pkamer) - Rafał Wrzeszcz (rafalwrzeszcz) + - Vincent CHALAMON (vincentchalamon) - Reen Lokum - Martin Parsiegla (spea) + - Nguyen Xuan Quynh (xuanquynh) - Quentin Schuler - Pierre Vanliefland (pvanliefland) - Sofiane HADDAG (sofhad) - frost-nzcr4 - Bozhidar Hristov - Ivan Nikolaev (destillat) + - Laurent Bassin (lbassin) - andrey1s - Abhoryo - Fabian Vogler (fabian) @@ -819,7 +830,6 @@ Symfony is the result of the work of many people who made the code better - Ivan Menshykov - David Romaní - Patrick Allaert - - Fabien Bourigault (fbourigault) - Gustavo Falco (gfalco) - Matt Robinson (inanimatt) - Ruud Kamphuis (ruudk) @@ -830,6 +840,7 @@ Symfony is the result of the work of many people who made the code better - Jörn Lang (j.lang) - Omar Yepez (oyepez003) - Gawain Lynch (gawain) + - Samuel NELA (snela) - mwsaz - Jelle Kapitein - Benoît Bourgeois @@ -838,6 +849,7 @@ Symfony is the result of the work of many people who made the code better - grizlik - Derek ROTH - Ben Johnson + - mweimerskirch - Dmytro Boiko (eagle) - Shin Ohno (ganchiku) - Geert De Deckere (geertdd) @@ -870,6 +882,7 @@ Symfony is the result of the work of many people who made the code better - Adán Lobato (adanlobato) - Ian Jenkins (jenkoian) - Matthew Davis (mdavis1982) + - Sam Fleming (sam_fleming) - Maks - Antoine LA - den @@ -880,6 +893,7 @@ Symfony is the result of the work of many people who made the code better - David Lima - Brian Freytag (brianfreytag) - Brunet Laurent (lbrunet) + - Florent Viel (luxifer) - Mikhail Yurasov (mym) - LOUARDI Abdeltif (ouardisoft) - Robert Gruendler (pulse00) @@ -891,8 +905,10 @@ Symfony is the result of the work of many people who made the code better - Erik Saunier (snickers) - Rootie - Kyle + - Daniel Alejandro Castro Arellano (lexcast) - Raul Fraile (raulfraile) - sensio + - Baptiste Leduc (bleduc) - Sebastien Morel (plopix) - Patrick Kaufmann - Piotr Stankowski @@ -1023,6 +1039,7 @@ Symfony is the result of the work of many people who made the code better - Michał Strzelecki - hugofonseca (fonsecas72) - Martynas Narbutas + - Toon Verwerft (veewee) - Bailey Parker - Eddie Jaoude - Antanas Arvasevicius @@ -1056,13 +1073,14 @@ Symfony is the result of the work of many people who made the code better - Alexander Cheprasov - Rodrigo Díez Villamuera (rodrigodiez) - e-ivanov - - Roberto Espinoza (respinoza) - Einenlum - Jochen Bayer (jocl) - Patrick Carlo-Hickman + - Bruno MATEU - Alex Bowers - Jeremy Bush - wizhippo + - Mathias STRASSER (roukmoute) - Thomason, James - Viacheslav Sychov - Helmut Hummel (helhum) @@ -1105,6 +1123,7 @@ Symfony is the result of the work of many people who made the code better - Pawel Smolinski - Oxan van Leeuwen - pkowalczyk + - Soner Sayakci - Max Voloshin (maxvoloshin) - Nicolas Fabre (nfabre) - Raul Rodriguez (raul782) @@ -1117,6 +1136,7 @@ Symfony is the result of the work of many people who made the code better - Felicitus - Krzysztof Przybyszewski - alexpozzi + - Frederic Godfrin - Paul Matthews - Jakub Kisielewski - Vacheslav Silyutin @@ -1206,6 +1226,7 @@ Symfony is the result of the work of many people who made the code better - Juanmi Rodriguez Cerón - Andy Raines - Anthony Ferrara + - Geoffrey Pécro (gpekz) - Klaas Cuvelier (kcuvelier) - Mathieu TUDISCO (mathieutu) - markusu49 @@ -1231,12 +1252,12 @@ Symfony is the result of the work of many people who made the code better - Andreas Frömer - Philip Frank - Lance McNearney - - Gonzalo Vilaseca (gonzalovilaseca) - Giorgio Premi - Andrew Berry - ncou - Ian Carroll - caponica + - Daniel Kay (danielkay-cp) - Matt Daum (daum) - Alberto Pirovano (geezmo) - Nicolas LEFEVRE (nicoweb) @@ -1271,7 +1292,6 @@ Symfony is the result of the work of many people who made the code better - Max Romanovsky (maxromanovsky) - Mathieu Morlon - Daniel Tschinder - - Alexander Schranz - Arnaud CHASSEUX - Rafał Muszyński (rafmus90) - Sébastien Decrême (sebdec) @@ -1368,6 +1388,8 @@ Symfony is the result of the work of many people who made the code better - Jakub Simon - Bouke Haarsma - Evert Harmeling + - mschop + - Alan Poulain - Martin Eckhardt - natechicago - Jonathan Poston @@ -1403,12 +1425,14 @@ Symfony is the result of the work of many people who made the code better - Jake Bishop (yakobeyak) - Dan Blows - Matt Wells + - Sander van der Vlugt - Nicolas Appriou - stloyd - Andreas - Chris Tickner - BoShurik - Andrew Coulton + - Ulugbek Miniyarov - Jeremy Benoist - Michal Gebauer - Gleb Sidora @@ -1441,9 +1465,9 @@ Symfony is the result of the work of many people who made the code better - Kamil Madejski - Jeremiah VALERIE - Mike Francis + - Gerd Christian Kunze (derdu) - Christoph Nissle (derstoffel) - Ionel Scutelnicu (ionelscutelnicu) - - Grenier Kévin (mcsky_biig) - Nicolas Tallefourtané (nicolab) - Botond Dani (picur) - Thierry Marianne (thierrymarianne) @@ -1461,6 +1485,7 @@ Symfony is the result of the work of many people who made the code better - Maksym Slesarenko (maksym_slesarenko) - Michal Kurzeja (mkurzeja) - Nicolas Bastien (nicolas_bastien) + - Nikola Svitlica (thecelavi) - Denis (yethee) - Andrew Zhilin (zhil) - Sjors Ottjes @@ -1504,6 +1529,7 @@ Symfony is the result of the work of many people who made the code better - Robin Duval (robin-duval) - Grinbergs Reinis (shima5) - Artem Lopata (bumz) + - alex - Nicole Cordes - Roman Orlov - VolCh @@ -1530,6 +1556,7 @@ Symfony is the result of the work of many people who made the code better - Dmitry Korotovsky - mcorteel - Michael van Tricht + - ReScO - Tim Strehle - Sam Ward - Walther Lalk @@ -1553,8 +1580,10 @@ Symfony is the result of the work of many people who made the code better - Dmitriy Fedorenko - vlakoff - bertillon + - Rudolf Ratusiński - Bertalan Attila - AmsTaFF (amstaff) + - Simon Müller (boscho) - Yannick Bensacq (cibou) - Frédéric G. Marand (fgm) - Freek Van der Herten (freekmurze) @@ -1569,6 +1598,7 @@ Symfony is the result of the work of many people who made the code better - Rares Vlaseanu (raresvla) - tante kinast (tante) - Vincent LEFORT (vlefort) + - Darryl Hein (xmmedia) - Sadicov Vladimir (xtech) - Kevin EMO (zarcox) - Alexander Zogheb @@ -1620,6 +1650,7 @@ Symfony is the result of the work of many people who made the code better - Matthieu Prat - Ion Bazan - Grummfy + - Paul Le Corre - Filipe Guerra - Jean Ragouin - Gerben Wijnja @@ -1636,7 +1667,7 @@ Symfony is the result of the work of many people who made the code better - Erik van Wingerden - Valouleloup - Dane Powell - - mweimerskirch + - Alexis MARQUIS - Gerrit Drost - Linnaea Von Lavia - Simon Mönch @@ -1655,6 +1686,7 @@ Symfony is the result of the work of many people who made the code better - Klaas Naaijkens - Daniel González Cerviño - Rafał + - Achilles Kaloeridis (achilles) - Adria Lopez (adlpz) - Aaron Scherer (aequasi) - Rosio (ben-rosio) @@ -1688,6 +1720,7 @@ Symfony is the result of the work of many people who made the code better - mlpo (mlpo) - Marek Šimeček (mssimi) - Cayetano Soriano Gallego (neoshadybeat) + - Olivier Laviale (olvlvl) - Ondrej Machulda (ondram) - Pablo Monterde Perez (plebs) - Jimmy Leger (redpanda) @@ -1798,7 +1831,6 @@ Symfony is the result of the work of many people who made the code better - Guillaume Aveline - Adrian Philipp - James Michael DuPont - - Tim Goudriaan - Kasperki - Tammy D - Daniel STANCU @@ -1875,6 +1907,7 @@ Symfony is the result of the work of many people who made the code better - phc - Дмитрий Пацура - ilyes kooli + - Marko Kaznovac - Matthias Althaus - Michaël VEROUX - Julia @@ -1937,7 +1970,6 @@ Symfony is the result of the work of many people who made the code better - samuel laulhau (lalop) - Laurent Bachelier (laurentb) - Luís Cobucci (lcobucci) - - Florent Viel (luxifer) - Matthieu Mota (matthieumota) - Matthieu Moquet (mattketmo) - Moritz Borgmann (mborgmann) @@ -1982,7 +2014,6 @@ Symfony is the result of the work of many people who made the code better - Moritz Kraft (userfriendly) - Víctor Mateo (victormateo) - Vincent (vincent1870) - - Vincent CHALAMON (vincentchalamon) - David Herrmann (vworldat) - Eugene Babushkin (warl) - Wouter Sioen (wouter_sioen) @@ -2025,13 +2056,11 @@ Symfony is the result of the work of many people who made the code better - Henne Van Och (hennevo) - Jeroen De Dauw (jeroendedauw) - Jonathan Scheiber (jmsche) - - Daniel Alejandro Castro Arellano (lexcast) - Maxime COLIN (maximecolin) - Muharrem Demirci (mdemirci) - Evgeny Z (meze) - Nicolas de Marqué (nicola) - Pierre Geyer (ptheg) - - Sam Fleming (sam_fleming) - Thomas BERTRAND (sevrahk) - Matej Žilák (teo_sk) - Vladislav Vlastovskiy (vlastv) diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit index 81b2e52d5a..51bf366283 100755 --- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit +++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit @@ -92,7 +92,7 @@ if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__ if (file_exists("phpunit-$PHPUNIT_VERSION")) { passthru(sprintf('\\' === DIRECTORY_SEPARATOR ? '(del /S /F /Q %s & rmdir %1$s) >nul': 'rm -rf %s', "phpunit-$PHPUNIT_VERSION")); } - if (extension_loaded('openssl') && ini_get('allow_url_fopen') && !isset($_SERVER['http_proxy']) && !isset($_SERVER['https_proxy'])) { + if (extension_loaded('openssl') && filter_var(ini_get('allow_url_fopen'), FILTER_VALIDATE_BOOLEAN) && !isset($_SERVER['http_proxy']) && !isset($_SERVER['https_proxy'])) { $remoteZip = "https://github.com/sebastianbergmann/phpunit/archive/$PHPUNIT_VERSION.zip"; $remoteZipStream = @fopen($remoteZip, 'rb'); if (!$remoteZipStream) { @@ -243,7 +243,7 @@ if ($components) { // STATUS_STACK_BUFFER_OVERRUN (-1073740791/0xC0000409) // STATUS_ACCESS_VIOLATION (-1073741819/0xC0000005) // STATUS_HEAP_CORRUPTION (-1073740940/0xC0000374) - if ($procStatus && ('\\' !== DIRECTORY_SEPARATOR || !extension_loaded('apcu') || !ini_get('apc.enable_cli') || !in_array($procStatus, array(-1073740791, -1073741819, -1073740940)))) { + if ($procStatus && ('\\' !== DIRECTORY_SEPARATOR || !extension_loaded('apcu') || !filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN) || !in_array($procStatus, array(-1073740791, -1073741819, -1073740940)))) { $exit = $procStatus; echo "\033[41mKO\033[0m $component\n\n"; } else { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php index 1536a5fbc4..d781f2a7e7 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php @@ -83,8 +83,8 @@ EOT array('Architecture', (PHP_INT_SIZE * 8).' bits'), array('Intl locale', class_exists('Locale', false) && \Locale::getDefault() ? \Locale::getDefault() : 'n/a'), array('Timezone', date_default_timezone_get().' ('.(new \DateTime())->format(\DateTime::W3C).')'), - array('OPcache', \extension_loaded('Zend OPcache') && ini_get('opcache.enable') ? 'true' : 'false'), - array('APCu', \extension_loaded('apcu') && ini_get('apc.enabled') ? 'true' : 'false'), + array('OPcache', \extension_loaded('Zend OPcache') && filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN) ? 'true' : 'false'), + array('APCu', \extension_loaded('apcu') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? 'true' : 'false'), array('Xdebug', \extension_loaded('xdebug') ? 'true' : 'false'), ); diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php index f6badd0552..8756d6133b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php @@ -344,6 +344,20 @@ class JsonDescriptor extends Descriptor if ($callable instanceof \Closure) { $data['type'] = 'closure'; + $r = new \ReflectionFunction($callable); + if (false !== strpos($r->name, '{closure}')) { + return $data; + } + $data['name'] = $r->name; + + $class = ($class = $r->getClosureThis()) ? \get_class($class) : null; + if ($scopeClass = $r->getClosureScopeClass() ?: $class) { + $data['class'] = $scopeClass; + if (!$class) { + $data['static'] = true; + } + } + return $data; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php index 85802d6975..23b420dd74 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php @@ -353,6 +353,20 @@ class MarkdownDescriptor extends Descriptor if ($callable instanceof \Closure) { $string .= "\n- Type: `closure`"; + $r = new \ReflectionFunction($callable); + if (false !== strpos($r->name, '{closure}')) { + return $this->write($string."\n"); + } + $string .= "\n".sprintf('- Name: `%s`', $r->name); + + $class = ($class = $r->getClosureThis()) ? \get_class($class) : null; + if ($scopeClass = $r->getClosureScopeClass() ?: $class) { + $string .= "\n".sprintf('- Class: `%s`', $class); + if (!$class) { + $string .= "\n- Static: yes"; + } + } + return $this->write($string."\n"); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php index f1f064c4f5..9a394da844 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php @@ -57,12 +57,7 @@ class TextDescriptor extends Descriptor if ($showControllers) { $controller = $route->getDefault('_controller'); - if ($controller instanceof \Closure) { - $controller = 'Closure'; - } elseif (\is_object($controller)) { - $controller = \get_class($controller); - } - $row[] = $controller; + $row[] = $this->formatCallable($controller); } $tableRows[] = $row; @@ -464,7 +459,18 @@ class TextDescriptor extends Descriptor } if ($callable instanceof \Closure) { - return '\Closure()'; + $r = new \ReflectionFunction($callable); + if (false !== strpos($r->name, '{closure}')) { + return 'Closure()'; + } + if ($class = $r->getClosureScopeClass()) { + return sprintf('%s::%s()', $class, $r->name); + } + if ($class = $r->getClosureThis()) { + return sprintf('%s::%s()', \get_class($class), $r->name); + } + + return $r->name.'()'; } if (method_exists($callable, '__invoke')) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php index bac8469fc9..1a5759c7a5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php @@ -524,6 +524,20 @@ class XmlDescriptor extends Descriptor if ($callable instanceof \Closure) { $callableXML->setAttribute('type', 'closure'); + $r = new \ReflectionFunction($callable); + if (false !== strpos($r->name, '{closure}')) { + return $dom; + } + $callableXML->setAttribute('name', $r->name); + + $class = ($class = $r->getClosureThis()) ? \get_class($class) : null; + if ($scopeClass = $r->getClosureScopeClass() ?: $class) { + $callableXML->setAttribute('class', $class); + if (!$class) { + $callableXML->setAttribute('static', 'true'); + } + } + return $dom; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_6.txt b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_6.txt index 9b030ab791..8bf37d37b9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_6.txt +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_6.txt @@ -1 +1 @@ -\Closure() \ No newline at end of file +Closure() diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_event1.txt b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_event1.txt index 99c7cba66f..f7a3cb0bd9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_event1.txt +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_event1.txt @@ -6,6 +6,6 @@  Order   Callable   Priority  ------- ------------------- ---------- #1 global_function() 255 - #2 \Closure() -1 + #2 Closure() -1 ------- ------------------- ---------- diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_events.txt b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_events.txt index 687323e9ed..475ad24cfd 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_events.txt +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_events.txt @@ -9,7 +9,7 @@  Order   Callable   Priority  ------- ------------------- ---------- #1 global_function() 255 - #2 \Closure() -1 + #2 Closure() -1 ------- ------------------- ---------- "event2" event diff --git a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php index e3b2a30987..571eb1468a 100644 --- a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php @@ -122,7 +122,7 @@ abstract class AbstractAdapter implements AdapterInterface, CacheInterface, Logg } $apcu = new ApcuAdapter($namespace, (int) $defaultLifetime / 5, $version); - if ('cli' === \PHP_SAPI && !ini_get('apc.enable_cli')) { + if ('cli' === \PHP_SAPI && !filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN)) { $apcu->setLogger(new NullLogger()); } elseif (null !== $logger) { $apcu->setLogger($logger); diff --git a/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php b/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php index bcc7a7c12f..22a4564d87 100644 --- a/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php @@ -68,7 +68,7 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte public static function create($file, CacheItemPoolInterface $fallbackPool) { // Shared memory is available in PHP 7.0+ with OPCache enabled - if (ini_get('opcache.enable')) { + if (filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN)) { if (!$fallbackPool instanceof AdapterInterface) { $fallbackPool = new ProxyAdapter($fallbackPool); } diff --git a/src/Symfony/Component/Cache/Simple/PhpArrayCache.php b/src/Symfony/Component/Cache/Simple/PhpArrayCache.php index 047ceea4ef..f25bb67bb9 100644 --- a/src/Symfony/Component/Cache/Simple/PhpArrayCache.php +++ b/src/Symfony/Component/Cache/Simple/PhpArrayCache.php @@ -48,7 +48,7 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt public static function create($file, CacheInterface $fallbackPool) { // Shared memory is available in PHP 7.0+ with OPCache enabled - if (ini_get('opcache.enable')) { + if (filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN)) { return new static($file, $fallbackPool); } diff --git a/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php index 2b3c6b4432..a17b42bce4 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php @@ -24,10 +24,10 @@ class ApcuAdapterTest extends AdapterTestCase public function createCachePool($defaultLifetime = 0) { - if (!\function_exists('apcu_fetch') || !ini_get('apc.enabled')) { + if (!\function_exists('apcu_fetch') || !filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN)) { $this->markTestSkipped('APCu extension is required.'); } - if ('cli' === \PHP_SAPI && !ini_get('apc.enable_cli')) { + if ('cli' === \PHP_SAPI && !filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN)) { if ('testWithCliSapi' !== $this->getName()) { $this->markTestSkipped('apc.enable_cli=1 is required.'); } diff --git a/src/Symfony/Component/Cache/Tests/Adapter/MemcachedAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/MemcachedAdapterTest.php index 46e9f4e5d5..85292994fe 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/MemcachedAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/MemcachedAdapterTest.php @@ -137,7 +137,7 @@ class MemcachedAdapterTest extends AdapterTestCase 'localhost', 11222, ); - if (ini_get('memcached.use_sasl')) { + if (filter_var(ini_get('memcached.use_sasl'), FILTER_VALIDATE_BOOLEAN)) { yield array( 'memcached://user:password@127.0.0.1?weight=50', '127.0.0.1', @@ -154,7 +154,7 @@ class MemcachedAdapterTest extends AdapterTestCase '/var/local/run/memcached.socket', 0, ); - if (ini_get('memcached.use_sasl')) { + if (filter_var(ini_get('memcached.use_sasl'), FILTER_VALIDATE_BOOLEAN)) { yield array( 'memcached://user:password@/var/local/run/memcached.socket?weight=25', '/var/local/run/memcached.socket', diff --git a/src/Symfony/Component/Cache/Tests/Simple/ApcuCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/ApcuCacheTest.php index 737ed4e99d..3df32c1c5e 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/ApcuCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/ApcuCacheTest.php @@ -23,7 +23,7 @@ class ApcuCacheTest extends CacheTestCase public function createSimpleCache($defaultLifetime = 0) { - if (!\function_exists('apcu_fetch') || !ini_get('apc.enabled') || ('cli' === \PHP_SAPI && !ini_get('apc.enable_cli'))) { + if (!\function_exists('apcu_fetch') || !filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) || ('cli' === \PHP_SAPI && !filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN))) { $this->markTestSkipped('APCu extension is required.'); } if ('\\' === \DIRECTORY_SEPARATOR) { diff --git a/src/Symfony/Component/Cache/Tests/Simple/MemcachedCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/MemcachedCacheTest.php index b46d7e443d..ee9e49d3dd 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/MemcachedCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/MemcachedCacheTest.php @@ -146,7 +146,7 @@ class MemcachedCacheTest extends CacheTestCase 'localhost', 11222, ); - if (ini_get('memcached.use_sasl')) { + if (filter_var(ini_get('memcached.use_sasl'), FILTER_VALIDATE_BOOLEAN)) { yield array( 'memcached://user:password@127.0.0.1?weight=50', '127.0.0.1', @@ -163,7 +163,7 @@ class MemcachedCacheTest extends CacheTestCase '/var/local/run/memcached.socket', 0, ); - if (ini_get('memcached.use_sasl')) { + if (filter_var(ini_get('memcached.use_sasl'), FILTER_VALIDATE_BOOLEAN)) { yield array( 'memcached://user:password@/var/local/run/memcached.socket?weight=25', '/var/local/run/memcached.socket', diff --git a/src/Symfony/Component/Cache/Traits/ApcuTrait.php b/src/Symfony/Component/Cache/Traits/ApcuTrait.php index 616227f634..a93fc812a1 100644 --- a/src/Symfony/Component/Cache/Traits/ApcuTrait.php +++ b/src/Symfony/Component/Cache/Traits/ApcuTrait.php @@ -23,7 +23,7 @@ trait ApcuTrait { public static function isSupported() { - return \function_exists('apcu_fetch') && ini_get('apc.enabled'); + return \function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN); } private function init($namespace, $defaultLifetime, $version) @@ -81,7 +81,7 @@ trait ApcuTrait */ protected function doClear($namespace) { - return isset($namespace[0]) && class_exists('APCuIterator', false) && ('cli' !== \PHP_SAPI || ini_get('apc.enable_cli')) + return isset($namespace[0]) && class_exists('APCuIterator', false) && ('cli' !== \PHP_SAPI || filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN)) ? apcu_delete(new \APCuIterator(sprintf('/^%s/', preg_quote($namespace, '/')), APC_ITER_KEY)) : apcu_clear_cache(); } diff --git a/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php b/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php index 2d021f0f79..4dacec8cfc 100644 --- a/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php +++ b/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php @@ -40,7 +40,7 @@ trait PhpFilesTrait { self::$startTime = self::$startTime ?? $_SERVER['REQUEST_TIME'] ?? time(); - return \function_exists('opcache_invalidate') && ini_get('opcache.enable') && ('cli' !== \PHP_SAPI || ini_get('opcache.enable_cli')); + return \function_exists('opcache_invalidate') && ('cli' !== \PHP_SAPI || filter_var(ini_get('opcache.enable_cli'), FILTER_VALIDATE_BOOLEAN)) && filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN); } /** diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php index 581e62c10d..4aa6fbf6dc 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php @@ -369,7 +369,17 @@ class AutowirePass extends AbstractRecursivePass private function createTypeNotFoundMessage(TypedReference $reference, $label) { - if (!$r = $this->container->getReflectionClass($type = $reference->getType(), false)) { + $trackResources = $this->container->isTrackingResources(); + $this->container->setResourceTracking(false); + try { + if ($r = $this->container->getReflectionClass($type = $reference->getType(), false)) { + $alternatives = $this->createTypeAlternatives($reference); + } + } finally { + $this->container->setResourceTracking($trackResources); + } + + if (!$r) { // either $type does not exist or a parent class does not exist try { $resource = new ClassExistenceResource($type, false); @@ -382,7 +392,6 @@ class AutowirePass extends AbstractRecursivePass $message = sprintf('has type "%s" but this class %s.', $type, $parentMsg ? sprintf('is missing a parent class (%s)', $parentMsg) : 'was not found'); } else { - $alternatives = $this->createTypeAlternatives($reference); $message = $this->container->has($type) ? 'this service is abstract' : 'no such service exists'; $message = sprintf('references %s "%s" but %s.%s', $r->isInterface() ? 'interface' : 'class', $type, $message, $alternatives); diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 43e2167d5c..f49288ccf6 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -346,7 +346,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface try { if (isset($this->classReflectors[$class])) { $classReflector = $this->classReflectors[$class]; - } elseif ($this->trackResources) { + } elseif (class_exists(ClassExistenceResource::class)) { $resource = new ClassExistenceResource($class, false); $classReflector = $resource->isFresh(0) ? false : new \ReflectionClass($class); } else { diff --git a/src/Symfony/Component/DependencyInjection/Dumper/GraphvizDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/GraphvizDumper.php index 9c35e066e7..8cef0549bb 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/GraphvizDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/GraphvizDumper.php @@ -132,6 +132,14 @@ class GraphvizDumper extends Dumper $edges[] = array('name' => $name, 'required' => $required, 'to' => $argument, 'lazy' => $lazyEdge); } elseif ($argument instanceof ArgumentInterface) { $edges = array_merge($edges, $this->findEdges($id, $argument->getValues(), $required, $name, true)); + } elseif ($argument instanceof Definition) { + $edges = array_merge($edges, + $this->findEdges($id, $argument->getArguments(), $required, ''), + $this->findEdges($id, $argument->getProperties(), false, '') + ); + foreach ($argument->getMethodCalls() as $call) { + $edges = array_merge($edges, $this->findEdges($id, $call[1], false, $call[0].'()')); + } } elseif (\is_array($argument)) { $edges = array_merge($edges, $this->findEdges($id, $argument, $required, $name, $lazy)); } diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 02197975bb..3649ef780c 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -342,9 +342,13 @@ EOF; if ($node->getValue() && ($edge->isLazy() || $edge->isWeak())) { // no-op } elseif (isset($currentPath[$id])) { + $currentId = $id; foreach (array_reverse($currentPath) as $parentId) { - $this->circularReferences[$parentId][$id] = $id; - $id = $parentId; + $this->circularReferences[$parentId][$currentId] = $currentId; + if ($parentId === $id) { + break; + } + $currentId = $parentId; } } elseif (!isset($checkedNodes[$id])) { $checkedNodes[$id] = true; @@ -459,7 +463,7 @@ EOF; * @throws InvalidArgumentException * @throws RuntimeException */ - private function addServiceInstance(string $id, Definition $definition, string $isSimpleInstance): string + private function addServiceInstance(string $id, Definition $definition, bool $isSimpleInstance): string { $class = $this->dumpValue($definition->getClass()); @@ -585,7 +589,7 @@ EOF; $this->definitionVariables = new \SplObjectStorage(); $this->referenceVariables = array(); $this->variableCount = 0; - $this->definitionVariables[$definition] = $this->referenceVariables[$id] = new Variable('instance'); + $this->referenceVariables[$id] = new Variable('instance'); $return = array(); @@ -658,22 +662,7 @@ EOF; $code .= sprintf(" @trigger_error(%s, E_USER_DEPRECATED);\n\n", $this->export($definition->getDeprecationMessage($id))); } - $head = $tail = ''; - $arguments = array($definition->getArguments(), $definition->getFactory()); - $this->addInlineVariables($head, $tail, $id, $arguments, true); - $code .= '' !== $head ? $head."\n" : ''; - - if ($arguments = array_filter(array($definition->getProperties(), $definition->getMethodCalls(), $definition->getConfigurator()))) { - $this->addInlineVariables($tail, $tail, $id, $arguments, false); - - $tail .= '' !== $tail ? "\n" : ''; - $tail .= $this->addServiceProperties($definition); - $tail .= $this->addServiceMethodCalls($definition); - $tail .= $this->addServiceConfigurator($definition); - } - - $code .= $this->addServiceInstance($id, $definition, '' === $tail) - .('' !== $tail ? "\n".$tail."\n return \$instance;\n" : ''); + $code .= $this->addInlineService($id, $definition); if ($asFile) { $code = implode("\n", array_map(function ($line) { return $line ? substr($line, 8) : $line; }, explode("\n", $code))); @@ -687,35 +676,41 @@ EOF; return array($file, $code); } - private function addInlineVariables(string &$head, string &$tail, string $id, array $arguments, bool $forConstructor): bool + private function addInlineVariables(string $id, Definition $definition, array $arguments, bool $forConstructor): string { - $hasSelfRef = false; + $code = ''; foreach ($arguments as $argument) { if (\is_array($argument)) { - $hasSelfRef = $this->addInlineVariables($head, $tail, $id, $argument, $forConstructor) || $hasSelfRef; + $code .= $this->addInlineVariables($id, $definition, $argument, $forConstructor); } elseif ($argument instanceof Reference) { - $hasSelfRef = $this->addInlineReference($head, $id, $argument, $forConstructor) || $hasSelfRef; + $code .= $this->addInlineReference($id, $definition, $argument, $forConstructor); } elseif ($argument instanceof Definition) { - $hasSelfRef = $this->addInlineService($head, $tail, $id, $argument, $forConstructor) || $hasSelfRef; + $code .= $this->addInlineService($id, $definition, $argument, $forConstructor); } } - return $hasSelfRef; + return $code; } - private function addInlineReference(string &$code, string $id, string $targetId, bool $forConstructor): bool + private function addInlineReference(string $id, Definition $definition, string $targetId, bool $forConstructor): string { - $hasSelfRef = isset($this->circularReferences[$id][$targetId]); - - if ('service_container' === $targetId || isset($this->referenceVariables[$targetId])) { - return $hasSelfRef; + if ($id === $targetId) { + return $this->addInlineService($id, $definition, $definition, $forConstructor); } + if ('service_container' === $targetId || isset($this->referenceVariables[$targetId])) { + return ''; + } + + $hasSelfRef = isset($this->circularReferences[$id][$targetId]); + $forConstructor = $forConstructor && !isset($this->definitionVariables[$definition]); list($callCount, $behavior) = $this->serviceCalls[$targetId]; - if (2 > $callCount && (!$hasSelfRef || !$forConstructor)) { - return $hasSelfRef; + $code = $hasSelfRef && !$forConstructor ? $this->addInlineService($id, $definition, $definition, $forConstructor) : ''; + + if (isset($this->referenceVariables[$targetId]) || (2 > $callCount && (!$hasSelfRef || !$forConstructor))) { + return $code; } $name = $this->getNextVariableName(); @@ -725,7 +720,7 @@ EOF; $code .= sprintf(" \$%s = %s;\n", $name, $this->getServiceCall($targetId, $reference)); if (!$hasSelfRef || !$forConstructor) { - return $hasSelfRef; + return $code; } $code .= sprintf(<<<'EOTXT' @@ -740,46 +735,56 @@ EOTXT $id ); - return false; + return $code; } - private function addInlineService(string &$head, string &$tail, string $id, Definition $definition, bool $forConstructor): bool + private function addInlineService(string $id, Definition $definition, Definition $inlineDef = null, bool $forConstructor = true): string { - if (isset($this->definitionVariables[$definition])) { - return false; + $isSimpleInstance = $isRootInstance = null === $inlineDef; + + if (isset($this->definitionVariables[$inlineDef = $inlineDef ?: $definition])) { + return ''; } - $arguments = array($definition->getArguments(), $definition->getFactory()); + $arguments = array($inlineDef->getArguments(), $inlineDef->getFactory()); - if (2 > $this->inlinedDefinitions[$definition] && !$definition->getMethodCalls() && !$definition->getProperties() && !$definition->getConfigurator()) { - return $this->addInlineVariables($head, $tail, $id, $arguments, $forConstructor); + $code = $this->addInlineVariables($id, $definition, $arguments, $forConstructor); + + if ($arguments = array_filter(array($inlineDef->getProperties(), $inlineDef->getMethodCalls(), $inlineDef->getConfigurator()))) { + $isSimpleInstance = false; + } elseif ($definition !== $inlineDef && 2 > $this->inlinedDefinitions[$inlineDef]) { + return $code; } - $name = $this->getNextVariableName(); - $this->definitionVariables[$definition] = new Variable($name); - - $code = ''; - if ($forConstructor) { - $hasSelfRef = $this->addInlineVariables($code, $tail, $id, $arguments, $forConstructor); + if (isset($this->definitionVariables[$inlineDef])) { + $isSimpleInstance = false; } else { - $hasSelfRef = $this->addInlineVariables($code, $code, $id, $arguments, $forConstructor); - } - $code .= $this->addNewInstance($definition, ' $'.$name.' = ', $id); - $hasSelfRef && !$forConstructor ? $tail .= ('' !== $tail ? "\n" : '').$code : $head .= ('' !== $head ? "\n" : '').$code; + $name = $definition === $inlineDef ? 'instance' : $this->getNextVariableName(); + $this->definitionVariables[$inlineDef] = new Variable($name); + $code .= '' !== $code ? "\n" : ''; - $code = ''; - $arguments = array($definition->getProperties(), $definition->getMethodCalls(), $definition->getConfigurator()); - $hasSelfRef = $this->addInlineVariables($code, $code, $id, $arguments, false) || $hasSelfRef; + if ('instance' === $name) { + $code .= $this->addServiceInstance($id, $definition, $isSimpleInstance); + } else { + $code .= $this->addNewInstance($inlineDef, ' $'.$name.' = ', $id); + } - $code .= '' !== $code ? "\n" : ''; - $code .= $this->addServiceProperties($definition, $name); - $code .= $this->addServiceMethodCalls($definition, $name); - $code .= $this->addServiceConfigurator($definition, $name); - if ('' !== $code) { - $hasSelfRef ? $tail .= ('' !== $tail ? "\n" : '').$code : $head .= $code; + if ('' !== $inline = $this->addInlineVariables($id, $definition, $arguments, false)) { + $code .= "\n".$inline."\n"; + } elseif ($arguments && 'instance' === $name) { + $code .= "\n"; + } + + $code .= $this->addServiceProperties($inlineDef, $name); + $code .= $this->addServiceMethodCalls($inlineDef, $name); + $code .= $this->addServiceConfigurator($inlineDef, $name); } - return $hasSelfRef; + if ($isRootInstance && !$isSimpleInstance) { + $code .= "\n return \$instance;\n"; + } + + return $code; } private function addServices(array &$services = null): string diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 529df68f86..af3962dd04 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -1362,6 +1362,8 @@ class ContainerBuilderTest extends TestCase $foo6 = $container->get('foo6'); $this->assertEquals((object) array('bar6' => (object) array()), $foo6); + + $this->assertInstanceOf(\stdClass::class, $container->get('root')); } public function provideAlmostCircular() diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/GraphvizDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/GraphvizDumperTest.php index ffdd0730c7..3c40bb5504 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/GraphvizDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/GraphvizDumperTest.php @@ -13,7 +13,9 @@ namespace Symfony\Component\DependencyInjection\Tests\Dumper; use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Dumper\GraphvizDumper; +use Symfony\Component\DependencyInjection\Reference; class GraphvizDumperTest extends TestCase { @@ -32,11 +34,11 @@ class GraphvizDumperTest extends TestCase $container = include self::$fixturesPath.'/containers/container9.php'; $dumper = new GraphvizDumper($container); - $this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services9.dot')), $dumper->dump(), '->dump() dumps services'); + $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services9.dot', $dumper->dump(), '->dump() dumps services'); $container = include self::$fixturesPath.'/containers/container10.php'; $dumper = new GraphvizDumper($container); - $this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services10.dot')), $dumper->dump(), '->dump() dumps services'); + $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services10.dot', $dumper->dump(), '->dump() dumps services'); $container = include self::$fixturesPath.'/containers/container10.php'; $dumper = new GraphvizDumper($container); @@ -47,21 +49,21 @@ class GraphvizDumperTest extends TestCase 'node.instance' => array('fillcolor' => 'green', 'style' => 'empty'), 'node.definition' => array('fillcolor' => 'grey'), 'node.missing' => array('fillcolor' => 'red', 'style' => 'empty'), - )), str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services10-1.dot')), '->dump() dumps services'); + )), file_get_contents(self::$fixturesPath.'/graphviz/services10-1.dot'), '->dump() dumps services'); } public function testDumpWithFrozenContainer() { $container = include self::$fixturesPath.'/containers/container13.php'; $dumper = new GraphvizDumper($container); - $this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services13.dot')), $dumper->dump(), '->dump() dumps services'); + $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services13.dot', $dumper->dump(), '->dump() dumps services'); } public function testDumpWithFrozenCustomClassContainer() { $container = include self::$fixturesPath.'/containers/container14.php'; $dumper = new GraphvizDumper($container); - $this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services14.dot')), $dumper->dump(), '->dump() dumps services'); + $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services14.dot', $dumper->dump(), '->dump() dumps services'); } public function testDumpWithUnresolvedParameter() @@ -69,6 +71,18 @@ class GraphvizDumperTest extends TestCase $container = include self::$fixturesPath.'/containers/container17.php'; $dumper = new GraphvizDumper($container); - $this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services17.dot')), $dumper->dump(), '->dump() dumps services'); + $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services17.dot', $dumper->dump(), '->dump() dumps services'); + } + + public function testDumpWithInlineDefinition() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->addArgument( + (new Definition('stdClass'))->addArgument(new Reference('bar')) + ); + $container->register('bar', 'stdClass'); + $dumper = new GraphvizDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services_inline.dot', $dumper->dump(), '->dump() dumps nested references'); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 941404c410..9798d849fa 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -880,6 +880,8 @@ class PhpDumperTest extends TestCase $foo6 = $container->get('foo6'); $this->assertEquals((object) array('bar6' => (object) array()), $foo6); + + $this->assertInstanceOf(\stdClass::class, $container->get('root')); } public function provideAlmostCircular() diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/FooForCircularWithAddCalls.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/FooForCircularWithAddCalls.php new file mode 100644 index 0000000000..a8331dc3eb --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/FooForCircularWithAddCalls.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Fixtures; + +class FooForCircularWithAddCalls +{ + public function call(\stdClass $argument) + { + } +} diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php index 3286f3d02f..4c9906f7ae 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php @@ -4,6 +4,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Dumper\PhpDumper; use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls; $public = 'public' === $visibility; $container = new ContainerBuilder(); @@ -115,4 +116,33 @@ $container->register('baz6', 'stdClass') ->setPublic(true) ->setProperty('bar6', new Reference('bar6')); +// provided by Christian Schiffler + +$container + ->register('root', 'stdClass') + ->setArguments([new Reference('level2'), new Reference('multiuse1')]) + ->setPublic(true); + +$container + ->register('level2', FooForCircularWithAddCalls::class) + ->addMethodCall('call', [new Reference('level3')]); + +$container->register('multiuse1', 'stdClass'); + +$container + ->register('level3', 'stdClass') + ->addArgument(new Reference('level4')); + +$container + ->register('level4', 'stdClass') + ->setArguments([new Reference('multiuse1'), new Reference('level5')]); + +$container + ->register('level5', 'stdClass') + ->addArgument(new Reference('level6')); + +$container + ->register('level6', FooForCircularWithAddCalls::class) + ->addMethodCall('call', [new Reference('level5')]); + return $container; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services_inline.dot b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services_inline.dot new file mode 100644 index 0000000000..b430b186d7 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services_inline.dot @@ -0,0 +1,10 @@ +digraph sc { + ratio="compress" + node [fontsize="11" fontname="Arial" shape="record"]; + edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"]; + + node_service_container [label="service_container (Psr\Container\ContainerInterface, Symfony\Component\DependencyInjection\ContainerInterface)\nSymfony\\Component\\DependencyInjection\\ContainerInterface\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_foo [label="foo\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_bar [label="bar\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_foo -> node_bar [label="" style="filled"]; +} diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt index 5bf6366c1c..903bd51bb3 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt @@ -221,7 +221,6 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException; $this->services['foo_with_inline'] = $instance = new \Foo(); $a = new \Bar(); - $a->pub = 'pub'; $a->setBaz(($this->services['baz'] ?? $this->load('getBazService.php'))); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php index b9560ffb2b..178280a02e 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php @@ -290,7 +290,6 @@ class ProjectServiceContainer extends Container $this->services['foo_with_inline'] = $instance = new \Foo(); $a = new \Bar(); - $a->pub = 'pub'; $a->setBaz(($this->services['baz'] ?? $this->getBazService())); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_adawson.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_adawson.php index e854e1781b..136972846b 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_adawson.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_adawson.php @@ -65,14 +65,13 @@ class ProjectServiceContainer extends Container $this->services['App\Bus'] = $instance = new \App\Bus($a); $b = ($this->privates['App\Schema'] ?? $this->getSchemaService()); + $c = new \App\Registry(); + $c->processor = array(0 => $a, 1 => $instance); - $d = new \App\Registry(); + $d = new \App\Processor($c, $a); - $d->processor = array(0 => $a, 1 => $instance); - $c = new \App\Processor($d, $a); - - $instance->handler1 = new \App\Handler1($a, $b, $c); - $instance->handler2 = new \App\Handler2($a, $b, $c); + $instance->handler1 = new \App\Handler1($a, $b, $d); + $instance->handler2 = new \App\Handler2($a, $b, $d); return $instance; } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php index 13a4c2407e..198427402a 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php @@ -36,6 +36,7 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container 'logger' => 'getLoggerService', 'manager' => 'getManagerService', 'manager2' => 'getManager2Service', + 'root' => 'getRootService', 'subscriber' => 'getSubscriberService', ); @@ -68,7 +69,13 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container 'foobar' => true, 'foobar2' => true, 'foobar3' => true, + 'level2' => true, + 'level3' => true, + 'level4' => true, + 'level5' => true, + 'level6' => true, 'logger2' => true, + 'multiuse1' => true, 'subscriber2' => true, ); } @@ -130,10 +137,10 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container $this->services['connection'] = $instance = new \stdClass($a, $b); - $a->subscriber = ($this->services['subscriber'] ?? $this->getSubscriberService()); - $b->logger = ($this->services['logger'] ?? $this->getLoggerService()); + $a->subscriber = ($this->services['subscriber'] ?? $this->getSubscriberService()); + return $instance; } @@ -146,19 +153,19 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container { $a = new \stdClass(); - $c = new \stdClass(); + $b = new \stdClass(); - $this->services['connection2'] = $instance = new \stdClass($a, $c); + $this->services['connection2'] = $instance = new \stdClass($a, $b); - $b = ($this->services['manager2'] ?? $this->getManager2Service()); + $c = new \stdClass($instance); - $a->subscriber2 = new \stdClass($b); + $d = ($this->services['manager2'] ?? $this->getManager2Service()); - $d = new \stdClass($instance); + $c->handler2 = new \stdClass($d); - $d->handler2 = new \stdClass($b); + $b->logger2 = $c; - $c->logger2 = $d; + $a->subscriber2 = new \stdClass($d); return $instance; } @@ -205,7 +212,6 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container $this->services['foo5'] = $instance = new \stdClass(); $a = new \stdClass($instance); - $a->foo = $instance; $instance->bar = $a; @@ -295,6 +301,22 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container return $this->services['manager2'] = new \stdClass($a); } + /** + * Gets the public 'root' shared service. + * + * @return \stdClass + */ + protected function getRootService() + { + $a = new \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls(); + + $b = new \stdClass(); + + $a->call(new \stdClass(new \stdClass($b, ($this->privates['level5'] ?? $this->getLevel5Service())))); + + return $this->services['root'] = new \stdClass($a, $b); + } + /** * Gets the public 'subscriber' shared service. * @@ -326,4 +348,20 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container return $this->privates['bar6'] = new \stdClass($a); } + + /** + * Gets the private 'level5' shared service. + * + * @return \stdClass + */ + protected function getLevel5Service() + { + $a = new \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls(); + + $this->privates['level5'] = $instance = new \stdClass($a); + + $a->call($instance); + + return $instance; + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php index 84ebe8df35..4aea8f6c57 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php @@ -43,6 +43,7 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container 'logger' => 'getLoggerService', 'manager' => 'getManagerService', 'manager2' => 'getManager2Service', + 'root' => 'getRootService', 'subscriber' => 'getSubscriberService', ); @@ -68,7 +69,13 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container 'bar6' => true, 'config' => true, 'config2' => true, + 'level2' => true, + 'level3' => true, + 'level4' => true, + 'level5' => true, + 'level6' => true, 'logger2' => true, + 'multiuse1' => true, 'subscriber2' => true, ); } @@ -165,7 +172,6 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container $this->services['connection2'] = $instance = new \stdClass(($this->services['dispatcher2'] ?? $this->getDispatcher2Service()), $a); $b = new \stdClass($instance); - $b->handler2 = new \stdClass(($this->services['manager2'] ?? $this->getManager2Service())); $a->logger2 = $b; @@ -385,6 +391,22 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container return $this->services['manager2'] = new \stdClass($a); } + /** + * Gets the public 'root' shared service. + * + * @return \stdClass + */ + protected function getRootService() + { + $a = new \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls(); + + $b = new \stdClass(); + + $a->call(new \stdClass(new \stdClass($b, ($this->privates['level5'] ?? $this->getLevel5Service())))); + + return $this->services['root'] = new \stdClass($a, $b); + } + /** * Gets the public 'subscriber' shared service. * @@ -410,4 +432,20 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container return $this->privates['bar6'] = new \stdClass($a); } + + /** + * Gets the private 'level5' shared service. + * + * @return \stdClass + */ + protected function getLevel5Service() + { + $a = new \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls(); + + $this->privates['level5'] = $instance = new \stdClass($a); + + $a->call($instance); + + return $instance; + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_deep_graph.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_deep_graph.php index e3500596c6..f729fd540e 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_deep_graph.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_deep_graph.php @@ -74,8 +74,8 @@ class Symfony_DI_PhpDumper_Test_Deep_Graph extends Container if (isset($this->services['foo'])) { return $this->services['foo']; } - $b = new \stdClass(); + $c = new \stdClass(); $c->p3 = new \stdClass(); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_errored_definition.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_errored_definition.php index b0506aae7a..8ef0dbf089 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_errored_definition.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_errored_definition.php @@ -290,7 +290,6 @@ class Symfony_DI_PhpDumper_Errored_Definition extends Container $this->services['foo_with_inline'] = $instance = new \Foo(); $a = new \Bar(); - $a->pub = 'pub'; $a->setBaz(($this->services['baz'] ?? $this->getBazService())); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_inline_self_ref.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_inline_self_ref.php index 2ae6f90d02..6eec371f01 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_inline_self_ref.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_inline_self_ref.php @@ -54,14 +54,14 @@ class Symfony_DI_PhpDumper_Test_Inline_Self_Ref extends Container */ protected function getFooService() { - $b = new \App\Bar(); - $a = new \App\Baz($b); + $a = new \App\Bar(); - $this->services['App\Foo'] = $instance = new \App\Foo($a); + $b = new \App\Baz($a); + $b->bar = $a; - $b->foo = $instance; + $this->services['App\Foo'] = $instance = new \App\Foo($b); - $a->bar = $b; + $a->foo = $instance; return $instance; } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_tsantos.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_tsantos.php index 3fa375382b..a992754433 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_tsantos.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_tsantos.php @@ -57,22 +57,20 @@ class ProjectServiceContainer extends Container { $a = new \TSantos\Serializer\NormalizerRegistry(); - $d = new \TSantos\Serializer\EventDispatcher\EventDispatcher(); - $d->addSubscriber(new \TSantos\SerializerBundle\EventListener\StopwatchListener(new \Symfony\Component\Stopwatch\Stopwatch(true))); - - $this->services['tsantos_serializer'] = $instance = new \TSantos\Serializer\EventEmitterSerializer(new \TSantos\Serializer\Encoder\JsonEncoder(), $a, $d); - $b = new \TSantos\Serializer\Normalizer\CollectionNormalizer(); + $c = new \TSantos\Serializer\EventDispatcher\EventDispatcher(); + $c->addSubscriber(new \TSantos\SerializerBundle\EventListener\StopwatchListener(new \Symfony\Component\Stopwatch\Stopwatch(true))); + + $this->services['tsantos_serializer'] = $instance = new \TSantos\Serializer\EventEmitterSerializer(new \TSantos\Serializer\Encoder\JsonEncoder(), $a, $c); + $b->setSerializer($instance); - - $c = new \TSantos\Serializer\Normalizer\JsonNormalizer(); - - $c->setSerializer($instance); + $d = new \TSantos\Serializer\Normalizer\JsonNormalizer(); + $d->setSerializer($instance); $a->add(new \TSantos\Serializer\Normalizer\ObjectNormalizer(new \TSantos\SerializerBundle\Serializer\CircularReferenceHandler())); $a->add($b); - $a->add($c); + $a->add($d); return $instance; } diff --git a/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php b/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php index 2d8126a65d..9038ae7798 100644 --- a/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php +++ b/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php @@ -34,7 +34,6 @@ class WrappedListener public function __construct($listener, $name, Stopwatch $stopwatch, EventDispatcherInterface $dispatcher = null) { $this->listener = $listener; - $this->name = $name; $this->stopwatch = $stopwatch; $this->dispatcher = $dispatcher; $this->called = false; @@ -44,7 +43,17 @@ class WrappedListener $this->name = \is_object($listener[0]) ? \get_class($listener[0]) : $listener[0]; $this->pretty = $this->name.'::'.$listener[1]; } elseif ($listener instanceof \Closure) { - $this->pretty = $this->name = 'closure'; + $r = new \ReflectionFunction($listener); + if (false !== strpos($r->name, '{closure}')) { + $this->pretty = $this->name = 'closure'; + } elseif ($this->name = $r->getClosureScopeClass()) { + $this->pretty = $this->name.'::'.$r->name; + } elseif ($class = $r->getClosureThis()) { + $this->name = \get_class($class); + $this->pretty = $this->name.'::'.$r->name; + } else { + $this->pretty = $this->name = $r->name; + } } elseif (\is_string($listener)) { $this->pretty = $this->name = $listener; } else { diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/AbstractSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/AbstractSessionHandler.php index e9e30f0196..95f110332a 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/AbstractSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/AbstractSessionHandler.php @@ -119,14 +119,14 @@ abstract class AbstractSessionHandler implements \SessionHandlerInterface, \Sess */ public function destroy($sessionId) { - if (!headers_sent() && ini_get('session.use_cookies')) { + if (!headers_sent() && filter_var(ini_get('session.use_cookies'), FILTER_VALIDATE_BOOLEAN)) { if (!$this->sessionName) { throw new \LogicException(sprintf('Session name cannot be empty, did you forget to call "parent::open()" in "%s"?.', \get_class($this))); } $cookie = SessionUtils::popSessionCookie($this->sessionName, $sessionId); if (null === $cookie) { if (\PHP_VERSION_ID < 70300) { - setcookie($this->sessionName, '', 0, ini_get('session.cookie_path'), ini_get('session.cookie_domain'), ini_get('session.cookie_secure'), ini_get('session.cookie_httponly')); + setcookie($this->sessionName, '', 0, ini_get('session.cookie_path'), ini_get('session.cookie_domain'), filter_var(ini_get('session.cookie_secure'), FILTER_VALIDATE_BOOLEAN), filter_var(ini_get('session.cookie_httponly'), FILTER_VALIDATE_BOOLEAN)); } else { $params = session_get_cookie_params(); unset($params['lifetime']); diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php index dd1a263fb9..1bb647ef42 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php @@ -637,7 +637,7 @@ class PdoSessionHandler extends AbstractSessionHandler throw new \RuntimeException('Failed to read session: INSERT reported a duplicate id but next SELECT did not return any data.'); } - if (!ini_get('session.use_strict_mode') && self::LOCK_TRANSACTIONAL === $this->lockMode && 'sqlite' !== $this->driver) { + if (!filter_var(ini_get('session.use_strict_mode'), FILTER_VALIDATE_BOOLEAN) && self::LOCK_TRANSACTIONAL === $this->lockMode && 'sqlite' !== $this->driver) { // In strict mode, session fixation is not possible: new sessions always start with a unique // random id, so that concurrency is not possible and this code path can be skipped. // Exclusive-reading of non-existent rows does not block, so we need to do an insert to block diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php index b5a2e0862f..156a0d4555 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php @@ -141,7 +141,7 @@ class NativeSessionStorage implements SessionStorageInterface throw new \RuntimeException('Failed to start the session: already started by PHP.'); } - if (ini_get('session.use_cookies') && headers_sent($file, $line)) { + if (filter_var(ini_get('session.use_cookies'), FILTER_VALIDATE_BOOLEAN) && headers_sent($file, $line)) { throw new \RuntimeException(sprintf('Failed to start the session because headers have already been sent by "%s" at line %d.', $file, $line)); } diff --git a/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/common.inc b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/common.inc index f9c40a9a3c..0bdf9e4b75 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/common.inc +++ b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/common.inc @@ -22,7 +22,7 @@ error_reporting(-1); ini_set('html_errors', 0); ini_set('display_errors', 1); -if (ini_get('xdebug.default_enable')) { +if (filter_var(ini_get('xdebug.default_enable'), FILTER_VALIDATE_BOOLEAN)) { xdebug_disable(); } diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php index 44e4f52041..0a65eaa8e4 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php @@ -153,7 +153,7 @@ class PdoSessionHandlerTest extends TestCase public function testReadLockedConvertsStreamToString() { - if (ini_get('session.use_strict_mode')) { + if (filter_var(ini_get('session.use_strict_mode'), FILTER_VALIDATE_BOOLEAN)) { $this->markTestSkipped('Strict mode needs no locking for new sessions.'); } diff --git a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php index 32cee4bff7..004f6118fe 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php @@ -420,12 +420,27 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter if ($controller instanceof \Closure) { $r = new \ReflectionFunction($controller); - return array( + $controller = array( 'class' => $r->getName(), 'method' => null, 'file' => $r->getFileName(), 'line' => $r->getStartLine(), ); + + if (false !== strpos($r->name, '{closure}')) { + return $controller; + } + $controller['method'] = $r->name; + + if ($class = $r->getClosureScopeClass()) { + $controller['class'] = $class; + } elseif ($class = $r->getClosureThis()) { + $controller['class'] = \get_class($class); + } else { + return $r->name; + } + + return $controller; } if (\is_object($controller)) { diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php index f36b4dd82b..3aa4a32025 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -795,7 +795,7 @@ class PropertyAccessor implements PropertyAccessorInterface } $apcu = new ApcuAdapter($namespace, $defaultLifetime / 5, $version); - if ('cli' === \PHP_SAPI && !ini_get('apc.enable_cli')) { + if ('cli' === \PHP_SAPI && !filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN)) { $apcu->setLogger(new NullLogger()); } elseif (null !== $logger) { $apcu->setLogger($logger); diff --git a/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php b/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php index a811c124dc..7f8f43e61c 100644 --- a/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php @@ -33,15 +33,24 @@ class ReflectionCaster public static function castClosure(\Closure $c, array $a, Stub $stub, $isNested, $filter = 0) { + $prefix = Caster::PREFIX_VIRTUAL; $c = new \ReflectionFunction($c); $a = static::castFunctionAbstract($c, $a, $stub, $isNested, $filter); - $stub->class .= self::getSignature($a); + if (false === strpos($c->name, '{closure}')) { + if (isset($a[$prefix.'class'])) { + $stub->class = $a[$prefix.'class']->value.'::'.$c->name; + } elseif (isset($a[$prefix.'this'])) { + $stub->class = $a[$prefix.'this']->class.'::'.$c->name; + } else { + $stub->class = $c->name; + } + unset($a[$prefix.'class']); + } + unset($a[$prefix.'extra']); - $prefix = Caster::PREFIX_DYNAMIC; - unset($a['name'], $a[$prefix.'this'], $a[$prefix.'parameter'], $a[Caster::PREFIX_VIRTUAL.'extra']); - $prefix = Caster::PREFIX_VIRTUAL; + $stub->class .= self::getSignature($a); if ($filter & Caster::EXCLUDE_VERBOSE) { $stub->cut += ($c->getFileName() ? 2 : 0) + \count($a); diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php index e43d308f44..64aa52a011 100644 --- a/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php @@ -85,6 +85,34 @@ EOTXT ); } + public function testFromCallableClosureCaster() + { + if (\defined('HHVM_VERSION_ID')) { + $this->markTestSkipped('Not for HHVM.'); + } + $var = array( + (new \ReflectionMethod($this, __FUNCTION__))->getClosure($this), + (new \ReflectionMethod(__CLASS__, 'tearDownAfterClass'))->getClosure(), + ); + + $this->assertDumpMatchesFormat( + << Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest::testFromCallableClosureCaster() { + this: Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest { …} + file: "%sReflectionCasterTest.php" + line: "%d to %d" + } + 1 => %sTestCase::tearDownAfterClass() { + file: "%sTestCase.php" + line: "%d to %d" + } +] +EOTXT + , $var + ); + } + public function testClosureCasterExcludingVerbosity() { $var = function &($a = 5) {};