Merge branch '3.3' into 3.4

* 3.3: (33 commits)
  Preserve HttpOnly value when deserializing a header
  [DX] [TwigBundle] Enhance the new exception page design
  Fix deprecated message
  [DI][Security] Prevent unwanted deprecation notices when using Expression Languages
  bumped Symfony version to 3.3.5
  updated VERSION for 3.3.4
  updated CHANGELOG for 3.3.4
  [VarDumper] Reduce size of serialized Data objects
  bumped Symfony version to 3.2.12
  updated VERSION for 3.2.11
  updated CHANGELOG for 3.2.11
  fixed bad merge
  Fix indent of methods
  [Cache] Handle APCu failures gracefully
  [DoctrineBridge] Use normalizedIds for resetting entity manager services
  [FrameworkBundle] Do not remove files from assets dir
  [FrameworkBundle] 3.3: Don't get() private services from debug:router
  bumped Symfony version to 3.3.4
  updated VERSION for 3.3.3
  updated CHANGELOG for 3.3.3
  ...
This commit is contained in:
Nicolas Grekas 2017-07-06 13:23:40 +03:00
commit 47ee1d53c1
30 changed files with 496 additions and 151 deletions

View File

@ -7,6 +7,63 @@ 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 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 To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v3.2.0...v3.2.1
* 3.2.11 (2017-07-05)
* bug #23390 [Cache] Handle APCu failures gracefully (nicolas-grekas)
* bug #23378 [FrameworkBundle] Do not remove files from assets dir (1ed)
* 3.2.10 (2017-07-04)
* bug #23366 [FrameworkBundle] Don't get() private services from debug:router (chalasr)
* bug #23341 [DoctrineBridge][Security][Validator] do not validate empty values (xabbuh)
* bug #23274 Display a better error design when the toolbar cannot be displayed (yceruto)
* bug #23296 [WebProfilerBundle] Fix css trick used for offsetting html anchor from fixed header (ogizanagi)
* bug #23333 [PropertyAccess] Fix TypeError discard (dunglas)
* bug #23326 [Cache] fix cleanup of expired items for PdoAdapter (dmaicher)
* bug #23345 [Console] fix description of INF default values (xabbuh)
* bug #23299 [Workflow] Added more events to the announce function (Nyholm)
* bug #23279 Don't call count on non countable object (pierredup)
* bug #23283 [TwigBundle] add back exception check (xabbuh)
* bug #23268 Show exception is checked twice in ExceptionController of twig (gmponos)
* bug #23266 Display a better error message when the toolbar cannot be displayed (javiereguiluz)
* bug #23271 [FrameworkBundle] allow SSI fragments configuration in XML files (xabbuh)
* bug #23254 [Form][TwigBridge] render hidden _method field in form_rest() (xabbuh)
* bug #23250 [Translation] return fallback locales whenever possible (xabbuh)
* bug #23240 [Console] Fix catching exception type in QuestionHelper (voronkovich)
* bug #23229 [WebProfilerBundle] Eliminate line wrap on count column (routing) (e-moe)
* bug #22732 [Security] fix switch user _exit without having current token (dmaicher)
* bug #22730 [FrameworkBundle] Sessions: configurable "use_strict_mode" option for NativeSessionStorage (MacDada)
* bug #23195 [FrameworkBundle] [Command] Clean bundle directory, fixes #23177 (NicolasPion)
* bug #23052 [TwigBundle] Add Content-Type header for exception response (rchoquet)
* bug #23199 Reset redirectCount when throwing exception (hvanoch)
* bug #23186 [TwigBundle] Move template.xml loading to a compiler pass (ogizanagi)
* bug #23130 Keep s-maxage when expiry and validation are used in combination (mpdude)
* bug #23129 Fix two edge cases in ResponseCacheStrategy (mpdude)
* feature #22636 [Routing] Expose request in route conditions, if needed and possible (ro0NL)
* bug #22636 [Routing] Expose request in route conditions, if needed and possible (ro0NL)
* bug #22943 [SecurityBundle] Move cache of the firewall context into the request parameters (GromNaN)
* bug #23057 [Translation][FrameworkBundle] Fix resource loading order inconsistency reported in #23034 (mpdude)
* bug #23092 [Filesystem] added workaround in Filesystem::rename for PHP bug (VolCh)
* bug #23128 [HttpFoundation] fix for Support for new 7.1 session options (vincentaubert)
* bug #23176 [VarDumper] fixes (nicolas-grekas)
* bug #23100 [PropertyAccess] Do not silence TypeErrors from client code. (tsufeki)
* bug #23156 [PropertyAccess] Fix Usage with anonymous classes (mablae)
* bug #23091 [Cache] ApcuAdapter::isSupported() should return true when apc.enable_cli=Off (nicolas-grekas)
* bug #22953 #22839 - changed debug toolbar dump section to relative and use full window width (mkurzeja)
* bug #23086 [FrameworkBundle] Fix perf issue in CacheClearCommand::warmup() (nicolas-grekas)
* bug #23098 Cache ipCheck (2.7) (gonzalovilaseca)
* bug #23069 [SecurityBundle] Show unique Inherited roles in profile panel (yceruto)
* bug #23073 [TwigBridge] Fix namespaced classes (ogizanagi)
* bug #23063 [Cache] Fix extensibility of TagAwareAdapter::TAGS_PREFIX (wucdbm)
* bug #22936 [Form] Mix attr option between guessed options and user options (yceruto)
* bug #22976 [DependencyInjection] Use more clear message when unused environment variables detected (voronkovich)
* bug #23045 [Cache] fix Redis scheme detection (xabbuh)
* bug #22988 [PropertyInfo][DoctrineBridge] The bigint Doctrine's type must be converted to string (dunglas)
* bug #23014 Fix optional cache warmers are always instantiated whereas they should be lazy-loaded (romainneutron)
* bug #23024 [EventDispatcher] Fix ContainerAwareEventDispatcher::hasListeners(null) (nicolas-grekas)
* bug #22996 [Form] Fix \IntlDateFormatter timezone parameter usage to bypass PHP bug #66323 (romainneutron)
* bug #22994 Harden the debugging of Twig filters and functions (stof)
* 3.2.9 (2017-05-29) * 3.2.9 (2017-05-29)
* bug #22847 [Console] ChoiceQuestion must have choices (ro0NL) * bug #22847 [Console] ChoiceQuestion must have choices (ro0NL)

View File

@ -7,6 +7,80 @@ 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 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 To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v3.3.0...v3.3.1
* 3.3.4 (2017-07-05)
* bug #23413 [VarDumper] Reduce size of serialized Data objects (nicolas-grekas)
* bug #23385 [DoctrineBridge] Fix resetting entity managers with case sensitive id (chalasr)
* bug #23390 [Cache] Handle APCu failures gracefully (nicolas-grekas)
* bug #23371 [FrameworkBundle] 3.3: Don't get() private services from debug:router (ogizanagi)
* bug #23378 [FrameworkBundle] Do not remove files from assets dir (1ed)
* 3.3.3 (2017-07-04)
* bug #23366 [FrameworkBundle] Don't get() private services from debug:router (chalasr)
* bug #23239 [FrameworkBundle] call setContainer() for autowired controllers (xabbuh)
* bug #23351 [Dotenv] parse concatenated variable values (xabbuh)
* bug #23341 [DoctrineBridge][Security][Validator] do not validate empty values (xabbuh)
* bug #23274 Display a better error design when the toolbar cannot be displayed (yceruto)
* bug #23342 [Dotenv] parse escaped quotes in unquoted env var values (xabbuh)
* bug #23291 [Security] Fix Firewall ExceptionListener priority (chalasr)
* bug #23296 [WebProfilerBundle] Fix css trick used for offsetting html anchor from fixed header (ogizanagi)
* bug #23333 [PropertyAccess] Fix TypeError discard (dunglas)
* bug #23326 [Cache] fix cleanup of expired items for PdoAdapter (dmaicher)
* bug #23345 [Console] fix description of INF default values (xabbuh)
* bug #23328 [FrameworkBundle] Display a proper warning on cache:clear without the --no-warmup option (ogizanagi)
* bug #23299 [Workflow] Added more events to the announce function (Nyholm)
* bug #23279 Don't call count on non countable object (pierredup)
* bug #23283 [TwigBundle] add back exception check (xabbuh)
* bug #23268 Show exception is checked twice in ExceptionController of twig (gmponos)
* bug #23266 Display a better error message when the toolbar cannot be displayed (javiereguiluz)
* bug #23271 [FrameworkBundle] allow SSI fragments configuration in XML files (xabbuh)
* bug #23254 [Form][TwigBridge] render hidden _method field in form_rest() (xabbuh)
* bug #23250 [Translation] return fallback locales whenever possible (xabbuh)
* bug #23237 [Cache] Fix Predis client cluster with pipeline (flolivaud)
* bug #23240 [Console] Fix catching exception type in QuestionHelper (voronkovich)
* bug #23218 [DI] Dedup tags when using instanceof/autoconfigure (ogizanagi)
* bug #23231 Improved the exception page when there is no message (javiereguiluz)
* bug #23229 [WebProfilerBundle] Eliminate line wrap on count column (routing) (e-moe)
* bug #22732 [Security] fix switch user _exit without having current token (dmaicher)
* bug #23226 [Validator] replace hardcoded service id (xabbuh)
* bug #22730 [FrameworkBundle] Sessions: configurable "use_strict_mode" option for NativeSessionStorage (MacDada)
* bug #23195 [FrameworkBundle] [Command] Clean bundle directory, fixes #23177 (NicolasPion)
* bug #23213 Fixed composer resources between web/cli (iltar)
* bug #23160 [WebProfilerBundle] Fix the icon for the Cache panel (javiereguiluz)
* bug #23052 [TwigBundle] Add Content-Type header for exception response (rchoquet)
* bug #23173 [WebServerBundle] Fix router script option BC (1ed)
* bug #23199 Reset redirectCount when throwing exception (hvanoch)
* bug #23180 [FrameworkBundle] Expose the AbstractController's container to its subclasses (BPScott)
* bug #23186 [TwigBundle] Move template.xml loading to a compiler pass (ogizanagi)
* bug #23130 Keep s-maxage when expiry and validation are used in combination (mpdude)
* bug #23129 Fix two edge cases in ResponseCacheStrategy (mpdude)
* feature #22636 [Routing] Expose request in route conditions, if needed and possible (ro0NL)
* bug #22636 [Routing] Expose request in route conditions, if needed and possible (ro0NL)
* bug #22943 [SecurityBundle] Move cache of the firewall context into the request parameters (GromNaN)
* bug #23088 [FrameworkBundle] Dont set pre-defined esi/ssi services (ro0NL)
* bug #23057 [Translation][FrameworkBundle] Fix resource loading order inconsistency reported in #23034 (mpdude)
* bug #23092 [Filesystem] added workaround in Filesystem::rename for PHP bug (VolCh)
* bug #23074 [HttpFoundation] add back support for legacy constant values (xabbuh)
* bug #23128 [HttpFoundation] fix for Support for new 7.1 session options (vincentaubert)
* bug #23176 [VarDumper] fixes (nicolas-grekas)
* bug #23100 [PropertyAccess] Do not silence TypeErrors from client code. (tsufeki)
* bug #23156 [PropertyAccess] Fix Usage with anonymous classes (mablae)
* bug #23168 [Config] Fix ** GlobResource on Windows (nicolas-grekas)
* bug #23171 [Yaml] Fix linting yaml with constants as keys (chalasr)
* bug #23121 [Routing] Revert the change in [#b42018] with respect to Routing/Route.php (Dan Wilga)
* bug #23141 [DI] Fix keys resolution in ResolveParameterPlaceHoldersPass (nicolas-grekas)
* bug #23145 Fix the conditional definition of the SymfonyTestsListener (stof)
* bug #23091 [Cache] ApcuAdapter::isSupported() should return true when apc.enable_cli=Off (nicolas-grekas)
* bug #22953 #22839 - changed debug toolbar dump section to relative and use full window width (mkurzeja)
* bug #23086 [FrameworkBundle] Fix perf issue in CacheClearCommand::warmup() (nicolas-grekas)
* bug #23090 [SecurityBundle] Made 2 service aliases private (nicolas-grekas)
* bug #23108 [Yaml] Remove line number in deprecation notices (nicolas-grekas)
* bug #23098 Cache ipCheck (2.7) (gonzalovilaseca)
* bug #23082 [MonologBridge] Do not silence errors in ServerLogHandler::formatRecord (lyrixx)
* bug #23007 [HttpKernel][Debug] Fix missing trace on deprecations collected during bootstrapping & silenced errors (ogizanagi)
* bug #23069 [SecurityBundle] Show unique Inherited roles in profile panel (yceruto)
* 3.3.2 (2017-06-06) * 3.3.2 (2017-06-06)
* bug #23073 [TwigBridge] Fix namespaced classes (ogizanagi) * bug #23073 [TwigBridge] Fix namespaced classes (ogizanagi)

View File

@ -20,11 +20,11 @@ Symfony is the result of the work of many people who made the code better
- Javier Eguiluz (javier.eguiluz) - Javier Eguiluz (javier.eguiluz)
- Hugo Hamon (hhamon) - Hugo Hamon (hhamon)
- Abdellatif Ait boudad (aitboudad) - Abdellatif Ait boudad (aitboudad)
- Maxime Steinhausser (ogizanagi)
- Robin Chalas (chalas_r)
- Romain Neutron (romain) - Romain Neutron (romain)
- Pascal Borreli (pborreli) - Pascal Borreli (pborreli)
- Wouter De Jong (wouterj) - Wouter De Jong (wouterj)
- Robin Chalas (chalas_r)
- Maxime Steinhausser (ogizanagi)
- Grégoire Pineau (lyrixx) - Grégoire Pineau (lyrixx)
- Joseph Bielawski (stloyd) - Joseph Bielawski (stloyd)
- Karma Dordrak (drak) - Karma Dordrak (drak)
@ -38,8 +38,8 @@ Symfony is the result of the work of many people who made the code better
- Jules Pietri (heah) - Jules Pietri (heah)
- Roland Franssen (ro0) - Roland Franssen (ro0)
- Sarah Khalil (saro0h) - Sarah Khalil (saro0h)
- Jonathan Wage (jwage)
- Guilhem Niot (energetick) - Guilhem Niot (energetick)
- Jonathan Wage (jwage)
- Diego Saint Esteben (dosten) - Diego Saint Esteben (dosten)
- Alexandre Salomé (alexandresalome) - Alexandre Salomé (alexandresalome)
- William Durand (couac) - William Durand (couac)
@ -48,24 +48,24 @@ Symfony is the result of the work of many people who made the code better
- stealth35 (stealth35) - stealth35 (stealth35)
- Alexander Mols (asm89) - Alexander Mols (asm89)
- Bulat Shakirzyanov (avalanche123) - Bulat Shakirzyanov (avalanche123)
- Peter Rehm (rpet)
- Iltar van der Berg (kjarli) - Iltar van der Berg (kjarli)
- Peter Rehm (rpet)
- Saša Stamenković (umpirsky) - Saša Stamenković (umpirsky)
- Henrik Bjørnskov (henrikbjorn) - Henrik Bjørnskov (henrikbjorn)
- Miha Vrhovnik - Miha Vrhovnik
- Diego Saint Esteben (dii3g0) - Diego Saint Esteben (dii3g0)
- Konstantin Kudryashov (everzet) - Konstantin Kudryashov (everzet)
- Matthias Pigulla (mpdude)
- Bilal Amarni (bamarni) - Bilal Amarni (bamarni)
- Florin Patan (florinpatan) - Florin Patan (florinpatan)
- Matthias Pigulla (mpdude) - Gábor Egyed (1ed)
- Kevin Bond (kbond) - Kevin Bond (kbond)
- Andrej Hudec (pulzarraider) - Andrej Hudec (pulzarraider)
- Gábor Egyed (1ed) - Pierre du Plessis (pierredup)
- Michel Weimerskirch (mweimerskirch) - Michel Weimerskirch (mweimerskirch)
- Eric Clemmons (ericclemmons) - Eric Clemmons (ericclemmons)
- Charles Sarrazin (csarrazi) - Charles Sarrazin (csarrazi)
- Christian Raue - Christian Raue
- Pierre du Plessis (pierredup)
- Arnout Boks (aboks) - Arnout Boks (aboks)
- Deni - Deni
- Henrik Westphal (snc) - Henrik Westphal (snc)
@ -83,25 +83,27 @@ Symfony is the result of the work of many people who made the code better
- Toni Uebernickel (havvg) - Toni Uebernickel (havvg)
- Bart van den Burg (burgov) - Bart van den Burg (burgov)
- Jordan Alliot (jalliot) - Jordan Alliot (jalliot)
- Jérôme Tamarelle (gromnan)
- John Wards (johnwards) - John Wards (johnwards)
- Dariusz Ruminski - Dariusz Ruminski
- Fran Moreno (franmomu) - Fran Moreno (franmomu)
- Antoine Hérault (herzult) - Antoine Hérault (herzult)
- Jérôme Tamarelle (gromnan)
- Paráda József (paradajozsef) - Paráda József (paradajozsef)
- Arnaud Le Blanc (arnaud-lb) - Arnaud Le Blanc (arnaud-lb)
- Maxime STEINHAUSSER - Maxime STEINHAUSSER
- Alexander M. Turek (derrabus)
- Michal Piotrowski (eventhorizon) - Michal Piotrowski (eventhorizon)
- Issei Murasawa (issei_m) - Issei Murasawa (issei_m)
- Tim Nagel (merk) - Tim Nagel (merk)
- Brice BERNARD (brikou) - Brice BERNARD (brikou)
- Alexander M. Turek (derrabus)
- Baptiste Clavié (talus) - Baptiste Clavié (talus)
- Vladimir Reznichenko (kalessil)
- marc.weistroff - marc.weistroff
- lenar - lenar
- Włodzimierz Gajda (gajdaw) - Włodzimierz Gajda (gajdaw)
- Vladimir Reznichenko (kalessil) - Yonel Ceruto González (yonelceruto)
- Alexander Schwenn (xelaris) - Alexander Schwenn (xelaris)
- Jacob Dreesen (jdreesen)
- Florian Voutzinos (florianv) - Florian Voutzinos (florianv)
- Colin Frei - Colin Frei
- Adrien Brault (adrienbrault) - Adrien Brault (adrienbrault)
@ -109,10 +111,8 @@ Symfony is the result of the work of many people who made the code better
- Peter Kokot (maastermedia) - Peter Kokot (maastermedia)
- David Buchmann (dbu) - David Buchmann (dbu)
- excelwebzone - excelwebzone
- Jacob Dreesen (jdreesen)
- Tobias Nyholm (tobias) - Tobias Nyholm (tobias)
- Tomáš Votruba (tomas_votruba) - Tomáš Votruba (tomas_votruba)
- Yonel Ceruto González (yonelceruto)
- Fabien Pennequin (fabienpennequin) - Fabien Pennequin (fabienpennequin)
- Gordon Franke (gimler) - Gordon Franke (gimler)
- Eric GELOEN (gelo) - Eric GELOEN (gelo)
@ -124,13 +124,13 @@ Symfony is the result of the work of many people who made the code better
- Sebastiaan Stok (sstok) - Sebastiaan Stok (sstok)
- Stefano Sala (stefano.sala) - Stefano Sala (stefano.sala)
- Evgeniy (ewgraf) - Evgeniy (ewgraf)
- Vincent AUBERT (vincent)
- Juti Noppornpitak (shiroyuki) - Juti Noppornpitak (shiroyuki)
- Tigran Azatyan (tigranazatyan) - Tigran Azatyan (tigranazatyan)
- Sebastian Hörl (blogsh) - Sebastian Hörl (blogsh)
- Daniel Gomes (danielcsgomes) - Daniel Gomes (danielcsgomes)
- Hidenori Goto (hidenorigoto) - Hidenori Goto (hidenorigoto)
- Guilherme Blanco (guilhermeblanco) - Guilherme Blanco (guilhermeblanco)
- Vincent AUBERT (vincent)
- Pablo Godel (pgodel) - Pablo Godel (pgodel)
- Jérémie Augustin (jaugustin) - Jérémie Augustin (jaugustin)
- Andréia Bohner (andreia) - Andréia Bohner (andreia)
@ -147,6 +147,7 @@ Symfony is the result of the work of many people who made the code better
- Thomas Rabaix (rande) - Thomas Rabaix (rande)
- Rouven Weßling (realityking) - Rouven Weßling (realityking)
- Teoh Han Hui (teohhanhui) - Teoh Han Hui (teohhanhui)
- David Maicher (dmaicher)
- Jérôme Vasseur (jvasseur) - Jérôme Vasseur (jvasseur)
- Clemens Tolboom - Clemens Tolboom
- Helmer Aaviksoo - Helmer Aaviksoo
@ -154,16 +155,16 @@ Symfony is the result of the work of many people who made the code better
- Hiromi Hishida (77web) - Hiromi Hishida (77web)
- Matthieu Ouellette-Vachon (maoueh) - Matthieu Ouellette-Vachon (maoueh)
- Michał Pipa (michal.pipa) - Michał Pipa (michal.pipa)
- Dawid Nowak
- Amal Raghav (kertz) - Amal Raghav (kertz)
- Jonathan Ingram (jonathaningram) - Jonathan Ingram (jonathaningram)
- Artur Kotyrba - Artur Kotyrba
- David Maicher (dmaicher)
- jeremyFreeAgent (Jérémy Romey) (jeremyfreeagent) - jeremyFreeAgent (Jérémy Romey) (jeremyfreeagent)
- James Halsall (jaitsu) - James Halsall (jaitsu)
- Warnar Boekkooi (boekkooi) - Warnar Boekkooi (boekkooi)
- Dmitrii Chekaliuk (lazyhammer) - Dmitrii Chekaliuk (lazyhammer)
- Clément JOBEILI (dator) - Clément JOBEILI (dator)
- Dawid Nowak - Lars Strojny (lstrojny)
- Possum - Possum
- Dorian Villet (gnutix) - Dorian Villet (gnutix)
- Richard Miller (mr_r_miller) - Richard Miller (mr_r_miller)
@ -176,12 +177,12 @@ Symfony is the result of the work of many people who made the code better
- Chris Wilkinson (thewilkybarkid) - Chris Wilkinson (thewilkybarkid)
- Andreas Hucks (meandmymonkey) - Andreas Hucks (meandmymonkey)
- Noel Guilbert (noel) - Noel Guilbert (noel)
- Lars Strojny (lstrojny)
- Stepan Anchugov (kix) - Stepan Anchugov (kix)
- bronze1man - bronze1man
- Daniel Espendiller - Daniel Espendiller
- sun (sun) - sun (sun)
- Larry Garfield (crell) - Larry Garfield (crell)
- Oleg Voronkovich
- Martin Schuhfuß (usefulthink) - Martin Schuhfuß (usefulthink)
- apetitpa - apetitpa
- Matthieu Bontemps (mbontemps) - Matthieu Bontemps (mbontemps)
@ -244,7 +245,6 @@ Symfony is the result of the work of many people who made the code better
- Uwe Jäger (uwej711) - Uwe Jäger (uwej711)
- Eugene Leonovich (rybakit) - Eugene Leonovich (rybakit)
- Filippo Tessarotto - Filippo Tessarotto
- Oleg Voronkovich
- Joseph Rouff (rouffj) - Joseph Rouff (rouffj)
- Félix Labrecque (woodspire) - Félix Labrecque (woodspire)
- GordonsLondon - GordonsLondon
@ -296,6 +296,7 @@ Symfony is the result of the work of many people who made the code better
- Victor Bocharsky (bocharsky_bw) - Victor Bocharsky (bocharsky_bw)
- Jan Decavele (jandc) - Jan Decavele (jandc)
- Gustavo Piltcher - Gustavo Piltcher
- Nikolay Labinskiy (e-moe)
- Stepan Tanasiychuk (stfalcon) - Stepan Tanasiychuk (stfalcon)
- Tiago Ribeiro (fixe) - Tiago Ribeiro (fixe)
- Hidde Boomsma (hboomsma) - Hidde Boomsma (hboomsma)
@ -361,7 +362,6 @@ Symfony is the result of the work of many people who made the code better
- Endre Fejes - Endre Fejes
- Tobias Naumann (tna) - Tobias Naumann (tna)
- Daniel Beyer - Daniel Beyer
- Nikolay Labinskiy (e-moe)
- Shein Alexey - Shein Alexey
- Romain Gautier (mykiwi) - Romain Gautier (mykiwi)
- Joe Lencioni - Joe Lencioni
@ -611,6 +611,7 @@ Symfony is the result of the work of many people who made the code better
- Kevin (oxfouzer) - Kevin (oxfouzer)
- Paweł Wacławczyk (pwc) - Paweł Wacławczyk (pwc)
- Oleg Zinchenko (cystbear) - Oleg Zinchenko (cystbear)
- Baptiste Meyer (meyerbaptiste)
- Johannes Klauss (cloppy) - Johannes Klauss (cloppy)
- Evan Villemez - Evan Villemez
- fzerorubigd - fzerorubigd
@ -673,6 +674,7 @@ Symfony is the result of the work of many people who made the code better
- Benoit Lévêque (benoit_leveque) - Benoit Lévêque (benoit_leveque)
- Jeroen Fiege (fieg) - Jeroen Fiege (fieg)
- Krzysiek Łabuś - Krzysiek Łabuś
- George Mponos (gmponos)
- Xavier Lacot (xavier) - Xavier Lacot (xavier)
- possum - possum
- Denis Zunke (donalberto) - Denis Zunke (donalberto)
@ -736,6 +738,7 @@ Symfony is the result of the work of many people who made the code better
- Omar Yepez (oyepez003) - Omar Yepez (oyepez003)
- mwsaz - mwsaz
- Jelle Kapitein - Jelle Kapitein
- Ben Scott
- Benoît Bourgeois - Benoît Bourgeois
- mantulo - mantulo
- corphi - corphi
@ -817,6 +820,7 @@ Symfony is the result of the work of many people who made the code better
- ttomor - ttomor
- Mei Gwilym (meigwilym) - Mei Gwilym (meigwilym)
- Michael H. Arieli (excelwebzone) - Michael H. Arieli (excelwebzone)
- Tom Panier (neemzy)
- Fred Cox - Fred Cox
- Luciano Mammino (loige) - Luciano Mammino (loige)
- fabios - fabios
@ -852,6 +856,7 @@ Symfony is the result of the work of many people who made the code better
- Máximo Cuadros (mcuadros) - Máximo Cuadros (mcuadros)
- tamirvs - tamirvs
- julien.galenski - julien.galenski
- Israel J. Carberry
- Bob van de Vijver - Bob van de Vijver
- Christian Neff - Christian Neff
- Per Sandström (per) - Per Sandström (per)
@ -890,7 +895,6 @@ Symfony is the result of the work of many people who made the code better
- Eddie Jaoude - Eddie Jaoude
- Antanas Arvasevicius - Antanas Arvasevicius
- Haritz Iturbe (hizai) - Haritz Iturbe (hizai)
- Baptiste Meyer (meyerbaptiste)
- Nerijus Arlauskas (nercury) - Nerijus Arlauskas (nercury)
- SPolischook - SPolischook
- Diego Sapriza - Diego Sapriza
@ -912,8 +916,10 @@ Symfony is the result of the work of many people who made the code better
- Marcin Chwedziak - Marcin Chwedziak
- hjkl - hjkl
- Tony Cosentino (tony-co) - Tony Cosentino (tony-co)
- Dan Wilga
- Alexander Cheprasov - Alexander Cheprasov
- Rodrigo Díez Villamuera (rodrigodiez) - Rodrigo Díez Villamuera (rodrigodiez)
- Malte Blättermann
- e-ivanov - e-ivanov
- Jochen Bayer (jocl) - Jochen Bayer (jocl)
- Jeremy Bush - Jeremy Bush
@ -925,12 +931,14 @@ Symfony is the result of the work of many people who made the code better
- Péter Buri (burci) - Péter Buri (burci)
- Davide Borsatto (davide.borsatto) - Davide Borsatto (davide.borsatto)
- kaiwa - kaiwa
- RJ Garcia
- Charles Sanquer (csanquer) - Charles Sanquer (csanquer)
- Albert Ganiev (helios-ag) - Albert Ganiev (helios-ag)
- Neil Katin - Neil Katin
- David Otton - David Otton
- Will Donohoe - Will Donohoe
- peter - peter
- Jaroslav Kuba
- flip111 - flip111
- Jérémy Jourdin (jjk801) - Jérémy Jourdin (jjk801)
- BRAMILLE Sébastien (oktapodia) - BRAMILLE Sébastien (oktapodia)
@ -938,6 +946,7 @@ Symfony is the result of the work of many people who made the code better
- Gustavo Adrian - Gustavo Adrian
- Yannick - Yannick
- spdionis - spdionis
- rchoquet
- Taras Girnyk - Taras Girnyk
- Eduardo García Sanz (coma) - Eduardo García Sanz (coma)
- James Gilliland - James Gilliland
@ -967,6 +976,7 @@ Symfony is the result of the work of many people who made the code better
- Paul Matthews - Paul Matthews
- Juan Traverso - Juan Traverso
- Tarjei Huse (tarjei) - Tarjei Huse (tarjei)
- tsufeki
- Philipp Strube - Philipp Strube
- Christian Sciberras - Christian Sciberras
- Clement Herreman (clemherreman) - Clement Herreman (clemherreman)
@ -1057,6 +1067,7 @@ Symfony is the result of the work of many people who made the code better
- m.chwedziak - m.chwedziak
- Philip Frank - Philip Frank
- Lance McNearney - Lance McNearney
- Gonzalo Vilaseca (gonzalovilaseca)
- Giorgio Premi - Giorgio Premi
- Ian Carroll - Ian Carroll
- caponica - caponica
@ -1067,7 +1078,6 @@ Symfony is the result of the work of many people who made the code better
- adev - adev
- Luis Galeas - Luis Galeas
- Martin Pärtel - Martin Pärtel
- George Mponos (gmponos)
- Patrick Daley (padrig) - Patrick Daley (padrig)
- Xavier Briand (xavierbriand) - Xavier Briand (xavierbriand)
- Max Summe - Max Summe
@ -1148,6 +1158,7 @@ Symfony is the result of the work of many people who made the code better
- Hoffmann András - Hoffmann András
- Olivier - Olivier
- pscheit - pscheit
- Wybren Koelmans
- Zdeněk Drahoš - Zdeněk Drahoš
- Dan Harper - Dan Harper
- moldcraft - moldcraft
@ -1235,6 +1246,7 @@ Symfony is the result of the work of many people who made the code better
- Fabien LUCAS (flucas2) - Fabien LUCAS (flucas2)
- Indra Gunawan (indragunawan) - Indra Gunawan (indragunawan)
- Karim Cassam Chenaï (ka) - Karim Cassam Chenaï (ka)
- Michal Kurzeja (mkurzeja)
- Nicolas Bastien (nicolas_bastien) - Nicolas Bastien (nicolas_bastien)
- Denis (yethee) - Denis (yethee)
- Andrew Zhilin (zhil) - Andrew Zhilin (zhil)
@ -1253,9 +1265,11 @@ Symfony is the result of the work of many people who made the code better
- Warwick - Warwick
- VJ - VJ
- Chris - Chris
- Florent Olivaud
- JakeFr - JakeFr
- Simon Sargeant - Simon Sargeant
- efeen - efeen
- Nicolas Pion
- Muhammed Akbulut - Muhammed Akbulut
- Michał Dąbrowski (defrag) - Michał Dąbrowski (defrag)
- Simone Fumagalli (hpatoio) - Simone Fumagalli (hpatoio)
@ -1272,6 +1286,7 @@ Symfony is the result of the work of many people who made the code better
- Grinbergs Reinis (shima5) - Grinbergs Reinis (shima5)
- Artem Lopata (bumz) - Artem Lopata (bumz)
- Nicole Cordes - Nicole Cordes
- VolCh
- Alexey Popkov - Alexey Popkov
- Gijs Kunze - Gijs Kunze
- Artyom Protaskin - Artyom Protaskin
@ -1377,6 +1392,7 @@ Symfony is the result of the work of many people who made the code better
- Dane Powell - Dane Powell
- Gerrit Drost - Gerrit Drost
- Linnaea Von Lavia - Linnaea Von Lavia
- Javan Eskander
- Lenar Lõhmus - Lenar Lõhmus
- Cristian Gonzalez - Cristian Gonzalez
- AlberT - AlberT
@ -1425,7 +1441,6 @@ Symfony is the result of the work of many people who made the code better
- Yanick Witschi - Yanick Witschi
- Ondrej Mirtes - Ondrej Mirtes
- akimsko - akimsko
- Ben Scott
- Youpie - Youpie
- srsbiz - srsbiz
- Taylan Kasap - Taylan Kasap
@ -1558,6 +1573,7 @@ Symfony is the result of the work of many people who made the code better
- Dawid Nowak - Dawid Nowak
- Lesnykh Ilia - Lesnykh Ilia
- Karolis Daužickas - Karolis Daužickas
- Nicolas
- Sergio Santoro - Sergio Santoro
- tirnanog06 - tirnanog06
- phc - phc
@ -1691,6 +1707,7 @@ Symfony is the result of the work of many people who made the code better
- Adam Elsodaney (archfizz) - Adam Elsodaney (archfizz)
- Daniel Kolvik (dkvk) - Daniel Kolvik (dkvk)
- Marc Lemay (flug) - Marc Lemay (flug)
- Henne Van Och (hennevo)
- Jeroen De Dauw (jeroendedauw) - Jeroen De Dauw (jeroendedauw)
- Maxime COLIN (maximecolin) - Maxime COLIN (maximecolin)
- Muharrem Demirci (mdemirci) - Muharrem Demirci (mdemirci)

View File

@ -440,7 +440,7 @@ HttpKernel
Ldap Ldap
---- ----
* The `RenameEntryInterface` has been deprecated, and merged with `EntryManagerInterface` * The `RenameEntryInterface` has been removed, and merged with `EntryManagerInterface`
Process Process
------- -------

View File

@ -53,7 +53,10 @@ abstract class ManagerRegistry extends AbstractManagerRegistry implements Contai
} }
$manager->setProxyInitializer(\Closure::bind( $manager->setProxyInitializer(\Closure::bind(
function (&$wrappedInstance, LazyLoadingInterface $manager) use ($name) { function (&$wrappedInstance, LazyLoadingInterface $manager) use ($name) {
if (isset($this->aliases[$name = strtolower($name)])) { if (isset($this->normalizedIds[$normalizedId = strtolower($name)])) {
$name = $this->normalizedIds[$normalizedId];
}
if (isset($this->aliases[$name])) {
$name = $this->aliases[$name]; $name = $this->aliases[$name];
} }
$method = !isset($this->methodMap[$name]) ? 'get'.strtr($name, $this->underscoreMap).'Service' : $this->methodMap[$name]; $method = !isset($this->methodMap[$name]) ? 'get'.strtr($name, $this->underscoreMap).'Service' : $this->methodMap[$name];

View File

@ -121,7 +121,9 @@ EOT
continue; continue;
} }
$targetDir = $bundlesDir.preg_replace('/bundle$/', '', strtolower($bundle->getName())); $assetDir = preg_replace('/bundle$/', '', strtolower($bundle->getName()));
$targetDir = $bundlesDir.$assetDir;
$validAssetDirs[] = $assetDir;
if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) { if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
$message = sprintf("%s\n-> %s", $bundle->getName(), $targetDir); $message = sprintf("%s\n-> %s", $bundle->getName(), $targetDir);
@ -153,14 +155,10 @@ EOT
$exitCode = 1; $exitCode = 1;
$rows[] = array(sprintf('<fg=red;options=bold>%s</>', '\\' === DIRECTORY_SEPARATOR ? 'ERROR' : "\xE2\x9C\x98" /* HEAVY BALLOT X (U+2718) */), $message, $e->getMessage()); $rows[] = array(sprintf('<fg=red;options=bold>%s</>', '\\' === DIRECTORY_SEPARATOR ? 'ERROR' : "\xE2\x9C\x98" /* HEAVY BALLOT X (U+2718) */), $message, $e->getMessage());
} }
$validAssetDirs[] = $targetDir;
} }
// remove the assets of the bundles that no longer exist // remove the assets of the bundles that no longer exist
foreach (new \FilesystemIterator($bundlesDir) as $dir) { $dirsToRemove = Finder::create()->depth(0)->directories()->exclude($validAssetDirs)->in($bundlesDir);
if (!in_array($dir, $validAssetDirs)) { $this->filesystem->remove($dirsToRemove);
$this->filesystem->remove($dir);
}
}
$io->table(array('', 'Bundle', 'Method / Error'), $rows); $io->table(array('', 'Bundle', 'Method / Error'), $rows);

View File

@ -12,6 +12,7 @@
namespace Symfony\Bundle\FrameworkBundle\Command; namespace Symfony\Bundle\FrameworkBundle\Command;
use Symfony\Bundle\FrameworkBundle\Console\Helper\DescriptorHelper; use Symfony\Bundle\FrameworkBundle\Console\Helper\DescriptorHelper;
use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputOption;
@ -112,7 +113,7 @@ EOF
private function convertController(Route $route) private function convertController(Route $route)
{ {
if ($route->hasDefault('_controller')) { if ($route->hasDefault('_controller')) {
$nameParser = $this->getContainer()->get('controller_name_converter'); $nameParser = new ControllerNameParser($this->getApplication()->getKernel());
try { try {
$route->setDefault('_controller', $nameParser->build($route->getDefault('_controller'))); $route->setDefault('_controller', $nameParser->build($route->getDefault('_controller')));
} catch (\InvalidArgumentException $e) { } catch (\InvalidArgumentException $e) {
@ -136,7 +137,7 @@ EOF
} }
} }
$nameParser = $this->getContainer()->get('controller_name_converter'); $nameParser = new ControllerNameParser($this->getApplication()->getKernel());
try { try {
$shortNotation = $nameParser->build($controller); $shortNotation = $nameParser->build($controller);
$route->setDefault('_controller', $shortNotation); $route->setDefault('_controller', $shortNotation);

View File

@ -49,7 +49,19 @@ class ControllerResolver extends ContainerControllerResolver
$controller = $this->parser->parse($controller); $controller = $this->parser->parse($controller);
} }
return parent::createController($controller); $resolvedController = parent::createController($controller);
if (1 === substr_count($controller, ':') && is_array($resolvedController)) {
if ($resolvedController[0] instanceof ContainerAwareInterface) {
$resolvedController[0]->setContainer($this->container);
}
if ($resolvedController[0] instanceof AbstractController && null !== $previousContainer = $resolvedController[0]->setContainer($this->container)) {
$resolvedController[0]->setContainer($previousContainer);
}
}
return $resolvedController;
} }
/** /**

View File

@ -12,9 +12,10 @@
namespace Symfony\Bundle\FrameworkBundle\Tests\Command; namespace Symfony\Bundle\FrameworkBundle\Tests\Command;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Application; use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Bundle\FrameworkBundle\Command\RouterDebugCommand; use Symfony\Bundle\FrameworkBundle\Command\RouterDebugCommand;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Routing\Route; use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\RouteCollection;
@ -51,16 +52,15 @@ class RouterDebugCommandTest extends TestCase
*/ */
private function createCommandTester() private function createCommandTester()
{ {
$application = new Application(); $application = new Application($this->getKernel());
$command = new RouterDebugCommand(); $command = new RouterDebugCommand();
$command->setContainer($this->getContainer());
$application->add($command); $application->add($command);
return new CommandTester($application->find('debug:router')); return new CommandTester($application->find('debug:router'));
} }
private function getContainer() private function getKernel()
{ {
$routeCollection = new RouteCollection(); $routeCollection = new RouteCollection();
$routeCollection->add('foo', new Route('foo')); $routeCollection->add('foo', new Route('foo'));
@ -82,14 +82,25 @@ class RouterDebugCommandTest extends TestCase
->with('router') ->with('router')
->will($this->returnValue(true)) ->will($this->returnValue(true))
; ;
$container $container
->expects($this->any())
->method('get') ->method('get')
->will($this->returnValueMap(array( ->with('router')
array('router', 1, $router), ->willReturn($router)
array('controller_name_converter', 1, $loader), ;
)));
return $container; $kernel = $this->getMockBuilder(KernelInterface::class)->getMock();
$kernel
->expects($this->any())
->method('getContainer')
->willReturn($container)
;
$kernel
->expects($this->once())
->method('getBundles')
->willReturn(array())
;
return $kernel;
} }
} }

View File

@ -12,10 +12,11 @@
namespace Symfony\Bundle\FrameworkBundle\Tests\Command; namespace Symfony\Bundle\FrameworkBundle\Tests\Command;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Application; use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Bundle\FrameworkBundle\Command\RouterMatchCommand; use Symfony\Bundle\FrameworkBundle\Command\RouterMatchCommand;
use Symfony\Bundle\FrameworkBundle\Command\RouterDebugCommand; use Symfony\Bundle\FrameworkBundle\Command\RouterDebugCommand;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Routing\Route; use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\RequestContext; use Symfony\Component\Routing\RequestContext;
@ -45,20 +46,14 @@ class RouterMatchCommandTest extends TestCase
*/ */
private function createCommandTester() private function createCommandTester()
{ {
$application = new Application(); $application = new Application($this->getKernel());
$application->add(new RouterMatchCommand());
$command = new RouterMatchCommand(); $application->add(new RouterDebugCommand());
$command->setContainer($this->getContainer());
$application->add($command);
$command = new RouterDebugCommand();
$command->setContainer($this->getContainer());
$application->add($command);
return new CommandTester($application->find('router:match')); return new CommandTester($application->find('router:match'));
} }
private function getContainer() private function getKernel()
{ {
$routeCollection = new RouteCollection(); $routeCollection = new RouteCollection();
$routeCollection->add('foo', new Route('foo')); $routeCollection->add('foo', new Route('foo'));
@ -81,16 +76,27 @@ class RouterMatchCommandTest extends TestCase
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock(); $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock();
$container $container
->expects($this->once()) ->expects($this->atLeastOnce())
->method('has') ->method('has')
->with('router') ->with('router')
->will($this->returnValue(true)); ->will($this->returnValue(true));
$container->method('get') $container
->will($this->returnValueMap(array( ->expects($this->any())
array('router', 1, $router), ->method('get')
array('controller_name_converter', 1, $loader), ->willReturn($router);
)));
return $container; $kernel = $this->getMockBuilder(KernelInterface::class)->getMock();
$kernel
->expects($this->any())
->method('getContainer')
->willReturn($container)
;
$kernel
->expects($this->once())
->method('getBundles')
->willReturn(array())
;
return $kernel;
} }
} }

View File

@ -13,6 +13,7 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Controller;
use Psr\Container\ContainerInterface as Psr11ContainerInterface; use Psr\Container\ContainerInterface as Psr11ContainerInterface;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser; use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser;
use Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver; use Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver;
use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\Container;
@ -68,6 +69,24 @@ class ControllerResolverTest extends ContainerControllerResolverTest
$this->assertSame('testAction', $controller[1]); $this->assertSame('testAction', $controller[1]);
} }
public function testContainerAwareControllerGetsContainerWhenNotSet()
{
class_exists(AbstractControllerTest::class);
$controller = new ContainerAwareController();
$container = new Container();
$container->set(TestAbstractController::class, $controller);
$resolver = $this->createControllerResolver(null, $container);
$request = Request::create('/');
$request->attributes->set('_controller', TestAbstractController::class.':testAction');
$this->assertSame(array($controller, 'testAction'), $resolver->getController($request));
$this->assertSame($container, $controller->getContainer());
}
public function testAbstractControllerGetsContainerWhenNotSet() public function testAbstractControllerGetsContainerWhenNotSet()
{ {
class_exists(AbstractControllerTest::class); class_exists(AbstractControllerTest::class);
@ -86,6 +105,24 @@ class ControllerResolverTest extends ContainerControllerResolverTest
$this->assertSame($container, $controller->setContainer($container)); $this->assertSame($container, $controller->setContainer($container));
} }
public function testAbstractControllerServiceWithFcqnIdGetsContainerWhenNotSet()
{
class_exists(AbstractControllerTest::class);
$controller = new DummyController();
$container = new Container();
$container->set(DummyController::class, $controller);
$resolver = $this->createControllerResolver(null, $container);
$request = Request::create('/');
$request->attributes->set('_controller', DummyController::class.':fooAction');
$this->assertSame(array($controller, 'fooAction'), $resolver->getController($request));
$this->assertSame($container, $controller->getContainer());
}
public function testAbstractControllerGetsNoContainerWhenSet() public function testAbstractControllerGetsNoContainerWhenSet()
{ {
class_exists(AbstractControllerTest::class); class_exists(AbstractControllerTest::class);
@ -106,6 +143,26 @@ class ControllerResolverTest extends ContainerControllerResolverTest
$this->assertSame($controllerContainer, $controller->setContainer($container)); $this->assertSame($controllerContainer, $controller->setContainer($container));
} }
public function testAbstractControllerServiceWithFcqnIdGetsNoContainerWhenSet()
{
class_exists(AbstractControllerTest::class);
$controller = new DummyController();
$controllerContainer = new Container();
$controller->setContainer($controllerContainer);
$container = new Container();
$container->set(DummyController::class, $controller);
$resolver = $this->createControllerResolver(null, $container);
$request = Request::create('/');
$request->attributes->set('_controller', DummyController::class.':fooAction');
$this->assertSame(array($controller, 'fooAction'), $resolver->getController($request));
$this->assertSame($controllerContainer, $controller->getContainer());
}
protected function createControllerResolver(LoggerInterface $logger = null, Psr11ContainerInterface $container = null, ControllerNameParser $parser = null) protected function createControllerResolver(LoggerInterface $logger = null, Psr11ContainerInterface $container = null, ControllerNameParser $parser = null)
{ {
if (!$parser) { if (!$parser) {
@ -152,3 +209,15 @@ class ContainerAwareController implements ContainerAwareInterface
{ {
} }
} }
class DummyController extends AbstractController
{
public function getContainer()
{
return $this->container;
}
public function fooAction()
{
}
}

View File

@ -78,27 +78,27 @@ class SecurityRoutingIntegrationTest extends WebTestCase
$this->assertRestricted($barredClient, '/secured-by-two-ips'); $this->assertRestricted($barredClient, '/secured-by-two-ips');
} }
/** /**
* @dataProvider getConfigs * @dataProvider getConfigs
*/ */
public function testSecurityConfigurationForExpression($config) public function testSecurityConfigurationForExpression($config)
{ {
$allowedClient = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config), array('HTTP_USER_AGENT' => 'Firefox 1.0')); $allowedClient = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config), array('HTTP_USER_AGENT' => 'Firefox 1.0'));
$this->assertAllowed($allowedClient, '/protected-via-expression'); $this->assertAllowed($allowedClient, '/protected-via-expression');
$barredClient = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config), array()); $barredClient = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config), array());
$this->assertRestricted($barredClient, '/protected-via-expression'); $this->assertRestricted($barredClient, '/protected-via-expression');
$allowedClient = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config), array()); $allowedClient = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config), array());
$allowedClient->request('GET', '/protected-via-expression'); $allowedClient->request('GET', '/protected-via-expression');
$form = $allowedClient->followRedirect()->selectButton('login')->form(); $form = $allowedClient->followRedirect()->selectButton('login')->form();
$form['_username'] = 'johannes'; $form['_username'] = 'johannes';
$form['_password'] = 'test'; $form['_password'] = 'test';
$allowedClient->submit($form); $allowedClient->submit($form);
$this->assertRedirect($allowedClient->getResponse(), '/protected-via-expression'); $this->assertRedirect($allowedClient->getResponse(), '/protected-via-expression');
$this->assertAllowed($allowedClient, '/protected-via-expression'); $this->assertAllowed($allowedClient, '/protected-via-expression');
} }
private function assertAllowed($client, $path) private function assertAllowed($client, $path)
{ {

View File

@ -1,28 +1,29 @@
{% if trace.file|default(false) %} <div class="trace-line-header {{ trace.file|default(false) ? 'sf-toggle' }}" data-toggle-selector="#trace-html-{{ prefix }}-{{ i }}" data-toggle-initial="{{ _display_code_snippet ? 'display' }}">
<span class="icon icon-close">{{ include('@Twig/images/icon-minus-square.svg') }}</span> {% if trace.file|default(false) %}
<span class="icon icon-open">{{ include('@Twig/images/icon-plus-square.svg') }}</span> <span class="icon icon-close">{{ include('@Twig/images/icon-minus-square.svg') }}</span>
{% endif %} <span class="icon icon-open">{{ include('@Twig/images/icon-plus-square.svg') }}</span>
{% endif %}
{% if trace.function %} {% if trace.function %}
<span class="trace-class">{{ trace.class|abbr_class }}</span>{% if trace.type is not empty %}<span class="trace-type">{{ trace.type }}</span>{% endif %}<span class="trace-method">{{ trace.function }}</span><span class="trace-arguments">({{ trace.args|format_args }})</span> <span class="trace-class">{{ trace.class|abbr_class }}</span>{% if trace.type is not empty %}<span class="trace-type">{{ trace.type }}</span>{% endif %}<span class="trace-method">{{ trace.function }}</span><span class="trace-arguments">({{ trace.args|format_args }})</span>
{% endif %} {% endif %}
{% if trace.file|default(false) %} {% if trace.file|default(false) %}
{% set line_number = trace.line|default(1) %} {% set line_number = trace.line|default(1) %}
{% set file_link = trace.file|file_link(line_number) %} {% set file_link = trace.file|file_link(line_number) %}
{% set file_path = trace.file|format_file(line_number)|striptags|replace({ (' at line ' ~ line_number): '' }) %} {% set file_path = trace.file|format_file(line_number)|striptags|replace({ (' at line ' ~ line_number): '' }) %}
{% set file_path_parts = file_path|split(constant('DIRECTORY_SEPARATOR')) %} {% set file_path_parts = file_path|split(constant('DIRECTORY_SEPARATOR')) %}
<span class="block trace-file-path">
in
<a href="{{ file_link }}">{{ file_path_parts[:-1]|join(constant('DIRECTORY_SEPARATOR')) }}{{ constant('DIRECTORY_SEPARATOR') }}<strong>{{ file_path_parts|last }}</strong></a>
(line {{ line_number }})
</span>
{% endif %}
<span class="block trace-file-path">
in
<a href="{{ file_link }}">{{ file_path_parts[:-1]|join(constant('DIRECTORY_SEPARATOR')) }}{{ constant('DIRECTORY_SEPARATOR') }}<strong>{{ file_path_parts|last }}</strong></a>
(line {{ line_number }})
</span>
{% endif %}
</div>
{% if trace.file|default(false) %} {% if trace.file|default(false) %}
<div id="trace-html-{{ prefix ~ '-' ~ i }}" class="trace-code sf-toggle-content"> <div id="trace-html-{{ prefix ~ '-' ~ i }}" class="trace-code sf-toggle-content">
{{ trace.file|file_excerpt(trace.line)|replace({ {{ trace.file|file_excerpt(trace.line, 5)|replace({
'#DD0000': '#183691', '#DD0000': '#183691',
'#007700': '#a71d5d', '#007700': '#a71d5d',
'#0000BB': '#222222', '#0000BB': '#222222',

View File

@ -1,37 +1,33 @@
<div class="trace trace-as-html"> <div class="trace trace-as-html">
<table class="trace-details"> <div class="trace-details">
<thead class="trace-head"> <div class="trace-head">
<tr> <span class="sf-toggle" data-toggle-selector="#trace-html-{{ index }}" data-toggle-initial="{{ expand ? 'display' }}">
<th class="sf-toggle" data-toggle-selector="#trace-html-{{ index }}" data-toggle-initial="{{ expand ? 'display' }}"> <h3 class="trace-class">
<h3 class="trace-class"> <span class="trace-namespace">
<span class="trace-namespace"> {{ exception.class|split('\\')|slice(0, -1)|join('\\') }}
{{ exception.class|split('\\')|slice(0, -1)|join('\\') }} {{- exception.class|split('\\')|length > 1 ? '\\' }}
{{- exception.class|split('\\')|length > 1 ? '\\' }} </span>
</span> {{ exception.class|split('\\')|last }}
{{ exception.class|split('\\')|last }}
<span class="icon icon-close">{{ include('@Twig/images/icon-minus-square-o.svg') }}</span> <span class="icon icon-close">{{ include('@Twig/images/icon-minus-square-o.svg') }}</span>
<span class="icon icon-open">{{ include('@Twig/images/icon-plus-square-o.svg') }}</span> <span class="icon icon-open">{{ include('@Twig/images/icon-plus-square-o.svg') }}</span>
</h3> </h3>
{% if exception.message is not empty and index > 1 %} {% if exception.message is not empty and index > 1 %}
<p class="break-long-words trace-message">{{ exception.message }}</p> <p class="break-long-words trace-message">{{ exception.message }}</p>
{% endif %} {% endif %}
</th> </span>
</tr> </div>
</thead>
<tbody id="trace-html-{{ index }}" class="sf-toggle-content"> <div id="trace-html-{{ index }}" class="sf-toggle-content">
{% set _is_first_user_code = true %} {% set _is_first_user_code = true %}
{% for i, trace in exception.trace %} {% for i, trace in exception.trace %}
{% set _display_code_snippet = _is_first_user_code and ('/vendor/' not in trace.file) and ('/var/cache/' not in trace.file) and (trace.file is not empty) %} {% set _display_code_snippet = _is_first_user_code and ('/vendor/' not in trace.file) and ('/var/cache/' not in trace.file) and (trace.file is not empty) %}
{% if _display_code_snippet %}{% set _is_first_user_code = false %}{% endif %} {% if _display_code_snippet %}{% set _is_first_user_code = false %}{% endif %}
<tr> <div class="trace-line">
<td class="trace-line {{ trace.file|default(false) ? 'sf-toggle' }}" data-toggle-selector="#trace-html-{{ index }}-{{ i }}" data-toggle-initial="{{ _display_code_snippet ? 'display' }}"> {{ include('@Twig/Exception/trace.html.twig', { prefix: index, i: i, trace: trace, _display_code_snippet: _display_code_snippet }, with_context = false) }}
{{ include('@Twig/Exception/trace.html.twig', { prefix: index, i: i, trace: trace }, with_context = false) }} </div>
</td>
</tr>
{% endfor %} {% endfor %}
</tbody> </div>
</table> </div>
</div> </div>

View File

@ -89,30 +89,34 @@ header .container { display: flex; justify-content: space-between; }
.exception-illustration { flex-basis: 111px; flex-shrink: 0; height: 66px; margin-left: 15px; opacity: .7; } .exception-illustration { flex-basis: 111px; flex-shrink: 0; height: 66px; margin-left: 15px; opacity: .7; }
.trace + .trace { margin-top: 30px; } .trace + .trace { margin-top: 30px; }
.trace-head { background-color: #e0e0e0; padding: 10px; }
.trace-head .trace-class { color: #222; font-size: 18px; font-weight: bold; line-height: 1.3; margin: 0; position: relative; } .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 .trace-namespace { color: #999; display: block; font-size: 13px; }
.trace-head .icon { position: absolute; right: 0; top: 0; } .trace-head .icon { position: absolute; right: 0; top: 0; }
.trace-head .icon svg { height: 24px; width: 24px; } .trace-head .icon svg { height: 24px; width: 24px; }
.trace-details { background: #FFF; border: 1px solid #E0E0E0; box-shadow: 0px 0px 1px rgba(128, 128, 128, .2); margin: 1em 0; }
.trace-message { font-size: 14px; font-weight: normal; margin: .5em 0 0; } .trace-message { font-size: 14px; font-weight: normal; margin: .5em 0 0; }
.trace-details { table-layout: fixed; } .trace-details { table-layout: fixed; }
.trace-line { position: relative; padding-left: 36px; } .trace-line { position: relative; padding-top: 8px; padding-bottom: 8px; }
.trace-line.sf-toggle:hover { background: #F5F5F5; } .trace-line:hover { background: #F5F5F5; }
.trace-line a { color: #222; } .trace-line a { color: #222; }
.trace-line .icon { opacity: .4; position: absolute; left: 10px; top: 11px; } .trace-line .icon { opacity: .4; position: absolute; left: 10px; top: 11px; }
.trace-line .icon svg { height: 16px; width: 16px; } .trace-line .icon svg { height: 16px; width: 16px; }
.trace-line-header { padding-left: 36px; }
.trace-file-path, .trace-file-path a { margin-top: 3px; color: #999; color: #795da3; color: #B0413E; color: #222; font-size: 13px; } .trace-file-path, .trace-file-path a { color: #999; color: #795da3; color: #B0413E; color: #222; font-size: 13px; }
.trace-class { color: #B0413E; } .trace-class { color: #B0413E; }
.trace-type { padding: 0 2px; } .trace-type { padding: 0 2px; }
.trace-method { color: #B0413E; color: #222; font-weight: bold; color: #B0413E; } .trace-method { color: #B0413E; color: #222; font-weight: bold; color: #B0413E; }
.trace-arguments { color: #222; color: #999; font-weight: normal; color: #795da3; color: #777; padding-left: 2px; } .trace-arguments { color: #222; color: #999; font-weight: normal; color: #795da3; color: #777; padding-left: 2px; }
.trace-code { background: #FFF; font-size: 12px; margin: 10px 0 2px; padding: 10px; overflow-x: auto; } .trace-code { background: #FFF; font-size: 12px; margin: 10px 10px 2px 10px; padding: 10px; overflow-x: auto; white-space: nowrap; }
.trace-code ol { margin: 0; float: left; } .trace-code ol { margin: 0; float: left; }
.trace-code li { color: #969896; margin: 0; padding-left: 10px; float: left; width: 100%; } .trace-code li { color: #969896; margin: 0; padding-left: 10px; float: left; width: 100%; }
.trace-code li + li { margin-top: 5px; } .trace-code li + li { margin-top: 5px; }
.trace-code li.selected { background: #F8EEC7; padding: 3px 0 3px 10px; margin-top: 2px; } .trace-code li.selected { background: #F7E5A1; margin-top: 2px; }
.trace-code li code { color: #222; white-space: nowrap; } .trace-code li code { color: #222; white-space: nowrap; }
.trace-as-text .stacktrace { line-height: 1.8; margin: 0 0 15px; white-space: pre-wrap; } .trace-as-text .stacktrace { line-height: 1.8; margin: 0 0 15px; white-space: pre-wrap; }

View File

@ -14,6 +14,7 @@ namespace Symfony\Component\Cache\Adapter;
use Psr\Cache\CacheItemInterface; use Psr\Cache\CacheItemInterface;
use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Symfony\Component\Cache\CacheItem; use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Exception\InvalidArgumentException; use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\Traits\AbstractTrait; use Symfony\Component\Cache\Traits\AbstractTrait;
@ -101,7 +102,9 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface
} }
$apcu = new ApcuAdapter($namespace, (int) $defaultLifetime / 5, $version); $apcu = new ApcuAdapter($namespace, (int) $defaultLifetime / 5, $version);
if (null !== $logger) { if ('cli' === PHP_SAPI && !ini_get('apc.enable_cli')) {
$apcu->setLogger(new NullLogger());
} elseif (null !== $logger) {
$apcu->setLogger($logger); $apcu->setLogger($logger);
} }

View File

@ -52,7 +52,7 @@ trait ApcuTrait
protected function doFetch(array $ids) protected function doFetch(array $ids)
{ {
try { try {
return apcu_fetch($ids); return apcu_fetch($ids) ?: array();
} catch (\Error $e) { } catch (\Error $e) {
throw new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine()); throw new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine());
} }
@ -94,7 +94,11 @@ trait ApcuTrait
protected function doSave(array $values, $lifetime) protected function doSave(array $values, $lifetime)
{ {
try { try {
return array_keys(apcu_store($values, null, $lifetime)); if (false === $failures = apcu_store($values, null, $lifetime)) {
$failures = $values;
}
return array_keys($failures);
} catch (\Error $e) { } catch (\Error $e) {
} catch (\Exception $e) { } catch (\Exception $e) {
} }

View File

@ -414,7 +414,7 @@ class ErrorHandler
$errorAsException = self::$silencedErrorCache[$message]; $errorAsException = self::$silencedErrorCache[$message];
++$errorAsException->count; ++$errorAsException->count;
} else { } else {
$lightTrace = $this->tracedErrors & $type ? $this->cleanTrace(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), $type, $file, $line, false) : array(); $lightTrace = $this->tracedErrors & $type ? $this->cleanTrace(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3), $type, $file, $line, false) : array();
$errorAsException = new SilencedErrorContext($type, $file, $line, $lightTrace); $errorAsException = new SilencedErrorContext($type, $file, $line, $lightTrace);
} }

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\DependencyInjection; namespace Symfony\Component\DependencyInjection;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage; use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage;
use Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface;
/** /**
* Adds some function to the default ExpressionLanguage. * Adds some function to the default ExpressionLanguage.
@ -23,7 +22,10 @@ use Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface;
*/ */
class ExpressionLanguage extends BaseExpressionLanguage class ExpressionLanguage extends BaseExpressionLanguage
{ {
public function __construct(ParserCacheInterface $cache = null, array $providers = array()) /**
* {@inheritdoc}
*/
public function __construct($cache = null, array $providers = array())
{ {
// prepend the default provider to let users override it easily // prepend the default provider to let users override it easily
array_unshift($providers, new ExpressionLanguageProvider()); array_unshift($providers, new ExpressionLanguageProvider());

View File

@ -46,7 +46,7 @@ class Cookie
'path' => '/', 'path' => '/',
'domain' => null, 'domain' => null,
'secure' => false, 'secure' => false,
'httponly' => true, 'httponly' => false,
'raw' => !$decode, 'raw' => !$decode,
'samesite' => null, 'samesite' => null,
); );

View File

@ -200,6 +200,15 @@ class CookieTest extends TestCase
$this->assertEquals(new Cookie('foo', 'bar', strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true, true, true), $cookie); $this->assertEquals(new Cookie('foo', 'bar', strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true, true, true), $cookie);
$cookie = Cookie::fromString('foo=bar', true); $cookie = Cookie::fromString('foo=bar', true);
$this->assertEquals(new Cookie('foo', 'bar'), $cookie); $this->assertEquals(new Cookie('foo', 'bar', 0, '/', null, false, false), $cookie);
}
public function testFromStringWithHttpOnly()
{
$cookie = Cookie::fromString('foo=bar; expires=Fri, 20-May-2011 15:25:52 GMT; path=/; domain=.myfoodomain.com; secure; httponly');
$this->assertTrue($cookie->isHttpOnly());
$cookie = Cookie::fromString('foo=bar; expires=Fri, 20-May-2011 15:25:52 GMT; path=/; domain=.myfoodomain.com; secure');
$this->assertFalse($cookie->isHttpOnly());
} }
} }

View File

@ -217,12 +217,12 @@ class ResponseHeaderBagTest extends TestCase
{ {
$bag = new ResponseHeaderBag(); $bag = new ResponseHeaderBag();
$bag->set('set-cookie', 'foo=bar'); $bag->set('set-cookie', 'foo=bar');
$this->assertEquals(array(new Cookie('foo', 'bar', 0, '/', null, false, true, true)), $bag->getCookies()); $this->assertEquals(array(new Cookie('foo', 'bar', 0, '/', null, false, false, true)), $bag->getCookies());
$bag->set('set-cookie', 'foo2=bar2', false); $bag->set('set-cookie', 'foo2=bar2', false);
$this->assertEquals(array( $this->assertEquals(array(
new Cookie('foo', 'bar', 0, '/', null, false, true, true), new Cookie('foo', 'bar', 0, '/', null, false, false, true),
new Cookie('foo2', 'bar2', 0, '/', null, false, true, true), new Cookie('foo2', 'bar2', 0, '/', null, false, false, true),
), $bag->getCookies()); ), $bag->getCookies());
$bag->remove('set-cookie'); $bag->remove('set-cookie');

View File

@ -120,6 +120,7 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
$log['priorityName'] = 'DEBUG'; $log['priorityName'] = 'DEBUG';
$log['channel'] = '-'; $log['channel'] = '-';
$log['scream'] = false; $log['scream'] = false;
unset($log['type'], $log['file'], $log['line'], $log['trace'], $log['trace'], $log['count']);
$logs[] = $log; $logs[] = $log;
} }
@ -251,7 +252,7 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
} }
foreach ($containerDeprecationLogs as $deprecationLog) { foreach ($containerDeprecationLogs as $deprecationLog) {
$count['deprecation_count'] += $deprecationLog['count']; $count['deprecation_count'] += $deprecationLog['context']['exception']->count;
} }
ksort($count['priorities']); ksort($count['priorities']);

View File

@ -551,7 +551,7 @@ abstract class Kernel implements KernelInterface, TerminableInterface
return; return;
} }
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
// Clean the trace by removing first frames added by the error handler itself. // Clean the trace by removing first frames added by the error handler itself.
for ($i = 0; isset($backtrace[$i]); ++$i) { for ($i = 0; isset($backtrace[$i]); ++$i) {
if (isset($backtrace[$i]['file'], $backtrace[$i]['line']) && $backtrace[$i]['line'] === $line && $backtrace[$i]['file'] === $file) { if (isset($backtrace[$i]['file'], $backtrace[$i]['line']) && $backtrace[$i]['line'] === $line && $backtrace[$i]['file'] === $file) {

View File

@ -50,7 +50,7 @@ class DumpDataCollectorTest extends TestCase
); );
$this->assertEquals($xDump, $dump); $this->assertEquals($xDump, $dump);
$this->assertStringMatchesFormat('a:3:{i:0;a:5:{s:4:"data";O:39:"Symfony\Component\VarDumper\Cloner\Data":%a', $collector->serialize()); $this->assertStringMatchesFormat('a:3:{i:0;a:5:{s:4:"data";%c:39:"Symfony\Component\VarDumper\Cloner\Data":%a', $collector->serialize());
$this->assertSame(0, $collector->getDumpsCount()); $this->assertSame(0, $collector->getDumpsCount());
$this->assertSame('a:2:{i:0;b:0;i:1;s:5:"UTF-8";}', $collector->serialize()); $this->assertSame('a:2:{i:0;b:0;i:1;s:5:"UTF-8";}', $collector->serialize());
} }

View File

@ -5,9 +5,9 @@ namespace Symfony\Component\Ldap\Adapter;
use Symfony\Component\Ldap\Entry; use Symfony\Component\Ldap\Entry;
/** /**
* @deprecated This interface will be deprecated in 4.0, and merged with `EntryManagerInterface`
*
* @author Kevin Schuurmans <kevin.schuurmans@freshheads.com> * @author Kevin Schuurmans <kevin.schuurmans@freshheads.com>
*
* @deprecated since version 3.3, will be merged with {@link EntryManagerInterface} in 4.0.
*/ */
interface RenameEntryInterface interface RenameEntryInterface
{ {

View File

@ -1,6 +1,11 @@
CHANGELOG CHANGELOG
========= =========
3.3.0
-----
* The `RenameEntryInterface` inferface is deprecated, and will be merged with `EntryManagerInterface` in 4.0.
3.1.0 3.1.0
----- -----

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Security\Core\Authorization; namespace Symfony\Component\Security\Core\Authorization;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage; use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage;
use Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface;
/** /**
* Adds some function to the default ExpressionLanguage. * Adds some function to the default ExpressionLanguage.
@ -23,7 +22,10 @@ use Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface;
*/ */
class ExpressionLanguage extends BaseExpressionLanguage class ExpressionLanguage extends BaseExpressionLanguage
{ {
public function __construct(ParserCacheInterface $cache = null, array $providers = array()) /**
* {@inheritdoc}
*/
public function __construct($cache = null, array $providers = array())
{ {
// prepend the default provider to let users override it easily // prepend the default provider to let users override it easily
array_unshift($providers, new ExpressionLanguageProvider()); array_unshift($providers, new ExpressionLanguageProvider());

View File

@ -192,7 +192,7 @@ abstract class AbstractNormalizer extends SerializerAwareNormalizer implements N
return call_user_func($this->circularReferenceHandler, $object); return call_user_func($this->circularReferenceHandler, $object);
} }
throw new CircularReferenceException(sprintf('A circular reference has been detected (configured limit: %d).', $this->circularReferenceLimit)); throw new CircularReferenceException(sprintf('A circular reference has been detected when serializing the object of class "%s" (configured limit: %d)', get_class($object), $this->circularReferenceLimit));
} }
/** /**

View File

@ -16,7 +16,7 @@ use Symfony\Component\VarDumper\Caster\Caster;
/** /**
* @author Nicolas Grekas <p@tchwork.com> * @author Nicolas Grekas <p@tchwork.com>
*/ */
class Data implements \ArrayAccess, \Countable, \IteratorAggregate class Data implements \ArrayAccess, \Countable, \IteratorAggregate, \Serializable
{ {
private $data; private $data;
private $position = 0; private $position = 0;
@ -278,6 +278,57 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
$this->dumpItem($dumper, new Cursor(), $refs, $this->data[$this->position][$this->key]); $this->dumpItem($dumper, new Cursor(), $refs, $this->data[$this->position][$this->key]);
} }
/**
* @internal
*/
public function serialize()
{
$data = $this->data;
foreach ($data as $i => $values) {
foreach ($values as $k => $v) {
if ($v instanceof Stub) {
if (Stub::TYPE_ARRAY === $v->type) {
$v = self::mapStubConsts($v, false);
$data[$i][$k] = array($v->class, $v->position, $v->cut);
} else {
$v = self::mapStubConsts($v, false);
$data[$i][$k] = array($v->class, $v->position, $v->cut, $v->type, $v->value, $v->handle, $v->refCount, $v->attr);
}
}
}
}
return serialize(array($data, $this->position, $this->key, $this->maxDepth, $this->maxItemsPerDepth, $this->useRefHandles));
}
/**
* @internal
*/
public function unserialize($serialized)
{
list($data, $this->position, $this->key, $this->maxDepth, $this->maxItemsPerDepth, $this->useRefHandles) = unserialize($serialized);
foreach ($data as $i => $values) {
foreach ($values as $k => $v) {
if ($v && is_array($v)) {
$s = new Stub();
if (3 === count($v)) {
$s->type = Stub::TYPE_ARRAY;
$s = self::mapStubConsts($s, false);
list($s->class, $s->position, $s->cut) = $v;
$s->value = $s->cut + count($data[$s->position]);
} else {
list($s->class, $s->position, $s->cut, $s->type, $s->value, $s->handle, $s->refCount, $s->attr) = $v;
}
$data[$i][$k] = self::mapStubConsts($s, true);
}
}
}
$this->data = $data;
}
/** /**
* Depth-first dumping of items. * Depth-first dumping of items.
* *
@ -406,4 +457,23 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
return $hashCut; return $hashCut;
} }
private static function mapStubConsts(Stub $stub, $resolve)
{
static $stubConstIndexes, $stubConstValues;
if (null === $stubConstIndexes) {
$r = new \ReflectionClass(Stub::class);
$stubConstIndexes = array_flip(array_values($r->getConstants()));
$stubConstValues = array_flip($stubConstIndexes);
}
$map = $resolve ? $stubConstValues : $stubConstIndexes;
$stub = clone $stub;
$stub->type = $map[$stub->type];
$stub->class = isset($map[$stub->class]) ? $map[$stub->class] : $stub->class;
return $stub;
}
} }