diff --git a/.travis.yml b/.travis.yml index 12cb4634049f3..18d21e04cdf47 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 0bff86ba3e027..60b848a532545 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/CHANGELOG-4.2.md b/CHANGELOG-4.2.md index 1a872d39753f9..dcb301da0f223 100644 --- a/CHANGELOG-4.2.md +++ b/CHANGELOG-4.2.md @@ -7,6 +7,51 @@ in 4.2 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.2.0...v4.2.1 +* 4.2.0-BETA2 (2018-11-16) + + * bug #29190 [Debug][HttpKernel] remove frames added by DebugClassLoader in stack traces (nicolas-grekas) + * bug #29233 [FrameworkBundle] metadata_update_threshold default value must be an int (dunglas) + * bug #29226 [Messenger] Improved message when handler class does not exist (neeckeloo) + * bug #29223 [Validator] Added the missing constraints instance checks (thomasbisignani) + * bug #28966 [PropertyAccessor] Fix unable to write to singular property using setter while plural adder/remover exist (karser) + * bug #29182 [Form] Fixed empty data for compound date types (HeahDude) + * bug #29224 [SecurityBundle] Fix remember-me cookie framework inheritance when session is disabled (fbourigault) + * bug #29220 [Translation] make intl+icu format seamless by handling it in MessageCatalogue (nicolas-grekas) + * feature #29166 [Messenger] Add handled & sent stamps (ogizanagi) + * bug #29209 [VarExporter] fix handling of __sleep() (nicolas-grekas) + * bug #29196 [Messenger] Fix collecting messages (ro0NL) + * bug #29205 [Dotenv] skip loading "local" env twice (nicolas-grekas) + * bug #29204 [FrameworkBundle][WebServerBundle] Revert deprecation of --env and --no-debug console options (chalasr) + * bug #29191 [Routing] generate(null) should throw an exception (nicolas-grekas) + * bug #29199 [FrameworkBundle] conflict with Dotenv <4.2 to simplify recipes (nicolas-grekas) + * bug #29197 Revert "bug #29154 [FrameworkBundle] Define APP_ENV/APP_DEBUG from argv via Application::bootstrapEnv() (nicolas-grekas) + * bug #29185 [Form] Fixed keeping hash of equal \DateTimeInterface on submit (HeahDude) + * bug #29183 [HttpKernel] Fix collecting uploaded files (ro0NL) + * bug #29141 [Workflow] Fixed bug of buildTransitionBlockerList when many transition are enabled (Tetragramat, lyrixx) + * bug #29137 [Workflow][FrameworkBundle] fixed guard event names for transitions (destillat, lyrixx) + * bug #29184 [WebProfilerBundle] Fix theme settings (ro0NL) + * feature #29159 [Messenger] collect all stamps added on Envelope as collections (nicolas-grekas) + * bug #29171 [Dotenv] load .env.dist when it exists and .env is not found (nicolas-grekas) + * bug #28731 [Form] invalidate forms on transformation failures (xabbuh) + * bug #29152 [Config] Unset key during normalization (ro0NL) + * bug #29165 [DI] align IniFileLoader to PHP bugfix #76965 (nicolas-grekas) + * bug #29154 [FrameworkBundle] Define APP_ENV/APP_DEBUG from argv via Application::bootstrapEnv() (chalasr) + * bug #29129 [Dotenv] add loadEnv(), a smoother alternative to loadForEnv() (nicolas-grekas) + * bug #29113 [Routing] fix dumping conditions that use the request (nicolas-grekas) + * bug #29115 Change button_widget class to btn-primary (neFAST) + * bug #29131 [Dotenv] dont use getenv() to read SYMFONY_DOTENV_VARS (nicolas-grekas) + * bug #29057 [HttpFoundation] replace any preexisting Content-Type headers (nicolas-grekas) + * bug #29076 [Serializer] Allow null values when denormalizing with constructor missing data (danut007ro) + * bug #29128 [FrameworkBundle] Cleaning translation commands and fix a bug for --all option (yceruto) + * bug #29104 [DI] fix dumping inlined services (nicolas-grekas) + * bug #29054 [VarDumper] fix dump of closures created from callables (nicolas-grekas) + * bug #29102 [DI] fix GraphvizDumper ignoring inline definitions (nicolas-grekas) + * bug #29090 LoggingTranslator should implement Symfony\Contracts\Translation\TranslatorInterface (desmax) + * bug #29095 [TwigBridge] require the needed symfony/contracts package (xabbuh) + * bug #29107 [DI] dont track classes/interfaces used to compute autowiring error messages (nicolas-grekas) + * bug #29094 Add samesite attribute to session cookie after session migration (rpkamp) + * bug #29080 [FrameworkBundle] fix deps (ro0NL) + * 4.2.0-BETA1 (2018-11-03) * feature #28622 [VarDumper] add caster for Memcached (jschaedl) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 66d9da5983a99..969c6a424cefc 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/UPGRADE-4.2.md b/UPGRADE-4.2.md index 7f3996d0a9b83..bdf2ab0cececf 100644 --- a/UPGRADE-4.2.md +++ b/UPGRADE-4.2.md @@ -14,7 +14,20 @@ Cache Config ------ - * Deprecated constructing a `TreeBuilder` without passing root node information. + * Deprecated constructing a `TreeBuilder` without passing root node information: + + Before: + ```php + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('my_config'); + ``` + + After: + ```php + $treeBuilder = new TreeBuilder('my_config'); + $rootNode = $treeBuilder->getRootNode(); + ``` + * Deprecated `FileLoaderLoadException`, use `LoaderLoadException` instead. Console @@ -106,25 +119,15 @@ Form * The `regions` option of the `TimezoneType` is deprecated. -HttpFoundation --------------- - - * The default value of the "$secure" and "$samesite" arguments of Cookie's constructor - will respectively change from "false" to "null" and from "null" to "lax" in Symfony - 5.0, you should define their values explicitly or use "Cookie::create()" instead. - -HttpKernel ----------- - - * The `Kernel::getRootDir()` and the `kernel.root_dir` parameter have been deprecated - * The `KernelInterface::getName()` and the `kernel.name` parameter have been deprecated - * Deprecated the first and second constructor argument of `ConfigDataCollector` - * Deprecated `ConfigDataCollector::getApplicationName()` - * Deprecated `ConfigDataCollector::getApplicationVersion()` - FrameworkBundle --------------- + * The following middleware service ids were renamed: + - `messenger.middleware.call_message_handler` becomes `messenger.middleware.handle_message` + - `messenger.middleware.route_messages` becomes `messenger.middleware.send_message` + + If you set `framework.messenger.buses.[bus_id].default_middleware` to `false`, + replace any of these names in the `framework.messenger.buses.[bus_id].middleware` list. * The `allow_no_handler` middleware has been removed. Use `framework.messenger.buses.[bus_id].default_middleware` instead: Before: @@ -172,14 +175,26 @@ FrameworkBundle ``` * The `ContainerAwareCommand` class has been deprecated, use `Symfony\Component\Console\Command\Command` with dependency injection instead. - * The `--env` console option and its "-e" shortcut have been deprecated, - set the "APP_ENV" environment variable instead. - * The `--no-debug` console option has been deprecated, - set the "APP_DEBUG" environment variable to "0" instead. * The `Templating\Helper\TranslatorHelper::transChoice()` method has been deprecated, use the `trans()` one instead with a `%count%` parameter. * Deprecated support for legacy translations directories `src/Resources/translations/` and `src/Resources//translations/`, use `translations/` instead. * Support for the legacy directory structure in `translation:update` and `debug:translation` commands has been deprecated. +HttpFoundation +-------------- + + * The default value of the `$secure` and `$samesite` arguments of Cookie's constructor + will respectively change from `false` to `null` and from `null` to `lax` in Symfony + 5.0, you should define their values explicitly or use `Cookie::create()` instead. + +HttpKernel +---------- + + * The `Kernel::getRootDir()` and the `kernel.root_dir` parameter have been deprecated + * The `KernelInterface::getName()` and the `kernel.name` parameter have been deprecated + * Deprecated the first and second constructor argument of `ConfigDataCollector` + * Deprecated `ConfigDataCollector::getApplicationName()` + * Deprecated `ConfigDataCollector::getApplicationVersion()` + Messenger --------- @@ -360,11 +375,5 @@ Validator * The `ValidatorBuilderInterface` has been deprecated and `ValidatorBuilder` made final * Deprecated validating instances of `\DateTimeInterface` in `DateTimeValidator`, `DateValidator` and `TimeValidator`. Use `Type` instead or remove the constraint if the underlying model is type hinted to `\DateTimeInterface` already. * Using the `Bic`, `Country`, `Currency`, `Language` and `Locale` constraints without `symfony/intl` is deprecated - * Using the `Email` constraint without `egulias/email-validator` is deprecated + * Using the `Email` constraint in strict mode without `egulias/email-validator` is deprecated * Using the `Expression` constraint without `symfony/expression-language` is deprecated - -WebServerBundle ---------------- - -* Omitting the `$environment` argument of the `ServerRunCommand` and - `ServerStartCommand` constructors is deprecated. diff --git a/UPGRADE-5.0.md b/UPGRADE-5.0.md index 5d87629bd719a..4ec9e24f4f0ce 100644 --- a/UPGRADE-5.0.md +++ b/UPGRADE-5.0.md @@ -126,7 +126,7 @@ Form FrameworkBundle --------------- - * Removed support for `bundle:controller:action` and `service:action` syntaxes to reference controllers. Use `serviceOrFqcn::method` + * Removed support for `bundle:controller:action` syntax to reference controllers. Use `serviceOrFqcn::method` instead where `serviceOrFqcn` is either the service ID when using controllers as services or the FQCN of the controller. Before: @@ -136,11 +136,6 @@ FrameworkBundle path: / defaults: _controller: FrameworkBundle:Redirect:redirect - - service_controller: - path: / - defaults: - _controller: app.my_controller:myAction ``` After: @@ -150,11 +145,6 @@ FrameworkBundle path: / defaults: _controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction - - service_controller: - path: / - defaults: - _controller: app.my_controller::myAction ``` * Removed `Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser`. @@ -164,10 +154,6 @@ FrameworkBundle * Added support for the SameSite attribute for session cookies. It is highly recommended to set this setting (`framework.session.cookie_samesite`) to `lax` for increased security against CSRF attacks. * The `ContainerAwareCommand` class has been removed, use `Symfony\Component\Console\Command\Command` with dependency injection instead. - * The `--env` console option and its "-e" shortcut have been removed, - set the "APP_ENV" environment variable instead. - * The `--no-debug` console option has been removed, - set the "APP_DEBUG" environment variable to "0" instead. * The `Templating\Helper\TranslatorHelper::transChoice()` method has been removed, use the `trans()` one instead with a `%count%` parameter. * Removed support for legacy translations directories `src/Resources/translations/` and `src/Resources//translations/`, use `translations/` instead. * Support for the legacy directory structure in `translation:update` and `debug:translation` commands has been removed. @@ -276,7 +262,7 @@ Validator * The `ValidatorBuilderInterface` has been removed and `ValidatorBuilder` is now final * Removed support for validating instances of `\DateTimeInterface` in `DateTimeValidator`, `DateValidator` and `TimeValidator`. Use `Type` instead or remove the constraint if the underlying model is type hinted to `\DateTimeInterface` already. * The `symfony/intl` component is now required for using the `Bic`, `Country`, `Currency`, `Language` and `Locale` constraints - * The `egulias/email-validator` component is now required for using the `Email` constraint + * The `egulias/email-validator` component is now required for using the `Email` constraint in strict mode * The `symfony/expression-language` component is now required for using the `Expression` constraint Workflow @@ -286,9 +272,3 @@ Workflow * `add` method has been removed use `addWorkflow` method in `Workflow\Registry` instead. * `SupportStrategyInterface` has been removed, use `WorkflowSupportStrategyInterface` instead. * `ClassInstanceSupportStrategy` has been removed, use `InstanceOfSupportStrategy` instead. - -WebServerBundle ---------------- - -* Omitting the `$environment` argument of the `ServerRunCommand` and - `ServerStartCommand` constructors now throws a `\TypeError`. diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 9717aa56f31c5..7e78dd8f75208 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,7 +1,7 @@ - Cache\IntegrationTests - Doctrine\Common\Cache - Symfony\Component\Cache - Symfony\Component\Cache\Tests\Fixtures - Symfony\Component\Cache\Traits - Symfony\Component\Console - Symfony\Component\HttpFoundation + Cache\IntegrationTests + Doctrine\Common\Cache + Symfony\Component\Cache + Symfony\Component\Cache\Tests\Fixtures + Symfony\Component\Cache\Traits + Symfony\Component\Console + Symfony\Component\HttpFoundation diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php index c0061dabc540e..d60992fcf119a 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php @@ -1482,4 +1482,43 @@ public function testSetDataNonEmptyArraySubmitNullMultiple() $this->assertEquals(array(), $form->getNormData()); $this->assertSame(array(), $form->getViewData(), 'View data is always an array'); } + + public function testSubmitNullUsesDefaultEmptyData($emptyData = 'empty', $expectedData = null) + { + $emptyData = '1'; + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $this->persist(array($entity1)); + + $form = $this->factory->create(static::TESTED_TYPE, null, array( + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + 'empty_data' => $emptyData, + )); + $form->submit(null); + + $this->assertSame($emptyData, $form->getViewData()); + $this->assertSame($entity1, $form->getNormData()); + $this->assertSame($entity1, $form->getData()); + } + + public function testSubmitNullMultipleUsesDefaultEmptyData() + { + $emptyData = array('1'); + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $this->persist(array($entity1)); + + $form = $this->factory->create(static::TESTED_TYPE, null, array( + 'em' => 'default', + 'class' => self::SINGLE_IDENT_CLASS, + 'multiple' => true, + 'empty_data' => $emptyData, + )); + $form->submit(null); + + $collection = new ArrayCollection(array($entity1)); + + $this->assertSame($emptyData, $form->getViewData()); + $this->assertEquals($collection, $form->getNormData()); + $this->assertEquals($collection, $form->getData()); + } } diff --git a/src/Symfony/Bridge/Doctrine/phpunit.xml.dist b/src/Symfony/Bridge/Doctrine/phpunit.xml.dist index 24f92f2ab8e2f..fa76fa9b500e7 100644 --- a/src/Symfony/Bridge/Doctrine/phpunit.xml.dist +++ b/src/Symfony/Bridge/Doctrine/phpunit.xml.dist @@ -1,7 +1,7 @@ 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/Bridge/PhpUnit/phpunit.xml.dist b/src/Symfony/Bridge/PhpUnit/phpunit.xml.dist index 816cfe4927ed3..d37d2eac3650a 100644 --- a/src/Symfony/Bridge/PhpUnit/phpunit.xml.dist +++ b/src/Symfony/Bridge/PhpUnit/phpunit.xml.dist @@ -1,7 +1,7 @@ '.(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/Command/DebugAutowiringCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/DebugAutowiringCommand.php index 3dd5663eada0a..1c832c04d30fa 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/DebugAutowiringCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/DebugAutowiringCommand.php @@ -86,7 +86,6 @@ protected function execute(InputInterface $input, OutputInterface $output) if ($search) { $io->text(sprintf('(only showing classes/interfaces matching %s)', $search)); } - $tableRows = array(); $hasAlias = array(); $all = $input->getOption('all'); $previousId = '-'; diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php index 7b478abcbe772..92c1c07628a3f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php @@ -165,7 +165,7 @@ protected function execute(InputInterface $input, OutputInterface $output) if (is_dir($dir = sprintf('%s/Resources/%s/translations', $rootDir, $bundle->getName()))) { $transPaths[] = $dir; $notice = sprintf('Storing translations files for "%s" in the "%s" directory is deprecated since Symfony 4.2, ', $dir, $bundle->getName()); - @trigger_error($notice.($this->defaultTransPath ? sprintf('use the "%s" directory instead.', $this->defaultTransPath) : sprintf('configure and use "framework.translator.default_path" instead.', $bundle->getName())), E_USER_DEPRECATED); + @trigger_error($notice.($this->defaultTransPath ? sprintf('use the "%s" directory instead.', $this->defaultTransPath) : 'configure and use "framework.translator.default_path" instead.'), E_USER_DEPRECATED); } $viewsPaths = array($bundle->getPath().'/Resources/views'); if ($this->defaultViewsPath) { @@ -174,7 +174,7 @@ protected function execute(InputInterface $input, OutputInterface $output) if (is_dir($dir = sprintf('%s/Resources/%s/views', $rootDir, $bundle->getName()))) { $viewsPaths[] = $dir; $notice = sprintf('Storing templates for "%s" in the "%s" directory is deprecated since Symfony 4.2, ', $bundle->getName(), $dir); - @trigger_error($notice.($this->defaultViewsPath ? sprintf('use the "%s" directory instead.', $this->defaultViewsPath) : sprintf('configure and use "twig.default_path" instead.', $bundle->getName())), E_USER_DEPRECATED); + @trigger_error($notice.($this->defaultViewsPath ? sprintf('use the "%s" directory instead.', $this->defaultViewsPath) : 'configure and use "twig.default_path" instead.'), E_USER_DEPRECATED); } } catch (\InvalidArgumentException $e) { // such a bundle does not exist, so treat the argument as path @@ -208,11 +208,11 @@ protected function execute(InputInterface $input, OutputInterface $output) $notice = sprintf('Storing translations files for "%s" in the "%s" directory is deprecated since Symfony 4.2, ', $bundle->getName(), $deprecatedPath); @trigger_error($notice.($this->defaultTransPath ? sprintf('use the "%s" directory instead.', $this->defaultTransPath) : 'configure and use "framework.translator.default_path" instead.'), E_USER_DEPRECATED); } - $viewsPaths[] = array($bundle->getPath().'/Resources/views'); + $viewsPaths[] = $bundle->getPath().'/Resources/views'; if (is_dir($deprecatedPath = sprintf('%s/Resources/%s/views', $rootDir, $bundle->getName()))) { $viewsPaths[] = $deprecatedPath; $notice = sprintf('Storing templates for "%s" in the "%s" directory is deprecated since Symfony 4.2, ', $bundle->getName(), $deprecatedPath); - @trigger_error($notice.($this->defaultViewsPath ? sprintf('use the "%s" directory instead.', $this->defaultViewsPath) : sprintf('configure and use "twig.default_path" instead.', $bundle->getName())), E_USER_DEPRECATED); + @trigger_error($notice.($this->defaultViewsPath ? sprintf('use the "%s" directory instead.', $this->defaultViewsPath) : 'configure and use "twig.default_path" instead.'), E_USER_DEPRECATED); } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php index 7b4d951c768ad..6e009173d75a9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php @@ -111,7 +111,7 @@ protected function execute(InputInterface $input, OutputInterface $output) // check format $supportedFormats = $this->writer->getFormats(); - if (!\in_array($input->getOption('output-format'), $supportedFormats)) { + if (!\in_array($input->getOption('output-format'), $supportedFormats, true)) { $errorIo->error(array('Wrong output format', 'Supported formats are: '.implode(', ', $supportedFormats).'.')); return 1; @@ -165,7 +165,7 @@ protected function execute(InputInterface $input, OutputInterface $output) if (is_dir($dir = sprintf('%s/Resources/%s/views', $rootDir, $foundBundle->getName()))) { $viewsPaths[] = $dir; $notice = sprintf('Storing templates for "%s" in the "%s" directory is deprecated since Symfony 4.2, ', $foundBundle->getName(), $dir); - @trigger_error($notice.($this->defaultViewsPath ? sprintf('use the "%s" directory instead.', $this->defaultViewsPath) : sprintf('configure and use "twig.default_path" instead.', $foundBundle->getName())), E_USER_DEPRECATED); + @trigger_error($notice.($this->defaultViewsPath ? sprintf('use the "%s" directory instead.', $this->defaultViewsPath) : 'configure and use "twig.default_path" instead.'), E_USER_DEPRECATED); } $currentName = $foundBundle->getName(); } catch (\InvalidArgumentException $e) { @@ -261,7 +261,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $extractedMessagesCount += $domainMessagesCount; } - if ('xlf' == $input->getOption('output-format')) { + if ('xlf' === $input->getOption('output-format')) { $errorIo->comment('Xliff output version is 1.2'); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Application.php b/src/Symfony/Bundle/FrameworkBundle/Console/Application.php index e885dfeaa5b56..04258131b539a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Application.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Application.php @@ -62,19 +62,6 @@ public function getKernel() */ public function doRun(InputInterface $input, OutputInterface $output) { - if ($input->hasParameterOption(array('-e', '--env'), true)) { - $notice = 'The "--env" option and its "-e" shortcut are deprecated since Symfony 4.2, set the "APP_ENV" environment variable instead.'; - $io = (new SymfonyStyle($input, $output))->getErrorStyle(); - $io->warning($notice); - @trigger_error($notice, E_USER_DEPRECATED); - } - - if ($input->hasParameterOption('--no-debug', true)) { - $notice = 'The "--no-debug" option is deprecated since Symfony 4.2, set the "APP_DEBUG" environment variable to "0" instead.'; - ($io ?? (new SymfonyStyle($input, $output))->getErrorStyle())->warning($notice); - @trigger_error($notice, E_USER_DEPRECATED); - } - $this->kernel->boot(); $this->setDispatcher($this->kernel->getContainer()->get('event_dispatcher')); diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php index f6badd0552b1a..e9650c7a9f31c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php @@ -344,6 +344,19 @@ private function getCallableData($callable, array $options = array()): array if ($callable instanceof \Closure) { $data['type'] = 'closure'; + $r = new \ReflectionFunction($callable); + if (false !== strpos($r->name, '{closure}')) { + return $data; + } + $data['name'] = $r->name; + + if ($class = $r->getClosureScopeClass()) { + $data['class'] = $class->name; + if (!$r->getClosureThis()) { + $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 85802d6975bd1..9a93695e56fdc 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php @@ -353,6 +353,19 @@ protected function describeCallable($callable, array $options = array()) 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); + + if ($class = $r->getClosureScopeClass()) { + $string .= "\n".sprintf('- Class: `%s`', $class->name); + if (!$r->getClosureThis()) { + $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 f1f064c4f5092..90cd0e5254aab 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php @@ -57,12 +57,7 @@ protected function describeRouteCollection(RouteCollection $routes, array $optio 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,15 @@ private function formatCallable($callable): string } 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->name, $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 bac8469fc9bc1..ead8fd3744a66 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php @@ -524,6 +524,19 @@ private function getCallableDocument($callable): \DOMDocument 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); + + if ($class = $r->getClosureScopeClass()) { + $callableXML->setAttribute('class', $class->name); + if (!$r->getClosureThis()) { + $callableXML->setAttribute('static', 'true'); + } + } + return $dom; } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index b98f7914be3aa..9153e63b70429 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -492,7 +492,7 @@ private function addSessionSection(ArrayNodeDefinition $rootNode) ->scalarNode('gc_maxlifetime')->end() ->scalarNode('save_path')->defaultValue('%kernel.cache_dir%/sessions')->end() ->integerNode('metadata_update_threshold') - ->defaultValue('0') + ->defaultValue(0) ->info('seconds to wait between 2 session metadata updates') ->end() ->end() diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index ab0e271a12dce..f4b20ee92d0a7 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -507,6 +507,7 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ foreach ($config['workflows'] as $name => $workflow) { $type = $workflow['type']; + $workflowId = sprintf('%s.%s', $type, $name); // Process Metadata (workflow + places (transition is done in the "create transition" block)) $metadataStoreDefinition = new Definition(Workflow\Metadata\InMemoryMetadataStore::class, array(array(), array(), null)); @@ -525,11 +526,25 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ // Create transitions $transitions = array(); + $guardsConfiguration = array(); $transitionsMetadataDefinition = new Definition(\SplObjectStorage::class); + // Global transition counter per workflow + $transitionCounter = 0; foreach ($workflow['transitions'] as $transition) { if ('workflow' === $type) { $transitionDefinition = new Definition(Workflow\Transition::class, array($transition['name'], $transition['from'], $transition['to'])); - $transitions[] = $transitionDefinition; + $transitionDefinition->setPublic(false); + $transitionId = sprintf('%s.transition.%s', $workflowId, $transitionCounter++); + $container->setDefinition($transitionId, $transitionDefinition); + $transitions[] = new Reference($transitionId); + if (isset($transition['guard'])) { + $configuration = new Definition(Workflow\EventListener\GuardExpression::class); + $configuration->addArgument(new Reference($transitionId)); + $configuration->addArgument($transition['guard']); + $configuration->setPublic(false); + $eventName = sprintf('workflow.%s.guard.%s', $name, $transition['name']); + $guardsConfiguration[$eventName][] = $configuration; + } if ($transition['metadata']) { $transitionsMetadataDefinition->addMethodCall('attach', array( $transitionDefinition, @@ -540,7 +555,18 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ foreach ($transition['from'] as $from) { foreach ($transition['to'] as $to) { $transitionDefinition = new Definition(Workflow\Transition::class, array($transition['name'], $from, $to)); - $transitions[] = $transitionDefinition; + $transitionDefinition->setPublic(false); + $transitionId = sprintf('%s.transition.%s', $workflowId, $transitionCounter++); + $container->setDefinition($transitionId, $transitionDefinition); + $transitions[] = new Reference($transitionId); + if (isset($transition['guard'])) { + $configuration = new Definition(Workflow\EventListener\GuardExpression::class); + $configuration->addArgument(new Reference($transitionId)); + $configuration->addArgument($transition['guard']); + $configuration->setPublic(false); + $eventName = sprintf('workflow.%s.guard.%s', $name, $transition['name']); + $guardsConfiguration[$eventName][] = $configuration; + } if ($transition['metadata']) { $transitionsMetadataDefinition->addMethodCall('attach', array( $transitionDefinition, @@ -582,7 +608,6 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ } // Create Workflow - $workflowId = sprintf('%s.%s', $type, $name); $workflowDefinition = new ChildDefinition(sprintf('%s.abstract', $type)); $workflowDefinition->replaceArgument(0, new Reference(sprintf('%s.definition', $workflowId))); if (isset($markingStoreDefinition)) { @@ -619,16 +644,7 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ } // Add Guard Listener - $guard = new Definition(Workflow\EventListener\GuardListener::class); - $guard->setPrivate(true); - $configuration = array(); - foreach ($workflow['transitions'] as $config) { - $transitionName = $config['name']; - - if (!isset($config['guard'])) { - continue; - } - + if ($guardsConfiguration) { if (!class_exists(ExpressionLanguage::class)) { throw new LogicException('Cannot guard workflows as the ExpressionLanguage component is not installed. Try running "composer require symfony/expression-language".'); } @@ -637,13 +653,11 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ throw new LogicException('Cannot guard workflows as the Security component is not installed. Try running "composer require symfony/security".'); } - $eventName = sprintf('workflow.%s.guard.%s', $name, $transitionName); - $guard->addTag('kernel.event_listener', array('event' => $eventName, 'method' => 'onTransition')); - $configuration[$eventName] = $config['guard']; - } - if ($configuration) { + $guard = new Definition(Workflow\EventListener\GuardListener::class); + $guard->setPrivate(true); + $guard->setArguments(array( - $configuration, + $guardsConfiguration, new Reference('workflow.security.expression_language'), new Reference('security.token_storage'), new Reference('security.authorization_checker'), @@ -651,6 +665,9 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ new Reference('security.role_hierarchy'), new Reference('validator', ContainerInterface::NULL_ON_INVALID_REFERENCE), )); + foreach ($guardsConfiguration as $eventName => $config) { + $guard->addTag('kernel.event_listener', array('event' => $eventName, 'method' => 'onTransition')); + } $container->setDefinition(sprintf('%s.listener.guard', $workflowId), $guard); $container->setParameter('workflow.has_guard_listeners', true); @@ -1578,12 +1595,13 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder if ('*' !== $message && !class_exists($message) && !interface_exists($message, false)) { throw new LogicException(sprintf('Invalid Messenger routing configuration: class or interface "%s" not found.', $message)); } - $senders = array_map(function ($sender) use ($senderAliases) { - return new Reference($senderAliases[$sender] ?? $sender); - }, $messageConfiguration['senders']); + $senders = array(); + foreach ($messageConfiguration['senders'] as $sender) { + $senders[$sender] = new Reference($senderAliases[$sender] ?? $sender); + } $sendersId = 'messenger.senders.'.$message; - $sendersDefinition = $container->register($sendersId, RewindableGenerator::class) + $container->register($sendersId, RewindableGenerator::class) ->setFactory('current') ->addArgument(array(new IteratorArgument($senders))); $messageToSendersMapping[$message] = new Reference($sendersId); diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml index 8cdbbbd9fb628..b36d7d42d6212 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml @@ -70,6 +70,11 @@ + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd index c99e543fa5b3c..f2b57a31e72c6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd @@ -314,6 +314,7 @@ + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php index 6c0c9b0f8d300..666b77b30a2c4 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php @@ -163,7 +163,7 @@ public static function getEventDispatchers() public static function getCallables() { - return array( + $callables = array( 'callable_1' => 'array_key_exists', 'callable_2' => array('Symfony\\Bundle\\FrameworkBundle\\Tests\\Console\\Descriptor\\CallableClass', 'staticMethod'), 'callable_3' => array(new CallableClass(), 'method'), @@ -172,6 +172,12 @@ public static function getCallables() 'callable_6' => function () { return 'Closure'; }, 'callable_7' => new CallableClass(), ); + + if (\PHP_VERSION_ID >= 70100) { + $callables['callable_from_callable'] = \Closure::fromCallable(new CallableClass()); + } + + return $callables; } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php index 5ef3cbf13585b..d7e8324b55b5e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -235,7 +235,7 @@ protected static function getBundleDefaultConfig() 'cookie_samesite' => null, 'gc_probability' => 1, 'save_path' => '%kernel.cache_dir%/sessions', - 'metadata_update_threshold' => '0', + 'metadata_update_threshold' => 0, ), 'request' => array( 'enabled' => false, diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflow_with_guard_expression.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflow_with_guard_expression.php new file mode 100644 index 0000000000000..89c86339afe15 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflow_with_guard_expression.php @@ -0,0 +1,51 @@ +loadFromExtension('framework', array( + 'workflows' => array( + 'article' => array( + 'type' => 'workflow', + 'marking_store' => array( + 'type' => 'multiple_state', + ), + 'supports' => array( + FrameworkExtensionTest::class, + ), + 'initial_place' => 'draft', + 'places' => array( + 'draft', + 'wait_for_journalist', + 'approved_by_journalist', + 'wait_for_spellchecker', + 'approved_by_spellchecker', + 'published', + ), + 'transitions' => array( + 'request_review' => array( + 'from' => 'draft', + 'to' => array('wait_for_journalist', 'wait_for_spellchecker'), + ), + 'journalist_approval' => array( + 'from' => 'wait_for_journalist', + 'to' => 'approved_by_journalist', + ), + 'spellchecker_approval' => array( + 'from' => 'wait_for_spellchecker', + 'to' => 'approved_by_spellchecker', + ), + 'publish' => array( + 'from' => array('approved_by_journalist', 'approved_by_spellchecker'), + 'to' => 'published', + 'guard' => '!!true', + ), + 'publish_editor_in_chief' => array( + 'name' => 'publish', + 'from' => 'draft', + 'to' => 'published', + 'guard' => '!!false', + ), + ), + ), + ), +)); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflow_with_guard_expression.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflow_with_guard_expression.xml new file mode 100644 index 0000000000000..a5124d1fe7776 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflow_with_guard_expression.xml @@ -0,0 +1,48 @@ + + + + + + + + a + a + + Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest + draft + wait_for_journalist + approved_by_journalist + wait_for_spellchecker + approved_by_spellchecker + published + + draft + wait_for_journalist + wait_for_spellchecker + + + wait_for_journalist + approved_by_journalist + + + wait_for_spellchecker + approved_by_spellchecker + + + approved_by_journalist + approved_by_spellchecker + published + !!true + + + draft + published + !!false + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflow_with_guard_expression.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflow_with_guard_expression.yml new file mode 100644 index 0000000000000..458cb4ae1ee77 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflow_with_guard_expression.yml @@ -0,0 +1,35 @@ +framework: + workflows: + article: + type: workflow + marking_store: + type: multiple_state + supports: + - Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest + initial_place: draft + places: + - draft + - wait_for_journalist + - approved_by_journalist + - wait_for_spellchecker + - approved_by_spellchecker + - published + transitions: + request_review: + from: [draft] + to: [wait_for_journalist, wait_for_spellchecker] + journalist_approval: + from: [wait_for_journalist] + to: [approved_by_journalist] + spellchecker_approval: + from: [wait_for_spellchecker] + to: [approved_by_spellchecker] + publish: + from: [approved_by_journalist, approved_by_spellchecker] + to: [published] + guard: "!!true" + publish_editor_in_chief: + name: publish + from: [draft] + to: [published] + guard: "!!false" diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index dd946c472d182..6fdec21057e93 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -50,7 +50,6 @@ use Symfony\Component\Serializer\Serializer; use Symfony\Component\Translation\DependencyInjection\TranslatorPass; use Symfony\Component\Validator\DependencyInjection\AddConstraintValidatorsPass; -use Symfony\Component\Validator\Validation; use Symfony\Component\Workflow; abstract class FrameworkExtensionTest extends TestCase @@ -324,14 +323,84 @@ public function testWorkflowMultipleTransitionsWithSameName() $this->assertCount(5, $transitions); - $this->assertSame('request_review', $transitions[0]->getArgument(0)); - $this->assertSame('journalist_approval', $transitions[1]->getArgument(0)); - $this->assertSame('spellchecker_approval', $transitions[2]->getArgument(0)); - $this->assertSame('publish', $transitions[3]->getArgument(0)); - $this->assertSame('publish', $transitions[4]->getArgument(0)); + $this->assertSame('workflow.article.transition.0', (string) $transitions[0]); + $this->assertSame(array( + 'request_review', + array( + 'draft', + ), + array( + 'wait_for_journalist', 'wait_for_spellchecker', + ), + ), $container->getDefinition($transitions[0])->getArguments()); + + $this->assertSame('workflow.article.transition.1', (string) $transitions[1]); + $this->assertSame(array( + 'journalist_approval', + array( + 'wait_for_journalist', + ), + array( + 'approved_by_journalist', + ), + ), $container->getDefinition($transitions[1])->getArguments()); + + $this->assertSame('workflow.article.transition.2', (string) $transitions[2]); + $this->assertSame(array( + 'spellchecker_approval', + array( + 'wait_for_spellchecker', + ), + array( + 'approved_by_spellchecker', + ), + ), $container->getDefinition($transitions[2])->getArguments()); + + $this->assertSame('workflow.article.transition.3', (string) $transitions[3]); + $this->assertSame(array( + 'publish', + array( + 'approved_by_journalist', + 'approved_by_spellchecker', + ), + array( + 'published', + ), + ), $container->getDefinition($transitions[3])->getArguments()); + + $this->assertSame('workflow.article.transition.4', (string) $transitions[4]); + $this->assertSame(array( + 'publish', + array( + 'draft', + ), + array( + 'published', + ), + ), $container->getDefinition($transitions[4])->getArguments()); + } - $this->assertSame(array('approved_by_journalist', 'approved_by_spellchecker'), $transitions[3]->getArgument(1)); - $this->assertSame(array('draft'), $transitions[4]->getArgument(1)); + public function testGuardExpressions() + { + $container = $this->createContainerFromFile('workflow_with_guard_expression'); + + $this->assertTrue($container->hasDefinition('workflow.article.listener.guard'), 'Workflow guard listener is registered as a service'); + $this->assertTrue($container->hasParameter('workflow.has_guard_listeners'), 'Workflow guard listeners parameter exists'); + $this->assertTrue(true === $container->getParameter('workflow.has_guard_listeners'), 'Workflow guard listeners parameter is enabled'); + $guardDefinition = $container->getDefinition('workflow.article.listener.guard'); + $this->assertSame(array( + array( + 'event' => 'workflow.article.guard.publish', + 'method' => 'onTransition', + ), + ), $guardDefinition->getTag('kernel.event_listener')); + $guardsConfiguration = $guardDefinition->getArgument(0); + $this->assertTrue(1 === \count($guardsConfiguration), 'Workflow guard configuration contains one element per transition name'); + $transitionGuardExpressions = $guardsConfiguration['workflow.article.guard.publish']; + $this->assertSame('workflow.article.transition.3', (string) $transitionGuardExpressions[0]->getArgument(0)); + $this->assertSame('!!true', $transitionGuardExpressions[0]->getArgument(1)); + $this->assertSame('workflow.article.transition.4', (string) $transitionGuardExpressions[1]->getArgument(0)); + $this->assertSame('!!false', $transitionGuardExpressions[1]->getArgument(1)); } public function testWorkflowServicesCanBeEnabled() @@ -570,7 +639,10 @@ public function testMessengerRouting() ); $this->assertSame($messageToSendAndHandleMapping, $senderLocatorDefinition->getArgument(1)); - $this->assertEquals(array(new Reference('messenger.transport.amqp'), new Reference('audit')), $container->getDefinition('messenger.senders.'.DummyMessage::class)->getArgument(0)[0]->getValues()); + $this->assertEquals(array( + 'amqp' => new Reference('messenger.transport.amqp'), + 'audit' => new Reference('audit'), + ), $container->getDefinition('messenger.senders.'.DummyMessage::class)->getArgument(0)[0]->getValues()); } /** 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 9b030ab7913a9..8bf37d37b9903 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/callable_from_callable.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.json new file mode 100644 index 0000000000000..fc0b749d998a9 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.json @@ -0,0 +1,5 @@ +{ + "type": "closure", + "name": "__invoke", + "class": "Symfony\\Bundle\\FrameworkBundle\\Tests\\Console\\Descriptor\\CallableClass" +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.md b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.md new file mode 100644 index 0000000000000..caf4193b4a98a --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.md @@ -0,0 +1,4 @@ + +- Type: `closure` +- Name: `__invoke` +- Class: `Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\CallableClass` diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.txt b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.txt new file mode 100644 index 0000000000000..78ef6a6527cae --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.txt @@ -0,0 +1 @@ +Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\CallableClass::__invoke() \ No newline at end of file diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.xml new file mode 100644 index 0000000000000..1ad2ee8f47d30 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.xml @@ -0,0 +1,2 @@ + + 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 99c7cba66f343..f7a3cb0bd90ca 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 687323e9ed8fb..475ad24cfda20 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/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 28f8a8d5db64d..f2b85c5f0c84a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -66,10 +66,11 @@ "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", "symfony/asset": "<3.4", "symfony/console": "<3.4", + "symfony/dotenv": "<4.2", "symfony/form": "<4.2", "symfony/messenger": "<4.2", "symfony/property-info": "<3.4", - "symfony/serializer": "<4.1", + "symfony/serializer": "<4.2", "symfony/stopwatch": "<3.4", "symfony/translation": "<4.2", "symfony/twig-bridge": "<4.1.1", diff --git a/src/Symfony/Bundle/FrameworkBundle/phpunit.xml.dist b/src/Symfony/Bundle/FrameworkBundle/phpunit.xml.dist index b447e1ac3e761..c0d8df4156168 100644 --- a/src/Symfony/Bundle/FrameworkBundle/phpunit.xml.dist +++ b/src/Symfony/Bundle/FrameworkBundle/phpunit.xml.dist @@ -1,7 +1,7 @@ register($debugVoterServiceId, TraceableVoter::class) ->setDecoratedService($voterServiceId) diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index 386bbdb44486e..69e605acf56b0 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -65,7 +65,7 @@ public function prepend(ContainerBuilder $container) return; } foreach ($container->getExtensionConfig('framework') as $config) { - if (isset($config['session'])) { + if (isset($config['session']) && \is_array($config['session'])) { $rememberMeSecureDefault = $config['session']['cookie_secure'] ?? $rememberMeSecureDefault; $rememberMeSameSiteDefault = array_key_exists('cookie_samesite', $config['session']) ? $config['session']['cookie_samesite'] : $rememberMeSameSiteDefault; } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/AddSecurityVotersPassTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/AddSecurityVotersPassTest.php index 82f89ac422ee0..ecc9717d4f32f 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/AddSecurityVotersPassTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/AddSecurityVotersPassTest.php @@ -95,13 +95,13 @@ public function testThatVotersAreDecoratedInDebugMode(): void $compilerPass = new AddSecurityVotersPass(); $compilerPass->process($container); - $def1 = $container->getDefinition('.debug.security.voter.voter1'); + $def1 = $container->getDefinition('debug.security.voter.voter1'); $this->assertEquals(array('voter1', null, 0), $def1->getDecoratedService(), 'voter1: wrong return from getDecoratedService'); - $this->assertEquals(new Reference('.debug.security.voter.voter1.inner'), $def1->getArgument(0), 'voter1: wrong decorator argument'); + $this->assertEquals(new Reference('debug.security.voter.voter1.inner'), $def1->getArgument(0), 'voter1: wrong decorator argument'); - $def2 = $container->getDefinition('.debug.security.voter.voter2'); + $def2 = $container->getDefinition('debug.security.voter.voter2'); $this->assertEquals(array('voter2', null, 0), $def2->getDecoratedService(), 'voter2: wrong return from getDecoratedService'); - $this->assertEquals(new Reference('.debug.security.voter.voter2.inner'), $def2->getArgument(0), 'voter2: wrong decorator argument'); + $this->assertEquals(new Reference('debug.security.voter.voter2.inner'), $def2->getArgument(0), 'voter2: wrong decorator argument'); $voters = $container->findTaggedServiceIds('security.voter'); $this->assertCount(2, $voters, 'Incorrect count of voters'); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php index 805ec281e6390..0154d2a5e5d66 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php @@ -12,6 +12,7 @@ namespace Symfony\Bundle\SecurityBundle\Tests\DependencyInjection; use PHPUnit\Framework\TestCase; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\FrameworkExtension; use Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension; use Symfony\Bundle\SecurityBundle\SecurityBundle; use Symfony\Bundle\SecurityBundle\Tests\DependencyInjection\Fixtures\UserProvider\DummyProvider; @@ -343,6 +344,59 @@ public function testDoNotRegisterTheUserProviderAliasWithMultipleProviders() $this->assertFalse($container->has(UserProviderInterface::class)); } + /** + * @dataProvider sessionConfigurationProvider + */ + public function testRememberMeCookieInheritFrameworkSessionCookie($config, $samesite, $secure) + { + $container = $this->getRawContainer(); + + $container->registerExtension(new FrameworkExtension()); + $container->setParameter('kernel.bundles_metadata', array()); + $container->setParameter('kernel.project_dir', __DIR__); + $container->setParameter('kernel.root_dir', __DIR__); + $container->setParameter('kernel.cache_dir', __DIR__); + + $container->loadFromExtension('security', array( + 'firewalls' => array( + 'default' => array( + 'form_login' => null, + 'remember_me' => array('secret' => 'baz'), + ), + ), + )); + $container->loadFromExtension('framework', array( + 'session' => $config, + )); + + $container->compile(); + + $definition = $container->getDefinition('security.authentication.rememberme.services.simplehash.default'); + + $this->assertEquals($samesite, $definition->getArgument(3)['samesite']); + $this->assertEquals($secure, $definition->getArgument(3)['secure']); + } + + public function sessionConfigurationProvider() + { + return array( + array( + false, + null, + false, + ), + array( + array( + 'cookie_secure' => true, + 'cookie_samesite' => 'lax', + 'save_path' => null, + ), + 'lax', + true, + ), + ); + } + protected function getRawContainer() { $container = new ContainerBuilder(); diff --git a/src/Symfony/Bundle/SecurityBundle/phpunit.xml.dist b/src/Symfony/Bundle/SecurityBundle/phpunit.xml.dist index 8636f70c187a5..0824bf04c1514 100644 --- a/src/Symfony/Bundle/SecurityBundle/phpunit.xml.dist +++ b/src/Symfony/Bundle/SecurityBundle/phpunit.xml.dist @@ -1,7 +1,7 @@ Help - + Symfony Support Channels diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig index 8e496fe8a458e..f6648b5b38fe1 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig @@ -143,7 +143,7 @@ File Name MIME Type - Size (bytes) + Size (bytes) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base.html.twig index bc5e8e2620306..1bf99d3e0ac7f 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base.html.twig @@ -15,7 +15,7 @@ {% block body '' %} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/settings.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/settings.html.twig index cc794e110400e..348d4a1d8bf29 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/settings.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/settings.html.twig @@ -1,6 +1,6 @@ -Settings +Settings