Merge branch '4.2'

* 4.2: (45 commits)
  [Form] various minor fixes
  Ensure the parent process is always killed
  bugfix: the terminal state was wrong and not reseted
  [Console] Fix inconsistent result for choice questions in non-interactive mode
  Define null return type for Constraint::getDefaultOption()
  [Routing] Fix: annotation loader ignores method's default values
  [HttpKernel] Fix DebugHandlersListener constructor docblock
  Skip Glob brace test when GLOB_BRACE is unavailable
  bumped Symfony version to 4.2.6
  updated VERSION for 4.2.5
  updated CHANGELOG for 4.2.5
  bumped Symfony version to 3.4.25
  updated VERSION for 3.4.24
  update CONTRIBUTORS for 3.4.24
  updated CHANGELOG for 3.4.24
  [EventDispatcher] cleanup
  fix testIgnoredAttributesInContext
  Re-generate icu 64.1 data
  Improve PHPdoc / IDE autocomplete for config tree builder
  [Bridge][Twig] DebugCommand - fix escaping and filter
  ...
This commit is contained in:
Fabien Potencier 2019-04-06 16:04:46 +02:00
commit f527acfac7
1144 changed files with 10154 additions and 3470 deletions

View File

@ -7,6 +7,52 @@ 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.5 (2019-04-02)
* bug #30660 [Bridge][Twig] DebugCommand - fix escaping and filter (SpacePossum)
* bug #30784 [Translator] Add resource path to exception message for schema valida… (jschaedl)
* bug #30720 Fix getSetMethodNormalizer to correctly ignore the attributes specified in "ignored_attributes" (Emmanuel BORGES)
* bug #30749 [Serializer] Added check of constuctor modifiers to AbstractNormalizer (NekaKawaii)
* bug #30776 [Routing] Fix routes annotation loading with glob pattern (snoob)
* bug #30773 [DependencyInjection] Fix hardcoded hotPathTagName (jderusse)
* bug #30737 [Validator] Improve constraint default option check (vudaltsov)
* bug #30736 [Validator] Fix annotation default for @Count and @Length (vudaltsov)
* bug #30621 [Cache] Ensure key exists before checking array value (jrjohnson)
* bug #30711 [Serializer] Use object class resolver when extracting attributes (joelwurtz)
* bug #30641 [FrameworkBundle] properly describe service definitions without class (xabbuh)
* bug #30620 [FrameworkBundle][HttpFoundation] make session service resettable (dmaicher)
* bug #30648 Debug finalized config in debug:config (ro0NL)
* bug #30640 [Phpunit] fixed support for PHP 5.3 (fabpot)
* bug #30616 Fix case when multiple loaders are providing paths for the same namespace (yceruto)
* bug #30595 Do not validate child constraints if form has no validation groups (maryo)
* bug #30440 [TwigBridge] Fix DebugCommand when chain loader is involved (yceruto)
* bug #30479 Check if Client exists when test.client does not exist, to provide clearer exception message (SerkanYildiz)
* bug #30597 [Form] Added ResetInterface to CachingFactoryDecorator (HeahDude)
* bug #30593 Fixed usage of TranslatorInterface in form extension (fixes #30591) (althaus)
* feature #30584 [Intl] Add compile binary (ro0NL)
* bug #30487 Fix Cache error while using anonymous class (Emmanuel BORGES)
* bug #30576 [Cache] fix LockRegistry (nicolas-grekas)
* bug #30548 Correct language code for ukrainian language (stanleyk)
* bug #30518 [Cache] Fix perf when using RedisCluster by reducing roundtrips to the servers (nicolas-grekas)
* bug #30515 [Cache] Only delete one key at a time when on Predis + Cluster (andrerom)
* bug #30511 [Process] fix using argument $php of new PhpProcess() (nicolas-grekas)
* bug #30507 [Routing] Fixed XML options resolution (Jules Pietri)
* bug #30506 [TwigBridge] remove deprecation triggered when using Twig 2.7 (nicolas-grekas)
* bug #30496 [PHPUnit-Bridge] override some Composer environment variables (nicoweb)
* bug #30505 [TwigBridge] Remove usages of the spaceless tag (nicolas-grekas)
* bug #30466 [Messenger] Make 'headers' key optional for encoded messages (yceruto)
* bug #30474 compatibility with phpunit8 (garak)
* bug #30497 [HttpKernel] Change default log level for output streams (yceruto)
* bug #30498 [translation] Update defaut format from yml to yaml (GaryPEGEOT)
* bug #30490 Don't resolve the Deprecation error handler mode until a deprecation is triggered (Emmanuel BORGES)
* bug #30396 [Form] Avoid a form type extension appears many times in debug:form (markitosgv)
* bug #30361 [PropertyInfo] Fix undefined variable fromConstructor when passing context to getTypes (mantis)
* bug #30361 [PropertyInfo] Fix undefined variable fromConstructor when passing context to getTypes (mantis, OskarStark)
* bug #30410 [Monolog] Really reset logger when calling logger::reset() (lyrixx)
* bug #30437 [Debug] detect annotations before blank docblock lines (xabbuh)
* bug #30417 Autoconfig: don't automatically tag decorators (dunglas)
* bug #30392 [PropertyAccess] Fixed PropertyPathBuilder remove that fails to reset internal indexes (GregOriol)
* 4.2.4 (2019-03-03)
* bug #30383 [WebProfilerBundle] toolbar: invisible route name in Firefox (inmarelibero)

View File

@ -15,21 +15,21 @@ Symfony is the result of the work of many people who made the code better
- Victor Berchet (victor)
- Kévin Dunglas (dunglas)
- Maxime Steinhausser (ogizanagi)
- Ryan Weaver (weaverryan)
- Jakub Zalas (jakubzalas)
- Johannes S (johannes)
- Javier Eguiluz (javier.eguiluz)
- Ryan Weaver (weaverryan)
- Kris Wallsmith (kriswallsmith)
- Roland Franssen (ro0)
- Grégoire Pineau (lyrixx)
- Roland Franssen (ro0)
- Hugo Hamon (hhamon)
- Abdellatif Ait boudad (aitboudad)
- Romain Neutron (romain)
- Pascal Borreli (pborreli)
- Wouter De Jong (wouterj)
- Samuel ROZE (sroze)
- Joseph Bielawski (stloyd)
- Karma Dordrak (drak)
- Samuel ROZE (sroze)
- Lukas Kahwe Smith (lsmith)
- Martin Hasoň (hason)
- Jeremy Mikola (jmikola)
@ -42,8 +42,8 @@ Symfony is the result of the work of many people who made the code better
- Guilhem Niot (energetick)
- Sarah Khalil (saro0h)
- Jonathan Wage (jwage)
- Hamza Amrouche (simperfit)
- Tobias Nyholm (tobias)
- Hamza Amrouche (simperfit)
- Diego Saint Esteben (dosten)
- Iltar van der Berg (kjarli)
- Alexandre Salomé (alexandresalome)
@ -54,8 +54,8 @@ Symfony is the result of the work of many people who made the code better
- stealth35 (stealth35)
- Alexander Mols (asm89)
- Bulat Shakirzyanov (avalanche123)
- Matthias Pigulla (mpdude)
- Jérémy DERUSSÉ (jderusse)
- Matthias Pigulla (mpdude)
- Saša Stamenković (umpirsky)
- Peter Rehm (rpet)
- Kevin Bond (kbond)
@ -69,23 +69,24 @@ Symfony is the result of the work of many people who made the code better
- Mathieu Piot (mpiot)
- Florin Patan (florinpatan)
- Gábor Egyed (1ed)
- Gabriel Ostrolucký (gadelat)
- Titouan Galopin (tgalopin)
- Vladimir Reznichenko (kalessil)
- Jáchym Toušek (enumag)
- David Maicher (dmaicher)
- Michel Weimerskirch (mweimerskirch)
- Andrej Hudec (pulzarraider)
- Konstantin Myakshin (koc)
- Eric Clemmons (ericclemmons)
- Charles Sarrazin (csarrazi)
- David Maicher (dmaicher)
- Christian Raue
- Issei Murasawa (issei_m)
- Valentin Udaltsov (vudaltsov)
- Arnout Boks (aboks)
- Deni
- Grégoire Paris (greg0ire)
- Henrik Westphal (snc)
- Dariusz Górecki (canni)
- Valentin Udaltsov (vudaltsov)
- Douglas Greenshields (shieldo)
- Dariusz Ruminski
- Lee McDermott
@ -99,7 +100,6 @@ Symfony is the result of the work of many people who made the code better
- Jérôme Tamarelle (gromnan)
- John Wards (johnwards)
- Fran Moreno (franmomu)
- gadelat (gadelat)
- Antoine Hérault (herzult)
- Paráda József (paradajozsef)
- Arnaud Le Blanc (arnaud-lb)
@ -108,13 +108,14 @@ Symfony is the result of the work of many people who made the code better
- Tim Nagel (merk)
- Brice BERNARD (brikou)
- Baptiste Clavié (talus)
- Chris Wilkinson (thewilkybarkid)
- marc.weistroff
- Tomáš Votruba (tomas_votruba)
- David Buchmann (dbu)
- lenar
- Alexander Schwenn (xelaris)
- Włodzimierz Gajda (gajdaw)
- Chris Wilkinson (thewilkybarkid)
- Thomas Calvet (fancyweb)
- Jérôme Vasseur (jvasseur)
- Peter Kokot (maastermedia)
- Jacob Dreesen (jdreesen)
@ -125,11 +126,10 @@ Symfony is the result of the work of many people who made the code better
- Daniel Wehner (dawehner)
- excelwebzone
- Gordon Franke (gimler)
- Thomas Calvet (fancyweb)
- Sebastiaan Stok (sstok)
- Javier Spagnoletti (phansys)
- Fabien Pennequin (fabienpennequin)
- Eric GELOEN (gelo)
- Sebastiaan Stok (sstok)
- Lars Strojny (lstrojny)
- Tugdual Saunier (tucksaun)
- Théo FIDRY (theofidry)
@ -140,14 +140,18 @@ Symfony is the result of the work of many people who made the code better
- Alex Pott
- Vincent AUBERT (vincent)
- Juti Noppornpitak (shiroyuki)
- Anthony MARTIN (xurudragon)
- Oskar Stark (oskarstark)
- Tigran Azatyan (tigranazatyan)
- Sebastian Hörl (blogsh)
- Daniel Gomes (danielcsgomes)
- Joel Wurtz (brouznouf)
- Gabriel Caruso
- Hidenori Goto (hidenorigoto)
- Arnaud Kleinpeter (nanocom)
- Jannik Zschiesche (apfelbox)
- Guilherme Blanco (guilhermeblanco)
- Teoh Han Hui (teohhanhui)
- Pablo Godel (pgodel)
- Jérémie Augustin (jaugustin)
- Andréia Bohner (andreia)
@ -155,9 +159,7 @@ Symfony is the result of the work of many people who made the code better
- Julien Falque (julienfalque)
- Rafael Dohms (rdohms)
- jwdeitch
- Teoh Han Hui (teohhanhui)
- Mikael Pajunen
- Joel Wurtz (brouznouf)
- Oleg Voronkovich
- Vyacheslav Pavlov
- Richard van Laak (rvanlaak)
@ -172,7 +174,6 @@ Symfony is the result of the work of many people who made the code better
- Matthieu Ouellette-Vachon (maoueh)
- Michał Pipa (michal.pipa)
- Dawid Nowak
- Gabriel Ostrolucký
- Amal Raghav (kertz)
- Jonathan Ingram (jonathaningram)
- Artur Kotyrba
@ -181,12 +182,12 @@ Symfony is the result of the work of many people who made the code better
- SpacePossum
- jeremyFreeAgent (Jérémy Romey) (jeremyfreeagent)
- James Halsall (jaitsu)
- Anthony MARTIN (xurudragon)
- Matthieu Napoli (mnapoli)
- Florent Mata (fmata)
- Warnar Boekkooi (boekkooi)
- Dmitrii Chekaliuk (lazyhammer)
- Clément JOBEILI (dator)
- Marek Štípek (maryo)
- Daniel Espendiller
- Possum
- Dorian Villet (gnutix)
@ -196,7 +197,7 @@ Symfony is the result of the work of many people who made the code better
- Mario A. Alvarez Garcia (nomack84)
- Dennis Benkert (denderello)
- DQNEO
- Oskar Stark (oskarstark)
- Samuel NELA (snela)
- Benjamin Dulau (dbenjamin)
- François-Xavier de Guillebon (de-gui_f)
- Mathieu Lemoine (lemoinem)
@ -205,7 +206,6 @@ Symfony is the result of the work of many people who made the code better
- Tom Van Looy (tvlooy)
- Noel Guilbert (noel)
- Yanick Witschi (toflar)
- Marek Štípek (maryo)
- Stepan Anchugov (kix)
- bronze1man
- sun (sun)
@ -217,24 +217,28 @@ Symfony is the result of the work of many people who made the code better
- apetitpa
- Matthieu Bontemps (mbontemps)
- apetitpa
- Samuel NELA (snela)
- Pierre Minnieur (pminnieur)
- fivestar
- Dominique Bongiraud
- Jeremy Livingston (jeremylivingston)
- Michael Lee (zerustech)
- Matthieu Auger (matthieuauger)
- Gregor Harlan (gharlan)
- Leszek Prabucki (l3l0)
- Fabien Bourigault (fbourigault)
- François Zaninotto (fzaninotto)
- Dustin Whittle (dustinwhittle)
- jeff
- John Kary (johnkary)
- Andreas Schempp (aschempp)
- Justin Hileman (bobthecow)
- Blanchon Vincent (blanchonvincent)
- Michele Orselli (orso)
- Sven Paulus (subsven)
- Maxime Veber (nek-)
- Gary PEGEOT (gary-p)
- Rui Marinho (ruimarinho)
- Massimiliano Arione (garak)
- Eugene Wissner
- Pascal Montoya
- Julien Brochet (mewt)
@ -242,15 +246,17 @@ Symfony is the result of the work of many people who made the code better
- Tristan Darricau (nicofuma)
- Marcel Beerta (mazen)
- Pavel Batanov (scaytrase)
- Mantis Development
- Loïc Faugeron
- Hidde Wieringa (hiddewie)
- Marco Pivetta (ocramius)
- Jan Schädlich (jschaedl)
- Rob Frawley 2nd (robfrawley)
- julien pauli (jpauli)
- Lorenz Schori
- Sébastien Lavoie (lavoiesl)
- Gregor Harlan (gharlan)
- Dariusz
- Michael Babker (mbabker)
- Francois Zaninotto
- Alexander Kotynia (olden)
- Daniel Tschinder
@ -265,7 +271,6 @@ 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
@ -277,6 +282,7 @@ Symfony is the result of the work of many people who made the code better
- Baptiste Lafontaine (magnetik)
- Jakub Kucharovic (jkucharovic)
- Edi Modrić (emodric)
- Alexander Schranz (alexander-schranz)
- Uwe Jäger (uwej711)
- Eugene Leonovich (rybakit)
- Filippo Tessarotto
@ -290,10 +296,9 @@ Symfony is the result of the work of many people who made the code better
- Viktor Bocharskyi (bocharsky_bw)
- Jhonny Lidfors (jhonne)
- Diego Agulló (aeoris)
- Andreas Schempp (aschempp)
- jdhoek
- Massimiliano Arione (garak)
- Bob den Otter (bopp)
- Thomas Schulz (king2500)
- Frank de Jonge (frenkynet)
- Nikita Konstantinov
- Wodor Wodorski
@ -301,7 +306,7 @@ Symfony is the result of the work of many people who made the code better
- mcfedr (mcfedr)
- Colin O'Dell (colinodell)
- Giorgio Premi
- Jan Schädlich (jschaedl)
- Alex Rock (pierstoval)
- Ben Davies (bendavies)
- Beau Simensen (simensen)
- Michael Hirschler (mvhirsch)
@ -309,9 +314,9 @@ Symfony is the result of the work of many people who made the code better
- Roumen Damianoff (roumen)
- Antonio J. García Lagar (ajgarlag)
- Kim Hemsø Rasmussen (kimhemsoe)
- Pascal Luna (skalpa)
- Wouter Van Hecke
- Jérôme Parmentier (lctrs)
- Michael Babker (mbabker)
- Peter Kruithof (pkruithof)
- Michael Holm (hollo)
- Remon van de Kamp (rpkamp)
@ -319,14 +324,13 @@ Symfony is the result of the work of many people who made the code better
- Marc Weistroff (futurecat)
- Christian Schmidt
- MatTheCat
- Alexander Schranz (alexander-schranz)
- Chad Sikorra (chadsikorra)
- Chris Smith (cs278)
- Florian Klein (docteurklein)
- Gary PEGEOT (gary-p)
- Manuel Kiessling (manuelkiessling)
- Atsuhiro KUBO (iteman)
- rudy onfroy (ronfroy)
- Serkan Yildiz (srknyldz)
- Andrew Moore (finewolf)
- Bertrand Zuchuat (garfield-fr)
- Sullivan SENECHAL (soullivaneuh)
@ -347,14 +351,16 @@ Symfony is the result of the work of many people who made the code better
- Hidde Boomsma (hboomsma)
- John Bafford (jbafford)
- Raul Fraile (raulfraile)
- David Prévot
- Adrian Rudnik (kreischweide)
- Francesc Rosàs (frosas)
- Romain Pierre (romain-pierre)
- Julien Galenski (ruian)
- Bongiraud Dominique
- janschoenherr
- Thomas Schulz (king2500)
- Emanuele Gaspari (inmarelibero)
- Dariusz Rumiński
- Vincent Touzet (vincenttouzet)
- Berny Cantos (xphere81)
- Thierry Thuon (lepiaf)
- Ricard Clau (ricardclau)
@ -367,8 +373,9 @@ Symfony is the result of the work of many people who made the code better
- Zan Baldwin (zanderbaldwin)
- Thomas Royer (cydonia7)
- alquerci
- Mateusz Sip (mateusz_sip)
- Andre Rømcke (andrerom)
- Francesco Levorato
- Pascal Luna (skalpa)
- Dmitrii Poddubnyi (karser)
- Vitaliy Zakharov (zakharovvi)
- Tobias Sjösten (tobiassjosten)
@ -384,6 +391,7 @@ Symfony is the result of the work of many people who made the code better
- Yaroslav Kiliba
- Terje Bråten
- Robbert Klarenbeek (robbertkl)
- Eric Masoero (eric-masoero)
- JhonnyL
- David Badura (davidbadura)
- hossein zolfi (ocean)
@ -394,6 +402,7 @@ Symfony is the result of the work of many people who made the code better
- ShinDarth
- Stéphane PY (steph_py)
- Philipp Kräutli (pkraeutli)
- Anton Chernikov (anton_ch1989)
- Grzegorz (Greg) Zdanowski (kiler129)
- Iker Ibarguren (ikerib)
- Kirill chEbba Chebunin (chebba)
@ -414,10 +423,10 @@ Symfony is the result of the work of many people who made the code better
- Tobias Naumann (tna)
- Daniel Beyer
- Shein Alexey
- Alex Rock Ancelet (pierstoval)
- Romain Gautier (mykiwi)
- Joe Lencioni
- Daniel Tschinder
- Emmanuel BORGES (eborges78)
- vladimir.reznichenko
- Kai
- Lee Rowlands
@ -427,7 +436,6 @@ Symfony is the result of the work of many people who made the code better
- Karoly Negyesi (chx)
- Ivan Kurnosov
- Xavier HAUSHERR
- David Prévot
- Albert Jessurum (ajessu)
- Laszlo Korte
- Miha Vrhovnik
@ -440,7 +448,6 @@ Symfony is the result of the work of many people who made the code better
- Karel Souffriau
- Christophe L. (christophelau)
- Anthon Pang (robocoder)
- Emanuele Gaspari (inmarelibero)
- Sébastien Santoro (dereckson)
- Brian King
- Michel Salib (michelsalib)
@ -461,7 +468,7 @@ Symfony is the result of the work of many people who made the code better
- Olivier Dolbeau (odolbeau)
- Jan Rosier (rosier)
- Alessandro Lai (jean85)
- Andre Rømcke (andrerom)
- Nicolas LEFEVRE (nicoweb)
- Arturs Vonda
- Josip Kruslin
- Asmir Mustafic (goetas)
@ -473,7 +480,6 @@ Symfony is the result of the work of many people who made the code better
- Vlad Gregurco (vgregurco)
- Boris Vujicic (boris.vujicic)
- Chris Sedlmayr (catchamonkey)
- Mateusz Sip (mateusz_sip)
- Kamil Kokot (pamil)
- Seb Koelen
- Christoph Mewes (xrstf)
@ -528,6 +534,7 @@ Symfony is the result of the work of many people who made the code better
- ondrowan
- Barry vd. Heuvel (barryvdh)
- Craig Duncan (duncan3dc)
- Patrick Landolt (scube)
- Sébastien Alfaiate (seb33300)
- Evan S Kaufman (evanskaufman)
- mcben
@ -603,6 +610,7 @@ Symfony is the result of the work of many people who made the code better
- Jan Behrens
- Mantas Var (mvar)
- Sebastian Krebs
- Piotr Stankowski
- Baptiste Leduc (bleduc)
- Laurent VOULLEMIER (lvo)
- Jean-Christophe Cuvelier [Artack]
@ -617,6 +625,7 @@ Symfony is the result of the work of many people who made the code better
- Renan
- Ricky Su (ricky)
- Gildas Quéméner (gquemener)
- Kyle Evans (kevans91)
- Charles-Henri Bruyand
- Max Rath (drak3)
- Stéphane Escandell (sescandell)
@ -625,6 +634,8 @@ Symfony is the result of the work of many people who made the code better
- Sinan Eldem
- Alexandre Dupuy (satchette)
- Malte Blättermann
- Kévin THERAGE (kevin_therage)
- Simeon Kolev (simeon_kolev9)
- Nahuel Cuesta (ncuesta)
- Chris Boden (cboden)
- Christophe Villeger (seragan)
@ -649,11 +660,13 @@ Symfony is the result of the work of many people who made the code better
- Sebastian Marek (proofek)
- Guilhem N (guilhemn)
- Erkhembayar Gantulga (erheme318)
- zenmate
- Michal Trojanowski
- David Fuhr
- Max Grigorian (maxakawizard)
- DerManoMann
- Rostyslav Kinash
- Dennis Fridrich (dfridrich)
- Maciej Malarz (malarzm)
- Daisuke Ohata
- Vincent Simonin
@ -707,6 +720,7 @@ Symfony is the result of the work of many people who made the code better
- Paweł Wacławczyk (pwc)
- Oleg Zinchenko (cystbear)
- Baptiste Meyer (meyerbaptiste)
- Tales Santos (tsantos84)
- Johannes Klauss (cloppy)
- Evan Villemez
- fzerorubigd
@ -720,6 +734,7 @@ Symfony is the result of the work of many people who made the code better
- flip111
- Greg Anderson
- VJ
- RJ Garcia
- Delf Tonder (leberknecht)
- Mark Sonnabaum
- Massimiliano Braglia (massimilianobraglia)
@ -738,15 +753,14 @@ Symfony is the result of the work of many people who made the code better
- Julien DIDIER (juliendidier)
- Dominik Ritter (dritter)
- Sebastian Grodzicki (sgrodzicki)
- Serkan Yildiz (srknyldz)
- Jeroen van den Enden (stoefke)
- nikos.sotiropoulos
- Pascal Helfenstein
- Anthony GRASSIOT (antograssiot)
- Baldur Rensch (brensch)
- Pierre Rineau
- Vladyslav Petrovych
- Alex Xandra Albert Sim
- Patrick Landolt (scube)
- Carson Full
- Sergey Yastrebov
- Trent Steel (trsteel88)
@ -761,6 +775,7 @@ Symfony is the result of the work of many people who made the code better
- Dave Marshall (davedevelopment)
- Jakub Kulhan (jakubkulhan)
- avorobiev
- Grégoire Penverne (gpenverne)
- Venu
- Lars Vierbergen
- Jonatan Männchen
@ -774,6 +789,7 @@ Symfony is the result of the work of many people who made the code better
- Jordan Deitch
- Casper Valdemar Poulsen
- Josiah (josiah)
- Greg ORIOL
- Joschi Kuphal
- John Bohn (jbohn)
- Marc Morera (mmoreram)
@ -922,6 +938,7 @@ Symfony is the result of the work of many people who made the code better
- Stéphane Delprat
- Brian Freytag (brianfreytag)
- Samuele Lilli (doncallisto)
- Marko Kaznovac (kaznovac)
- Brunet Laurent (lbrunet)
- Florent Viel (luxifer)
- Mikhail Yurasov (mym)
@ -937,15 +954,17 @@ Symfony is the result of the work of many people who made the code better
- Kyle
- Daniel Alejandro Castro Arellano (lexcast)
- sensio
- Thomas Jarrand
- Sebastien Morel (plopix)
- Patrick Kaufmann
- Piotr Stankowski
- Anton Dyshkant
- Reece Fowell (reecefowell)
- Mátyás Somfai (smatyas)
- stefan.r
- Valérian Galliat
- d-ph
- Renan Taranto (renan-taranto)
- Thomas Talbot (ioni)
- Rikijs Murgs
- Ben Ramsey (ramsey)
- Amaury Leroux de Lens (amo__)
@ -954,12 +973,14 @@ Symfony is the result of the work of many people who made the code better
- The Whole Life to Learn
- ergiegonzaga
- Farhad Safarov
- Alexis Lefebvre
- Liverbool (liverbool)
- Sam Malone
- Phan Thanh Ha (haphan)
- Chris Jones (leek)
- xaav
- Mahmoud Mostafa (mahmoud)
- Ahmed Abdou
- Pieter
- Michael Tibben
- Billie Thompson
@ -992,21 +1013,23 @@ Symfony is the result of the work of many people who made the code better
- Irmantas Šiupšinskas (irmantas)
- Danilo Silva
- Arnaud PETITPAS (apetitpa)
- Ken Stanley
- Zachary Tong (polyfractal)
- Ashura
- Hryhorii Hrebiniuk
- johnstevenson
- Dennis Fridrich (dfridrich)
- hamza
- dantleech
- Bastien DURAND (deamon)
- Xavier Leune
- Rudy Onfroy
- Tero Alén (tero)
- Stanislav Kocanda
- DerManoMann
- Guillaume Royer
- Artem (digi)
- boite
- Silvio Ginter
- MGDSoft
- Vadim Tyukov (vatson)
- David Wolter (davewww)
@ -1015,6 +1038,7 @@ Symfony is the result of the work of many people who made the code better
- Wojciech Sznapka
- Gavin Staniforth
- Ariel J. Birnbaum
- Danijel Obradović
- Pablo Borowicz
- Mathieu Santostefano
- Arjan Keeman
@ -1065,7 +1089,6 @@ Symfony is the result of the work of many people who made the code better
- Jean-Guilhem Rouel (jean-gui)
- jfcixmedia
- Dominic Tubach
- Tales Santos (tsantos84)
- Nikita Konstantinov
- Martijn Evers
- Vitaliy Ryaboy (vitaliy)
@ -1094,6 +1117,7 @@ Symfony is the result of the work of many people who made the code better
- Tadas Gliaubicas (tadcka)
- Thanos Polymeneas (thanos)
- Benoit Garret
- Maximilian Ruta (deltachaos)
- Jakub Sacha
- Olaf Klischat
- orlovv
@ -1131,7 +1155,6 @@ Symfony is the result of the work of many people who made the code better
- rpg600
- Péter Buri (burci)
- kaiwa
- RJ Garcia
- Charles Sanquer (csanquer)
- Albert Ganiev (helios-ag)
- Neil Katin
@ -1148,7 +1171,6 @@ Symfony is the result of the work of many people who made the code better
- rchoquet
- gitlost
- Taras Girnyk
- nikos.sotiropoulos
- Eduardo García Sanz (coma)
- Sergio (deverad)
- James Gilliland
@ -1207,7 +1229,6 @@ Symfony is the result of the work of many people who made the code better
- Mario Young
- Ilia (aliance)
- Chris McCafferty (cilefen)
- Grégoire Penverne (gpenverne)
- Mo Di (modi)
- Pablo Schläpfer
- Gert de Pagter
@ -1215,6 +1236,7 @@ Symfony is the result of the work of many people who made the code better
- Quique Porta (quiqueporta)
- stoccc
- Tomasz Szymczyk (karion)
- Alex Vasilchenko
- Xavier Coureau
- ConneXNL
- Aharon Perkel
@ -1232,8 +1254,10 @@ Symfony is the result of the work of many people who made the code better
- Sebastian Göttschkes (sgoettschkes)
- Tatsuya Tsuruoka
- Ross Tuck
- Andreas Erhard
- Kévin Gomez (kevin)
- Mihai Nica (redecs)
- Soufian EZ-ZANTAR (soezz)
- Andrei Igna
- azine
- Dawid Sajdak
@ -1249,6 +1273,7 @@ Symfony is the result of the work of many people who made the code better
- Saem Ghani
- Clément LEFEBVRE
- Conrad Kleinespel
- Matthias Althaus
- Zacharias Luiten
- Sebastian Utz
- Adrien Gallou (agallou)
@ -1288,6 +1313,7 @@ Symfony is the result of the work of many people who made the code better
- Markus Fasselt (digilist)
- Vašek Purchart (vasek-purchart)
- Janusz Jabłoński (yanoosh)
- Fleuv
- Sandro Hopf
- Łukasz Makuch
- George Giannoulopoulos
@ -1311,11 +1337,11 @@ Symfony is the result of the work of many people who made the code better
- Daniel Kay (danielkay-cp)
- Matt Daum (daum)
- Alberto Pirovano (geezmo)
- Nicolas LEFEVRE (nicoweb)
- Pete Mitchell (peterjmit)
- Tom Corrigan (tomcorrigan)
- Luis Galeas
- Martin Pärtel
- Frédéric Bouchery (fbouchery)
- Patrick Daley (padrig)
- Xavier Briand (xavierbriand)
- Max Summe
@ -1336,6 +1362,7 @@ Symfony is the result of the work of many people who made the code better
- Emmanuel Vella (emmanuel.vella)
- Guillaume BRETOU (guiguiboy)
- Jonathan Johnson (jrjohnson)
- Dāvis Zālītis (k0d3r1s)
- Carsten Nielsen (phreaknerd)
- Roger Guasch (rogerguasch)
- Mathieu Rochette
@ -1371,6 +1398,7 @@ Symfony is the result of the work of many people who made the code better
- mlively
- Amine Matmati
- caalholm
- Nouhail AL FIDI (alfidi)
- Fabian Steiner (fabstei)
- Felipy Tavares Amorim (felipyamorim)
- Klaus Silveira (klaussilveira)
@ -1420,7 +1448,6 @@ Symfony is the result of the work of many people who made the code better
- Hoffmann András
- LubenZA
- Olivier
- Anton Chernikov
- Cyril PASCAL
- pscheit
- Wybren Koelmans
@ -1432,6 +1459,7 @@ Symfony is the result of the work of many people who made the code better
- Antonio Peric-Mazar (antonioperic)
- César Suárez (csuarez)
- Bjorn Twachtmann (dotbjorn)
- Tobias Genberg (lorceroth)
- Luis Tacón (lutacon)
- Nicolas Badey (nico-b)
- Shane Preece (shane)
@ -1465,10 +1493,9 @@ Symfony is the result of the work of many people who made the code better
- Przemysław Piechota (kibao)
- Leonid Terentyev (li0n)
- Martynas Sudintas (martiis)
- Gabriel Ostrolucký
- ryunosuke
- zenmate
- victoria
- Dmytro Borysovskyi (dmytr0)
- Francisco Facioni (fran6co)
- Iwan van Staveren (istaveren)
- Povilas S. (povilas)
@ -1488,6 +1515,7 @@ Symfony is the result of the work of many people who made the code better
- Ikhsan Agustian
- Arnau González (arnaugm)
- Simon Bouland (bouland)
- Jibé Barth (jibbarth)
- Matthew Foster (mfoster)
- Reyo Stallenberg (reyostallenberg)
- Paul Seiffert (seiffert)
@ -1531,7 +1559,6 @@ Symfony is the result of the work of many people who made the code better
- Gunther Konig
- Mickael GOETZ
- Maciej Schmidt
- Greg ORIOL
- Dennis Væversted
- nuncanada
- flack
@ -1652,6 +1679,7 @@ Symfony is the result of the work of many people who made the code better
- Trevor Suarez
- gedrox
- Alan Bondarchuk
- Joe Bennett
- dropfen
- Andrey Chernykh
- Edvinas Klovas
@ -1671,6 +1699,7 @@ Symfony is the result of the work of many people who made the code better
- AmsTaFF (amstaff)
- Simon Müller (boscho)
- Yannick Bensacq (cibou)
- Damien (damien_vauchel)
- Frédéric G. Marand (fgm)
- Freek Van der Herten (freekmurze)
- Luca Genuzio (genuzio)
@ -1735,6 +1764,7 @@ Symfony is the result of the work of many people who made the code better
- timaschew
- Jochen Mandl
- Marin Nicolae
- soyuka
- Alessandro Loffredo
- Ian Phillips
- Marco Lipparini
@ -1810,6 +1840,7 @@ Symfony is the result of the work of many people who made the code better
- Kevin Verschaeve (keversc)
- Kevin Herrera (kherge)
- Luis Ramón López López (lrlopez)
- Mehdi Mabrouk (mehdidev)
- Bart Reunes (metalarend)
- Muriel (metalmumu)
- Michael Pohlers (mick_the_big)
@ -1861,6 +1892,7 @@ Symfony is the result of the work of many people who made the code better
- Ramon Henrique Ornelas (ramonornela)
- Ricardo de Vries (ricknox)
- Markus S. (staabm)
- Thomas Dutrion (theocrite)
- Till Klampaeckel (till)
- Tobias Weinert (tweini)
- Ulf Reimers (ureimers)
@ -2011,7 +2043,6 @@ 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
@ -2073,6 +2104,7 @@ Symfony is the result of the work of many people who made the code better
- samuel laulhau (lalop)
- Laurent Bachelier (laurentb)
- Luís Cobucci (lcobucci)
- Marcos Gómez Vilches (markitosgv)
- Matthieu Mota (matthieumota)
- Matthieu Moquet (mattketmo)
- Moritz Borgmann (mborgmann)

View File

@ -83,7 +83,7 @@ class ClockMock
{
$self = \get_called_class();
$mockedNs = [substr($class, 0, strrpos($class, '\\'))];
$mockedNs = array(substr($class, 0, strrpos($class, '\\')));
if (0 < strpos($class, '\\Tests\\')) {
$ns = str_replace('\\Tests\\', '\\', $class);
$mockedNs[] = substr($ns, 0, strrpos($ns, '\\'));

View File

@ -16,8 +16,8 @@ namespace Symfony\Bridge\PhpUnit;
*/
class DnsMock
{
private static $hosts = [];
private static $dnsTypes = [
private static $hosts = array();
private static $dnsTypes = array(
'A' => DNS_A,
'MX' => DNS_MX,
'NS' => DNS_NS,
@ -30,7 +30,7 @@ class DnsMock
'NAPTR' => DNS_NAPTR,
'TXT' => DNS_TXT,
'HINFO' => DNS_HINFO,
];
);
/**
* Configures the mock values for DNS queries.
@ -68,7 +68,7 @@ class DnsMock
if (!self::$hosts) {
return \getmxrr($hostname, $mxhosts, $weight);
}
$mxhosts = $weight = [];
$mxhosts = $weight = array();
if (isset(self::$hosts[$hostname])) {
foreach (self::$hosts[$hostname] as $record) {
@ -125,7 +125,7 @@ class DnsMock
$ips = false;
if (isset(self::$hosts[$hostname])) {
$ips = [];
$ips = array();
foreach (self::$hosts[$hostname] as $record) {
if ('A' === $record['type']) {
@ -149,11 +149,11 @@ class DnsMock
if (DNS_ANY === $type) {
$type = DNS_ALL;
}
$records = [];
$records = array();
foreach (self::$hosts[$hostname] as $record) {
if (isset(self::$dnsTypes[$record['type']]) && (self::$dnsTypes[$record['type']] & $type)) {
$records[] = array_merge(['host' => $hostname, 'class' => 'IN', 'ttl' => 1, 'type' => $record['type']], $record);
$records[] = array_merge(array('host' => $hostname, 'class' => 'IN', 'ttl' => 1, 'type' => $record['type']), $record);
}
}
}
@ -165,7 +165,7 @@ class DnsMock
{
$self = \get_called_class();
$mockedNs = [substr($class, 0, strrpos($class, '\\'))];
$mockedNs = array(substr($class, 0, strrpos($class, '\\')));
if (0 < strpos($class, '\\Tests\\')) {
$ns = str_replace('\\Tests\\', '\\', $class);
$mockedNs[] = substr($ns, 0, strrpos($ns, '\\'));

View File

@ -31,7 +31,7 @@ class CoverageListenerTrait
{
$this->sutFqcnResolver = $sutFqcnResolver;
$this->warningOnSutNotFound = $warningOnSutNotFound;
$this->warnings = [];
$this->warnings = array();
}
public function startTest($test)
@ -42,7 +42,7 @@ class CoverageListenerTrait
$annotations = $test->getAnnotations();
$ignoredAnnotations = ['covers', 'coversDefaultClass', 'coversNothing'];
$ignoredAnnotations = array('covers', 'coversDefaultClass', 'coversNothing');
foreach ($ignoredAnnotations as $annotation) {
if (isset($annotations['class'][$annotation]) || isset($annotations['method'][$annotation])) {
@ -74,11 +74,11 @@ class CoverageListenerTrait
$r->setAccessible(true);
$cache = $r->getValue();
$cache = array_replace_recursive($cache, [
\get_class($test) => [
'covers' => [$sutFqcn],
],
]);
$cache = array_replace_recursive($cache, array(
\get_class($test) => array(
'covers' => array($sutFqcn),
),
));
$r->setValue($testClass, $cache);
}

View File

@ -22,7 +22,7 @@ class SymfonyTestsListenerForV5 extends \PHPUnit_Framework_BaseTestListener
{
private $trait;
public function __construct(array $mockedNamespaces = [])
public function __construct(array $mockedNamespaces = array())
{
$this->trait = new SymfonyTestsListenerTrait($mockedNamespaces);
}

View File

@ -27,7 +27,7 @@ class SymfonyTestsListenerForV6 extends BaseTestListener
{
private $trait;
public function __construct(array $mockedNamespaces = [])
public function __construct(array $mockedNamespaces = array())
{
$this->trait = new SymfonyTestsListenerTrait($mockedNamespaces);
}

View File

@ -30,7 +30,7 @@ class SymfonyTestsListenerForV7 implements TestListener
private $trait;
public function __construct(array $mockedNamespaces = [])
public function __construct(array $mockedNamespaces = array())
{
$this->trait = new SymfonyTestsListenerTrait($mockedNamespaces);
}

View File

@ -32,10 +32,10 @@ class SymfonyTestsListenerTrait
private static $globallyEnabled = false;
private $state = -1;
private $skippedFile = false;
private $wasSkipped = [];
private $isSkipped = [];
private $expectedDeprecations = [];
private $gatheredDeprecations = [];
private $wasSkipped = array();
private $isSkipped = array();
private $expectedDeprecations = array();
private $gatheredDeprecations = array();
private $previousErrorHandler;
private $testsWithWarnings;
private $reportUselessTests;
@ -45,7 +45,7 @@ class SymfonyTestsListenerTrait
/**
* @param array $mockedNamespaces List of namespaces, indexed by mocked features (time-sensitive or dns-sensitive)
*/
public function __construct(array $mockedNamespaces = [])
public function __construct(array $mockedNamespaces = array())
{
if (class_exists('PHPUnit_Util_Blacklist')) {
\PHPUnit_Util_Blacklist::$blacklistedClassNames['\Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait'] = 2;
@ -57,7 +57,7 @@ class SymfonyTestsListenerTrait
foreach ($mockedNamespaces as $type => $namespaces) {
if (!\is_array($namespaces)) {
$namespaces = [$namespaces];
$namespaces = array($namespaces);
}
if ('time-sensitive' === $type) {
foreach ($namespaces as $ns) {
@ -104,7 +104,7 @@ class SymfonyTestsListenerTrait
$Test = 'PHPUnit\Util\Test';
}
$suiteName = $suite->getName();
$this->testsWithWarnings = [];
$this->testsWithWarnings = array();
foreach ($suite->tests() as $test) {
if (!($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase)) {
@ -135,11 +135,11 @@ class SymfonyTestsListenerTrait
if (!$this->wasSkipped = require $this->skippedFile) {
echo "All tests already ran successfully.\n";
$suite->setTests([]);
$suite->setTests(array());
}
}
}
$testSuites = [$suite];
$testSuites = array($suite);
for ($i = 0; isset($testSuites[$i]); ++$i) {
foreach ($testSuites[$i]->tests() as $test) {
if ($test instanceof \PHPUnit_Framework_TestSuite || $test instanceof TestSuite) {
@ -158,7 +158,7 @@ class SymfonyTestsListenerTrait
}
}
} elseif (2 === $this->state) {
$skipped = [];
$skipped = array();
foreach ($suite->tests() as $test) {
if (!($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase)
|| isset($this->wasSkipped[$suiteName]['*'])
@ -230,7 +230,7 @@ class SymfonyTestsListenerTrait
$test->getTestResultObject()->beStrictAboutTestsThatDoNotTestAnything(false);
$this->expectedDeprecations = $annotations['method']['expectedDeprecation'];
$this->previousErrorHandler = set_error_handler([$this, 'handleError']);
$this->previousErrorHandler = set_error_handler(array($this, 'handleError'));
}
}
}
@ -271,8 +271,8 @@ class SymfonyTestsListenerTrait
$deprecations = file_get_contents($this->runsInSeparateProcess);
unlink($this->runsInSeparateProcess);
putenv('SYMFONY_DEPRECATIONS_SERIALIZE');
foreach ($deprecations ? unserialize($deprecations) : [] as $deprecation) {
$error = serialize(['deprecation' => $deprecation[1], 'class' => $className, 'method' => $test->getName(false), 'triggering_file' => isset($deprecation[2]) ? $deprecation[2] : null]);
foreach ($deprecations ? unserialize($deprecations) : array() as $deprecation) {
$error = serialize(array('deprecation' => $deprecation[1], 'class' => $className, 'method' => $test->getName(false), 'triggering_file' => isset($deprecation[2]) ? $deprecation[2] : null));
if ($deprecation[0]) {
@trigger_error($error, E_USER_DEPRECATED);
} else {
@ -283,13 +283,13 @@ class SymfonyTestsListenerTrait
}
if ($this->expectedDeprecations) {
if (!\in_array($test->getStatus(), [$BaseTestRunner::STATUS_SKIPPED, $BaseTestRunner::STATUS_INCOMPLETE], true)) {
if (!\in_array($test->getStatus(), array($BaseTestRunner::STATUS_SKIPPED, $BaseTestRunner::STATUS_INCOMPLETE), true)) {
$test->addToAssertionCount(\count($this->expectedDeprecations));
}
restore_error_handler();
if (!$errored && !\in_array($test->getStatus(), [$BaseTestRunner::STATUS_SKIPPED, $BaseTestRunner::STATUS_INCOMPLETE, $BaseTestRunner::STATUS_FAILURE, $BaseTestRunner::STATUS_ERROR], true)) {
if (!$errored && !\in_array($test->getStatus(), array($BaseTestRunner::STATUS_SKIPPED, $BaseTestRunner::STATUS_INCOMPLETE, $BaseTestRunner::STATUS_FAILURE, $BaseTestRunner::STATUS_ERROR), true)) {
try {
$prefix = "@expectedDeprecation:\n";
$test->assertStringMatchesFormat($prefix.'%A '.implode("\n%A ", $this->expectedDeprecations)."\n%A", $prefix.' '.implode("\n ", $this->gatheredDeprecations)."\n");
@ -300,7 +300,7 @@ class SymfonyTestsListenerTrait
}
}
$this->expectedDeprecations = $this->gatheredDeprecations = [];
$this->expectedDeprecations = $this->gatheredDeprecations = array();
$this->previousErrorHandler = null;
}
if (!$this->runsInSeparateProcess && -2 < $this->state && ($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase)) {
@ -308,12 +308,12 @@ class SymfonyTestsListenerTrait
ClockMock::withClockMock(false);
}
if (\in_array('dns-sensitive', $groups, true)) {
DnsMock::withMockedHosts([]);
DnsMock::withMockedHosts(array());
}
}
}
public function handleError($type, $msg, $file, $line, $context = [])
public function handleError($type, $msg, $file, $line, $context = array())
{
if (E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type) {
$h = $this->previousErrorHandler;

View File

@ -27,7 +27,7 @@ class TestRunnerForV5 extends \PHPUnit_TextUI_TestRunner
$result = parent::handleConfiguration($arguments);
$arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : [];
$arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : array();
$registeredLocally = false;

View File

@ -30,7 +30,7 @@ class TestRunnerForV6 extends BaseRunner
parent::handleConfiguration($arguments);
$arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : [];
$arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : array();
$registeredLocally = false;

View File

@ -30,7 +30,7 @@ class TestRunnerForV7 extends BaseRunner
parent::handleConfiguration($arguments);
$arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : [];
$arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : array();
$registeredLocally = false;

View File

@ -25,7 +25,7 @@ class Test
{
public static function getGroups()
{
return [];
return array();
}
}
EOPHP
@ -35,7 +35,7 @@ class PHPUnit_Util_Test
{
public static function getGroups()
{
return [];
return array();
}
}

View File

@ -7,7 +7,7 @@ class Test
{
public static function getGroups()
{
return [];
return array();
}
}
EOPHP

View File

@ -25,7 +25,7 @@ class Test
{
public static function getGroups()
{
return [];
return array();
}
}
EOPHP
@ -35,7 +35,7 @@ class PHPUnit_Util_Test
{
public static function getGroups()
{
return [];
return array();
}
}

View File

@ -25,7 +25,7 @@ class Test
{
public static function getGroups()
{
return [];
return array();
}
}
EOPHP

View File

@ -18,15 +18,15 @@ class DnsMockTest extends TestCase
{
protected function tearDown()
{
DnsMock::withMockedHosts([]);
DnsMock::withMockedHosts(array());
}
public function testCheckdnsrr()
{
DnsMock::withMockedHosts(['example.com' => [['type' => 'MX']]]);
DnsMock::withMockedHosts(array('example.com' => array(array('type' => 'MX'))));
$this->assertTrue(DnsMock::checkdnsrr('example.com'));
DnsMock::withMockedHosts(['example.com' => [['type' => 'A']]]);
DnsMock::withMockedHosts(array('example.com' => array(array('type' => 'A'))));
$this->assertFalse(DnsMock::checkdnsrr('example.com'));
$this->assertTrue(DnsMock::checkdnsrr('example.com', 'a'));
$this->assertTrue(DnsMock::checkdnsrr('example.com', 'any'));
@ -35,34 +35,34 @@ class DnsMockTest extends TestCase
public function testGetmxrr()
{
DnsMock::withMockedHosts([
'example.com' => [[
DnsMock::withMockedHosts(array(
'example.com' => array(array(
'type' => 'MX',
'host' => 'mx.example.com',
'pri' => 10,
]],
]);
)),
));
$this->assertFalse(DnsMock::getmxrr('foobar.com', $mxhosts, $weight));
$this->assertTrue(DnsMock::getmxrr('example.com', $mxhosts, $weight));
$this->assertSame(['mx.example.com'], $mxhosts);
$this->assertSame([10], $weight);
$this->assertSame(array('mx.example.com'), $mxhosts);
$this->assertSame(array(10), $weight);
}
public function testGethostbyaddr()
{
DnsMock::withMockedHosts([
'example.com' => [
[
DnsMock::withMockedHosts(array(
'example.com' => array(
array(
'type' => 'A',
'ip' => '1.2.3.4',
],
[
),
array(
'type' => 'AAAA',
'ipv6' => '::12',
],
],
]);
),
),
));
$this->assertSame('::21', DnsMock::gethostbyaddr('::21'));
$this->assertSame('example.com', DnsMock::gethostbyaddr('::12'));
@ -71,18 +71,18 @@ class DnsMockTest extends TestCase
public function testGethostbyname()
{
DnsMock::withMockedHosts([
'example.com' => [
[
DnsMock::withMockedHosts(array(
'example.com' => array(
array(
'type' => 'AAAA',
'ipv6' => '::12',
],
[
),
array(
'type' => 'A',
'ip' => '1.2.3.4',
],
],
]);
),
),
));
$this->assertSame('foobar.com', DnsMock::gethostbyname('foobar.com'));
$this->assertSame('1.2.3.4', DnsMock::gethostbyname('example.com'));
@ -90,59 +90,59 @@ class DnsMockTest extends TestCase
public function testGethostbynamel()
{
DnsMock::withMockedHosts([
'example.com' => [
[
DnsMock::withMockedHosts(array(
'example.com' => array(
array(
'type' => 'A',
'ip' => '1.2.3.4',
],
[
),
array(
'type' => 'A',
'ip' => '2.3.4.5',
],
],
]);
),
),
));
$this->assertFalse(DnsMock::gethostbynamel('foobar.com'));
$this->assertSame(['1.2.3.4', '2.3.4.5'], DnsMock::gethostbynamel('example.com'));
$this->assertSame(array('1.2.3.4', '2.3.4.5'), DnsMock::gethostbynamel('example.com'));
}
public function testDnsGetRecord()
{
DnsMock::withMockedHosts([
'example.com' => [
[
DnsMock::withMockedHosts(array(
'example.com' => array(
array(
'type' => 'A',
'ip' => '1.2.3.4',
],
[
),
array(
'type' => 'PTR',
'ip' => '2.3.4.5',
],
],
]);
),
),
));
$records = [
[
$records = array(
array(
'host' => 'example.com',
'class' => 'IN',
'ttl' => 1,
'type' => 'A',
'ip' => '1.2.3.4',
],
$ptr = [
),
$ptr = array(
'host' => 'example.com',
'class' => 'IN',
'ttl' => 1,
'type' => 'PTR',
'ip' => '2.3.4.5',
],
];
),
);
$this->assertFalse(DnsMock::dns_get_record('foobar.com'));
$this->assertSame($records, DnsMock::dns_get_record('example.com'));
$this->assertSame($records, DnsMock::dns_get_record('example.com', DNS_ALL));
$this->assertSame($records, DnsMock::dns_get_record('example.com', DNS_A | DNS_PTR));
$this->assertSame([$ptr], DnsMock::dns_get_record('example.com', DNS_PTR));
$this->assertSame(array($ptr), DnsMock::dns_get_record('example.com', DNS_PTR));
}
}

View File

@ -126,7 +126,7 @@ if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__
$prevRoot = getenv('COMPOSER_ROOT_VERSION');
putenv("COMPOSER_ROOT_VERSION=$PHPUNIT_VERSION.99");
// --no-suggest is not in the list to keep compat with composer 1.0, which is shipped with Ubuntu 16.04LTS
$exit = proc_close(proc_open("$COMPOSER install --no-dev --prefer-dist --no-progress --ansi", [], $p, getcwd(), null, ['bypass_shell' => true]));
$exit = proc_close(proc_open("$COMPOSER install --no-dev --prefer-dist --no-progress --ansi", array(), $p, getcwd(), null, array('bypass_shell' => true)));
putenv('COMPOSER_ROOT_VERSION'.(false !== $prevRoot ? '='.$prevRoot : ''));
if ($exit) {
exit($exit);
@ -159,9 +159,9 @@ EOPHP
}
global $argv, $argc;
$argv = isset($_SERVER['argv']) ? $_SERVER['argv'] : [];
$argv = isset($_SERVER['argv']) ? $_SERVER['argv'] : array();
$argc = isset($_SERVER['argc']) ? $_SERVER['argc'] : 0;
$components = [];
$components = array();
$cmd = array_map('escapeshellarg', $argv);
$exit = 0;
@ -196,7 +196,7 @@ if ('\\' === DIRECTORY_SEPARATOR) {
if ($components) {
$skippedTests = isset($_SERVER['SYMFONY_PHPUNIT_SKIPPED_TESTS']) ? $_SERVER['SYMFONY_PHPUNIT_SKIPPED_TESTS'] : false;
$runningProcs = [];
$runningProcs = array();
foreach ($components as $component) {
// Run phpunit tests in parallel
@ -207,7 +207,7 @@ if ($components) {
$c = escapeshellarg($component);
if ($proc = proc_open(sprintf($cmd, $c, " > $c/phpunit.stdout 2> $c/phpunit.stderr"), [], $pipes)) {
if ($proc = proc_open(sprintf($cmd, $c, " > $c/phpunit.stdout 2> $c/phpunit.stderr"), array(), $pipes)) {
$runningProcs[$component] = $proc;
} else {
$exit = 1;
@ -217,7 +217,7 @@ if ($components) {
while ($runningProcs) {
usleep(300000);
$terminatedProcs = [];
$terminatedProcs = array();
foreach ($runningProcs as $component => $proc) {
$procStatus = proc_get_status($proc);
if (!$procStatus['running']) {
@ -228,7 +228,7 @@ if ($components) {
}
foreach ($terminatedProcs as $component => $procStatus) {
foreach (['out', 'err'] as $file) {
foreach (array('out', 'err') as $file) {
$file = "$component/phpunit.std$file";
readfile($file);
unlink($file);
@ -238,7 +238,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') || !filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN) || !in_array($procStatus, [-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 {
@ -250,7 +250,7 @@ if ($components) {
if (!class_exists('SymfonyBlacklistSimplePhpunit', false)) {
class SymfonyBlacklistSimplePhpunit {}
}
array_splice($argv, 1, 0, ['--colors=always']);
array_splice($argv, 1, 0, array('--colors=always'));
$_SERVER['argv'] = $argv;
$_SERVER['argc'] = ++$argc;
include "$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit";

View File

@ -13,6 +13,7 @@ namespace Symfony\Bridge\Twig\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
@ -203,12 +204,13 @@ EOF
private function displayGeneralText(SymfonyStyle $io, string $filter = null)
{
$decorated = $io->isDecorated();
$types = ['functions', 'filters', 'tests', 'globals'];
foreach ($types as $index => $type) {
$items = [];
foreach ($this->twig->{'get'.ucfirst($type)}() as $name => $entity) {
if (!$filter || false !== strpos($name, $filter)) {
$items[$name] = $name.$this->getPrettyMetadata($type, $entity);
$items[$name] = $name.$this->getPrettyMetadata($type, $entity, $decorated);
}
}
@ -236,6 +238,7 @@ EOF
private function displayGeneralJson(SymfonyStyle $io, $filter)
{
$decorated = $io->isDecorated();
$types = ['functions', 'filters', 'tests', 'globals'];
$data = [];
foreach ($types as $type) {
@ -253,11 +256,12 @@ EOF
$data['loader_paths'] = $paths;
}
if ($wronBundles = $this->findWrongBundleOverrides()) {
$data['warnings'] = $this->buildWarningMessages($wronBundles);
if ($wrongBundles = $this->findWrongBundleOverrides()) {
$data['warnings'] = $this->buildWarningMessages($wrongBundles);
}
$io->writeln(json_encode($data));
$data = json_encode($data, JSON_PRETTY_PRINT);
$io->writeln($decorated ? OutputFormatter::escape($data) : $data);
}
private function getLoaderPaths(string $name = null): array
@ -342,7 +346,7 @@ EOF
}
}
private function getPrettyMetadata($type, $entity)
private function getPrettyMetadata($type, $entity, $decorated)
{
if ('tests' === $type) {
return '';
@ -354,7 +358,7 @@ EOF
return '(unknown?)';
}
} catch (\UnexpectedValueException $e) {
return ' <error>'.$e->getMessage().'</error>';
return sprintf(' <error>%s</error>', $decorated ? OutputFormatter::escape($e->getMessage()) : $e->getMessage());
}
if ('globals' === $type) {
@ -362,7 +366,9 @@ EOF
return ' = object('.\get_class($meta).')';
}
return ' = '.substr(@json_encode($meta), 0, 50);
$description = substr(@json_encode($meta), 0, 50);
return sprintf(' = %s', $decorated ? OutputFormatter::escape($description) : $description);
}
if ('functions' === $type) {

View File

@ -289,7 +289,38 @@ TXT
$this->assertContains('[OK]', $tester->getDisplay());
}
private function createCommandTester(array $paths = [], array $bundleMetadata = [], string $defaultPath = null, string $rootDir = null, bool $useChainLoader = false): CommandTester
public function testWithGlobals()
{
$message = '<error>foo</error>';
$tester = $this->createCommandTester([], [], null, null, false, ['message' => $message]);
$tester->execute([], ['decorated' => true]);
$display = $tester->getDisplay();
$this->assertContains(\json_encode($message), $display);
}
public function testWithGlobalsJson()
{
$globals = ['message' => '<error>foo</error>'];
$tester = $this->createCommandTester([], [], null, null, false, $globals);
$tester->execute(['--format' => 'json'], ['decorated' => true]);
$display = $tester->getDisplay();
$display = \json_decode($display, true);
$this->assertSame($globals, $display['globals']);
}
public function testWithFilter()
{
$tester = $this->createCommandTester();
$tester->execute(['--format' => 'json'], ['decorated' => false]);
$display = $tester->getDisplay();
$display1 = \json_decode($display, true);
$tester->execute(['--filter' => 'date', '--format' => 'json'], ['decorated' => false]);
$display = $tester->getDisplay();
$display2 = \json_decode($display, true);
$this->assertNotSame($display1, $display2);
}
private function createCommandTester(array $paths = [], array $bundleMetadata = [], string $defaultPath = null, string $rootDir = null, bool $useChainLoader = false, array $globals = []): CommandTester
{
$projectDir = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Fixtures';
$loader = new FilesystemLoader([], $projectDir);
@ -305,8 +336,13 @@ TXT
$loader = new ChainLoader([$loader]);
}
$environment = new Environment($loader);
foreach ($globals as $name => $value) {
$environment->addGlobal($name, $value);
}
$application = new Application();
$application->add(new DebugCommand(new Environment($loader), $projectDir, $bundleMetadata, $defaultPath, $rootDir));
$application->add(new DebugCommand($environment, $projectDir, $bundleMetadata, $defaultPath, $rootDir));
$command = $application->find('debug:twig');
return new CommandTester($command);

View File

@ -235,7 +235,7 @@ class JsonDescriptor extends Descriptor
'autoconfigure' => $definition->isAutoconfigured(),
];
if ('' !== $classDescription = $this->getClassDescription($definition->getClass())) {
if ('' !== $classDescription = $this->getClassDescription((string) $definition->getClass())) {
$data['description'] = $classDescription;
}

View File

@ -188,7 +188,7 @@ class MarkdownDescriptor extends Descriptor
{
$output = '';
if ('' !== $classDescription = $this->getClassDescription($definition->getClass())) {
if ('' !== $classDescription = $this->getClassDescription((string) $definition->getClass())) {
$output .= '- Description: `'.$classDescription.'`'."\n";
}

View File

@ -269,7 +269,7 @@ class TextDescriptor extends Descriptor
$options['output']->title(sprintf('Information for Service "<info>%s</info>"', $options['id']));
}
if ('' !== $classDescription = $this->getClassDescription($definition->getClass())) {
if ('' !== $classDescription = $this->getClassDescription((string) $definition->getClass())) {
$options['output']->text($classDescription."\n");
}

View File

@ -318,7 +318,7 @@ class XmlDescriptor extends Descriptor
$serviceXML->setAttribute('id', $id);
}
if ('' !== $classDescription = $this->getClassDescription($definition->getClass())) {
if ('' !== $classDescription = $this->getClassDescription((string) $definition->getClass())) {
$serviceXML->appendChild($descriptionXML = $dom->createElement('description'));
$descriptionXML->appendChild($dom->createCDATASection($classDescription));
}

View File

@ -15,6 +15,7 @@
<argument type="service" id="session.storage" />
<argument type="service" id="session.attribute_bag" />
<argument type="service" id="session.flash_bag" />
<tag name="kernel.reset" method="save" />
</service>
<service id="Symfony\Component\HttpFoundation\Session\SessionInterface" alias="session" />

View File

@ -78,11 +78,7 @@ class RouterMatchCommandTest extends TestCase
->expects($this->atLeastOnce())
->method('has')
->will($this->returnCallback(function ($id) {
if ('console.command_loader' === $id) {
return false;
}
return true;
return 'console.command_loader' !== $id;
}))
;
$container

View File

@ -140,6 +140,7 @@ class ObjectsProvider
->addTag('tag2')
->addMethodCall('setMailer', [new Reference('mailer')])
->setFactory([new Reference('factory.service'), 'get']),
'definition_without_class' => new Definition(),
];
}

View File

@ -67,6 +67,19 @@
"factory_method": "get",
"tags": []
},
"definition_without_class": {
"class": "",
"public": false,
"synthetic": false,
"lazy": false,
"shared": true,
"abstract": false,
"autowire": false,
"autoconfigure": false,
"arguments": [],
"file": null,
"tags": []
},
"service_container": {
"class": "Symfony\\Component\\DependencyInjection\\ContainerInterface",
"public": true,

View File

@ -18,6 +18,18 @@ Definitions
- Factory Class: `Full\Qualified\FactoryClass`
- Factory Method: `get`
### definition_without_class
- Class: ``
- Public: no
- Synthetic: no
- Lazy: no
- Shared: yes
- Abstract: no
- Autowired: no
- Autoconfigured: no
- Arguments: no
### service_container
- Description: `ContainerInterface is the interface implemented by service container classes.`

View File

@ -2,11 +2,12 @@
Symfony Container Services
==========================
------------------- ----------------------------------------------------------
 Service ID   Class name 
------------------- ----------------------------------------------------------
alias_1 alias for "service_1"
definition_1 Full\Qualified\Class1
service_container Symfony\Component\DependencyInjection\ContainerInterface
------------------- ----------------------------------------------------------
-------------------------- ----------------------------------------------------------
 Service ID   Class name 
-------------------------- ----------------------------------------------------------
alias_1 alias for "service_1"
definition_1 Full\Qualified\Class1
definition_without_class
service_container Symfony\Component\DependencyInjection\ContainerInterface
-------------------------- ----------------------------------------------------------

View File

@ -23,6 +23,7 @@
<argument type="service" id=".definition_2"/>
</argument>
</definition>
<definition id="definition_without_class" class="" public="false" synthetic="false" lazy="false" shared="true" abstract="false" autowired="false" autoconfigured="false" file=""/>
<definition id="service_container" class="Symfony\Component\DependencyInjection\ContainerInterface" public="true" synthetic="true" lazy="false" shared="true" abstract="false" autowired="false" autoconfigured="false" file="">
<description><![CDATA[ContainerInterface is the interface implemented by service container classes.]]></description>
</definition>

View File

@ -14,6 +14,18 @@
"factory_method": "get",
"tags": []
},
"definition_without_class": {
"class": "",
"public": false,
"synthetic": false,
"lazy": false,
"shared": true,
"abstract": false,
"autowire": false,
"autoconfigure": false,
"file": null,
"tags": []
},
"service_container": {
"class": "Symfony\\Component\\DependencyInjection\\ContainerInterface",
"public": true,

View File

@ -17,6 +17,17 @@ Definitions
- Factory Class: `Full\Qualified\FactoryClass`
- Factory Method: `get`
### definition_without_class
- Class: ``
- Public: no
- Synthetic: no
- Lazy: no
- Shared: yes
- Abstract: no
- Autowired: no
- Autoconfigured: no
### service_container
- Description: `ContainerInterface is the interface implemented by service container classes.`

View File

@ -2,11 +2,12 @@
Symfony Container Services
==========================
------------------- ----------------------------------------------------------
 Service ID   Class name 
------------------- ----------------------------------------------------------
alias_1 alias for "service_1"
definition_1 Full\Qualified\Class1
service_container Symfony\Component\DependencyInjection\ContainerInterface
------------------- ----------------------------------------------------------
-------------------------- ----------------------------------------------------------
 Service ID   Class name 
-------------------------- ----------------------------------------------------------
alias_1 alias for "service_1"
definition_1 Full\Qualified\Class1
definition_without_class
service_container Symfony\Component\DependencyInjection\ContainerInterface
-------------------------- ----------------------------------------------------------

View File

@ -4,6 +4,7 @@
<definition id="definition_1" class="Full\Qualified\Class1" public="true" synthetic="false" lazy="true" shared="true" abstract="true" autowired="false" autoconfigured="false" file="">
<factory class="Full\Qualified\FactoryClass" method="get"/>
</definition>
<definition id="definition_without_class" class="" public="false" synthetic="false" lazy="false" shared="true" abstract="false" autowired="false" autoconfigured="false" file=""/>
<definition id="service_container" class="Symfony\Component\DependencyInjection\ContainerInterface" public="true" synthetic="true" lazy="false" shared="true" abstract="false" autowired="false" autoconfigured="false" file="">
<description><![CDATA[ContainerInterface is the interface implemented by service container classes.]]></description>
</definition>

View File

@ -0,0 +1,13 @@
{
"class": "",
"public": false,
"synthetic": false,
"lazy": false,
"shared": true,
"abstract": false,
"autowire": false,
"autoconfigure": false,
"arguments": [],
"file": null,
"tags": []
}

View File

@ -0,0 +1,9 @@
- Class: ``
- Public: no
- Synthetic: no
- Lazy: no
- Shared: yes
- Abstract: no
- Autowired: no
- Autoconfigured: no
- Arguments: no

View File

@ -0,0 +1,15 @@
---------------- -------
 Option   Value 
---------------- -------
Service ID -
Class -
Tags -
Public no
Synthetic no
Lazy no
Shared yes
Abstract no
Autowired no
Autoconfigured no
---------------- -------

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<definition class="" public="false" synthetic="false" lazy="false" shared="true" abstract="false" autowired="false" autoconfigured="false" file=""/>

View File

@ -0,0 +1,12 @@
{
"class": "",
"public": false,
"synthetic": false,
"lazy": false,
"shared": true,
"abstract": false,
"autowire": false,
"autoconfigure": false,
"file": null,
"tags": []
}

View File

@ -0,0 +1,8 @@
- Class: ``
- Public: no
- Synthetic: no
- Lazy: no
- Shared: yes
- Abstract: no
- Autowired: no
- Autoconfigured: no

View File

@ -0,0 +1,15 @@
---------------- -------
 Option   Value 
---------------- -------
Service ID -
Class -
Tags -
Public no
Synthetic no
Lazy no
Shared yes
Abstract no
Autowired no
Autoconfigured no
---------------- -------

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<definition class="" public="false" synthetic="false" lazy="false" shared="true" abstract="false" autowired="false" autoconfigured="false" file=""/>

View File

@ -133,7 +133,7 @@ trait PhpFilesTrait
*/
protected function doHave($id)
{
if ($this->appendOnly && $this->values[$id]) {
if ($this->appendOnly && isset($this->values[$id])) {
return true;
}

View File

@ -51,6 +51,9 @@ class TreeBuilder implements NodeParentInterface
return $this->root = $builder->node($name, $type)->setParent($this);
}
/**
* @return NodeDefinition|ArrayNodeDefinition The root node (as an ArrayNodeDefinition when the type is 'array')
*/
public function getRootNode(): NodeDefinition
{
if (null === $this->root) {

View File

@ -49,7 +49,13 @@ class QuestionHelper extends Helper
if (!$input->isInteractive()) {
$default = $question->getDefault();
if (null !== $default && $question instanceof ChoiceQuestion) {
if (null === $default) {
return $default;
}
if ($validator = $question->getValidator()) {
return \call_user_func($question->getValidator(), $default);
} elseif ($question instanceof ChoiceQuestion) {
$choices = $question->getChoices();
if (!$question->isMultiselect()) {
@ -215,6 +221,7 @@ class QuestionHelper extends Helper
// as opposed to fgets(), fread() returns an empty string when the stream content is empty, not false.
if (false === $c || ('' === $ret && '' === $c && null === $question->getDefault())) {
shell_exec(sprintf('stty %s', $sttyMode));
throw new RuntimeException('Aborted.');
} elseif ("\177" === $c) { // Backspace Character
if (0 === $numMatches && 0 !== $i) {

View File

@ -35,6 +35,10 @@ trait TesterTrait
*/
public function getDisplay($normalize = false)
{
if (null === $this->output) {
throw new \RuntimeException('Output not initialized, did you execute the command before requesting the display?');
}
rewind($this->output->getStream());
$display = stream_get_contents($this->output->getStream());

View File

@ -137,6 +137,9 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
$question->setMultiselect(true);
$this->assertNull($questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question));
$question = new ChoiceQuestion('Who are your favorite superheros?', ['a' => 'Batman', 'b' => 'Superman'], 'a');
$this->assertSame('a', $questionHelper->ask($this->createStreamableInputInterfaceMock('', false), $this->createOutputInterface(), $question), 'ChoiceQuestion validator returns the key if it\'s a string');
try {
$question = new ChoiceQuestion('Who are your favorite superheros?', $heroes, '');
$question->setMultiselect(true);

View File

@ -306,12 +306,12 @@ class XmlDumper extends Dumper
} elseif ($value instanceof Reference) {
$element->setAttribute('type', 'service');
$element->setAttribute('id', (string) $value);
$behaviour = $value->getInvalidBehavior();
if (ContainerInterface::NULL_ON_INVALID_REFERENCE == $behaviour) {
$behavior = $value->getInvalidBehavior();
if (ContainerInterface::NULL_ON_INVALID_REFERENCE == $behavior) {
$element->setAttribute('on-invalid', 'null');
} elseif (ContainerInterface::IGNORE_ON_INVALID_REFERENCE == $behaviour) {
} elseif (ContainerInterface::IGNORE_ON_INVALID_REFERENCE == $behavior) {
$element->setAttribute('on-invalid', 'ignore');
} elseif (ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE == $behaviour) {
} elseif (ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE == $behavior) {
$element->setAttribute('on-invalid', 'ignore_uninitialized');
}
} elseif ($value instanceof Definition) {

View File

@ -0,0 +1,21 @@
<?php
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
class BarFactory
{
/**
* @var iterable
*/
private $bars;
public function __construct(iterable $bars)
{
$this->bars = \iterator_to_array($bars);
}
public function getDefaultBar(): BarInterface
{
return reset($this->bars);
}
}

View File

@ -0,0 +1,14 @@
services:
_instanceof:
Symfony\Component\DependencyInjection\Tests\Fixtures\BarInterface:
tags:
- { name: bar }
Symfony\Component\DependencyInjection\Tests\Fixtures\Bar:
public: true
Symfony\Component\DependencyInjection\Tests\Fixtures\BarFactory:
arguments: [!tagged 'bar']
Symfony\Component\DependencyInjection\Tests\Fixtures\BarInterface:
factory: ['@Symfony\Component\DependencyInjection\Tests\Fixtures\BarFactory', 'getDefaultBar']

View File

@ -812,4 +812,15 @@ class YamlFileLoaderTest extends TestCase
$definition = $container->getDefinition('foo');
$this->assertSame([['interface' => 'SomeInterface']], $definition->getTag('proxy'));
}
public function testServiceWithSameNameAsInterfaceAndFactoryIsNotTagged()
{
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('service_instanceof_factory.yml');
$container->compile();
$tagged = $container->findTaggedServiceIds('bar');
$this->assertCount(1, $tagged);
}
}

View File

@ -34,7 +34,6 @@ final class Dotenv
private $lineno;
private $data;
private $end;
private $state;
private $values;
/**
@ -162,27 +161,27 @@ final class Dotenv
$this->lineno = 1;
$this->cursor = 0;
$this->end = \strlen($this->data);
$this->state = self::STATE_VARNAME;
$state = self::STATE_VARNAME;
$this->values = [];
$name = '';
$this->skipEmptyLines();
while ($this->cursor < $this->end) {
switch ($this->state) {
switch ($state) {
case self::STATE_VARNAME:
$name = $this->lexVarname();
$this->state = self::STATE_VALUE;
$state = self::STATE_VALUE;
break;
case self::STATE_VALUE:
$this->values[$name] = $this->lexValue();
$this->state = self::STATE_VARNAME;
$state = self::STATE_VARNAME;
break;
}
}
if (self::STATE_VALUE === $this->state) {
if (self::STATE_VALUE === $state) {
$this->values[$name] = '';
}

View File

@ -115,7 +115,7 @@ class RegisterListenersPass implements CompilerPassInterface
$definition->addMethodCall('addListener', $args);
if (isset($this->hotPathEvents[$args[0]])) {
$container->getDefinition($id)->addTag('container.hot_path');
$container->getDefinition($id)->addTag($this->hotPathTagName);
}
}
$extractingDispatcher->listeners = [];

View File

@ -924,6 +924,10 @@ class FinderTest extends Iterator\RealIteratorTestCase
public function testInWithGlobBrace()
{
if (!\defined('GLOB_BRACE')) {
$this->markTestSkipped('Glob brace is not supported on this system.');
}
$finder = $this->buildFinder();
$finder->in([__DIR__.'/Fixtures/{A,copy/A}/B/C'])->getIterator();

View File

@ -36,7 +36,7 @@ abstract class AbstractExtension implements FormExtensionInterface
/**
* The type guesser provided by this extension.
*
* @var FormTypeGuesserInterface
* @var FormTypeGuesserInterface|null
*/
private $typeGuesser;
@ -136,7 +136,7 @@ abstract class AbstractExtension implements FormExtensionInterface
/**
* Registers the type guesser.
*
* @return FormTypeGuesserInterface|null A type guesser
* @return FormTypeGuesserInterface|null
*/
protected function loadTypeGuesser()
{

View File

@ -131,7 +131,7 @@ abstract class AbstractRendererEngine implements FormRendererEngineInterface
* resource
* @param FormView $view The form view for finding the applying
* themes
* @param array $blockNameHierarchy The block hierarchy, with the most
* @param string[] $blockNameHierarchy The block hierarchy, with the most
* specific block name at the end
* @param int $hierarchyLevel The level in the block hierarchy that
* should be loaded

View File

@ -22,7 +22,7 @@ use Symfony\Component\Form\Exception\BadMethodCallException;
class Button implements \IteratorAggregate, FormInterface
{
/**
* @var FormInterface|null
* @var FormInterface
*/
private $parent;
@ -111,6 +111,8 @@ class Button implements \IteratorAggregate, FormInterface
}
$this->parent = $parent;
return $this;
}
/**
@ -199,11 +201,13 @@ class Button implements \IteratorAggregate, FormInterface
* This method should not be invoked.
*
* @param mixed $modelData
*
* @return $this
*/
public function setData($modelData)
{
// called during initialization of the form tree
// noop
// no-op, called during initialization of the form tree
return $this;
}
/**
@ -211,6 +215,7 @@ class Button implements \IteratorAggregate, FormInterface
*/
public function getData()
{
return null;
}
/**
@ -218,6 +223,7 @@ class Button implements \IteratorAggregate, FormInterface
*/
public function getNormData()
{
return null;
}
/**
@ -225,6 +231,7 @@ class Button implements \IteratorAggregate, FormInterface
*/
public function getViewData()
{
return null;
}
/**
@ -240,7 +247,7 @@ class Button implements \IteratorAggregate, FormInterface
/**
* Returns the button's configuration.
*
* @return FormConfigInterface The configuration
* @return FormConfigInterface The configuration instance
*/
public function getConfig()
{
@ -272,6 +279,7 @@ class Button implements \IteratorAggregate, FormInterface
*/
public function getPropertyPath()
{
return null;
}
/**
@ -309,11 +317,11 @@ class Button implements \IteratorAggregate, FormInterface
*/
public function isDisabled()
{
if (null === $this->parent || !$this->parent->isDisabled()) {
return $this->config->getDisabled();
if ($this->parent && $this->parent->isDisabled()) {
return true;
}
return true;
return $this->config->getDisabled();
}
/**
@ -341,6 +349,7 @@ class Button implements \IteratorAggregate, FormInterface
*/
public function getTransformationFailure()
{
return null;
}
/**
@ -368,7 +377,7 @@ class Button implements \IteratorAggregate, FormInterface
/**
* Submits data to the button.
*
* @param string|null $submittedData The data
* @param string|null $submittedData Not used
* @param bool $clearMissing Not used
*
* @return $this

View File

@ -22,9 +22,6 @@ use Symfony\Component\Form\Exception\InvalidArgumentException;
*/
class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface
{
/**
* @var bool
*/
protected $locked = false;
/**
@ -530,6 +527,7 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface
*/
public function getEventDispatcher()
{
return null;
}
/**
@ -545,6 +543,7 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface
*/
public function getPropertyPath()
{
return null;
}
/**
@ -612,6 +611,7 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface
*/
public function getDataMapper()
{
return null;
}
/**
@ -649,6 +649,7 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface
*/
public function getEmptyData()
{
return null;
}
/**
@ -691,6 +692,7 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface
*/
public function getData()
{
return null;
}
/**
@ -698,6 +700,7 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface
*/
public function getDataClass()
{
return null;
}
/**
@ -715,6 +718,7 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface
*/
public function getFormFactory()
{
throw new BadMethodCallException('Buttons do not support adding children.');
}
/**
@ -722,6 +726,7 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface
*/
public function getAction()
{
return null;
}
/**
@ -729,6 +734,7 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface
*/
public function getMethod()
{
return null;
}
/**
@ -736,6 +742,7 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface
*/
public function getRequestHandler()
{
return null;
}
/**

View File

@ -11,9 +11,6 @@
namespace Symfony\Component\Form;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
class CallbackTransformer implements DataTransformerInterface
{
private $transform;
@ -30,14 +27,7 @@ class CallbackTransformer implements DataTransformerInterface
}
/**
* Transforms a value from the original representation to a transformed representation.
*
* @param mixed $data The value in the original representation
*
* @return mixed The value in the transformed representation
*
* @throws UnexpectedTypeException when the argument is not of the expected type
* @throws TransformationFailedException when the transformation fails
* {@inheritdoc}
*/
public function transform($data)
{
@ -45,15 +35,7 @@ class CallbackTransformer implements DataTransformerInterface
}
/**
* Transforms a value from the transformed representation to its original
* representation.
*
* @param mixed $data The value in the transformed representation
*
* @return mixed The value in the original representation
*
* @throws UnexpectedTypeException when the argument is not of the expected type
* @throws TransformationFailedException when the transformation fails
* {@inheritdoc}
*/
public function reverseTransform($data)
{

View File

@ -17,22 +17,46 @@ namespace Symfony\Component\Form;
interface DataMapperInterface
{
/**
* Maps properties of some data to a list of forms.
* Maps the view data of a compound form to its children.
*
* @param mixed $data Structured data
* @param FormInterface[]|\Traversable $forms A list of {@link FormInterface} instances
* The method is responsible for calling {@link FormInterface::setData()}
* on the children of compound forms, defining their underlying model data.
*
* @param mixed $viewData View data of the compound form being initialized
* @param FormInterface[]|\Traversable $forms A list of {@link FormInterface} instances
*
* @throws Exception\UnexpectedTypeException if the type of the data parameter is not supported
*/
public function mapDataToForms($data, $forms);
public function mapDataToForms($viewData, $forms);
/**
* Maps the data of a list of forms into the properties of some data.
* Maps the model data of a list of children forms into the view data of their parent.
*
* @param FormInterface[]|\Traversable $forms A list of {@link FormInterface} instances
* @param mixed $data Structured data
* This is the internal cascade call of FormInterface::submit for compound forms, since they
* cannot be bound to any input nor the request as scalar, but their children may:
*
* $compoundForm->submit($arrayOfChildrenViewData)
* // inside:
* $childForm->submit($childViewData);
* // for each entry, do the same and/or reverse transform
* $this->dataMapper->mapFormsToData($compoundForm, $compoundInitialViewData)
* // then reverse transform
*
* When a simple form is submitted the following is happening:
*
* $simpleForm->submit($submittedViewData)
* // inside:
* $this->viewData = $submittedViewData
* // then reverse transform
*
* The model data can be an array or an object, so this second argument is always passed
* by reference.
*
* @param FormInterface[]|\Traversable $forms A list of {@link FormInterface} instances
* @param mixed $viewData The compound form's view data that get mapped
* its children model data
*
* @throws Exception\UnexpectedTypeException if the type of the data parameter is not supported
*/
public function mapFormsToData($forms, &$data);
public function mapFormsToData($forms, &$viewData);
}

View File

@ -23,23 +23,35 @@ interface DataTransformerInterface
/**
* Transforms a value from the original representation to a transformed representation.
*
* This method is called on two occasions inside a form field:
* This method is called when the form field is initialized with its default data, on
* two occasions for two types of transformers:
*
* 1. When the form field is initialized with the data attached from the datasource (object or array).
* 2. When data from a request is submitted using {@link Form::submit()} to transform the new input data
* back into the renderable format. For example if you have a date field and submit '2009-10-10'
* you might accept this value because its easily parsed, but the transformer still writes back
* "2009/10/10" onto the form field (for further displaying or other purposes).
* 1. Model transformers which normalize the model data.
* This is mainly useful when the same form type (the same configuration)
* has to handle different kind of underlying data, e.g The DateType can
* deal with strings or \DateTime objects as input.
*
* 2. View transformers which adapt the normalized data to the view format.
* a/ When the form is simple, the value returned by convention is used
* directly in the view and thus can only be a string or an array. In
* this case the data class should be null.
*
* b/ When the form is compound the returned value should be an array or
* an object to be mapped to the children. Each property of the compound
* data will be used as model data by each child and will be transformed
* too. In this case data class should be the class of the object, or null
* when it is an array.
*
* All transformers are called in a configured order from model data to view value.
* At the end of this chain the view data will be validated against the data class
* setting.
*
* This method must be able to deal with empty values. Usually this will
* be NULL, but depending on your implementation other empty values are
* possible as well (such as empty strings). The reasoning behind this is
* that value transformers must be chainable. If the transform() method
* of the first value transformer outputs NULL, the second value transformer
* must be able to process that value.
*
* By convention, transform() should return an empty string if NULL is
* passed.
* that data transformers must be chainable. If the transform() method
* of the first data transformer outputs NULL, the second must be able to
* process that value.
*
* @param mixed $value The value in the original representation
*
@ -54,7 +66,10 @@ interface DataTransformerInterface
* representation.
*
* This method is called when {@link Form::submit()} is called to transform the requests tainted data
* into an acceptable format for your data processing/model layer.
* into an acceptable format.
*
* The same transformers are called in the reverse order so the responsibility is to
* return one of the types that would be expected as input of transform().
*
* This method must be able to deal with empty values. Usually this will
* be an empty string, but depending on your implementation other empty

View File

@ -43,8 +43,6 @@ class ButtonType extends BaseType implements ButtonTypeInterface
{
parent::configureOptions($resolver);
$resolver->setDefaults([
'auto_initialize' => false,
]);
$resolver->setDefault('auto_initialize', false);
}
}

View File

@ -311,8 +311,8 @@ class ChoiceType extends AbstractType
'placeholder' => $placeholderDefault,
'error_bubbling' => false,
'compound' => $compound,
// The view data is always a string, even if the "data" option
// is manually set to an object.
// The view data is always a string or an array of strings,
// even if the "data" option is manually set to an object.
// See https://github.com/symfony/symfony/pull/5582
'data_class' => null,
'choice_translation_domain' => true,

View File

@ -27,6 +27,7 @@ use Symfony\Component\Form\Util\FormUtil;
use Symfony\Component\Form\Util\InheritDataAwareIterator;
use Symfony\Component\Form\Util\OrderedHashMap;
use Symfony\Component\PropertyAccess\PropertyPath;
use Symfony\Component\PropertyAccess\PropertyPathInterface;
/**
* Form represents a form.
@ -69,79 +70,57 @@ use Symfony\Component\PropertyAccess\PropertyPath;
class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterface
{
/**
* The form's configuration.
*
* @var FormConfigInterface
*/
private $config;
/**
* The parent of this form.
*
* @var FormInterface
* @var FormInterface|null
*/
private $parent;
/**
* The children of this form.
*
* @var FormInterface[] A map of FormInterface instances
* @var FormInterface[]|OrderedHashMap A map of FormInterface instances
*/
private $children;
/**
* The errors of this form.
*
* @var FormError[] An array of FormError instances
*/
private $errors = [];
/**
* Whether this form was submitted.
*
* @var bool
*/
private $submitted = false;
/**
* The button that was used to submit the form.
*
* @var Button
* @var ClickableInterface|null The button that was used to submit the form
*/
private $clickedButton;
/**
* The form data in model format.
*
* @var mixed
*/
private $modelData;
/**
* The form data in normalized format.
*
* @var mixed
*/
private $normData;
/**
* The form data in view format.
*
* @var mixed
*/
private $viewData;
/**
* The submitted values that don't belong to any children.
*
* @var array
* @var array The submitted values that don't belong to any children
*/
private $extraData = [];
/**
* Returns the transformation failure generated during submission, if any.
*
* @var TransformationFailedException|null
* @var TransformationFailedException|null The transformation failure generated during submission, if any
*/
private $transformationFailure;
@ -167,8 +146,21 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
private $lockSetData = false;
/**
* Creates a new form based on the given configuration.
*
* @var string|int|null
*/
private $name;
/**
* @var bool Whether the form inherits its underlying data from its parent
*/
private $inheritData;
/**
* @var PropertyPathInterface|null
*/
private $propertyPath;
/**
* @throws LogicException if a data mapper is not provided for a compound form
*/
public function __construct(FormConfigInterface $config)
@ -182,12 +174,13 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
// If the form inherits the data from its parent, it is not necessary
// to call setData() with the default data.
if ($config->getInheritData()) {
if ($this->inheritData = $config->getInheritData()) {
$this->defaultDataSet = true;
}
$this->config = $config;
$this->children = new OrderedHashMap();
$this->name = $config->getName();
}
public function __clone()
@ -212,7 +205,7 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
*/
public function getName()
{
return $this->config->getName();
return $this->name;
}
/**
@ -220,11 +213,11 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
*/
public function getPropertyPath()
{
if (null !== $this->config->getPropertyPath()) {
return $this->config->getPropertyPath();
if ($this->propertyPath || $this->propertyPath = $this->config->getPropertyPath()) {
return $this->propertyPath;
}
if (null === $this->getName() || '' === $this->getName()) {
if (null === $this->name || '' === $this->name) {
return null;
}
@ -235,10 +228,12 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
}
if ($parent && null === $parent->getConfig()->getDataClass()) {
return new PropertyPath('['.$this->getName().']');
$this->propertyPath = new PropertyPath('['.$this->name.']');
} else {
$this->propertyPath = new PropertyPath($this->name);
}
return new PropertyPath($this->getName());
return $this->propertyPath;
}
/**
@ -274,7 +269,7 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
throw new AlreadySubmittedException('You cannot set the parent of a submitted form');
}
if (null !== $parent && '' === $this->config->getName()) {
if (null !== $parent && '' === $this->name) {
throw new LogicException('A form with an empty name cannot have a parent form.');
}
@ -321,7 +316,7 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
// If the form inherits its parent's data, disallow data setting to
// prevent merge conflicts
if ($this->config->getInheritData()) {
if ($this->inheritData) {
throw new RuntimeException('You cannot change the data of a form inheriting its parent data.');
}
@ -341,7 +336,7 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
$this->lockSetData = true;
$dispatcher = LegacyEventDispatcherProxy::decorate($this->config->getEventDispatcher());
// Hook to change content of the data
// Hook to change content of the model data before transformation and mapping children
if ($dispatcher->hasListeners(FormEvents::PRE_SET_DATA)) {
$event = new PreSetDataEvent($this, $modelData);
$dispatcher->dispatch($event, FormEvents::PRE_SET_DATA);
@ -354,6 +349,7 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
}
// Synchronize representations - must not change the content!
// Transformation exceptions are not caught on initialization
$normData = $this->modelToNorm($modelData);
$viewData = $this->normToView($normData);
@ -376,13 +372,10 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
$this->defaultDataSet = true;
$this->lockSetData = false;
// It is not necessary to invoke this method if the form doesn't have children,
// even if the form is compound.
// Compound forms don't need to invoke this method if they don't have children
if (\count($this->children) > 0) {
// Update child forms from the data
$iterator = new InheritDataAwareIterator($this->children);
$iterator = new \RecursiveIteratorIterator($iterator);
$this->config->getDataMapper()->mapDataToForms($viewData, $iterator);
// Update child forms from the data (unless their config data is locked)
$this->config->getDataMapper()->mapDataToForms($viewData, new \RecursiveIteratorIterator(new InheritDataAwareIterator($this->children)));
}
if ($dispatcher->hasListeners(FormEvents::POST_SET_DATA)) {
@ -398,7 +391,7 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
*/
public function getData()
{
if ($this->config->getInheritData()) {
if ($this->inheritData) {
if (!$this->parent) {
throw new RuntimeException('The form is configured to inherit its parent\'s data, but does not have a parent.');
}
@ -422,7 +415,7 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
*/
public function getNormData()
{
if ($this->config->getInheritData()) {
if ($this->inheritData) {
if (!$this->parent) {
throw new RuntimeException('The form is configured to inherit its parent\'s data, but does not have a parent.');
}
@ -446,7 +439,7 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
*/
public function getViewData()
{
if ($this->config->getInheritData()) {
if ($this->inheritData) {
if (!$this->parent) {
throw new RuntimeException('The form is configured to inherit its parent\'s data, but does not have a parent.');
}
@ -511,8 +504,8 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
throw new AlreadySubmittedException('A form can only be submitted once');
}
// Initialize errors in the very beginning so that we don't lose any
// errors added during listeners
// Initialize errors in the very beginning so we're sure
// they are collectable during submission only
$this->errors = [];
// Obviously, a disabled form should not change its data upon submission.
@ -611,18 +604,16 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
// changes in the grandchildren (i.e. children of the form that inherits
// its parent's data) into account.
// (see InheritDataAwareIterator below)
if (!$this->config->getInheritData()) {
// If the form is compound, the default data in view format
// is reused. The data of the children is merged into this
// default data using the data mapper.
// If the form is not compound, the submitted data is also the data in view format.
if (!$this->inheritData) {
// If the form is compound, the view data is merged with the data
// of the children using the data mapper.
// If the form is not compound, the view data is assigned to the submitted data.
$viewData = $this->config->getCompound() ? $this->viewData : $submittedData;
if (FormUtil::isEmpty($viewData)) {
$emptyData = $this->config->getEmptyData();
if ($emptyData instanceof \Closure) {
/* @var \Closure $emptyData */
$emptyData = $emptyData($this, $viewData);
}
@ -637,9 +628,10 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
// descendants that inherit this form's data.
// These descendants will not be submitted normally (see the check
// for $this->config->getInheritData() above)
$childrenIterator = new InheritDataAwareIterator($this->children);
$childrenIterator = new \RecursiveIteratorIterator($childrenIterator);
$this->config->getDataMapper()->mapFormsToData($childrenIterator, $viewData);
$this->config->getDataMapper()->mapFormsToData(
new \RecursiveIteratorIterator(new InheritDataAwareIterator($this->children)),
$viewData
);
}
// Normalize data to unified representation
@ -664,7 +656,7 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
// the erroneous data is accessible on the form.
// Forms that inherit data never set any data, because the getters
// forward to the parent form's getters anyway.
if (null === $viewData && !$this->config->getInheritData()) {
if (null === $viewData && !$this->inheritData) {
$viewData = $submittedData;
}
}
@ -761,8 +753,7 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
/**
* Returns the button that was used to submit the form.
*
* @return Button|null The clicked button or NULL if the form was not
* submitted
* @return ClickableInterface|null
*/
public function getClickedButton()
{
@ -851,29 +842,6 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
throw new LogicException('You cannot add children to a simple form. Maybe you should set the option "compound" to true?');
}
// Obtain the view data
$viewData = null;
// If setData() is currently being called, there is no need to call
// mapDataToForms() here, as mapDataToForms() is called at the end
// of setData() anyway. Not doing this check leads to an endless
// recursion when initializing the form lazily and an event listener
// (such as ResizeFormListener) adds fields depending on the data:
//
// * setData() is called, the form is not initialized yet
// * add() is called by the listener (setData() is not complete, so
// the form is still not initialized)
// * getViewData() is called
// * setData() is called since the form is not initialized yet
// * ... endless recursion ...
//
// Also skip data mapping if setData() has not been called yet.
// setData() will be called upon form initialization and data mapping
// will take place by then.
if (!$this->lockSetData && $this->defaultDataSet && !$this->config->getInheritData()) {
$viewData = $this->getViewData();
}
if (!$child instanceof FormInterface) {
if (!\is_string($child) && !\is_int($child)) {
throw new UnexpectedTypeException($child, 'string, integer or Symfony\Component\Form\FormInterface');
@ -903,10 +871,28 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
$child->setParent($this);
if (!$this->lockSetData && $this->defaultDataSet && !$this->config->getInheritData()) {
$iterator = new InheritDataAwareIterator(new \ArrayIterator([$child->getName() => $child]));
$iterator = new \RecursiveIteratorIterator($iterator);
$this->config->getDataMapper()->mapDataToForms($viewData, $iterator);
// If setData() is currently being called, there is no need to call
// mapDataToForms() here, as mapDataToForms() is called at the end
// of setData() anyway. Not doing this check leads to an endless
// recursion when initializing the form lazily and an event listener
// (such as ResizeFormListener) adds fields depending on the data:
//
// * setData() is called, the form is not initialized yet
// * add() is called by the listener (setData() is not complete, so
// the form is still not initialized)
// * getViewData() is called
// * setData() is called since the form is not initialized yet
// * ... endless recursion ...
//
// Also skip data mapping if setData() has not been called yet.
// setData() will be called upon form initialization and data mapping
// will take place by then.
if (!$this->lockSetData && $this->defaultDataSet && !$this->inheritData) {
$viewData = $this->getViewData();
$this->config->getDataMapper()->mapDataToForms(
$viewData,
new \RecursiveIteratorIterator(new InheritDataAwareIterator(new \ArrayIterator([$child->getName() => $child])))
);
}
return $this;
@ -1055,13 +1041,13 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
}
/**
* Normalizes the value if a model transformer is set.
* Normalizes the underlying data if a model transformer is set.
*
* @param mixed $value The value to transform
*
* @return mixed
*
* @throws TransformationFailedException If the value cannot be transformed to "normalized" format
* @throws TransformationFailedException If the underlying data cannot be transformed to "normalized" format
*/
private function modelToNorm($value)
{
@ -1070,7 +1056,7 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
$value = $transformer->transform($value);
}
} catch (TransformationFailedException $exception) {
throw new TransformationFailedException('Unable to transform value for property path "'.$this->getPropertyPath().'": '.$exception->getMessage(), $exception->getCode(), $exception, $exception->getInvalidMessage(), $exception->getInvalidMessageParameters());
throw new TransformationFailedException('Unable to transform data for property path "'.$this->getPropertyPath().'": '.$exception->getMessage(), $exception->getCode(), $exception, $exception->getInvalidMessage(), $exception->getInvalidMessageParameters());
}
return $value;
@ -1107,7 +1093,7 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
*
* @return mixed
*
* @throws TransformationFailedException If the value cannot be transformed to "view" format
* @throws TransformationFailedException If the normalized value cannot be transformed to "view" format
*/
private function normToView($value)
{
@ -1116,12 +1102,12 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
// Only do this for simple forms, as the resulting value in
// compound forms is passed to the data mapper and thus should
// not be converted to a string before.
if (!$this->config->getViewTransformers() && !$this->config->getCompound()) {
if (!($transformers = $this->config->getViewTransformers()) && !$this->config->getCompound()) {
return null === $value || is_scalar($value) ? (string) $value : $value;
}
try {
foreach ($this->config->getViewTransformers() as $transformer) {
foreach ($transformers as $transformer) {
$value = $transformer->transform($value);
}
} catch (TransformationFailedException $exception) {
@ -1138,13 +1124,11 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
*
* @return mixed
*
* @throws TransformationFailedException If the value cannot be transformed to "normalized" format
* @throws TransformationFailedException If the submitted value cannot be transformed to "normalized" format
*/
private function viewToNorm($value)
{
$transformers = $this->config->getViewTransformers();
if (!$transformers) {
if (!$transformers = $this->config->getViewTransformers()) {
return '' === $value ? null : $value;
}

View File

@ -72,10 +72,7 @@ class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormB
// Add to "children" to maintain order
$this->children[$child] = null;
$this->unresolvedChildren[$child] = [
'type' => $type,
'options' => $options,
];
$this->unresolvedChildren[$child] = [$type, $options];
return $this;
}
@ -143,15 +140,7 @@ class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormB
throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
}
if (isset($this->unresolvedChildren[$name])) {
return true;
}
if (isset($this->children[$name])) {
return true;
}
return false;
return isset($this->unresolvedChildren[$name]) || isset($this->children[$name]);
}
/**
@ -223,7 +212,7 @@ class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormB
/**
* {@inheritdoc}
*
* @return FormBuilderInterface[]
* @return FormBuilderInterface[]|\Traversable
*/
public function getIterator()
{
@ -239,12 +228,11 @@ class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormB
*/
private function resolveChild(string $name): FormBuilderInterface
{
$info = $this->unresolvedChildren[$name];
$child = $this->create($name, $info['type'], $info['options']);
$this->children[$name] = $child;
list($type, $options) = $this->unresolvedChildren[$name];
unset($this->unresolvedChildren[$name]);
return $child;
return $this->children[$name] = $this->create($name, $type, $options);
}
/**
@ -253,7 +241,7 @@ class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormB
private function resolveChildren()
{
foreach ($this->unresolvedChildren as $name => $info) {
$this->children[$name] = $this->create($name, $info['type'], $info['options']);
$this->children[$name] = $this->create($name, $info[0], $info[1]);
}
$this->unresolvedChildren = [];

View File

@ -37,41 +37,18 @@ class FormConfigBuilder implements FormConfigBuilderInterface
/**
* @var bool
*/
protected $locked = false;
/**
* @var EventDispatcherInterface
*/
private $dispatcher;
/**
* @var string
*/
private $name;
/**
* @var PropertyPathInterface
* @var PropertyPathInterface|string|null
*/
private $propertyPath;
/**
* @var bool
*/
private $mapped = true;
/**
* @var bool
*/
private $byReference = true;
/**
* @var bool
*/
private $inheritData = false;
/**
* @var bool
*/
private $compound = false;
/**
@ -79,34 +56,16 @@ class FormConfigBuilder implements FormConfigBuilderInterface
*/
private $type;
/**
* @var array
*/
private $viewTransformers = [];
/**
* @var array
*/
private $modelTransformers = [];
/**
* @var DataMapperInterface
* @var DataMapperInterface|null
*/
private $dataMapper;
/**
* @var bool
*/
private $required = true;
/**
* @var bool
*/
private $disabled = false;
/**
* @var bool
*/
private $errorBubbling = false;
/**
@ -114,9 +73,6 @@ class FormConfigBuilder implements FormConfigBuilderInterface
*/
private $emptyData;
/**
* @var array
*/
private $attributes = [];
/**
@ -129,39 +85,26 @@ class FormConfigBuilder implements FormConfigBuilderInterface
*/
private $dataClass;
/**
* @var bool
*/
private $dataLocked;
private $dataLocked = false;
/**
* @var FormFactoryInterface
* @var FormFactoryInterface|null
*/
private $formFactory;
/**
* @var string
* @var string|null
*/
private $action;
/**
* @var string
*/
private $method = 'POST';
/**
* @var RequestHandlerInterface
* @var RequestHandlerInterface|null
*/
private $requestHandler;
/**
* @var bool
*/
private $autoInitialize = false;
/**
* @var array
*/
private $options;
/**
@ -603,7 +546,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface
throw new BadMethodCallException('FormConfigBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
}
$this->errorBubbling = null === $errorBubbling ? null : (bool) $errorBubbling;
$this->errorBubbling = (bool) $errorBubbling;
return $this;
}
@ -649,7 +592,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface
throw new BadMethodCallException('FormConfigBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
}
$this->mapped = $mapped;
$this->mapped = (bool) $mapped;
return $this;
}
@ -663,7 +606,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface
throw new BadMethodCallException('FormConfigBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
}
$this->byReference = $byReference;
$this->byReference = (bool) $byReference;
return $this;
}
@ -677,7 +620,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface
throw new BadMethodCallException('FormConfigBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
}
$this->inheritData = $inheritData;
$this->inheritData = (bool) $inheritData;
return $this;
}
@ -691,7 +634,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface
throw new BadMethodCallException('FormConfigBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
}
$this->compound = $compound;
$this->compound = (bool) $compound;
return $this;
}
@ -733,7 +676,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface
throw new BadMethodCallException('FormConfigBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
}
$this->dataLocked = $locked;
$this->dataLocked = (bool) $locked;
return $this;
}
@ -761,7 +704,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface
throw new BadMethodCallException('The config builder cannot be modified anymore.');
}
$this->action = $action;
$this->action = (string) $action;
return $this;
}
@ -827,7 +770,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface
/**
* Validates whether the given variable is a valid form name.
*
* @param string|int $name The tested form name
* @param string|int|null $name The tested form name
*
* @throws UnexpectedTypeException if the name is not a string or an integer
* @throws InvalidArgumentException if the name contains invalid characters
@ -853,7 +796,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface
* * contains only letters, digits, numbers, underscores ("_"),
* hyphens ("-") and colons (":")
*
* @param string $name The tested form name
* @param string|null $name The tested form name
*
* @return bool Whether the name is valid
*/

View File

@ -108,7 +108,7 @@ interface FormConfigBuilderInterface extends FormConfigInterface
public function setDataMapper(DataMapperInterface $dataMapper = null);
/**
* Set whether the form is disabled.
* Sets whether the form is disabled.
*
* @param bool $disabled Whether the form is disabled
*
@ -166,8 +166,7 @@ interface FormConfigBuilderInterface extends FormConfigInterface
/**
* Sets whether the form's data should be modified by reference.
*
* @param bool $byReference Whether the data should be
* modified by reference
* @param bool $byReference Whether the data should be modified by reference
*
* @return $this The configuration object
*/
@ -194,7 +193,7 @@ interface FormConfigBuilderInterface extends FormConfigInterface
public function setCompound($compound);
/**
* Set the types.
* Sets the resolved type.
*
* @return $this The configuration object
*/
@ -203,7 +202,7 @@ interface FormConfigBuilderInterface extends FormConfigInterface
/**
* Sets the initial data of the form.
*
* @param mixed $data The data of the form in application format
* @param mixed $data The data of the form in model format
*
* @return $this The configuration object
*/
@ -214,9 +213,12 @@ interface FormConfigBuilderInterface extends FormConfigInterface
*
* A form with locked data is restricted to the data passed in
* this configuration. The data can only be modified then by
* submitting the form.
* submitting the form or using PRE_SET_DATA event.
*
* @param bool $locked Whether to lock the default data
* It means data passed to a factory method or mapped from the
* parent will be ignored.
*
* @param bool $locked Whether to lock the default configured data
*
* @return $this The configuration object
*/

View File

@ -70,15 +70,17 @@ interface FormConfigInterface
* This property is independent of whether the form actually has
* children. A form can be compound and have no children at all, like
* for example an empty collection form.
* The contrary is not possible, a form which is not compound
* cannot have any children.
*
* @return bool Whether the form is compound
*/
public function getCompound();
/**
* Returns the form types used to construct the form.
* Returns the resolved form type used to construct the form.
*
* @return ResolvedFormTypeInterface The form's type
* @return ResolvedFormTypeInterface The form's resolved type
*/
public function getType();
@ -97,7 +99,7 @@ interface FormConfigInterface
public function getModelTransformers();
/**
* Returns the data mapper of the form.
* Returns the data mapper of the compound form or null for a simple form.
*
* @return DataMapperInterface|null The data mapper
*/
@ -125,9 +127,15 @@ interface FormConfigInterface
public function getErrorBubbling();
/**
* Returns the data that should be returned when the form is empty.
* Used when the view data is empty on submission.
*
* @return mixed The data returned if the form is empty
* When the form is compound it will also be used to map the
* children data.
*
* The empty data must match the view format as it will passed to the first view transformer's
* "reverseTransform" method.
*
* @return mixed The data used when the submitted form is initially empty
*/
public function getEmptyData();
@ -165,7 +173,7 @@ interface FormConfigInterface
public function getData();
/**
* Returns the class of the form data or null if the data is scalar or an array.
* Returns the class of the view data or null if the data is scalar or an array.
*
* @return string|null The data class or null
*/

View File

@ -49,7 +49,7 @@ class FormError
*/
public function __construct(?string $message, string $messageTemplate = null, array $messageParameters = [], int $messagePluralization = null, $cause = null)
{
$this->message = $message;
$this->message = (string) $message;
$this->messageTemplate = $messageTemplate ?: $message;
$this->messageParameters = $messageParameters;
$this->messagePluralization = $messagePluralization;

View File

@ -39,10 +39,9 @@ class FormErrorIterator implements \RecursiveIterator, \SeekableIterator, \Array
private $errors;
/**
* Creates a new iterator.
*
* @param FormInterface $form The erroneous form
* @param FormError[]|FormErrorIterator[] $errors The form errors
* @param FormInterface $form The erroneous form
* @param FormError[]|self[] $errors An array of form errors and instances
* of FormErrorIterator
*
* @throws InvalidArgumentException If the errors are invalid
*/
@ -71,7 +70,7 @@ class FormErrorIterator implements \RecursiveIterator, \SeekableIterator, \Array
if ($error instanceof FormError) {
$string .= 'ERROR: '.$error->getMessage()."\n";
} else {
/* @var $error FormErrorIterator */
/** @var self $error */
$string .= $error->form->getName().":\n";
$string .= self::indent((string) $error);
}
@ -93,8 +92,7 @@ class FormErrorIterator implements \RecursiveIterator, \SeekableIterator, \Array
/**
* Returns the current element of the iterator.
*
* @return FormError|FormErrorIterator an error or an iterator containing
* nested errors
* @return FormError|self An error or an iterator containing nested errors
*/
public function current()
{

View File

@ -21,6 +21,10 @@ class FormEvent extends Event
private $form;
protected $data;
/**
* @param FormInterface $form The associated form
* @param mixed $data The data
*/
public function __construct(FormInterface $form, $data)
{
$this->form = $form;

View File

@ -34,21 +34,35 @@ final class FormEvents
const PRE_SUBMIT = 'form.pre_submit';
/**
* The SUBMIT event is dispatched just before the Form::submit() method
* transforms back the normalized data to the model and view data.
* The SUBMIT event is dispatched after the Form::submit() method
* has changed the view data by the request data, or submitted and mapped
* the children if the form is compound, and after reverse transformation
* to normalized representation.
*
* It can be used to change data from the normalized representation of the data.
* It's also dispatched just before the Form::submit() method transforms back
* the normalized data to the model and view data.
*
* So at this stage children of compound forms are submitted and synchronized, unless
* their transformation failed, but a parent would still be at the PRE_SUBMIT level.
*
* Since the current form is not synchronized yet, it is still possible to add and
* remove fields.
*
* @Event("Symfony\Component\Form\Event\SubmitEvent")
*/
const SUBMIT = 'form.submit';
/**
* The FormEvents::POST_SUBMIT event is dispatched after the Form::submit()
* once the model and view data have been denormalized.
* The FormEvents::POST_SUBMIT event is dispatched at the very end of the Form::submit().
*
* It this stage the model and view data may have been denormalized. Otherwise the form
* is desynchronized because transformation failed during submission.
*
* It can be used to fetch data after denormalization.
*
* The event attaches the current view data. To know whether this is the renormalized data
* or the invalid request data, call Form::isSynchronized() first.
*
* @Event("Symfony\Component\Form\Event\PostSubmitEvent")
*/
const POST_SUBMIT = 'form.post_submit';
@ -58,7 +72,7 @@ final class FormEvents
*
* It can be used to:
* - Modify the data given during pre-population;
* - Modify a form depending on the pre-populated data (adding or removing fields dynamically).
* - Keep synchronized the form depending on the data (adding or removing fields dynamically).
*
* @Event("Symfony\Component\Form\Event\PreSetDataEvent")
*/
@ -67,7 +81,8 @@ final class FormEvents
/**
* The FormEvents::POST_SET_DATA event is dispatched at the end of the Form::setData() method.
*
* This event is mostly here for reading data after having pre-populated the form.
* This event can be used to modify the form depending on the final state of the underlying data
* accessible in every representation: model, normalized and view.
*
* @Event("Symfony\Component\Form\Event\PostSetDataEvent")
*/

View File

@ -11,7 +11,7 @@
namespace Symfony\Component\Form;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Symfony\Component\PropertyAccess\PropertyPathInterface;
/**
* A form group bundling multiple forms in a hierarchical structure.
@ -23,7 +23,9 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable
/**
* Sets the parent form.
*
* @return self
* @param FormInterface|null $parent The parent form or null if it's the root
*
* @return $this
*
* @throws Exception\AlreadySubmittedException if the form has already been submitted
* @throws Exception\LogicException when trying to set a parent for a form with
@ -45,7 +47,7 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable
* @param string|null $type The child's type, if a name was passed
* @param array $options The child's options, if a name was passed
*
* @return self
* @return $this
*
* @throws Exception\AlreadySubmittedException if the form has already been submitted
* @throws Exception\LogicException when trying to add a child to a non-compound form
@ -104,44 +106,70 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable
public function getErrors($deep = false, $flatten = true);
/**
* Updates the form with default data.
* Updates the form with default model data.
*
* @param mixed $modelData The data formatted as expected for the underlying object
*
* @return $this
*
* @throws Exception\AlreadySubmittedException if the form has already been submitted
* @throws Exception\LogicException If listeners try to call setData in a cycle. Or if
* the view data does not match the expected type
* according to {@link FormConfigInterface::getDataClass}.
* @throws Exception\AlreadySubmittedException If the form has already been submitted
* @throws Exception\LogicException If the view data does not match the expected type
* according to {@link FormConfigInterface::getDataClass}.
* @throws Exception\RuntimeException If listeners try to call setData in a cycle or if
* the form inherits data from its parent
* @throws Exception\TransformationFailedException If the synchronization failed.
*/
public function setData($modelData);
/**
* Returns the data in the format needed for the underlying object.
* Returns the model data in the format needed for the underlying object.
*
* @return mixed
* @return mixed When the field is not submitted, the default data is returned.
* When the field is submitted, the default data has been bound
* to the submitted view data.
*
* @throws Exception\RuntimeException If the form inherits data but has no parent
*/
public function getData();
/**
* Returns the normalized data of the field.
* Returns the normalized data of the field, used as internal bridge
* between model data and view data.
*
* @return mixed When the field is not submitted, the default data is returned.
* When the field is submitted, the normalized submitted data is
* returned if the field is valid, null otherwise.
* When the field is submitted, the normalized submitted data
* is returned if the field is synchronized with the view data,
* null otherwise.
*
* @throws Exception\RuntimeException If the form inherits data but has no parent
*/
public function getNormData();
/**
* Returns the data transformed by the value transformer.
* Returns the view data of the field.
*
* It may be defined by {@link FormConfigInterface::getDataClass}.
*
* There are two cases:
*
* - When the form is compound the view data is mapped to the children.
* Each child will use its mapped data as model data.
* It can be an array, an object or null.
*
* - When the form is simple its view data is used to be bound
* to the submitted data.
* It can be a string or an array.
*
* In both cases the view data is the actual altered data on submission.
*
* @return mixed
*
* @throws Exception\RuntimeException If the form inherits data but has no parent
*/
public function getViewData();
/**
* Returns the extra data.
* Returns the extra submitted data.
*
* @return array The submitted data which do not belong to a child
*/
@ -150,7 +178,7 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable
/**
* Returns the form's configuration.
*
* @return FormConfigInterface The configuration
* @return FormConfigInterface The configuration instance
*/
public function getConfig();
@ -164,6 +192,8 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable
/**
* Returns the name by which the form is identified in forms.
*
* Only root forms are allowed to have an empty name.
*
* @return string The name of the form
*/
public function getName();
@ -171,7 +201,7 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable
/**
* Returns the property path that the form is mapped to.
*
* @return \Symfony\Component\PropertyAccess\PropertyPathInterface|null The property path
* @return PropertyPathInterface|null The property path instance
*/
public function getPropertyPath();
@ -230,14 +260,16 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable
* If the data is not synchronized, you can get the transformation failure
* by calling {@link getTransformationFailure()}.
*
* If the form is not submitted, this method always returns true.
*
* @return bool
*/
public function isSynchronized();
/**
* Returns the data transformation failure, if any.
* Returns the data transformation failure, if any, during submission.
*
* @return TransformationFailedException|null The transformation failure
* @return Exception\TransformationFailedException|null The transformation failure or null
*/
public function getTransformationFailure();
@ -247,6 +279,8 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable
* Should be called on the root form after constructing the tree.
*
* @return $this
*
* @throws Exception\RuntimeException If the form is not the root
*/
public function initialize();
@ -265,11 +299,13 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable
public function handleRequest($request = null);
/**
* Submits data to the form, transforms and validates it.
* Submits data to the form.
*
* @param mixed $submittedData The submitted data
* @param bool $clearMissing Whether to set fields to NULL when they
* are missing in the submitted data
* @param string|array|null $submittedData The submitted data
* @param bool $clearMissing Whether to set fields to NULL
* when they are missing in the
* submitted data. This argument
* is only used in compound form
*
* @return $this
*
@ -280,7 +316,7 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable
/**
* Returns the root of the form tree.
*
* @return self The root of the tree
* @return self The root of the tree, may be the instance itself
*/
public function getRoot();
@ -292,8 +328,6 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable
public function isRoot();
/**
* Creates a view.
*
* @return FormView The view
*/
public function createView(FormView $parent = null);

View File

@ -26,7 +26,7 @@ class FormRegistry implements FormRegistryInterface
/**
* Extensions.
*
* @var FormExtensionInterface[] An array of FormExtensionInterface
* @var FormExtensionInterface[]
*/
private $extensions = [];

View File

@ -74,7 +74,7 @@ interface FormRendererEngineInterface
* First the themes attached directly to
* the view with {@link setTheme()} are
* considered, then the ones of its parent etc.
* @param array $blockNameHierarchy The block name hierarchy, with the root block
* @param string[] $blockNameHierarchy The block name hierarchy, with the root block
* at the beginning
* @param int $hierarchyLevel The level in the hierarchy at which to start
* looking. Level 0 indicates the root block, i.e.
@ -112,7 +112,7 @@ interface FormRendererEngineInterface
* First the themes attached directly to
* the view with {@link setTheme()} are
* considered, then the ones of its parent etc.
* @param array $blockNameHierarchy The block name hierarchy, with the root block
* @param string[] $blockNameHierarchy The block name hierarchy, with the root block
* at the beginning
* @param int $hierarchyLevel The level in the hierarchy at which to start
* looking. Level 0 indicates the root block, i.e.

View File

@ -19,7 +19,7 @@ class FormTypeGuesserChain implements FormTypeGuesserInterface
private $guessers = [];
/**
* @param FormTypeGuesserInterface[] $guessers Guessers as instances of FormTypeGuesserInterface
* @param FormTypeGuesserInterface[] $guessers
*
* @throws UnexpectedTypeException if any guesser does not implement FormTypeGuesserInterface
*/

View File

@ -49,8 +49,8 @@ interface FormTypeGuesserInterface
/**
* Returns a guess about the field's pattern.
*
* - When you have a min value, you guess a min length of this min (LOW_CONFIDENCE) , lines below
* - If this value is a float type, this is wrong so you guess null with MEDIUM_CONFIDENCE to override the previous guess.
* - When you have a min value, you guess a min length of this min (LOW_CONFIDENCE)
* - Then line below, if this value is a float type, this is wrong so you guess null with MEDIUM_CONFIDENCE to override the previous guess.
* Example:
* You want a float greater than 5, 4.512313 is not valid but length(4.512314) > length(5)
*

View File

@ -41,6 +41,8 @@ class NativeRequestHandler implements RequestHandlerInterface
/**
* {@inheritdoc}
*
* @throws Exception\UnexpectedTypeException If the $request is not null
*/
public function handleRequest(FormInterface $form, $request = null)
{

View File

@ -450,6 +450,31 @@ class CompoundFormTest extends AbstractFormTest
$form->setData('foo');
}
public function testSetDataDoesNotMapViewDataToChildrenWithLockedSetData()
{
$mapper = new PropertyPathMapper();
$viewData = [
'firstName' => 'Fabien',
'lastName' => 'Pot',
];
$form = $this->getBuilder()
->setCompound(true)
->setDataMapper($mapper)
->addViewTransformer(new FixedDataTransformer([
'' => '',
'foo' => $viewData,
]))
->getForm();
$form->add($child1 = $this->getBuilder('firstName')->getForm());
$form->add($child2 = $this->getBuilder('lastName')->setData('Potencier')->setDataLocked(true)->getForm());
$form->setData('foo');
$this->assertSame('Fabien', $form->get('firstName')->getData());
$this->assertSame('Potencier', $form->get('lastName')->getData());
}
public function testSubmitSupportsDynamicAdditionAndRemovalOfChildren()
{
$form = $this->form;

View File

@ -51,7 +51,6 @@ class LanguageTypeTest extends BaseTypeTest
// Don't check objects for identity
$this->assertContains(new ChoiceView('en', 'en', 'англійська'), $choices, '', false, false);
$this->assertContains(new ChoiceView('en_GB', 'en_GB', 'British English'), $choices, '', false, false);
$this->assertContains(new ChoiceView('en_US', 'en_US', 'англійська (США)'), $choices, '', false, false);
$this->assertContains(new ChoiceView('fr', 'fr', 'французька'), $choices, '', false, false);
$this->assertContains(new ChoiceView('my', 'my', 'бірманська'), $choices, '', false, false);

View File

@ -33,7 +33,7 @@ class LocaleTypeTest extends BaseTypeTest
$this->assertContains(new ChoiceView('en', 'en', 'English'), $choices, '', false, false);
$this->assertContains(new ChoiceView('en_GB', 'en_GB', 'English (United Kingdom)'), $choices, '', false, false);
$this->assertContains(new ChoiceView('zh_Hant_MO', 'zh_Hant_MO', 'Chinese (Traditional, Macau SAR China)'), $choices, '', false, false);
$this->assertContains(new ChoiceView('zh_Hant_HK', 'zh_Hant_HK', 'Chinese (Traditional, Hong Kong SAR China)'), $choices, '', false, false);
}
/**

View File

@ -54,6 +54,26 @@ class SimpleFormTest_Traversable implements \IteratorAggregate
class SimpleFormTest extends AbstractFormTest
{
/**
* @dataProvider provideFormNames
*/
public function testGetPropertyPath($name, $propertyPath)
{
$config = new FormConfigBuilder($name, null, $this->dispatcher);
$form = new Form($config);
$this->assertEquals(new PropertyPath($propertyPath), $form->getPropertyPath());
}
public function provideFormNames()
{
yield [null, null];
yield ['', null];
yield ['0', '0'];
yield [0, '0'];
yield ['name', 'name'];
}
public function testDataIsInitializedToConfiguredValue()
{
$model = new FixedDataTransformer([
@ -76,7 +96,7 @@ class SimpleFormTest extends AbstractFormTest
/**
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
* @expectedExceptionMessage Unable to transform value for property path "name": No mapping for value "arg"
* @expectedExceptionMessage Unable to transform data for property path "name": No mapping for value "arg"
*/
public function testDataTransformationFailure()
{

View File

@ -200,10 +200,10 @@ CHANGELOG
* Added `FlashBag`. Flashes expire when retrieved by `get()` or `all()`. This
implementation is ESI compatible.
* Added `AutoExpireFlashBag` (default) to replicate Symfony 2.0.x auto expire
behaviour of messages auto expiring after one page page load. Messages must
behavior of messages auto expiring after one page page load. Messages must
be retrieved by `get()` or `all()`.
* Added `Symfony\Component\HttpFoundation\Attribute\AttributeBag` to replicate
attributes storage behaviour from 2.0.x (default).
attributes storage behavior from 2.0.x (default).
* Added `Symfony\Component\HttpFoundation\Attribute\NamespacedAttributeBag` for
namespace session attributes.
* Flash API can stores messages in an array so there may be multiple messages

View File

@ -193,7 +193,9 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable
*/
public function save()
{
$this->storage->save();
if ($this->isStarted()) {
$this->storage->save();
}
}
/**

View File

@ -260,4 +260,14 @@ class SessionTest extends TestCase
$flash->get('hello');
$this->assertTrue($this->session->isEmpty());
}
public function testSaveIfNotStarted()
{
$storage = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface')->getMock();
$session = new Session($storage);
$storage->expects($this->once())->method('isStarted')->willReturn(false);
$storage->expects($this->never())->method('save');
$session->save();
}
}

View File

@ -19,6 +19,7 @@ use Symfony\Component\Debug\ErrorHandler;
use Symfony\Component\Debug\ExceptionHandler;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Debug\FileLinkFormatter;
use Symfony\Component\HttpKernel\Event\KernelEvent;
use Symfony\Component\HttpKernel\KernelEvents;
@ -40,13 +41,13 @@ class DebugHandlersListener implements EventSubscriberInterface
private $hasTerminatedWithException;
/**
* @param callable|null $exceptionHandler A handler that will be called on Exception
* @param LoggerInterface|null $logger A PSR-3 logger
* @param array|int $levels An array map of E_* to LogLevel::* or an integer bit field of E_* constants
* @param int|null $throwAt Thrown errors in a bit field of E_* constants, or null to keep the current value
* @param bool $scream Enables/disables screaming mode, where even silenced errors are logged
* @param string|array $fileLinkFormat The format for links to source files
* @param bool $scope Enables/disables scoping mode
* @param callable|null $exceptionHandler A handler that will be called on Exception
* @param LoggerInterface|null $logger A PSR-3 logger
* @param array|int $levels An array map of E_* to LogLevel::* or an integer bit field of E_* constants
* @param int|null $throwAt Thrown errors in a bit field of E_* constants, or null to keep the current value
* @param bool $scream Enables/disables screaming mode, where even silenced errors are logged
* @param string|FileLinkFormatter|null $fileLinkFormat The format for links to source files
* @param bool $scope Enables/disables scoping mode
*/
public function __construct(callable $exceptionHandler = null, LoggerInterface $logger = null, $levels = E_ALL, ?int $throwAt = E_ALL, bool $scream = true, $fileLinkFormat = null, bool $scope = true)
{
@ -105,7 +106,7 @@ class DebugHandlersListener implements EventSubscriberInterface
if (method_exists($kernel = $event->getKernel(), 'terminateWithException')) {
$request = $event->getRequest();
$hasRun = &$this->hasTerminatedWithException;
$this->exceptionHandler = function (\Exception $e) use ($kernel, $request, &$hasRun) {
$this->exceptionHandler = static function (\Exception $e) use ($kernel, $request, &$hasRun) {
if ($hasRun) {
throw $e;
}

View File

@ -215,7 +215,7 @@ class ResponseCacheStrategy implements ResponseCacheStrategyInterface
}
if (false !== $this->ageDirectives[$directive]) {
$value = $value - $age;
$value -= $age;
$this->ageDirectives[$directive] = null !== $this->ageDirectives[$directive] ? min($this->ageDirectives[$directive], $value) : $value;
}
}

View File

@ -39,6 +39,7 @@ class LanguageDataGenerator extends AbstractDataGenerator
'cs' => 'ces',
'cy' => 'cym',
'de' => 'deu',
'dz' => 'dzo',
'el' => 'ell',
'et' => 'est',
'eu' => 'eus',

View File

@ -235,7 +235,7 @@ final class Intl
*/
public static function getIcuStubVersion()
{
return '63.1';
return '64.1';
}
/**

View File

@ -85,7 +85,9 @@ final class Locale extends \Locale
array_pop($localeSubTags);
return locale_compose($localeSubTags);
$fallback = locale_compose($localeSubTags);
return false !== $fallback ? $fallback : null;
}
if (false !== $pos = strrpos($locale, '_')) {

View File

@ -1,12 +1,14 @@
#!/usr/bin/env bash
if [[ $1 == force || ! $(docker ps -a | grep symfony-intl) ]]; then
docker rm -f symfony-intl
docker create --name symfony-intl -it -v /tmp:/tmp -v $(pwd):/app -w /app jakzal/php-intl:7.2-63.1 bash
docker start symfony-intl
docker exec symfony-intl bash -xc "apt-get update && apt-get -y install build-essential"
else
docker start symfony-intl
if [[ $1 == force ]]; then
docker pull jakzal/php-intl
fi;
docker exec -u $(id -u):$(id -g) symfony-intl php src/Symfony/Component/Intl/Resources/bin/update-data.php
docker run \
-it --rm --name symfony-intl \
-u $(id -u):$(id -g) \
-v /tmp/symfony/icu:/tmp \
-v $(pwd):/symfony \
-w /symfony \
jakzal/php-intl:latest \
php src/Symfony/Component/Intl/Resources/bin/update-data.php

View File

@ -1,5 +1,5 @@
{
"Version": "2.1.43.65",
"Version": "2.1.48.17",
"Names": {
"AED": [
"AED",

View File

@ -1,5 +1,5 @@
{
"Version": "2.1.38.69",
"Version": "2.1.48.22",
"Names": {
"NAD": [
"$",

View File

@ -1,5 +1,5 @@
{
"Version": "2.1.39.11",
"Version": "2.1.47.82",
"Names": {
"AED": [
"AED",

View File

@ -1,5 +1,5 @@
{
"Version": "2.1.43.65",
"Version": "2.1.48.18",
"Names": {
"AED": [
"AED",

View File

@ -1,5 +1,5 @@
{
"Version": "2.1.43.50",
"Version": "2.1.48.22",
"Names": {
"ADP": [
"ADP",
@ -105,6 +105,10 @@
"BEL",
"فرنك بلجيكي مالي"
],
"BGL": [
"BGL",
"BGL"
],
"BGN": [
"BGN",
"ليف بلغاري"

View File

@ -1,5 +1,5 @@
{
"Version": "2.1.38.80",
"Version": "2.1.47.69",
"Names": {
"DJF": [
"Fdj",

View File

@ -1,5 +1,5 @@
{
"Version": "2.1.38.80",
"Version": "2.1.47.69",
"Names": {
"ERN": [
"Nfk",

View File

@ -1,5 +1,5 @@
{
"Version": "2.1.38.80",
"Version": "2.1.47.69",
"Names": {
"KMF": [
"CF",

Some files were not shown because too many files have changed in this diff Show More