Merge branch '3.3' into 3.4
* 3.3: (31 commits) Using FQ name for PHP_VERSION_ID [EventDispatcher] Handle laziness internally instead of relying on ClosureProxyArgument Fix CacheCollectorPass priority [Form] Fix \IntlDateFormatter timezone parameter usage to bypass PHP bug #66323 [Routing] Allow GET requests to be redirected. Fixes #23004 [DI] Deal with inlined non-shared services [Cache] Ignore missing annotations.php [DI] Autowiring exception thrown when inlined service is removed Improving deprecation message when hitting the "deprecated type" lookup, but an alias is available Harden the debugging of Twig filters and functions Fixing a bug where an autowiring exception was thrown even when that service was removed Remove extra arg in call to TraceableAdapter::start() Support unknown compiler log format [Config] Allow empty globs Fix decorating TagAware adapters in dev [Profiler] Fix clicking on links inside toggle [Profiler] Fix text selection on exception pages bumped Symfony version to 3.3.1 updated VERSION for 3.3.0 updated CHANGELOG for 3.3.0 ...
This commit is contained in:
commit
69f1578d8c
2
.github/build-packages.php
vendored
2
.github/build-packages.php
vendored
@ -11,7 +11,7 @@ array_shift($dirs);
|
||||
$mergeBase = trim(shell_exec(sprintf('git merge-base %s HEAD', array_shift($dirs))));
|
||||
|
||||
$packages = array();
|
||||
$flags = PHP_VERSION_ID >= 50400 ? JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE : 0;
|
||||
$flags = \PHP_VERSION_ID >= 50400 ? JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE : 0;
|
||||
|
||||
foreach ($dirs as $k => $dir) {
|
||||
if (!system("git diff --name-only $mergeBase -- $dir", $exitStatus)) {
|
||||
|
@ -7,6 +7,29 @@ in 3.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/v3.2.0...v3.2.1
|
||||
|
||||
* 3.2.9 (2017-05-29)
|
||||
|
||||
* bug #22847 [Console] ChoiceQuestion must have choices (ro0NL)
|
||||
* bug #22900 [FrameworkBundle][Console] Fix the override of a command registered by the kernel (aaa2000)
|
||||
* bug #22910 [Filesystem] improve error handling in lock() (xabbuh)
|
||||
* bug #22924 [Cache] Dont use pipelining with RedisCluster (nicolas-grekas)
|
||||
* bug #22718 [Console] Fixed different behaviour of key and value user inputs in multiple choice question (borNfreee)
|
||||
* bug #22829 [Yaml] fix colon without space deprecation (xabbuh)
|
||||
* bug #22901 Fix missing abstract key in XmlDumper (weaverryan)
|
||||
* bug #22912 [DI] Avoid private call to Container::has() (ro0NL)
|
||||
* bug #22866 [DI] Check for privates before shared services (ro0NL)
|
||||
* bug #22874 [WebProfilerBundle] Fix sub-requests display in time profiler panel (nicolas-grekas)
|
||||
* bug #22817 [PhpUnitBridge] optional error handler arguments (xabbuh)
|
||||
* bug #22752 Improved how profiler errors are displayed on small screens (javiereguiluz)
|
||||
* bug #22715 [FrameworkBundle] remove Security deps from the require section (xabbuh)
|
||||
* bug #22647 [VarDumper] Fix dumping of non-nested stubs (nicolas-grekas)
|
||||
* bug #22409 [Yaml] respect inline level when dumping objects as maps (goetas, xabbuh)
|
||||
* bug #22584 [Security] Avoid unnecessary route lookup for empty logout path (ro0NL)
|
||||
* bug #22690 [Console] Fix errors not rethrown even if not handled by console.error listeners (chalasr)
|
||||
* bug #22669 [FrameworkBundle] AbstractConfigCommand: do not try registering bundles twice (ogizanagi)
|
||||
* bug #22676 [FrameworkBundle] Adding the extension XML (flug)
|
||||
* bug #22652 [Workflow] Move twig extension registration to twig bundle (ogizanagi)
|
||||
|
||||
* 3.2.8 (2017-05-01)
|
||||
|
||||
* bug #22550 Allow Upper Case property names in ObjectNormalizer (insekticid)
|
||||
|
@ -7,6 +7,45 @@ in 3.3 minor versions.
|
||||
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
|
||||
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v3.3.0...v3.3.1
|
||||
|
||||
* 3.3.0 (2017-05-29)
|
||||
|
||||
* bug #22940 [Config] Fallback to regular import when glob fails (nicolas-grekas)
|
||||
* bug #22847 [Console] ChoiceQuestion must have choices (ro0NL)
|
||||
* bug #22900 [FrameworkBundle][Console] Fix the override of a command registered by the kernel (aaa2000)
|
||||
* bug #22930 Revert "bug #22925 [PhpUnitBridge] Adjust PHPUnit class_alias check (nicolas-grekas)
|
||||
* bug #22910 [Filesystem] improve error handling in lock() (xabbuh)
|
||||
* bug #22924 [Cache] Dont use pipelining with RedisCluster (nicolas-grekas)
|
||||
* bug #22928 [WebProfilerBundle] Fixed options stub values display in form profiler (HeahDude)
|
||||
* feature #22838 Make the simple exception pages match the new style (javiereguiluz)
|
||||
* bug #22925 [PhpUnitBridge] Adjust PHPUnit class_alias check to also check for namespaced class (GawainLynch)
|
||||
* bug #22718 [Console] Fixed different behaviour of key and value user inputs in multiple choice question (borNfreee)
|
||||
* bug #22921 [FrameworkBundle] Only override getProjectDir if it exists in the kernel (aschempp)
|
||||
* feature #22905 [FrameworkBundle][Validator] Move the PSR-11 factory to the component (ogizanagi)
|
||||
* bug #22728 [HttpKernel] Fix kernel.project_dir extensibility (chalasr)
|
||||
* bug #22829 [Yaml] fix colon without space deprecation (xabbuh)
|
||||
* bug #22901 Fix missing abstract key in XmlDumper (weaverryan)
|
||||
* bug #22912 [DI] Avoid private call to Container::has() (ro0NL)
|
||||
* feature #22904 [HttpFoundation] Add Request::HEADER_X_FORWARDED_AWS_ELB const (nicolas-grekas)
|
||||
* bug #22878 [Yaml] parse PHP constants in mapping keys (xabbuh)
|
||||
* bug #22873 [HttpKernel] don't call getTrustedHeaderName() if possible (xabbuh)
|
||||
* feature #22892 [ProxyManager] Add FC layer (nicolas-grekas)
|
||||
* bug #22866 [DI] Check for privates before shared services (ro0NL)
|
||||
* feature #22884 [DI] Add missing deprecation on Extension::getClassesToCompile (nicolas-grekas)
|
||||
* bug #22874 [WebProfilerBundle] Fix sub-requests display in time profiler panel (nicolas-grekas)
|
||||
* bug #22853 [Yaml] fix multiline block handling (xabbuh)
|
||||
* bug #22872 [FrameworkBundle] Handle project dir in cache:clear command (nicolas-grekas)
|
||||
* feature #22808 [FrameworkBundle][Validator] Deprecate passing validator instances/aliases over using the service locator (ogizanagi)
|
||||
* bug #22857 [DI] Fix autowire error for inlined services (weaverryan)
|
||||
* bug #22858 [SecurityBundle] Prevent auto-registration of UserPasswordEncoderCommand (chalasr)
|
||||
* bug #22859 [Profiler][VarDumper] Fix searchbar css when in toolbar (ogizanagi)
|
||||
* bug #22614 [Process] Fixed escaping arguments on Windows when inheritEnvironmentVariables is set to false (maryo)
|
||||
* bug #22817 [PhpUnitBridge] optional error handler arguments (xabbuh)
|
||||
* bug #22781 [DI][Serializer] Fix missing de(normalizer|coder) autoconfig (ogizanagi)
|
||||
* bug #22790 [DependencyInjection] Fix dumping of RewindableGenerator with empty IteratorArgument (meyerbaptiste)
|
||||
* bug #22787 [MonologBridge] Fix the Monlog ServerLogHandler from Hanging on Windows (ChadSikorra)
|
||||
* bug #22768 Use 0.0.0.0 as the server log command host default. (ChadSikorra)
|
||||
* bug #22752 Improved how profiler errors are displayed on small screens (javiereguiluz)
|
||||
|
||||
* 3.3.0-RC1 (2017-05-17)
|
||||
|
||||
* bug #22715 [FrameworkBundle] remove Security deps from the require section (xabbuh)
|
||||
|
@ -24,20 +24,20 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Wouter De Jong (wouterj)
|
||||
- Romain Neutron (romain)
|
||||
- Grégoire Pineau (lyrixx)
|
||||
- Joseph Bielawski (stloyd)
|
||||
- Karma Dordrak (drak)
|
||||
- Robin Chalas (chalas_r)
|
||||
- Joseph Bielawski (stloyd)
|
||||
- Maxime Steinhausser (ogizanagi)
|
||||
- Karma Dordrak (drak)
|
||||
- Lukas Kahwe Smith (lsmith)
|
||||
- Martin Hasoň (hason)
|
||||
- Maxime Steinhausser (ogizanagi)
|
||||
- Jeremy Mikola (jmikola)
|
||||
- Jean-François Simon (jfsimon)
|
||||
- Benjamin Eberlei (beberlei)
|
||||
- Igor Wiedler (igorw)
|
||||
- Eriksen Costa (eriksencosta)
|
||||
- Jules Pietri (heah)
|
||||
- Sarah Khalil (saro0h)
|
||||
- Roland Franssen (ro0)
|
||||
- Sarah Khalil (saro0h)
|
||||
- Jonathan Wage (jwage)
|
||||
- Guilhem Niot (energetick)
|
||||
- Diego Saint Esteben (dosten)
|
||||
@ -49,10 +49,10 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Alexander Mols (asm89)
|
||||
- Bulat Shakirzyanov (avalanche123)
|
||||
- Peter Rehm (rpet)
|
||||
- Iltar van der Berg (kjarli)
|
||||
- Saša Stamenković (umpirsky)
|
||||
- Henrik Bjørnskov (henrikbjorn)
|
||||
- Miha Vrhovnik
|
||||
- Roland Franssen (ro0)
|
||||
- Diego Saint Esteben (dii3g0)
|
||||
- Konstantin Kudryashov (everzet)
|
||||
- Bilal Amarni (bamarni)
|
||||
@ -64,8 +64,8 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Michel Weimerskirch (mweimerskirch)
|
||||
- Eric Clemmons (ericclemmons)
|
||||
- Charles Sarrazin (csarrazi)
|
||||
- Pierre du Plessis (pierredup)
|
||||
- Christian Raue
|
||||
- Pierre du Plessis (pierredup)
|
||||
- Arnout Boks (aboks)
|
||||
- Deni
|
||||
- Henrik Westphal (snc)
|
||||
@ -77,12 +77,12 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Lee McDermott
|
||||
- Brandon Turner
|
||||
- Luis Cordova (cordoval)
|
||||
- Jérémy DERUSSÉ (jderusse)
|
||||
- Graham Campbell (graham)
|
||||
- Daniel Holmes (dholmes)
|
||||
- Toni Uebernickel (havvg)
|
||||
- Bart van den Burg (burgov)
|
||||
- Jordan Alliot (jalliot)
|
||||
- Jérémy DERUSSÉ (jderusse)
|
||||
- John Wards (johnwards)
|
||||
- Dariusz Ruminski
|
||||
- Fran Moreno (franmomu)
|
||||
@ -92,8 +92,8 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Arnaud Le Blanc (arnaud-lb)
|
||||
- Maxime STEINHAUSSER
|
||||
- Michal Piotrowski (eventhorizon)
|
||||
- Tim Nagel (merk)
|
||||
- Issei Murasawa (issei_m)
|
||||
- Tim Nagel (merk)
|
||||
- Brice BERNARD (brikou)
|
||||
- Alexander M. Turek (derrabus)
|
||||
- Baptiste Clavié (talus)
|
||||
@ -115,6 +115,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Fabien Pennequin (fabienpennequin)
|
||||
- Gordon Franke (gimler)
|
||||
- Eric GELOEN (gelo)
|
||||
- Yonel Ceruto González (yonelceruto)
|
||||
- Daniel Wehner (dawehner)
|
||||
- Tugdual Saunier (tucksaun)
|
||||
- Théo FIDRY (theofidry)
|
||||
@ -122,7 +123,6 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Florian Lonqueu-Brochard (florianlb)
|
||||
- Sebastiaan Stok (sstok)
|
||||
- Stefano Sala (stefano.sala)
|
||||
- Yonel Ceruto González (yonelceruto)
|
||||
- Evgeniy (ewgraf)
|
||||
- Juti Noppornpitak (shiroyuki)
|
||||
- Tigran Azatyan (tigranazatyan)
|
||||
@ -157,6 +157,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Amal Raghav (kertz)
|
||||
- Jonathan Ingram (jonathaningram)
|
||||
- Artur Kotyrba
|
||||
- David Maicher (dmaicher)
|
||||
- jeremyFreeAgent (Jérémy Romey) (jeremyfreeagent)
|
||||
- James Halsall (jaitsu)
|
||||
- Warnar Boekkooi (boekkooi)
|
||||
@ -166,6 +167,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Possum
|
||||
- Dorian Villet (gnutix)
|
||||
- Richard Miller (mr_r_miller)
|
||||
- Julien Falque (julienfalque)
|
||||
- Mario A. Alvarez Garcia (nomack84)
|
||||
- Dennis Benkert (denderello)
|
||||
- Benjamin Dulau (dbenjamin)
|
||||
@ -180,7 +182,6 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Daniel Espendiller
|
||||
- sun (sun)
|
||||
- Larry Garfield (crell)
|
||||
- Julien Falque (julienfalque)
|
||||
- Martin Schuhfuß (usefulthink)
|
||||
- apetitpa
|
||||
- Matthieu Bontemps (mbontemps)
|
||||
@ -203,6 +204,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Tom Van Looy (tvlooy)
|
||||
- Sven Paulus (subsven)
|
||||
- Rui Marinho (ruimarinho)
|
||||
- Marek Štípek (maryo)
|
||||
- SpacePossum
|
||||
- Eugene Wissner
|
||||
- Julien Brochet (mewt)
|
||||
@ -217,7 +219,6 @@ Symfony is the result of the work of many people who made the code better
|
||||
- julien pauli (jpauli)
|
||||
- Lorenz Schori
|
||||
- Sébastien Lavoie (lavoiesl)
|
||||
- David Maicher (dmaicher)
|
||||
- Francois Zaninotto
|
||||
- Alexander Kotynia (olden)
|
||||
- Daniel Tschinder
|
||||
@ -254,6 +255,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Albert Casademont (acasademont)
|
||||
- Jhonny Lidfors (jhonne)
|
||||
- Diego Agulló (aeoris)
|
||||
- Andreas Schempp (aschempp)
|
||||
- jdhoek
|
||||
- Pavel Batanov (scaytrase)
|
||||
- Nikita Konstantinov
|
||||
@ -272,8 +274,8 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Michael Holm (hollo)
|
||||
- Marc Weistroff (futurecat)
|
||||
- Christian Schmidt
|
||||
- Marek Štípek (maryo)
|
||||
- Hidde Wieringa (hiddewie)
|
||||
- Chad Sikorra (chadsikorra)
|
||||
- Jordan Samouh (jordansamouh)
|
||||
- Chris Smith (cs278)
|
||||
- Florian Klein (docteurklein)
|
||||
@ -303,10 +305,10 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Francesc Rosàs (frosas)
|
||||
- Massimiliano Arione (garak)
|
||||
- Julien Galenski (ruian)
|
||||
- Andreas Schempp (aschempp)
|
||||
- Bongiraud Dominique
|
||||
- janschoenherr
|
||||
- Thomas Schulz (king2500)
|
||||
- Dariusz Rumiński
|
||||
- Berny Cantos (xphere81)
|
||||
- Ricard Clau (ricardclau)
|
||||
- Mark Challoner (markchalloner)
|
||||
@ -385,7 +387,6 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Christophe L. (christophelau)
|
||||
- Anthon Pang (robocoder)
|
||||
- Emanuele Gaspari (inmarelibero)
|
||||
- Dariusz Rumiński
|
||||
- Sébastien Santoro (dereckson)
|
||||
- Brian King
|
||||
- Michel Salib (michelsalib)
|
||||
@ -402,6 +403,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Jan Rosier (rosier)
|
||||
- Thomas Royer (cydonia7)
|
||||
- Josip Kruslin
|
||||
- Asmir Mustafic (goetas)
|
||||
- vagrant
|
||||
- EdgarPE
|
||||
- Florian Pfitzer (marmelatze)
|
||||
@ -420,7 +422,6 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Marcin Sikoń (marphi)
|
||||
- Dominik Zogg (dominik.zogg)
|
||||
- Marek Pietrzak
|
||||
- Chad Sikorra (chadsikorra)
|
||||
- franek (franek)
|
||||
- Christian Wahler
|
||||
- Gintautas Miselis
|
||||
@ -544,7 +545,6 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Andre Rømcke (andrerom)
|
||||
- Nahuel Cuesta (ncuesta)
|
||||
- Chris Boden (cboden)
|
||||
- Asmir Mustafic (goetas)
|
||||
- Stefan Gehrig (sgehrig)
|
||||
- Hany el-Kerdany
|
||||
- Wang Jingyu
|
||||
@ -582,6 +582,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Sergey Kolodyazhnyy (skolodyazhnyy)
|
||||
- umpirski
|
||||
- Denis Brumann (dbrumann)
|
||||
- Michael Babker (mbabker)
|
||||
- Quentin de Longraye (quentinus95)
|
||||
- Chris Heng (gigablah)
|
||||
- Richard Bradley
|
||||
@ -629,6 +630,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- twifty
|
||||
- Indra Gunawan (guind)
|
||||
- Peter Ward
|
||||
- insekticid
|
||||
- Julien DIDIER (juliendidier)
|
||||
- Dominik Ritter (dritter)
|
||||
- Sebastian Grodzicki (sgrodzicki)
|
||||
@ -745,6 +747,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Jan Kramer (jankramer)
|
||||
- abdul malik ikhsan (samsonasik)
|
||||
- Henry Snoek (snoek09)
|
||||
- Jérémy M (th3mouk)
|
||||
- Simone Di Maulo (toretto460)
|
||||
- Christian Morgan
|
||||
- Alexander Miehe (engerim)
|
||||
@ -761,6 +764,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Douglas Reith (douglas_reith)
|
||||
- Harry Walter (haswalt)
|
||||
- Johnson Page (jwpage)
|
||||
- Ruben Gonzalez (rubenruateltek)
|
||||
- Michael Roterman (wtfzdotnet)
|
||||
- Arno Geurts
|
||||
- Adán Lobato (adanlobato)
|
||||
@ -886,6 +890,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Eddie Jaoude
|
||||
- Antanas Arvasevicius
|
||||
- Haritz Iturbe (hizai)
|
||||
- Baptiste Meyer (meyerbaptiste)
|
||||
- Nerijus Arlauskas (nercury)
|
||||
- SPolischook
|
||||
- Diego Sapriza
|
||||
@ -914,6 +919,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Jeremy Bush
|
||||
- wizhippo
|
||||
- Viacheslav Sychov
|
||||
- Tyson Andre
|
||||
- Carlos Ortega Huetos
|
||||
- rpg600
|
||||
- Péter Buri (burci)
|
||||
@ -1014,6 +1020,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Conrad Kleinespel
|
||||
- Sebastian Utz
|
||||
- Adrien Gallou (agallou)
|
||||
- Maks Rafalko (bornfree)
|
||||
- Karol Sójko (karolsojko)
|
||||
- Grzegorz Zdanowski (kiler129)
|
||||
- sl_toto (sl_toto)
|
||||
@ -1048,7 +1055,6 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Kim Laï Trinh
|
||||
- Jason Desrosiers
|
||||
- m.chwedziak
|
||||
- insekticid
|
||||
- Philip Frank
|
||||
- Lance McNearney
|
||||
- Giorgio Premi
|
||||
@ -1058,6 +1064,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Alberto Pirovano (geezmo)
|
||||
- Pete Mitchell (peterjmit)
|
||||
- Tom Corrigan (tomcorrigan)
|
||||
- adev
|
||||
- Luis Galeas
|
||||
- Martin Pärtel
|
||||
- George Mponos (gmponos)
|
||||
@ -1226,6 +1233,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Romain Dorgueil
|
||||
- Grayson Koonce (breerly)
|
||||
- Fabien LUCAS (flucas2)
|
||||
- Indra Gunawan (indragunawan)
|
||||
- Karim Cassam Chenaï (ka)
|
||||
- Nicolas Bastien (nicolas_bastien)
|
||||
- Denis (yethee)
|
||||
@ -1273,6 +1281,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Daan van Renterghem
|
||||
- Nicole Cordes
|
||||
- Bram Van der Sype (brammm)
|
||||
- Christopher Hertel (chertel)
|
||||
- Guile (guile)
|
||||
- Julien Moulin (lizjulien)
|
||||
- Mauro Foti (skler)
|
||||
@ -1291,6 +1300,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Johann Pardanaud
|
||||
- Trevor Suarez
|
||||
- gedrox
|
||||
- Alan Bondarchuk
|
||||
- dropfen
|
||||
- Andrey Chernykh
|
||||
- Edvinas Klovas
|
||||
@ -1303,6 +1313,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- bertillon
|
||||
- Bertalan Attila
|
||||
- Yannick Bensacq (cibou)
|
||||
- Gawain Lynch (gawain)
|
||||
- Luca Genuzio (genuzio)
|
||||
- Hans Nilsson (hansnilsson)
|
||||
- Andrew Marcinkevičius (ifdattic)
|
||||
@ -1312,7 +1323,6 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Dan Patrick (mdpatrick)
|
||||
- Rares Vlaseanu (raresvla)
|
||||
- tante kinast (tante)
|
||||
- Jérémy M (th3mouk)
|
||||
- Vincent LEFORT (vlefort)
|
||||
- Sadicov Vladimir (xtech)
|
||||
- Kevin EMO (zarcox)
|
||||
@ -1336,7 +1346,6 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Jonny Schmid (schmidjon)
|
||||
- Götz Gottwald
|
||||
- Veres Lajos
|
||||
- Michael Babker
|
||||
- grifx
|
||||
- Robert Campbell
|
||||
- Matt Lehner
|
||||
@ -1415,9 +1424,11 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Yanick Witschi
|
||||
- Ondrej Mirtes
|
||||
- akimsko
|
||||
- Ben Scott
|
||||
- Youpie
|
||||
- srsbiz
|
||||
- Taylan Kasap
|
||||
- Michael Orlitzky
|
||||
- Nicolas A. Bérard-Nault
|
||||
- Saem Ghani
|
||||
- Stefan Oderbolz
|
||||
@ -1430,6 +1441,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Ben
|
||||
- Evgeniy Tetenchuk
|
||||
- dasmfm
|
||||
- Mathias Geat
|
||||
- Arnaud Buathier (arnapou)
|
||||
- chesteroni (chesteroni)
|
||||
- Mauricio Lopez (diaspar)
|
||||
@ -1516,6 +1528,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Abdulkadir N. A.
|
||||
- Yevgen Kovalienia
|
||||
- Lebnik
|
||||
- Ondřej Führer
|
||||
- Sema
|
||||
- Elan Ruusamäe
|
||||
- Thorsten Hallwas
|
||||
@ -1568,6 +1581,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Bill Hance (billhance)
|
||||
- Bernd Matzner (bmatzner)
|
||||
- Bram Tweedegolf (bram_tweedegolf)
|
||||
- Brandon Kelly (brandonkelly)
|
||||
- Choong Wei Tjeng (choonge)
|
||||
- Kousuke Ebihara (co3k)
|
||||
- Loïc Vernet (coil)
|
||||
@ -1675,6 +1689,7 @@ Symfony is the result of the work of many people who made the code better
|
||||
- Andrew Carter (andrewcarteruk)
|
||||
- Adam Elsodaney (archfizz)
|
||||
- Daniel Kolvik (dkvk)
|
||||
- Marc Lemay (flug)
|
||||
- Jeroen De Dauw (jeroendedauw)
|
||||
- Maxime COLIN (maximecolin)
|
||||
- Muharrem Demirci (mdemirci)
|
||||
|
2
phpunit
2
phpunit
@ -7,7 +7,7 @@ if (!file_exists(__DIR__.'/vendor/symfony/phpunit-bridge/bin/simple-phpunit')) {
|
||||
echo "Unable to find the `simple-phpunit` script in `vendor/symfony/phpunit-bridge/bin/`.\nPlease run `composer update` before running this command.\n";
|
||||
exit(1);
|
||||
}
|
||||
if (PHP_VERSION_ID >= 70000 && !getenv('SYMFONY_PHPUNIT_VERSION')) {
|
||||
if (\PHP_VERSION_ID >= 70000 && !getenv('SYMFONY_PHPUNIT_VERSION')) {
|
||||
putenv('SYMFONY_PHPUNIT_VERSION=6.0');
|
||||
}
|
||||
putenv('SYMFONY_PHPUNIT_DIR='.__DIR__.'/.phpunit');
|
||||
|
@ -156,14 +156,20 @@ EOF
|
||||
throw new \UnexpectedValueException('Unsupported callback type');
|
||||
}
|
||||
|
||||
// filter out context/environment args
|
||||
$args = array_filter($refl->getParameters(), function ($param) use ($entity) {
|
||||
if ($entity->needsContext() && $param->getName() === 'context') {
|
||||
return false;
|
||||
}
|
||||
$args = $refl->getParameters();
|
||||
|
||||
return !$param->getClass() || $param->getClass()->getName() !== 'Twig_Environment';
|
||||
});
|
||||
// filter out context/environment args
|
||||
if ($entity->needsEnvironment()) {
|
||||
array_shift($args);
|
||||
}
|
||||
if ($entity->needsContext()) {
|
||||
array_shift($args);
|
||||
}
|
||||
|
||||
if ($type === 'filters') {
|
||||
// remove the value the filter is applied on
|
||||
array_shift($args);
|
||||
}
|
||||
|
||||
// format args
|
||||
$args = array_map(function ($param) {
|
||||
@ -174,11 +180,6 @@ EOF
|
||||
return $param->getName();
|
||||
}, $args);
|
||||
|
||||
if ($type === 'filters') {
|
||||
// remove the value the filter is applied on
|
||||
array_shift($args);
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ if ($this->env->isDebug()) {
|
||||
|
||||
EOTXT;
|
||||
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
$expected = preg_replace('/%(.*?)%/', '($context["$1"] ?? null)', $expected);
|
||||
} else {
|
||||
$expected = preg_replace('/%(.*?)%/', '(isset($context["$1"]) ? $context["$1"] : null)', $expected);
|
||||
|
@ -67,7 +67,7 @@ class FormThemeTest extends TestCase
|
||||
|
||||
protected function getVariableGetter($name)
|
||||
{
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
return sprintf('($context["%s"] ?? null)', $name, $name);
|
||||
}
|
||||
|
||||
|
@ -264,7 +264,7 @@ class SearchAndRenderBlockNodeTest extends TestCase
|
||||
|
||||
protected function getVariableGetter($name)
|
||||
{
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
return sprintf('($context["%s"] ?? null)', $name, $name);
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ class TransNodeTest extends TestCase
|
||||
|
||||
protected function getVariableGetterWithoutStrictCheck($name)
|
||||
{
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
return sprintf('($context["%s"] ?? null)', $name, $name);
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ class TransNodeTest extends TestCase
|
||||
return sprintf('(isset($context["%s"]) || array_key_exists("%s", $context) ? $context["%s"] : (function () { throw new Twig_Error_Runtime(\'Variable "%s" does not exist.\', 0, $this->getSourceContext()); })())', $name, $name, $name, $name);
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
return sprintf('($context["%s"] ?? $this->getContext($context, "%s"))', $name, $name, $name);
|
||||
}
|
||||
|
||||
|
@ -11,9 +11,12 @@
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface;
|
||||
use Symfony\Component\Cache\Adapter\TraceableAdapter;
|
||||
use Symfony\Component\Cache\Adapter\TraceableTagAwareAdapter;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
@ -34,17 +37,30 @@ class CacheCollectorPass implements CompilerPassInterface
|
||||
|
||||
$collectorDefinition = $container->getDefinition('data_collector.cache');
|
||||
foreach ($container->findTaggedServiceIds('cache.pool') as $id => $attributes) {
|
||||
if ($container->getDefinition($id)->isAbstract()) {
|
||||
$definition = $container->getDefinition($id);
|
||||
if ($definition->isAbstract()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$container->register($id.'.recorder', TraceableAdapter::class)
|
||||
->setDecoratedService($id)
|
||||
->addArgument(new Reference($id.'.recorder.inner'))
|
||||
->setPublic(false);
|
||||
$recorder = new Definition(is_subclass_of($definition->getClass(), TagAwareAdapterInterface::class) ? TraceableTagAwareAdapter::class : TraceableAdapter::class);
|
||||
$recorder->setTags($definition->getTags());
|
||||
$recorder->setPublic($definition->isPublic());
|
||||
$recorder->setArguments(array(new Reference($innerId = $id.'.recorder_inner')));
|
||||
|
||||
$definition->setTags(array());
|
||||
$definition->setPublic(false);
|
||||
|
||||
if ($types = $definition->getAutowiringTypes(false)) {
|
||||
$recorder->setAutowiringTypes($types);
|
||||
$definition->setAutowiringTypes(array());
|
||||
}
|
||||
|
||||
$container->setDefinition($innerId, $definition);
|
||||
$container->setDefinition($id, $recorder);
|
||||
|
||||
// Tell the collector to add the new instance
|
||||
$collectorDefinition->addMethodCall('addInstance', array($id, new Reference($id)));
|
||||
$collectorDefinition->setPublic(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ class FrameworkBundle extends Bundle
|
||||
$container->addCompilerPass(new UnusedTagsPass(), PassConfig::TYPE_AFTER_REMOVING);
|
||||
$container->addCompilerPass(new ContainerBuilderDebugDumpPass(), PassConfig::TYPE_BEFORE_REMOVING, -255);
|
||||
$this->addCompilerPassIfExists($container, ConfigCachePass::class);
|
||||
$container->addCompilerPass(new CacheCollectorPass());
|
||||
$container->addCompilerPass(new CacheCollectorPass(), PassConfig::TYPE_BEFORE_REMOVING);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,8 @@
|
||||
<services>
|
||||
<defaults public="false" />
|
||||
|
||||
<!-- DataCollector -->
|
||||
<service id="data_collector.cache" class="Symfony\Component\Cache\DataCollector\CacheDataCollector">
|
||||
<!-- DataCollector (public to prevent inlining, made private in CacheCollectorPass) -->
|
||||
<service id="data_collector.cache" class="Symfony\Component\Cache\DataCollector\CacheDataCollector" public="true">
|
||||
<tag name="data_collector" template="@WebProfiler/Collector/cache.html.twig" id="cache" priority="275" />
|
||||
</service>
|
||||
</services>
|
||||
|
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CacheCollectorPass;
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
use Symfony\Component\Cache\Adapter\TagAwareAdapter;
|
||||
use Symfony\Component\Cache\Adapter\TraceableAdapter;
|
||||
use Symfony\Component\Cache\Adapter\TraceableTagAwareAdapter;
|
||||
use Symfony\Component\Cache\DataCollector\CacheDataCollector;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
class CacheCollectorPassTest extends TestCase
|
||||
{
|
||||
public function testProcess()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container
|
||||
->register('fs', FilesystemAdapter::class)
|
||||
->addTag('cache.pool');
|
||||
$container
|
||||
->register('tagged_fs', TagAwareAdapter::class)
|
||||
->addArgument(new Reference('fs'))
|
||||
->addTag('cache.pool');
|
||||
|
||||
$collector = $container->register('data_collector.cache', CacheDataCollector::class);
|
||||
(new CacheCollectorPass())->process($container);
|
||||
|
||||
$this->assertEquals(array(
|
||||
array('addInstance', array('fs', new Reference('fs'))),
|
||||
array('addInstance', array('tagged_fs', new Reference('tagged_fs'))),
|
||||
), $collector->getMethodCalls());
|
||||
|
||||
$this->assertSame(TraceableAdapter::class, $container->findDefinition('fs')->getClass());
|
||||
$this->assertSame(TraceableTagAwareAdapter::class, $container->getDefinition('tagged_fs')->getClass());
|
||||
$this->assertFalse($collector->isPublic(), 'The "data_collector.cache" should be private after processing');
|
||||
}
|
||||
}
|
@ -85,7 +85,7 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface
|
||||
foreach ($files as $file) {
|
||||
$this->parseTokens(token_get_all(file_get_contents($file)), $catalog);
|
||||
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
// PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098
|
||||
gc_mem_caches();
|
||||
}
|
||||
|
@ -478,6 +478,11 @@
|
||||
addEventListener(toggles[i], 'click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if ('' !== window.getSelection().toString()) {
|
||||
/* Don't do anything on text selection */
|
||||
return;
|
||||
}
|
||||
|
||||
var toggle = e.target || e.srcElement;
|
||||
|
||||
/* needed because when the toggle contains HTML contents, user can click */
|
||||
@ -507,6 +512,14 @@
|
||||
var altContent = toggle.getAttribute('data-toggle-alt-content');
|
||||
toggle.innerHTML = currentContent !== altContent ? altContent : originalContent;
|
||||
});
|
||||
|
||||
/* Prevents from disallowing clicks on links inside toggles */
|
||||
var toggleLinks = document.querySelectorAll('.sf-toggle a');
|
||||
for (var i = 0; i < toggleLinks.length; i++) {
|
||||
addEventListener(toggleLinks[i], 'click', function(e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -89,7 +89,6 @@ header .container { display: flex; justify-content: space-between; }
|
||||
.exception-illustration { flex-basis: 111px; flex-shrink: 0; height: 66px; margin-left: 15px; opacity: .7; }
|
||||
|
||||
.trace + .trace { margin-top: 30px; }
|
||||
.trace-head { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }
|
||||
.trace-head .trace-class { color: #222; font-size: 18px; font-weight: bold; line-height: 1.3; margin: 0; position: relative; }
|
||||
.trace-head .trace-namespace { color: #999; display: block; font-size: 13px; }
|
||||
.trace-head .icon { position: absolute; right: 0; top: 0; }
|
||||
|
@ -478,6 +478,11 @@
|
||||
addEventListener(toggles[i], 'click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if ('' !== window.getSelection().toString()) {
|
||||
/* Don't do anything on text selection */
|
||||
return;
|
||||
}
|
||||
|
||||
var toggle = e.target || e.srcElement;
|
||||
|
||||
/* needed because when the toggle contains HTML contents, user can click */
|
||||
@ -508,6 +513,14 @@
|
||||
toggle.innerHTML = currentContent !== altContent ? altContent : originalContent;
|
||||
});
|
||||
}
|
||||
|
||||
/* Prevents from disallowing clicks on links inside toggles */
|
||||
var toggleLinks = document.querySelectorAll('.sf-toggle a');
|
||||
for (var i = 0; i < toggleLinks.length; i++) {
|
||||
addEventListener(toggleLinks[i], 'click', function(e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
@ -22,7 +22,7 @@ use Psr\Cache\CacheItemInterface;
|
||||
*/
|
||||
class TraceableAdapter implements AdapterInterface
|
||||
{
|
||||
private $pool;
|
||||
protected $pool;
|
||||
private $calls = array();
|
||||
|
||||
public function __construct(AdapterInterface $pool)
|
||||
@ -107,7 +107,7 @@ class TraceableAdapter implements AdapterInterface
|
||||
*/
|
||||
public function getItems(array $keys = array())
|
||||
{
|
||||
$event = $this->start(__FUNCTION__, $keys);
|
||||
$event = $this->start(__FUNCTION__);
|
||||
try {
|
||||
$result = $this->pool->getItems($keys);
|
||||
} finally {
|
||||
@ -177,7 +177,7 @@ class TraceableAdapter implements AdapterInterface
|
||||
}
|
||||
}
|
||||
|
||||
private function start($name)
|
||||
protected function start($name)
|
||||
{
|
||||
$this->calls[] = $event = new TraceableAdapterEvent();
|
||||
$event->name = $name;
|
||||
|
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
/**
|
||||
* @author Robin Chalas <robin.chalas@gmail.com>
|
||||
*/
|
||||
class TraceableTagAwareAdapter extends TraceableAdapter implements TagAwareAdapterInterface
|
||||
{
|
||||
public function __construct(TagAwareAdapterInterface $pool)
|
||||
{
|
||||
parent::__construct($pool);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function invalidateTags(array $tags)
|
||||
{
|
||||
$event = $this->start(__FUNCTION__);
|
||||
try {
|
||||
return $event->result = $this->pool->invalidateTags($tags);
|
||||
} finally {
|
||||
$event->end = microtime(true);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
use Symfony\Component\Cache\Adapter\TagAwareAdapter;
|
||||
use Symfony\Component\Cache\Adapter\TraceableTagAwareAdapter;
|
||||
|
||||
class TraceableTagAwareAdapterTest extends TraceableAdapterTest
|
||||
{
|
||||
public function testInvalidateTags()
|
||||
{
|
||||
$pool = new TraceableTagAwareAdapter(new TagAwareAdapter(new FilesystemAdapter()));
|
||||
$pool->invalidateTags(array('foo'));
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(1, $calls);
|
||||
|
||||
$call = $calls[0];
|
||||
$this->assertSame('invalidateTags', $call->name);
|
||||
$this->assertSame(0, $call->hits);
|
||||
$this->assertSame(0, $call->misses);
|
||||
$this->assertNotEmpty($call->start);
|
||||
$this->assertNotEmpty($call->end);
|
||||
}
|
||||
}
|
@ -126,6 +126,6 @@ EOF;
|
||||
*/
|
||||
private function initialize()
|
||||
{
|
||||
$this->values = @(include $this->file) ?: array();
|
||||
$this->values = file_exists($this->file) ? (include $this->file ?: array()) : array();
|
||||
}
|
||||
}
|
||||
|
@ -262,7 +262,7 @@ REGEX;
|
||||
|
||||
$output .= self::compressCode($rawChunk);
|
||||
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
// PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098
|
||||
unset($tokens, $rawChunk);
|
||||
gc_mem_caches();
|
||||
|
@ -68,7 +68,7 @@ class ClassMapGenerator
|
||||
|
||||
$classes = self::findClasses($path);
|
||||
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
// PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098
|
||||
gc_mem_caches();
|
||||
}
|
||||
|
@ -83,13 +83,18 @@ abstract class FileLoader extends Loader
|
||||
*/
|
||||
public function import($resource, $type = null, $ignoreErrors = false, $sourceResource = null)
|
||||
{
|
||||
if (is_string($resource) && false !== strpbrk($resource, '*?{[')) {
|
||||
if (is_string($resource) && strlen($resource) !== $i = strcspn($resource, '*?{[')) {
|
||||
$ret = array();
|
||||
foreach ($this->glob($resource, false, $_, true) as $path => $info) {
|
||||
$ret[] = $this->doImport($path, $type, $ignoreErrors, $sourceResource);
|
||||
$isSubpath = 0 !== $i && false !== strpos(substr($resource, 0, $i), '/');
|
||||
foreach ($this->glob($resource, false, $_, $ignoreErrors || !$isSubpath) as $path => $info) {
|
||||
if (null !== $res = $this->doImport($path, $type, $ignoreErrors, $sourceResource)) {
|
||||
$ret[] = $res;
|
||||
}
|
||||
$isSubpath = true;
|
||||
}
|
||||
if ($ret) {
|
||||
return count($ret) > 1 ? $ret : $ret[0];
|
||||
|
||||
if ($isSubpath) {
|
||||
return isset($ret[1]) ? $ret : (isset($ret[0]) ? $ret[0] : null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,7 +109,7 @@ abstract class FileLoader extends Loader
|
||||
if (strlen($pattern) === $i = strcspn($pattern, '*?{[')) {
|
||||
$prefix = $pattern;
|
||||
$pattern = '';
|
||||
} elseif (0 === $i) {
|
||||
} elseif (0 === $i || false === strpos(substr($pattern, 0, $i), '/')) {
|
||||
$prefix = '.';
|
||||
$pattern = '/'.$pattern;
|
||||
} else {
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace Symfony\Component\Config\Tests\Loader;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Config\FileLocator;
|
||||
use Symfony\Component\Config\Loader\FileLoader;
|
||||
use Symfony\Component\Config\Loader\LoaderResolver;
|
||||
|
||||
@ -74,6 +75,21 @@ class FileLoaderTest extends TestCase
|
||||
|
||||
$this->assertSame('[foo]', $loader->import('[foo]'));
|
||||
}
|
||||
|
||||
public function testImportWithNoGlobMatch()
|
||||
{
|
||||
$locatorMock = $this->getMockBuilder('Symfony\Component\Config\FileLocatorInterface')->getMock();
|
||||
$loader = new TestFileLoader($locatorMock);
|
||||
|
||||
$this->assertNull($loader->import('./*.abc'));
|
||||
}
|
||||
|
||||
public function testImportWithSimpleGlob()
|
||||
{
|
||||
$loader = new TestFileLoader(new FileLocator(__DIR__));
|
||||
|
||||
$this->assertSame(__FILE__, strtr($loader->import('FileLoaderTest.*'), '/', DIRECTORY_SEPARATOR));
|
||||
}
|
||||
}
|
||||
|
||||
class TestFileLoader extends FileLoader
|
||||
|
@ -316,7 +316,6 @@ EOF;
|
||||
.exception-illustration { flex-basis: 111px; flex-shrink: 0; height: 66px; margin-left: 15px; opacity: .7; }
|
||||
|
||||
.trace + .trace { margin-top: 30px; }
|
||||
.trace-head { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }
|
||||
.trace-head .trace-class { color: #222; font-size: 18px; font-weight: bold; line-height: 1.3; margin: 0; position: relative; }
|
||||
|
||||
.trace-message { font-size: 14px; font-weight: normal; margin: .5em 0 0; }
|
||||
|
@ -61,7 +61,7 @@ class DebugClassLoaderTest extends TestCase
|
||||
|
||||
public function testUnsilencing()
|
||||
{
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
$this->markTestSkipped('PHP7 throws exceptions, unsilencing is not required anymore.');
|
||||
}
|
||||
if (defined('HHVM_VERSION')) {
|
||||
@ -109,7 +109,7 @@ class DebugClassLoaderTest extends TestCase
|
||||
} catch (\ErrorException $exception) {
|
||||
// if an exception is thrown, the test passed
|
||||
$this->assertStringStartsWith(__FILE__, $exception->getFile());
|
||||
if (PHP_VERSION_ID < 70000) {
|
||||
if (\PHP_VERSION_ID < 70000) {
|
||||
$this->assertRegExp('/^Runtime Notice: Declaration/', $exception->getMessage());
|
||||
$this->assertEquals(E_STRICT, $exception->getSeverity());
|
||||
} else {
|
||||
@ -245,7 +245,7 @@ class DebugClassLoaderTest extends TestCase
|
||||
|
||||
public function testReservedForPhp7()
|
||||
{
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
$this->markTestSkipped('PHP7 already prevents using reserved names.');
|
||||
}
|
||||
|
||||
|
@ -44,9 +44,27 @@ class AutowireExceptionPass implements CompilerPassInterface
|
||||
$this->inlineServicePass = null;
|
||||
|
||||
foreach ($exceptions as $exception) {
|
||||
if ($container->hasDefinition($exception->getServiceId()) || in_array($exception->getServiceId(), $inlinedIds)) {
|
||||
if ($this->doesServiceExistInTheContainer($exception->getServiceId(), $container, $inlinedIds)) {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function doesServiceExistInTheContainer($serviceId, ContainerBuilder $container, array $inlinedIds)
|
||||
{
|
||||
if ($container->hasDefinition($serviceId)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// was the service inlined? Of so, does its parent service exist?
|
||||
if (isset($inlinedIds[$serviceId])) {
|
||||
foreach ($inlinedIds[$serviceId] as $parentId) {
|
||||
if ($this->doesServiceExistInTheContainer($parentId, $container, $inlinedIds)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ class AutowirePass extends AbstractRecursivePass
|
||||
private function doProcessValue($value, $isRoot = false)
|
||||
{
|
||||
if ($value instanceof TypedReference) {
|
||||
if ($ref = $this->getAutowiredReference($value)) {
|
||||
if ($ref = $this->getAutowiredReference($value, $value->getRequiringClass() ? sprintf('for "%s" in "%s"', $value->getType(), $value->getRequiringClass()) : '')) {
|
||||
return $ref;
|
||||
}
|
||||
$this->container->log($this, $this->createTypeNotFoundMessage($value, 'it'));
|
||||
@ -133,7 +133,13 @@ class AutowirePass extends AbstractRecursivePass
|
||||
$autowiredMethods = $this->getMethodsToAutowire($reflectionClass);
|
||||
$methodCalls = $value->getMethodCalls();
|
||||
|
||||
if ($constructor = $this->getConstructor($value, false)) {
|
||||
try {
|
||||
$constructor = $this->getConstructor($value, false);
|
||||
} catch (RuntimeException $e) {
|
||||
throw new AutowiringFailedException($this->currentId, $e->getMessage(), 0, $e);
|
||||
}
|
||||
|
||||
if ($constructor) {
|
||||
array_unshift($methodCalls, array($constructor, $value->getArguments()));
|
||||
}
|
||||
|
||||
@ -242,7 +248,7 @@ class AutowirePass extends AbstractRecursivePass
|
||||
*
|
||||
* @return array The autowired arguments
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @throws AutowiringFailedException
|
||||
*/
|
||||
private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, array $arguments)
|
||||
{
|
||||
@ -276,7 +282,7 @@ class AutowirePass extends AbstractRecursivePass
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$value = $this->getAutowiredReference($ref = new TypedReference($type, $type, !$parameter->isOptional() ? $class : ''))) {
|
||||
if (!$value = $this->getAutowiredReference($ref = new TypedReference($type, $type, !$parameter->isOptional() ? $class : ''), 'for '.sprintf('argument "$%s" of method "%s()"', $parameter->name, $class.'::'.$method))) {
|
||||
$failureMessage = $this->createTypeNotFoundMessage($ref, sprintf('argument "$%s" of method "%s()"', $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method));
|
||||
|
||||
if ($parameter->isDefaultValueAvailable()) {
|
||||
@ -310,7 +316,7 @@ class AutowirePass extends AbstractRecursivePass
|
||||
/**
|
||||
* @return TypedReference|null A reference to the service matching the given type, if any
|
||||
*/
|
||||
private function getAutowiredReference(TypedReference $reference)
|
||||
private function getAutowiredReference(TypedReference $reference, $deprecationMessage)
|
||||
{
|
||||
$this->lastFailure = null;
|
||||
$type = $reference->getType();
|
||||
@ -328,7 +334,14 @@ class AutowirePass extends AbstractRecursivePass
|
||||
}
|
||||
|
||||
if (isset($this->types[$type])) {
|
||||
@trigger_error(sprintf('Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won\'t be supported in version 4.0. You should %s the "%s" service to "%s" instead.', isset($this->types[$this->types[$type]]) ? 'alias' : 'rename (or alias)', $this->types[$type], $type), E_USER_DEPRECATED);
|
||||
$message = 'Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won\'t be supported in version 4.0.';
|
||||
if ($aliasSuggestion = $this->getAliasesSuggestionForType($type = $reference->getType(), $deprecationMessage)) {
|
||||
$message .= ' '.$aliasSuggestion;
|
||||
} else {
|
||||
$message .= sprintf(' You should %s the "%s" service to "%s" instead.', isset($this->types[$this->types[$type]]) ? 'alias' : 'rename (or alias)', $this->types[$type], $type);
|
||||
}
|
||||
|
||||
@trigger_error($message, E_USER_DEPRECATED);
|
||||
|
||||
return new TypedReference($this->types[$type], $type);
|
||||
}
|
||||
@ -484,25 +497,9 @@ class AutowirePass extends AbstractRecursivePass
|
||||
|
||||
private function createTypeAlternatives(TypedReference $reference)
|
||||
{
|
||||
$type = $reference->getType();
|
||||
$aliases = array();
|
||||
foreach (class_parents($type) + class_implements($type) as $parent) {
|
||||
if ($this->container->has($parent) && !$this->container->findDefinition($parent)->isAbstract()) {
|
||||
$aliases[] = $parent;
|
||||
}
|
||||
}
|
||||
|
||||
if (1 < $len = count($aliases)) {
|
||||
$message = ' Try changing the type-hint to one of its parents: ';
|
||||
for ($i = 0, --$len; $i < $len; ++$i) {
|
||||
$message .= sprintf('%s "%s", ', class_exists($aliases[$i], false) ? 'class' : 'interface', $aliases[$i]);
|
||||
}
|
||||
$message .= sprintf('or %s "%s".', class_exists($aliases[$i], false) ? 'class' : 'interface', $aliases[$i]);
|
||||
|
||||
return $message;
|
||||
}
|
||||
if ($aliases) {
|
||||
return sprintf(' Try changing the type-hint to "%s" instead.', $aliases[0]);
|
||||
// try suggesting available aliases first
|
||||
if ($message = $this->getAliasesSuggestionForType($type = $reference->getType())) {
|
||||
return ' '.$message;
|
||||
}
|
||||
|
||||
if (isset($this->ambiguousServiceTypes[$type])) {
|
||||
@ -542,4 +539,29 @@ class AutowirePass extends AbstractRecursivePass
|
||||
|
||||
return $methodArgumentsMetadata;
|
||||
}
|
||||
|
||||
private function getAliasesSuggestionForType($type, $extraContext = null)
|
||||
{
|
||||
$aliases = array();
|
||||
foreach (class_parents($type) + class_implements($type) as $parent) {
|
||||
if ($this->container->has($parent) && !$this->container->findDefinition($parent)->isAbstract()) {
|
||||
$aliases[] = $parent;
|
||||
}
|
||||
}
|
||||
|
||||
$extraContext = $extraContext ? ' '.$extraContext : '';
|
||||
if (1 < $len = count($aliases)) {
|
||||
$message = sprintf('Try changing the type-hint%s to one of its parents: ', $extraContext);
|
||||
for ($i = 0, --$len; $i < $len; ++$i) {
|
||||
$message .= sprintf('%s "%s", ', class_exists($aliases[$i], false) ? 'class' : 'interface', $aliases[$i]);
|
||||
}
|
||||
$message .= sprintf('or %s "%s".', class_exists($aliases[$i], false) ? 'class' : 'interface', $aliases[$i]);
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
if ($aliases) {
|
||||
return sprintf('Try changing the type-hint%s to "%s" instead.', $extraContext, $aliases[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,9 @@ class InlineServiceDefinitionsPass extends AbstractRecursivePass implements Repe
|
||||
/**
|
||||
* Returns an array of all services inlined by this pass.
|
||||
*
|
||||
* @return array Service id strings
|
||||
* The key is the inlined service id and its value is the list of services it was inlined into.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getInlinedServiceIds()
|
||||
{
|
||||
@ -57,7 +59,7 @@ class InlineServiceDefinitionsPass extends AbstractRecursivePass implements Repe
|
||||
|
||||
if ($this->isInlineableDefinition($id, $definition, $this->container->getCompiler()->getServiceReferenceGraph())) {
|
||||
$this->container->log($this, sprintf('Inlined service "%s" to "%s".', $id, $this->currentId));
|
||||
$this->inlinedServiceIds[] = $id;
|
||||
$this->inlinedServiceIds[$id][] = $this->currentId;
|
||||
|
||||
if ($definition->isShared()) {
|
||||
return $definition;
|
||||
|
@ -18,7 +18,7 @@ class AutowiringFailedException extends RuntimeException
|
||||
{
|
||||
private $serviceId;
|
||||
|
||||
public function __construct($serviceId, $message = '', $code = 0, Exception $previous = null)
|
||||
public function __construct($serviceId, $message = '', $code = 0, \Exception $previous = null)
|
||||
{
|
||||
$this->serviceId = $serviceId;
|
||||
|
||||
|
@ -54,7 +54,7 @@ class AutowireExceptionPassTest extends TestCase
|
||||
$autowirePass = $this->getMockBuilder(AutowirePass::class)
|
||||
->getMock();
|
||||
|
||||
$autowireException = new AutowiringFailedException('foo_service_id', 'An autowiring exception message');
|
||||
$autowireException = new AutowiringFailedException('a_service', 'An autowiring exception message');
|
||||
$autowirePass->expects($this->any())
|
||||
->method('getAutowiringExceptions')
|
||||
->will($this->returnValue(array($autowireException)));
|
||||
@ -63,10 +63,16 @@ class AutowireExceptionPassTest extends TestCase
|
||||
->getMock();
|
||||
$inlinePass->expects($this->any())
|
||||
->method('getInlinedServiceIds')
|
||||
->will($this->returnValue(array('foo_service_id')));
|
||||
->will($this->returnValue(array(
|
||||
// a_service inlined into b_service
|
||||
'a_service' => array('b_service'),
|
||||
// b_service inlined into c_service
|
||||
'b_service' => array('c_service'),
|
||||
)));
|
||||
|
||||
// don't register the foo_service_id service
|
||||
$container = new ContainerBuilder();
|
||||
// ONLY register c_service in the final container
|
||||
$container->register('c_service', 'stdClass');
|
||||
|
||||
$pass = new AutowireExceptionPass($autowirePass, $inlinePass);
|
||||
|
||||
@ -78,6 +84,37 @@ class AutowireExceptionPassTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function testDoNotThrowExceptionIfServiceInlinedButRemoved()
|
||||
{
|
||||
$autowirePass = $this->getMockBuilder(AutowirePass::class)
|
||||
->getMock();
|
||||
|
||||
$autowireException = new AutowiringFailedException('a_service', 'An autowiring exception message');
|
||||
$autowirePass->expects($this->any())
|
||||
->method('getAutowiringExceptions')
|
||||
->will($this->returnValue(array($autowireException)));
|
||||
|
||||
$inlinePass = $this->getMockBuilder(InlineServiceDefinitionsPass::class)
|
||||
->getMock();
|
||||
$inlinePass->expects($this->any())
|
||||
->method('getInlinedServiceIds')
|
||||
->will($this->returnValue(array(
|
||||
// a_service inlined into b_service
|
||||
'a_service' => array('b_service'),
|
||||
// b_service inlined into c_service
|
||||
'b_service' => array('c_service'),
|
||||
)));
|
||||
|
||||
// do NOT register c_service in the container
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$pass = new AutowireExceptionPass($autowirePass, $inlinePass);
|
||||
|
||||
$pass->process($container);
|
||||
// mark the test as passed
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testNoExceptionIfServiceRemoved()
|
||||
{
|
||||
$autowirePass = $this->getMockBuilder(AutowirePass::class)
|
||||
|
@ -78,6 +78,28 @@ class AutowirePassTest extends TestCase
|
||||
$this->assertEquals(B::class, (string) $container->getDefinition('c')->getArgument(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @expectedDeprecation Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won't be supported in version 4.0. Try changing the type-hint for argument "$a" of method "Symfony\Component\DependencyInjection\Tests\Compiler\C::__construct()" to "Symfony\Component\DependencyInjection\Tests\Compiler\AInterface" instead.
|
||||
* @expectedExceptionInSymfony4 \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedExceptionMessageInSymfony4 Cannot autowire service "c": argument "$a" of method "Symfony\Component\DependencyInjection\Tests\Compiler\C::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\A" but no such service exists. You should maybe alias this class to the existing "Symfony\Component\DependencyInjection\Tests\Compiler\B" service.
|
||||
*/
|
||||
public function testProcessLegacyAutowireWithAvailableInterface()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container->setAlias(AInterface::class, B::class);
|
||||
$container->register(B::class);
|
||||
$cDefinition = $container->register('c', __NAMESPACE__.'\C');
|
||||
$cDefinition->setAutowired(true);
|
||||
|
||||
(new ResolveClassPass())->process($container);
|
||||
(new AutowirePass())->process($container);
|
||||
|
||||
$this->assertCount(1, $container->getDefinition('c')->getArguments());
|
||||
$this->assertEquals(B::class, (string) $container->getDefinition('c')->getArgument(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @expectedDeprecation Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won't be supported in version 4.0. You should alias the "Symfony\Component\DependencyInjection\Tests\Compiler\F" service to "Symfony\Component\DependencyInjection\Tests\Compiler\DInterface" instead.
|
||||
@ -151,7 +173,21 @@ class AutowirePassTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
|
||||
* @expectedExceptionMessage Unable to resolve service "private_service": constructor of class "Symfony\Component\DependencyInjection\Tests\Compiler\PrivateConstructor" must be public.
|
||||
*/
|
||||
public function testPrivateConstructorThrowsAutowireException()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container->autowire('private_service', __NAMESPACE__.'\PrivateConstructor');
|
||||
|
||||
$pass = new AutowirePass(true);
|
||||
$pass->process($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
|
||||
* @expectedExceptionMessage Cannot autowire service "a": argument "$collision" of method "Symfony\Component\DependencyInjection\Tests\Compiler\CannotBeAutowired::__construct()" references interface "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" but no such service exists. You should maybe alias this interface to one of these existing services: "c1", "c2", "c3".
|
||||
*/
|
||||
public function testTypeCollision()
|
||||
@ -169,7 +205,7 @@ class AutowirePassTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
|
||||
* @expectedExceptionMessage Cannot autowire service "a": argument "$k" of method "Symfony\Component\DependencyInjection\Tests\Compiler\NotGuessableArgument::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" but no such service exists. You should maybe alias this class to one of these existing services: "a1", "a2".
|
||||
*/
|
||||
public function testTypeNotGuessable()
|
||||
@ -186,7 +222,7 @@ class AutowirePassTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
|
||||
* @expectedExceptionMessage Cannot autowire service "a": argument "$k" of method "Symfony\Component\DependencyInjection\Tests\Compiler\NotGuessableArgumentForSubclass::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\A" but no such service exists. You should maybe alias this class to one of these existing services: "a1", "a2".
|
||||
*/
|
||||
public function testTypeNotGuessableWithSubclass()
|
||||
@ -203,7 +239,7 @@ class AutowirePassTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
|
||||
* @expectedExceptionMessage Cannot autowire service "a": argument "$collision" of method "Symfony\Component\DependencyInjection\Tests\Compiler\CannotBeAutowired::__construct()" references interface "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" but no such service exists.
|
||||
*/
|
||||
public function testTypeNotGuessableNoServicesFound()
|
||||
@ -322,7 +358,7 @@ class AutowirePassTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
|
||||
* @expectedExceptionMessage Cannot autowire service "a": argument "$r" of method "Symfony\Component\DependencyInjection\Tests\Compiler\BadTypeHintedArgument::__construct()" has type "Symfony\Component\DependencyInjection\Tests\Compiler\NotARealClass" but this class does not exist.
|
||||
*/
|
||||
public function testClassNotFoundThrowsException()
|
||||
@ -337,7 +373,7 @@ class AutowirePassTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
|
||||
* @expectedExceptionMessage Cannot autowire service "a": argument "$r" of method "Symfony\Component\DependencyInjection\Tests\Compiler\BadParentTypeHintedArgument::__construct()" has type "Symfony\Component\DependencyInjection\Tests\Compiler\OptionalServiceClass" but this class does not exist.
|
||||
*/
|
||||
public function testParentClassNotFoundThrowsException()
|
||||
@ -354,7 +390,7 @@ class AutowirePassTest extends TestCase
|
||||
/**
|
||||
* @group legacy
|
||||
* @expectedDeprecation Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won't be supported in version 4.0. You should rename (or alias) the "foo" service to "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" instead.
|
||||
* @expectedExceptionInSymfony4 \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedExceptionInSymfony4 \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
|
||||
* @expectedExceptionMessageInSymfony4 Cannot autowire service "bar": argument "$foo" of method "Symfony\Component\DependencyInjection\Tests\Compiler\Bar::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" but this service is abstract. You should maybe alias this class to the existing "foo" service.
|
||||
*/
|
||||
public function testDontUseAbstractServices()
|
||||
@ -399,7 +435,7 @@ class AutowirePassTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
|
||||
* @expectedExceptionMessage Cannot autowire service "arg_no_type_hint": argument "$foo" of method "Symfony\Component\DependencyInjection\Tests\Compiler\MultipleArguments::__construct()" must have a type-hint or be given a value explicitly.
|
||||
*/
|
||||
public function testScalarArgsCannotBeAutowired()
|
||||
@ -607,7 +643,7 @@ class AutowirePassTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
|
||||
* @expectedExceptionMessage Cannot autowire service "setter_injection_collision": argument "$collision" of method "Symfony\Component\DependencyInjection\Tests\Compiler\SetterInjectionCollision::setMultipleInstancesForOneArg()" references interface "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" but no such service exists. You should maybe alias this interface to one of these existing services: "c1", "c2".
|
||||
*/
|
||||
public function testSetterInjectionCollisionThrowsException()
|
||||
@ -626,7 +662,7 @@ class AutowirePassTest extends TestCase
|
||||
/**
|
||||
* @group legacy
|
||||
* @expectedDeprecation Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won't be supported in version 4.0. You should rename (or alias) the "foo" service to "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" instead.
|
||||
* @expectedExceptionInSymfony4 \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedExceptionInSymfony4 \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
|
||||
* @expectedExceptionMessageInSymfony4 Cannot autowire service "bar": argument "$foo" of method "Symfony\Component\DependencyInjection\Tests\Compiler\Bar::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" but no such service exists. You should maybe alias this class to the existing "foo" service.
|
||||
*/
|
||||
public function testProcessDoesNotTriggerDeprecations()
|
||||
@ -677,7 +713,7 @@ class AutowirePassTest extends TestCase
|
||||
|
||||
/**
|
||||
* @dataProvider provideNotWireableCalls
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
|
||||
*/
|
||||
public function testNotWireableCalls($method, $expectedMsg)
|
||||
{
|
||||
@ -716,8 +752,8 @@ class AutowirePassTest extends TestCase
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @expectedDeprecation Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won't be supported in version 4.0. You should rename (or alias) the "i" service to "Symfony\Component\DependencyInjection\Tests\Compiler\I" instead.
|
||||
* @expectedExceptionInSymfony4 \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedDeprecation Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won't be supported in version 4.0. Try changing the type-hint for argument "$i" of method "Symfony\Component\DependencyInjection\Tests\Compiler\J::__construct()" to "Symfony\Component\DependencyInjection\Tests\Compiler\IInterface" instead.
|
||||
* @expectedExceptionInSymfony4 \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
|
||||
* @expectedExceptionMessageInSymfony4 Cannot autowire service "j": argument "$i" of method "Symfony\Component\DependencyInjection\Tests\Compiler\J::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\I" but no such service exists. Try changing the type-hint to "Symfony\Component\DependencyInjection\Tests\Compiler\IInterface" instead.
|
||||
*/
|
||||
public function testByIdAlternative()
|
||||
@ -734,7 +770,26 @@ class AutowirePassTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @group legacy
|
||||
* @expectedDeprecation Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won't be supported in version 4.0. Try changing the type-hint for "Symfony\Component\DependencyInjection\Tests\Compiler\A" in "Symfony\Component\DependencyInjection\Tests\Compiler\Bar" to "Symfony\Component\DependencyInjection\Tests\Compiler\AInterface" instead.
|
||||
*/
|
||||
public function testTypedReferenceDeprecationNotice()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container->register('aClass', A::class);
|
||||
$container->setAlias(AInterface::class, 'aClass');
|
||||
$container
|
||||
->register('bar', Bar::class)
|
||||
->setProperty('a', array(new TypedReference(A::class, A::class, Bar::class)))
|
||||
;
|
||||
|
||||
$pass = new AutowirePass();
|
||||
$pass->process($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
|
||||
* @expectedExceptionMessage Cannot autowire service "j": argument "$i" of method "Symfony\Component\DependencyInjection\Tests\Compiler\J::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\I" but no such service exists. Try changing the type-hint to "Symfony\Component\DependencyInjection\Tests\Compiler\IInterface" instead.
|
||||
*/
|
||||
public function testExceptionWhenAliasExists()
|
||||
@ -754,7 +809,7 @@ class AutowirePassTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
|
||||
* @expectedExceptionMessage Cannot autowire service "j": argument "$i" of method "Symfony\Component\DependencyInjection\Tests\Compiler\J::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\I" but no such service exists. You should maybe alias this class to one of these existing services: "i", "i2".
|
||||
*/
|
||||
public function testExceptionWhenAliasDoesNotExist()
|
||||
@ -784,7 +839,11 @@ class Bar
|
||||
}
|
||||
}
|
||||
|
||||
class A
|
||||
interface AInterface
|
||||
{
|
||||
}
|
||||
|
||||
class A implements AInterface
|
||||
{
|
||||
public static function create(Foo $foo)
|
||||
{
|
||||
@ -1091,3 +1150,10 @@ class NotWireable
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class PrivateConstructor
|
||||
{
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ class InlineServiceDefinitionsPassTest extends TestCase
|
||||
$this->assertSame('inline', (string) $values[0]);
|
||||
}
|
||||
|
||||
public function testGetInlinedServiceIds()
|
||||
public function testGetInlinedServiceIdData()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container
|
||||
@ -265,7 +265,7 @@ class InlineServiceDefinitionsPassTest extends TestCase
|
||||
;
|
||||
|
||||
$container
|
||||
->register('service')
|
||||
->register('other_service')
|
||||
->setArguments(array(new Reference('inlinable.service')))
|
||||
;
|
||||
|
||||
@ -273,7 +273,7 @@ class InlineServiceDefinitionsPassTest extends TestCase
|
||||
$repeatedPass = new RepeatedPass(array(new AnalyzeServiceReferencesPass(), $inlinePass));
|
||||
$repeatedPass->process($container);
|
||||
|
||||
$this->assertEquals(array('inlinable.service'), $inlinePass->getInlinedServiceIds());
|
||||
$this->assertEquals(array('inlinable.service' => array('other_service')), $inlinePass->getInlinedServiceIds());
|
||||
}
|
||||
|
||||
protected function process(ContainerBuilder $container)
|
||||
|
@ -116,7 +116,7 @@ class ContainerAwareEventDispatcher extends EventDispatcher
|
||||
public function hasListeners($eventName = null)
|
||||
{
|
||||
if (null === $eventName) {
|
||||
return (bool) count($this->listenerIds) || (bool) count($this->listeners);
|
||||
return count($this->listenerIds) || count($this->listeners) || parent::hasListeners();
|
||||
}
|
||||
|
||||
if (isset($this->listenerIds[$eventName])) {
|
||||
|
@ -11,10 +11,11 @@
|
||||
|
||||
namespace Symfony\Component\EventDispatcher\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Argument\ClosureProxyArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
@ -78,7 +79,7 @@ class RegisterListenersPass implements CompilerPassInterface
|
||||
$event['method'] = preg_replace('/[^a-z0-9]/i', '', $event['method']);
|
||||
}
|
||||
|
||||
$definition->addMethodCall('addListener', array($event['event'], new ClosureProxyArgument($id, $event['method']), $priority));
|
||||
$definition->addMethodCall('addListener', array($event['event'], array(new ServiceClosureArgument(new Reference($id)), $event['method']), $priority));
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,7 +104,7 @@ class RegisterListenersPass implements CompilerPassInterface
|
||||
ExtractingEventDispatcher::$subscriber = $class;
|
||||
$extractingDispatcher->addSubscriber($extractingDispatcher);
|
||||
foreach ($extractingDispatcher->listeners as $args) {
|
||||
$args[1] = new ClosureProxyArgument($id, $args[1]);
|
||||
$args[1] = array(new ServiceClosureArgument(new Reference($id)), $args[1]);
|
||||
$definition->addMethodCall('addListener', $args);
|
||||
}
|
||||
$extractingDispatcher->listeners = array();
|
||||
|
@ -24,6 +24,7 @@ namespace Symfony\Component\EventDispatcher;
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @author Jordan Alliot <jordan.alliot@gmail.com>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class EventDispatcher implements EventDispatcherInterface
|
||||
{
|
||||
@ -52,7 +53,7 @@ class EventDispatcher implements EventDispatcherInterface
|
||||
public function getListeners($eventName = null)
|
||||
{
|
||||
if (null !== $eventName) {
|
||||
if (!isset($this->listeners[$eventName])) {
|
||||
if (empty($this->listeners[$eventName])) {
|
||||
return array();
|
||||
}
|
||||
|
||||
@ -77,13 +78,23 @@ class EventDispatcher implements EventDispatcherInterface
|
||||
*/
|
||||
public function getListenerPriority($eventName, $listener)
|
||||
{
|
||||
if (!isset($this->listeners[$eventName])) {
|
||||
if (empty($this->listeners[$eventName])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
|
||||
$listener[0] = $listener[0]();
|
||||
}
|
||||
|
||||
foreach ($this->listeners[$eventName] as $priority => $listeners) {
|
||||
if (false !== in_array($listener, $listeners, true)) {
|
||||
return $priority;
|
||||
foreach ($listeners as $k => $v) {
|
||||
if ($v !== $listener && is_array($v) && isset($v[0]) && $v[0] instanceof \Closure) {
|
||||
$v[0] = $v[0]();
|
||||
$this->listeners[$eventName][$priority][$k] = $v;
|
||||
}
|
||||
if ($v === $listener) {
|
||||
return $priority;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -93,7 +104,17 @@ class EventDispatcher implements EventDispatcherInterface
|
||||
*/
|
||||
public function hasListeners($eventName = null)
|
||||
{
|
||||
return (bool) $this->getListeners($eventName);
|
||||
if (null !== $eventName) {
|
||||
return !empty($this->listeners[$eventName]);
|
||||
}
|
||||
|
||||
foreach ($this->listeners as $eventListeners) {
|
||||
if ($eventListeners) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -110,13 +131,30 @@ class EventDispatcher implements EventDispatcherInterface
|
||||
*/
|
||||
public function removeListener($eventName, $listener)
|
||||
{
|
||||
if (!isset($this->listeners[$eventName])) {
|
||||
if (empty($this->listeners[$eventName])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
|
||||
$listener[0] = $listener[0]();
|
||||
}
|
||||
|
||||
foreach ($this->listeners[$eventName] as $priority => $listeners) {
|
||||
if (false !== ($key = array_search($listener, $listeners, true))) {
|
||||
unset($this->listeners[$eventName][$priority][$key], $this->sorted[$eventName]);
|
||||
foreach ($listeners as $k => $v) {
|
||||
if ($v !== $listener && is_array($v) && isset($v[0]) && $v[0] instanceof \Closure) {
|
||||
$v[0] = $v[0]();
|
||||
}
|
||||
if ($v === $listener) {
|
||||
unset($listeners[$k], $this->sorted[$eventName]);
|
||||
} else {
|
||||
$listeners[$k] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
if ($listeners) {
|
||||
$this->listeners[$eventName][$priority] = $listeners;
|
||||
} else {
|
||||
unset($this->listeners[$eventName][$priority]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -183,6 +221,16 @@ class EventDispatcher implements EventDispatcherInterface
|
||||
private function sortListeners($eventName)
|
||||
{
|
||||
krsort($this->listeners[$eventName]);
|
||||
$this->sorted[$eventName] = call_user_func_array('array_merge', $this->listeners[$eventName]);
|
||||
$this->sorted[$eventName] = array();
|
||||
|
||||
foreach ($this->listeners[$eventName] as $priority => $listeners) {
|
||||
foreach ($listeners as $k => $listener) {
|
||||
if (is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
|
||||
$listener[0] = $listener[0]();
|
||||
$this->listeners[$eventName][$priority][$k] = $listener;
|
||||
}
|
||||
$this->sorted[$eventName][] = $listener;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -302,6 +302,73 @@ abstract class AbstractEventDispatcherTest extends TestCase
|
||||
$this->assertFalse($this->dispatcher->hasListeners('foo'));
|
||||
$this->assertFalse($this->dispatcher->hasListeners());
|
||||
}
|
||||
|
||||
public function testHasListenersIsLazy()
|
||||
{
|
||||
$called = 0;
|
||||
$listener = array(function () use (&$called) { ++$called; }, 'onFoo');
|
||||
$this->dispatcher->addListener('foo', $listener);
|
||||
$this->assertTrue($this->dispatcher->hasListeners());
|
||||
$this->assertTrue($this->dispatcher->hasListeners('foo'));
|
||||
$this->assertSame(0, $called);
|
||||
}
|
||||
|
||||
public function testDispatchLazyListener()
|
||||
{
|
||||
$called = 0;
|
||||
$factory = function () use (&$called) {
|
||||
++$called;
|
||||
|
||||
return new TestWithDispatcher();
|
||||
};
|
||||
$this->dispatcher->addListener('foo', array($factory, 'foo'));
|
||||
$this->assertSame(0, $called);
|
||||
$this->dispatcher->dispatch('foo', new Event());
|
||||
$this->dispatcher->dispatch('foo', new Event());
|
||||
$this->assertSame(1, $called);
|
||||
}
|
||||
|
||||
public function testRemoveFindsLazyListeners()
|
||||
{
|
||||
$test = new TestWithDispatcher();
|
||||
$factory = function () use ($test) { return $test; };
|
||||
|
||||
$this->dispatcher->addListener('foo', array($factory, 'foo'));
|
||||
$this->assertTrue($this->dispatcher->hasListeners('foo'));
|
||||
$this->dispatcher->removeListener('foo', array($test, 'foo'));
|
||||
$this->assertFalse($this->dispatcher->hasListeners('foo'));
|
||||
|
||||
$this->dispatcher->addListener('foo', array($test, 'foo'));
|
||||
$this->assertTrue($this->dispatcher->hasListeners('foo'));
|
||||
$this->dispatcher->removeListener('foo', array($factory, 'foo'));
|
||||
$this->assertFalse($this->dispatcher->hasListeners('foo'));
|
||||
}
|
||||
|
||||
public function testPriorityFindsLazyListeners()
|
||||
{
|
||||
$test = new TestWithDispatcher();
|
||||
$factory = function () use ($test) { return $test; };
|
||||
|
||||
$this->dispatcher->addListener('foo', array($factory, 'foo'), 3);
|
||||
$this->assertSame(3, $this->dispatcher->getListenerPriority('foo', array($test, 'foo')));
|
||||
$this->dispatcher->removeListener('foo', array($factory, 'foo'));
|
||||
|
||||
$this->dispatcher->addListener('foo', array($test, 'foo'), 5);
|
||||
$this->assertSame(5, $this->dispatcher->getListenerPriority('foo', array($factory, 'foo')));
|
||||
}
|
||||
|
||||
public function testGetLazyListeners()
|
||||
{
|
||||
$test = new TestWithDispatcher();
|
||||
$factory = function () use ($test) { return $test; };
|
||||
|
||||
$this->dispatcher->addListener('foo', array($factory, 'foo'), 3);
|
||||
$this->assertSame(array(array($test, 'foo')), $this->dispatcher->getListeners('foo'));
|
||||
|
||||
$this->dispatcher->removeListener('foo', array($test, 'foo'));
|
||||
$this->dispatcher->addListener('bar', array($factory, 'foo'), 3);
|
||||
$this->assertSame(array('bar' => array(array($test, 'foo'))), $this->dispatcher->getListeners());
|
||||
}
|
||||
}
|
||||
|
||||
class CallableClass
|
||||
|
@ -12,8 +12,9 @@
|
||||
namespace Symfony\Component\EventDispatcher\Tests\DependencyInjection;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\DependencyInjection\Argument\ClosureProxyArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass;
|
||||
|
||||
class RegisterListenersPassTest extends TestCase
|
||||
@ -127,17 +128,17 @@ class RegisterListenersPassTest extends TestCase
|
||||
$registerListenersPass->process($container);
|
||||
|
||||
$definition = $container->getDefinition('event_dispatcher');
|
||||
$expected_calls = array(
|
||||
$expectedCalls = array(
|
||||
array(
|
||||
'addListener',
|
||||
array(
|
||||
'event',
|
||||
new ClosureProxyArgument('foo', 'onEvent'),
|
||||
array(new ServiceClosureArgument(new Reference('foo')), 'onEvent'),
|
||||
0,
|
||||
),
|
||||
),
|
||||
);
|
||||
$this->assertEquals($expected_calls, $definition->getMethodCalls());
|
||||
$this->assertEquals($expectedCalls, $definition->getMethodCalls());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -31,7 +31,7 @@ abstract class FilterIterator extends \FilterIterator
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
if (PHP_VERSION_ID > 50607 || (PHP_VERSION_ID > 50523 && PHP_VERSION_ID < 50600)) {
|
||||
if (\PHP_VERSION_ID > 50607 || (\PHP_VERSION_ID > 50523 && \PHP_VERSION_ID < 50600)) {
|
||||
parent::rewind();
|
||||
|
||||
return;
|
||||
|
@ -119,7 +119,7 @@ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
|
||||
}
|
||||
|
||||
// @see https://bugs.php.net/68557
|
||||
if (PHP_VERSION_ID < 50523 || PHP_VERSION_ID >= 50600 && PHP_VERSION_ID < 50607) {
|
||||
if (\PHP_VERSION_ID < 50523 || \PHP_VERSION_ID >= 50600 && \PHP_VERSION_ID < 50607) {
|
||||
parent::next();
|
||||
}
|
||||
|
||||
|
@ -162,6 +162,10 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer
|
||||
$dateFormat = $this->dateFormat;
|
||||
$timeFormat = $this->timeFormat;
|
||||
$timezone = $ignoreTimezone ? 'UTC' : $this->outputTimezone;
|
||||
if (class_exists('IntlTimeZone', false)) {
|
||||
// see https://bugs.php.net/bug.php?id=66323
|
||||
$timezone = \IntlTimeZone::createTimeZone($timezone);
|
||||
}
|
||||
$calendar = $this->calendar;
|
||||
$pattern = $this->pattern;
|
||||
|
||||
|
@ -82,7 +82,8 @@ class DateType extends AbstractType
|
||||
\Locale::getDefault(),
|
||||
$dateFormat,
|
||||
$timeFormat,
|
||||
null,
|
||||
// see https://bugs.php.net/bug.php?id=66323
|
||||
class_exists('IntlTimeZone', false) ? \IntlTimeZone::createDefault() : null,
|
||||
$calendar,
|
||||
$pattern
|
||||
);
|
||||
|
@ -18,19 +18,14 @@ namespace Symfony\Component\Form\Guess;
|
||||
*/
|
||||
class ValueGuess extends Guess
|
||||
{
|
||||
/**
|
||||
* The guessed value.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $value The guessed value
|
||||
* @param int $confidence The confidence that the guessed class name
|
||||
* is correct
|
||||
* @param string|int|bool|null $value The guessed value
|
||||
* @param int $confidence The confidence that the guessed class name
|
||||
* is correct
|
||||
*/
|
||||
public function __construct($value, $confidence)
|
||||
{
|
||||
@ -42,7 +37,7 @@ class ValueGuess extends Guess
|
||||
/**
|
||||
* Returns the guessed value.
|
||||
*
|
||||
* @return mixed
|
||||
* @return string|int|bool|null
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
|
@ -1577,7 +1577,7 @@ class Request
|
||||
public function getContent($asResource = false)
|
||||
{
|
||||
$currentContentIsResource = is_resource($this->content);
|
||||
if (PHP_VERSION_ID < 50600 && false === $this->content) {
|
||||
if (\PHP_VERSION_ID < 50600 && false === $this->content) {
|
||||
throw new \LogicException('getContent() can only be called once when using the resource return type and PHP below 5.6.');
|
||||
}
|
||||
|
||||
|
@ -1057,7 +1057,7 @@ class RequestTest extends TestCase
|
||||
*/
|
||||
public function testGetContentCantBeCalledTwiceWithResources($first, $second)
|
||||
{
|
||||
if (PHP_VERSION_ID >= 50600) {
|
||||
if (\PHP_VERSION_ID >= 50600) {
|
||||
$this->markTestSkipped('PHP >= 5.6 allows to open php://input several times.');
|
||||
}
|
||||
|
||||
|
@ -138,6 +138,9 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
|
||||
$logs = array();
|
||||
foreach (file($file, FILE_IGNORE_NEW_LINES) as $log) {
|
||||
$log = explode(': ', $log, 2);
|
||||
if (!isset($log[1]) || !preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)++$/', $log[0])) {
|
||||
$log = array('Unknown Compiler Pass', implode(': ', $log));
|
||||
}
|
||||
|
||||
$logs[$log[0]][] = array('message' => $log[1]);
|
||||
}
|
||||
|
@ -822,7 +822,7 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
||||
|
||||
$output .= $rawChunk;
|
||||
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
// PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098
|
||||
unset($tokens, $rawChunk);
|
||||
gc_mem_caches();
|
||||
|
@ -0,0 +1,4 @@
|
||||
Symfony\Component\DependencyInjection\Compiler\RemovePrivateAliasesPass: Removed service "Psr\Container\ContainerInterface"; reason: private alias.
|
||||
Symfony\Component\DependencyInjection\Compiler\RemovePrivateAliasesPass: Removed service "Symfony\Component\DependencyInjection\ContainerInterface"; reason: private alias.
|
||||
Some custom logging message
|
||||
With ending :
|
@ -17,6 +17,27 @@ use Symfony\Component\HttpKernel\DataCollector\LoggerDataCollector;
|
||||
|
||||
class LoggerDataCollectorTest extends TestCase
|
||||
{
|
||||
public function testCollectWithUnexpectedFormat()
|
||||
{
|
||||
$logger = $this->getMockBuilder('Symfony\Component\HttpKernel\Log\DebugLoggerInterface')->getMock();
|
||||
$logger->expects($this->once())->method('countErrors')->will($this->returnValue('foo'));
|
||||
$logger->expects($this->exactly(2))->method('getLogs')->will($this->returnValue(array()));
|
||||
|
||||
$c = new LoggerDataCollector($logger, __DIR__.'/');
|
||||
$c->lateCollect();
|
||||
$compilerLogs = $c->getCompilerLogs()->getValue('message');
|
||||
|
||||
$this->assertSame(array(
|
||||
array('message' => 'Removed service "Psr\Container\ContainerInterface"; reason: private alias.'),
|
||||
array('message' => 'Removed service "Symfony\Component\DependencyInjection\ContainerInterface"; reason: private alias.'),
|
||||
), $compilerLogs['Symfony\Component\DependencyInjection\Compiler\RemovePrivateAliasesPass']);
|
||||
|
||||
$this->assertSame(array(
|
||||
array('message' => 'Some custom logging message'),
|
||||
array('message' => 'With ending :'),
|
||||
), $compilerLogs['Unknown Compiler Pass']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getCollectTestData
|
||||
*/
|
||||
|
@ -435,7 +435,7 @@ abstract class AbstractIntlDateFormatterTest extends TestCase
|
||||
|
||||
public function testFormatWithDateTimeZoneGmtOffset()
|
||||
{
|
||||
if (defined('HHVM_VERSION_ID') || PHP_VERSION_ID <= 50509) {
|
||||
if (defined('HHVM_VERSION_ID') || \PHP_VERSION_ID <= 50509) {
|
||||
$this->markTestSkipped('DateTimeZone GMT offsets are supported since 5.5.10. See https://github.com/facebook/hhvm/issues/5875 for HHVM.');
|
||||
}
|
||||
|
||||
|
@ -195,7 +195,7 @@ class PropertyAccessor implements PropertyAccessorInterface
|
||||
$overwrite = true;
|
||||
|
||||
try {
|
||||
if (PHP_VERSION_ID < 70000 && false === self::$previousErrorHandler) {
|
||||
if (\PHP_VERSION_ID < 70000 && false === self::$previousErrorHandler) {
|
||||
self::$previousErrorHandler = set_error_handler(self::$errorHandler);
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ class AnnotationFileLoader extends FileLoader
|
||||
$collection->addResource(new FileResource($path));
|
||||
$collection->addCollection($this->loader->load($class, $type));
|
||||
}
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
// PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098
|
||||
gc_mem_caches();
|
||||
}
|
||||
|
@ -238,7 +238,7 @@ EOF;
|
||||
$hostMatches = false;
|
||||
$methods = $route->getMethods();
|
||||
|
||||
$supportsTrailingSlash = $supportsRedirections && (!$methods || in_array('HEAD', $methods));
|
||||
$supportsTrailingSlash = $supportsRedirections && (!$methods || in_array('HEAD', $methods) || in_array('GET', $methods));
|
||||
$regex = $compiledRoute->getRegex();
|
||||
|
||||
if (!count($compiledRoute->getPathVariables()) && false !== preg_match('#^(.)\^(?P<url>.*?)\$\1#'.(substr($regex, -1) === 'u' ? 'u' : ''), $regex, $m)) {
|
||||
|
@ -0,0 +1,204 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
|
||||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
|
||||
/**
|
||||
* ProjectUrlMatcher.
|
||||
*
|
||||
* This class has been auto-generated
|
||||
* by the Symfony Routing Component.
|
||||
*/
|
||||
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct(RequestContext $context)
|
||||
{
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
public function match($pathinfo)
|
||||
{
|
||||
$allow = array();
|
||||
$pathinfo = rawurldecode($pathinfo);
|
||||
$trimmedPathinfo = rtrim($pathinfo, '/');
|
||||
$context = $this->context;
|
||||
$request = $this->request;
|
||||
$requestMethod = $canonicalMethod = $context->getMethod();
|
||||
$scheme = $context->getScheme();
|
||||
|
||||
if ('HEAD' === $requestMethod) {
|
||||
$canonicalMethod = 'GET';
|
||||
}
|
||||
|
||||
|
||||
if (0 === strpos($pathinfo, '/trailing/simple')) {
|
||||
// simple_trailing_slash_no_methods
|
||||
if ('/trailing/simple/no-methods/' === $pathinfo) {
|
||||
return array('_route' => 'simple_trailing_slash_no_methods');
|
||||
}
|
||||
|
||||
// simple_trailing_slash_GET_method
|
||||
if ('/trailing/simple/get-method/' === $pathinfo) {
|
||||
if ('GET' !== $canonicalMethod) {
|
||||
$allow[] = 'GET';
|
||||
goto not_simple_trailing_slash_GET_method;
|
||||
}
|
||||
|
||||
return array('_route' => 'simple_trailing_slash_GET_method');
|
||||
}
|
||||
not_simple_trailing_slash_GET_method:
|
||||
|
||||
// simple_trailing_slash_HEAD_method
|
||||
if ('/trailing/simple/head-method/' === $pathinfo) {
|
||||
if ('HEAD' !== $requestMethod) {
|
||||
$allow[] = 'HEAD';
|
||||
goto not_simple_trailing_slash_HEAD_method;
|
||||
}
|
||||
|
||||
return array('_route' => 'simple_trailing_slash_HEAD_method');
|
||||
}
|
||||
not_simple_trailing_slash_HEAD_method:
|
||||
|
||||
// simple_trailing_slash_POST_method
|
||||
if ('/trailing/simple/post-method/' === $pathinfo) {
|
||||
if ('POST' !== $canonicalMethod) {
|
||||
$allow[] = 'POST';
|
||||
goto not_simple_trailing_slash_POST_method;
|
||||
}
|
||||
|
||||
return array('_route' => 'simple_trailing_slash_POST_method');
|
||||
}
|
||||
not_simple_trailing_slash_POST_method:
|
||||
|
||||
}
|
||||
|
||||
elseif (0 === strpos($pathinfo, '/trailing/regex')) {
|
||||
// regex_trailing_slash_no_methods
|
||||
if (0 === strpos($pathinfo, '/trailing/regex/no-methods') && preg_match('#^/trailing/regex/no\\-methods/(?P<param>[^/]++)/$#s', $pathinfo, $matches)) {
|
||||
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_no_methods')), array ());
|
||||
}
|
||||
|
||||
// regex_trailing_slash_GET_method
|
||||
if (0 === strpos($pathinfo, '/trailing/regex/get-method') && preg_match('#^/trailing/regex/get\\-method/(?P<param>[^/]++)/$#s', $pathinfo, $matches)) {
|
||||
if ('GET' !== $canonicalMethod) {
|
||||
$allow[] = 'GET';
|
||||
goto not_regex_trailing_slash_GET_method;
|
||||
}
|
||||
|
||||
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_GET_method')), array ());
|
||||
}
|
||||
not_regex_trailing_slash_GET_method:
|
||||
|
||||
// regex_trailing_slash_HEAD_method
|
||||
if (0 === strpos($pathinfo, '/trailing/regex/head-method') && preg_match('#^/trailing/regex/head\\-method/(?P<param>[^/]++)/$#s', $pathinfo, $matches)) {
|
||||
if ('HEAD' !== $requestMethod) {
|
||||
$allow[] = 'HEAD';
|
||||
goto not_regex_trailing_slash_HEAD_method;
|
||||
}
|
||||
|
||||
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_HEAD_method')), array ());
|
||||
}
|
||||
not_regex_trailing_slash_HEAD_method:
|
||||
|
||||
// regex_trailing_slash_POST_method
|
||||
if (0 === strpos($pathinfo, '/trailing/regex/post-method') && preg_match('#^/trailing/regex/post\\-method/(?P<param>[^/]++)/$#s', $pathinfo, $matches)) {
|
||||
if ('POST' !== $canonicalMethod) {
|
||||
$allow[] = 'POST';
|
||||
goto not_regex_trailing_slash_POST_method;
|
||||
}
|
||||
|
||||
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_POST_method')), array ());
|
||||
}
|
||||
not_regex_trailing_slash_POST_method:
|
||||
|
||||
}
|
||||
|
||||
elseif (0 === strpos($pathinfo, '/not-trailing/simple')) {
|
||||
// simple_not_trailing_slash_no_methods
|
||||
if ('/not-trailing/simple/no-methods' === $pathinfo) {
|
||||
return array('_route' => 'simple_not_trailing_slash_no_methods');
|
||||
}
|
||||
|
||||
// simple_not_trailing_slash_GET_method
|
||||
if ('/not-trailing/simple/get-method' === $pathinfo) {
|
||||
if ('GET' !== $canonicalMethod) {
|
||||
$allow[] = 'GET';
|
||||
goto not_simple_not_trailing_slash_GET_method;
|
||||
}
|
||||
|
||||
return array('_route' => 'simple_not_trailing_slash_GET_method');
|
||||
}
|
||||
not_simple_not_trailing_slash_GET_method:
|
||||
|
||||
// simple_not_trailing_slash_HEAD_method
|
||||
if ('/not-trailing/simple/head-method' === $pathinfo) {
|
||||
if ('HEAD' !== $requestMethod) {
|
||||
$allow[] = 'HEAD';
|
||||
goto not_simple_not_trailing_slash_HEAD_method;
|
||||
}
|
||||
|
||||
return array('_route' => 'simple_not_trailing_slash_HEAD_method');
|
||||
}
|
||||
not_simple_not_trailing_slash_HEAD_method:
|
||||
|
||||
// simple_not_trailing_slash_POST_method
|
||||
if ('/not-trailing/simple/post-method' === $pathinfo) {
|
||||
if ('POST' !== $canonicalMethod) {
|
||||
$allow[] = 'POST';
|
||||
goto not_simple_not_trailing_slash_POST_method;
|
||||
}
|
||||
|
||||
return array('_route' => 'simple_not_trailing_slash_POST_method');
|
||||
}
|
||||
not_simple_not_trailing_slash_POST_method:
|
||||
|
||||
}
|
||||
|
||||
elseif (0 === strpos($pathinfo, '/not-trailing/regex')) {
|
||||
// regex_not_trailing_slash_no_methods
|
||||
if (0 === strpos($pathinfo, '/not-trailing/regex/no-methods') && preg_match('#^/not\\-trailing/regex/no\\-methods/(?P<param>[^/]++)$#s', $pathinfo, $matches)) {
|
||||
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_no_methods')), array ());
|
||||
}
|
||||
|
||||
// regex_not_trailing_slash_GET_method
|
||||
if (0 === strpos($pathinfo, '/not-trailing/regex/get-method') && preg_match('#^/not\\-trailing/regex/get\\-method/(?P<param>[^/]++)$#s', $pathinfo, $matches)) {
|
||||
if ('GET' !== $canonicalMethod) {
|
||||
$allow[] = 'GET';
|
||||
goto not_regex_not_trailing_slash_GET_method;
|
||||
}
|
||||
|
||||
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_GET_method')), array ());
|
||||
}
|
||||
not_regex_not_trailing_slash_GET_method:
|
||||
|
||||
// regex_not_trailing_slash_HEAD_method
|
||||
if (0 === strpos($pathinfo, '/not-trailing/regex/head-method') && preg_match('#^/not\\-trailing/regex/head\\-method/(?P<param>[^/]++)$#s', $pathinfo, $matches)) {
|
||||
if ('HEAD' !== $requestMethod) {
|
||||
$allow[] = 'HEAD';
|
||||
goto not_regex_not_trailing_slash_HEAD_method;
|
||||
}
|
||||
|
||||
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_HEAD_method')), array ());
|
||||
}
|
||||
not_regex_not_trailing_slash_HEAD_method:
|
||||
|
||||
// regex_not_trailing_slash_POST_method
|
||||
if (0 === strpos($pathinfo, '/not-trailing/regex/post-method') && preg_match('#^/not\\-trailing/regex/post\\-method/(?P<param>[^/]++)$#s', $pathinfo, $matches)) {
|
||||
if ('POST' !== $canonicalMethod) {
|
||||
$allow[] = 'POST';
|
||||
goto not_regex_not_trailing_slash_POST_method;
|
||||
}
|
||||
|
||||
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_POST_method')), array ());
|
||||
}
|
||||
not_regex_not_trailing_slash_POST_method:
|
||||
|
||||
}
|
||||
|
||||
throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
|
||||
}
|
||||
}
|
@ -0,0 +1,228 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
|
||||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
|
||||
/**
|
||||
* ProjectUrlMatcher.
|
||||
*
|
||||
* This class has been auto-generated
|
||||
* by the Symfony Routing Component.
|
||||
*/
|
||||
class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct(RequestContext $context)
|
||||
{
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
public function match($pathinfo)
|
||||
{
|
||||
$allow = array();
|
||||
$pathinfo = rawurldecode($pathinfo);
|
||||
$trimmedPathinfo = rtrim($pathinfo, '/');
|
||||
$context = $this->context;
|
||||
$request = $this->request;
|
||||
$requestMethod = $canonicalMethod = $context->getMethod();
|
||||
$scheme = $context->getScheme();
|
||||
|
||||
if ('HEAD' === $requestMethod) {
|
||||
$canonicalMethod = 'GET';
|
||||
}
|
||||
|
||||
|
||||
if (0 === strpos($pathinfo, '/trailing/simple')) {
|
||||
// simple_trailing_slash_no_methods
|
||||
if ('/trailing/simple/no-methods' === $trimmedPathinfo) {
|
||||
if (substr($pathinfo, -1) !== '/') {
|
||||
return $this->redirect($pathinfo.'/', 'simple_trailing_slash_no_methods');
|
||||
}
|
||||
|
||||
return array('_route' => 'simple_trailing_slash_no_methods');
|
||||
}
|
||||
|
||||
// simple_trailing_slash_GET_method
|
||||
if ('/trailing/simple/get-method' === $trimmedPathinfo) {
|
||||
if ('GET' !== $canonicalMethod) {
|
||||
$allow[] = 'GET';
|
||||
goto not_simple_trailing_slash_GET_method;
|
||||
}
|
||||
|
||||
if (substr($pathinfo, -1) !== '/') {
|
||||
return $this->redirect($pathinfo.'/', 'simple_trailing_slash_GET_method');
|
||||
}
|
||||
|
||||
return array('_route' => 'simple_trailing_slash_GET_method');
|
||||
}
|
||||
not_simple_trailing_slash_GET_method:
|
||||
|
||||
// simple_trailing_slash_HEAD_method
|
||||
if ('/trailing/simple/head-method' === $trimmedPathinfo) {
|
||||
if ('HEAD' !== $requestMethod) {
|
||||
$allow[] = 'HEAD';
|
||||
goto not_simple_trailing_slash_HEAD_method;
|
||||
}
|
||||
|
||||
if (substr($pathinfo, -1) !== '/') {
|
||||
return $this->redirect($pathinfo.'/', 'simple_trailing_slash_HEAD_method');
|
||||
}
|
||||
|
||||
return array('_route' => 'simple_trailing_slash_HEAD_method');
|
||||
}
|
||||
not_simple_trailing_slash_HEAD_method:
|
||||
|
||||
// simple_trailing_slash_POST_method
|
||||
if ('/trailing/simple/post-method/' === $pathinfo) {
|
||||
if ('POST' !== $canonicalMethod) {
|
||||
$allow[] = 'POST';
|
||||
goto not_simple_trailing_slash_POST_method;
|
||||
}
|
||||
|
||||
return array('_route' => 'simple_trailing_slash_POST_method');
|
||||
}
|
||||
not_simple_trailing_slash_POST_method:
|
||||
|
||||
}
|
||||
|
||||
elseif (0 === strpos($pathinfo, '/trailing/regex')) {
|
||||
// regex_trailing_slash_no_methods
|
||||
if (0 === strpos($pathinfo, '/trailing/regex/no-methods') && preg_match('#^/trailing/regex/no\\-methods/(?P<param>[^/]++)/?$#s', $pathinfo, $matches)) {
|
||||
if (substr($pathinfo, -1) !== '/') {
|
||||
return $this->redirect($pathinfo.'/', 'regex_trailing_slash_no_methods');
|
||||
}
|
||||
|
||||
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_no_methods')), array ());
|
||||
}
|
||||
|
||||
// regex_trailing_slash_GET_method
|
||||
if (0 === strpos($pathinfo, '/trailing/regex/get-method') && preg_match('#^/trailing/regex/get\\-method/(?P<param>[^/]++)/?$#s', $pathinfo, $matches)) {
|
||||
if ('GET' !== $canonicalMethod) {
|
||||
$allow[] = 'GET';
|
||||
goto not_regex_trailing_slash_GET_method;
|
||||
}
|
||||
|
||||
if (substr($pathinfo, -1) !== '/') {
|
||||
return $this->redirect($pathinfo.'/', 'regex_trailing_slash_GET_method');
|
||||
}
|
||||
|
||||
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_GET_method')), array ());
|
||||
}
|
||||
not_regex_trailing_slash_GET_method:
|
||||
|
||||
// regex_trailing_slash_HEAD_method
|
||||
if (0 === strpos($pathinfo, '/trailing/regex/head-method') && preg_match('#^/trailing/regex/head\\-method/(?P<param>[^/]++)/?$#s', $pathinfo, $matches)) {
|
||||
if ('HEAD' !== $requestMethod) {
|
||||
$allow[] = 'HEAD';
|
||||
goto not_regex_trailing_slash_HEAD_method;
|
||||
}
|
||||
|
||||
if (substr($pathinfo, -1) !== '/') {
|
||||
return $this->redirect($pathinfo.'/', 'regex_trailing_slash_HEAD_method');
|
||||
}
|
||||
|
||||
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_HEAD_method')), array ());
|
||||
}
|
||||
not_regex_trailing_slash_HEAD_method:
|
||||
|
||||
// regex_trailing_slash_POST_method
|
||||
if (0 === strpos($pathinfo, '/trailing/regex/post-method') && preg_match('#^/trailing/regex/post\\-method/(?P<param>[^/]++)/$#s', $pathinfo, $matches)) {
|
||||
if ('POST' !== $canonicalMethod) {
|
||||
$allow[] = 'POST';
|
||||
goto not_regex_trailing_slash_POST_method;
|
||||
}
|
||||
|
||||
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_POST_method')), array ());
|
||||
}
|
||||
not_regex_trailing_slash_POST_method:
|
||||
|
||||
}
|
||||
|
||||
elseif (0 === strpos($pathinfo, '/not-trailing/simple')) {
|
||||
// simple_not_trailing_slash_no_methods
|
||||
if ('/not-trailing/simple/no-methods' === $pathinfo) {
|
||||
return array('_route' => 'simple_not_trailing_slash_no_methods');
|
||||
}
|
||||
|
||||
// simple_not_trailing_slash_GET_method
|
||||
if ('/not-trailing/simple/get-method' === $pathinfo) {
|
||||
if ('GET' !== $canonicalMethod) {
|
||||
$allow[] = 'GET';
|
||||
goto not_simple_not_trailing_slash_GET_method;
|
||||
}
|
||||
|
||||
return array('_route' => 'simple_not_trailing_slash_GET_method');
|
||||
}
|
||||
not_simple_not_trailing_slash_GET_method:
|
||||
|
||||
// simple_not_trailing_slash_HEAD_method
|
||||
if ('/not-trailing/simple/head-method' === $pathinfo) {
|
||||
if ('HEAD' !== $requestMethod) {
|
||||
$allow[] = 'HEAD';
|
||||
goto not_simple_not_trailing_slash_HEAD_method;
|
||||
}
|
||||
|
||||
return array('_route' => 'simple_not_trailing_slash_HEAD_method');
|
||||
}
|
||||
not_simple_not_trailing_slash_HEAD_method:
|
||||
|
||||
// simple_not_trailing_slash_POST_method
|
||||
if ('/not-trailing/simple/post-method' === $pathinfo) {
|
||||
if ('POST' !== $canonicalMethod) {
|
||||
$allow[] = 'POST';
|
||||
goto not_simple_not_trailing_slash_POST_method;
|
||||
}
|
||||
|
||||
return array('_route' => 'simple_not_trailing_slash_POST_method');
|
||||
}
|
||||
not_simple_not_trailing_slash_POST_method:
|
||||
|
||||
}
|
||||
|
||||
elseif (0 === strpos($pathinfo, '/not-trailing/regex')) {
|
||||
// regex_not_trailing_slash_no_methods
|
||||
if (0 === strpos($pathinfo, '/not-trailing/regex/no-methods') && preg_match('#^/not\\-trailing/regex/no\\-methods/(?P<param>[^/]++)$#s', $pathinfo, $matches)) {
|
||||
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_no_methods')), array ());
|
||||
}
|
||||
|
||||
// regex_not_trailing_slash_GET_method
|
||||
if (0 === strpos($pathinfo, '/not-trailing/regex/get-method') && preg_match('#^/not\\-trailing/regex/get\\-method/(?P<param>[^/]++)$#s', $pathinfo, $matches)) {
|
||||
if ('GET' !== $canonicalMethod) {
|
||||
$allow[] = 'GET';
|
||||
goto not_regex_not_trailing_slash_GET_method;
|
||||
}
|
||||
|
||||
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_GET_method')), array ());
|
||||
}
|
||||
not_regex_not_trailing_slash_GET_method:
|
||||
|
||||
// regex_not_trailing_slash_HEAD_method
|
||||
if (0 === strpos($pathinfo, '/not-trailing/regex/head-method') && preg_match('#^/not\\-trailing/regex/head\\-method/(?P<param>[^/]++)$#s', $pathinfo, $matches)) {
|
||||
if ('HEAD' !== $requestMethod) {
|
||||
$allow[] = 'HEAD';
|
||||
goto not_regex_not_trailing_slash_HEAD_method;
|
||||
}
|
||||
|
||||
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_HEAD_method')), array ());
|
||||
}
|
||||
not_regex_not_trailing_slash_HEAD_method:
|
||||
|
||||
// regex_not_trailing_slash_POST_method
|
||||
if (0 === strpos($pathinfo, '/not-trailing/regex/post-method') && preg_match('#^/not\\-trailing/regex/post\\-method/(?P<param>[^/]++)$#s', $pathinfo, $matches)) {
|
||||
if ('POST' !== $canonicalMethod) {
|
||||
$allow[] = 'POST';
|
||||
goto not_regex_not_trailing_slash_POST_method;
|
||||
}
|
||||
|
||||
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_POST_method')), array ());
|
||||
}
|
||||
not_regex_not_trailing_slash_POST_method:
|
||||
|
||||
}
|
||||
|
||||
throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
|
||||
}
|
||||
}
|
@ -345,12 +345,33 @@ class PhpMatcherDumperTest extends TestCase
|
||||
$groupOptimisedCollection->add('slashed_b', new Route('/slashed/group/b/'));
|
||||
$groupOptimisedCollection->add('slashed_c', new Route('/slashed/group/c/'));
|
||||
|
||||
$trailingSlashCollection = new RouteCollection();
|
||||
$trailingSlashCollection->add('simple_trailing_slash_no_methods', new Route('/trailing/simple/no-methods/', array(), array(), array(), '', array(), array()));
|
||||
$trailingSlashCollection->add('simple_trailing_slash_GET_method', new Route('/trailing/simple/get-method/', array(), array(), array(), '', array(), array('GET')));
|
||||
$trailingSlashCollection->add('simple_trailing_slash_HEAD_method', new Route('/trailing/simple/head-method/', array(), array(), array(), '', array(), array('HEAD')));
|
||||
$trailingSlashCollection->add('simple_trailing_slash_POST_method', new Route('/trailing/simple/post-method/', array(), array(), array(), '', array(), array('POST')));
|
||||
$trailingSlashCollection->add('regex_trailing_slash_no_methods', new Route('/trailing/regex/no-methods/{param}/', array(), array(), array(), '', array(), array()));
|
||||
$trailingSlashCollection->add('regex_trailing_slash_GET_method', new Route('/trailing/regex/get-method/{param}/', array(), array(), array(), '', array(), array('GET')));
|
||||
$trailingSlashCollection->add('regex_trailing_slash_HEAD_method', new Route('/trailing/regex/head-method/{param}/', array(), array(), array(), '', array(), array('HEAD')));
|
||||
$trailingSlashCollection->add('regex_trailing_slash_POST_method', new Route('/trailing/regex/post-method/{param}/', array(), array(), array(), '', array(), array('POST')));
|
||||
|
||||
$trailingSlashCollection->add('simple_not_trailing_slash_no_methods', new Route('/not-trailing/simple/no-methods', array(), array(), array(), '', array(), array()));
|
||||
$trailingSlashCollection->add('simple_not_trailing_slash_GET_method', new Route('/not-trailing/simple/get-method', array(), array(), array(), '', array(), array('GET')));
|
||||
$trailingSlashCollection->add('simple_not_trailing_slash_HEAD_method', new Route('/not-trailing/simple/head-method', array(), array(), array(), '', array(), array('HEAD')));
|
||||
$trailingSlashCollection->add('simple_not_trailing_slash_POST_method', new Route('/not-trailing/simple/post-method', array(), array(), array(), '', array(), array('POST')));
|
||||
$trailingSlashCollection->add('regex_not_trailing_slash_no_methods', new Route('/not-trailing/regex/no-methods/{param}', array(), array(), array(), '', array(), array()));
|
||||
$trailingSlashCollection->add('regex_not_trailing_slash_GET_method', new Route('/not-trailing/regex/get-method/{param}', array(), array(), array(), '', array(), array('GET')));
|
||||
$trailingSlashCollection->add('regex_not_trailing_slash_HEAD_method', new Route('/not-trailing/regex/head-method/{param}', array(), array(), array(), '', array(), array('HEAD')));
|
||||
$trailingSlashCollection->add('regex_not_trailing_slash_POST_method', new Route('/not-trailing/regex/post-method/{param}', array(), array(), array(), '', array(), array('POST')));
|
||||
|
||||
return array(
|
||||
array($collection, 'url_matcher1.php', array()),
|
||||
array($redirectCollection, 'url_matcher2.php', array('base_class' => 'Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher')),
|
||||
array($rootprefixCollection, 'url_matcher3.php', array()),
|
||||
array($headMatchCasesCollection, 'url_matcher4.php', array()),
|
||||
array($groupOptimisedCollection, 'url_matcher5.php', array('base_class' => 'Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher')),
|
||||
array($trailingSlashCollection, 'url_matcher6.php', array()),
|
||||
array($trailingSlashCollection, 'url_matcher7.php', array('base_class' => 'Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher')),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -476,7 +476,7 @@ EOTXT
|
||||
*/
|
||||
public function testBuggyRefs()
|
||||
{
|
||||
if (PHP_VERSION_ID >= 50600) {
|
||||
if (\PHP_VERSION_ID >= 50600) {
|
||||
$this->markTestSkipped('PHP 5.6 fixed refs counting');
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user