From eed3cc5b5272dc2105b66483853d495613e20613 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Sun, 18 Sep 2016 15:25:59 +0200 Subject: [PATCH 01/69] [Console] Escape default value and question in SymfonyStyle::ask() --- .../Console/Helper/SymfonyQuestionHelper.php | 9 +++++---- .../Helper/SymfonyQuestionHelperTest.php | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Console/Helper/SymfonyQuestionHelper.php b/src/Symfony/Component/Console/Helper/SymfonyQuestionHelper.php index 8abec46007e49..363449534049a 100644 --- a/src/Symfony/Component/Console/Helper/SymfonyQuestionHelper.php +++ b/src/Symfony/Component/Console/Helper/SymfonyQuestionHelper.php @@ -17,6 +17,7 @@ use Symfony\Component\Console\Question\ConfirmationQuestion; use Symfony\Component\Console\Question\Question; use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\Console\Formatter\OutputFormatter; /** * Symfony Style Guide compliant question helper. @@ -52,7 +53,7 @@ public function ask(InputInterface $input, OutputInterface $output, Question $qu */ protected function writePrompt(OutputInterface $output, Question $question) { - $text = $question->getQuestion(); + $text = OutputFormatter::escape($question->getQuestion()); $default = $question->getDefault(); switch (true) { @@ -74,18 +75,18 @@ protected function writePrompt(OutputInterface $output, Question $question) $default[$key] = $choices[trim($value)]; } - $text = sprintf(' %s [%s]:', $text, implode(', ', $default)); + $text = sprintf(' %s [%s]:', $text, OutputFormatter::escape(implode(', ', $default))); break; case $question instanceof ChoiceQuestion: $choices = $question->getChoices(); - $text = sprintf(' %s [%s]:', $text, $choices[$default]); + $text = sprintf(' %s [%s]:', $text, OutputFormatter::escape($choices[$default])); break; default: - $text = sprintf(' %s [%s]:', $text, $default); + $text = sprintf(' %s [%s]:', $text, OutputFormatter::escape($default)); } $output->writeln($text); diff --git a/src/Symfony/Component/Console/Tests/Helper/SymfonyQuestionHelperTest.php b/src/Symfony/Component/Console/Tests/Helper/SymfonyQuestionHelperTest.php index 032e153f068f1..4b49d309784fd 100644 --- a/src/Symfony/Component/Console/Tests/Helper/SymfonyQuestionHelperTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/SymfonyQuestionHelperTest.php @@ -6,6 +6,7 @@ use Symfony\Component\Console\Helper\HelperSet; use Symfony\Component\Console\Helper\SymfonyQuestionHelper; use Symfony\Component\Console\Output\StreamOutput; +use Symfony\Component\Console\Question\Question; use Symfony\Component\Console\Question\ChoiceQuestion; /** @@ -73,6 +74,24 @@ public function testAskChoice() $this->assertOutputContains('What is your favorite superhero? [Superman, Batman]', $output); } + public function testAskEscapeDefaultValue() + { + $helper = new SymfonyQuestionHelper(); + $helper->setInputStream($this->getInputStream('\\')); + $helper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), new Question('Can I have a backslash?', '\\')); + + $this->assertOutputContains('Can I have a backslash? [\]', $output); + } + + public function testAskEscapeLabel() + { + $helper = new SymfonyQuestionHelper(); + $helper->setInputStream($this->getInputStream('sure')); + $helper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), new Question('Do you want a \?')); + + $this->assertOutputContains('Do you want a \?', $output); + } + protected function getInputStream($input) { $stream = fopen('php://memory', 'r+', false); From ad3ac95d2d35e1afc4dd09239c5d969f42613458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20M=C3=A4nnchen?= Date: Wed, 24 Aug 2016 15:49:11 +0000 Subject: [PATCH 02/69] bug #18042 [Security] $attributes can be anything, but RoleVoter assumes strings --- .../Security/Core/Authorization/Voter/RoleVoter.php | 7 ++++++- .../Core/Tests/Authorization/Voter/RoleVoterTest.php | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Security/Core/Authorization/Voter/RoleVoter.php b/src/Symfony/Component/Security/Core/Authorization/Voter/RoleVoter.php index 722675d29be0c..539dcda327932 100644 --- a/src/Symfony/Component/Security/Core/Authorization/Voter/RoleVoter.php +++ b/src/Symfony/Component/Security/Core/Authorization/Voter/RoleVoter.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Security\Core\Authorization\Voter; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Role\RoleInterface; /** * RoleVoter votes if any attribute starts with a given prefix. @@ -37,7 +38,7 @@ public function __construct($prefix = 'ROLE_') */ public function supportsAttribute($attribute) { - return 0 === strpos($attribute, $this->prefix); + return is_string($attribute) && 0 === strpos($attribute, $this->prefix); } /** @@ -57,6 +58,10 @@ public function vote(TokenInterface $token, $object, array $attributes) $roles = $this->extractRoles($token); foreach ($attributes as $attribute) { + if ($attribute instanceof RoleInterface) { + $attribute = $attribute->getRole(); + } + if (!$this->supportsAttribute($attribute)) { continue; } diff --git a/src/Symfony/Component/Security/Core/Tests/Authorization/Voter/RoleVoterTest.php b/src/Symfony/Component/Security/Core/Tests/Authorization/Voter/RoleVoterTest.php index 03ab2da27e050..c15e936f6e58c 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authorization/Voter/RoleVoterTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authorization/Voter/RoleVoterTest.php @@ -43,6 +43,12 @@ public function getVoteTests() array(array('ROLE_FOO'), array('ROLE_FOO'), VoterInterface::ACCESS_GRANTED), array(array('ROLE_FOO'), array('FOO', 'ROLE_FOO'), VoterInterface::ACCESS_GRANTED), array(array('ROLE_BAR', 'ROLE_FOO'), array('ROLE_FOO'), VoterInterface::ACCESS_GRANTED), + + // Test mixed Types + array(array(), array(array()), VoterInterface::ACCESS_ABSTAIN), + array(array(), array(new \stdClass()), VoterInterface::ACCESS_ABSTAIN), + array(array('ROLE_BAR'), array(new Role('ROLE_BAR')), VoterInterface::ACCESS_GRANTED), + array(array('ROLE_BAR'), array(new Role('ROLE_FOO')), VoterInterface::ACCESS_DENIED), ); } From af84d2389159f386900827b9b66c3673076bc157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Haso=C5=88?= Date: Mon, 3 Oct 2016 09:43:29 +0200 Subject: [PATCH 03/69] [Validator] Add Czech and Slovak translations for BIC --- .../Validator/Resources/translations/validators.cs.xlf | 4 ++++ .../Validator/Resources/translations/validators.sk.xlf | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.cs.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.cs.xlf index 143fc166682c7..62779e19df978 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.cs.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.cs.xlf @@ -310,6 +310,10 @@ This value does not match the expected {{ charset }} charset. Tato hodnota neodpovídá očekávané znakové sadě {{ charset }}. + + This is not a valid Business Identifier Code (BIC). + Tato hodnota není platný identifikační kód podniku (BIC). + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.sk.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.sk.xlf index 93f196585e963..8ddb66d9c0b6f 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.sk.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.sk.xlf @@ -310,6 +310,10 @@ This value does not match the expected {{ charset }} charset. Táto hodnota nezodpovedá očakávanej znakovej sade {{ charset }}. + + This is not a valid Business Identifier Code (BIC). + Táto hodnota nie je platný identifikačný kód podniku (BIC). + From 34acc351d332e6904a9746a096306e497e6959e5 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 3 Oct 2016 11:06:05 -0700 Subject: [PATCH 04/69] updated CHANGELOG for 2.7.19 --- CHANGELOG-2.7.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/CHANGELOG-2.7.md b/CHANGELOG-2.7.md index c5f93200d0d51..e05a5f9bf7142 100644 --- a/CHANGELOG-2.7.md +++ b/CHANGELOG-2.7.md @@ -7,6 +7,31 @@ in 2.7 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/v2.7.0...v2.7.1 +* 2.7.19 (2016-10-03) + + * bug #20102 [Validator] Url validator not validating hosts ending in a number (gwkunze) + * bug #20132 Use "more entropy" option for uniqid() (javiereguiluz) + * bug #20122 [Validator] Reset constraint options (ro0NL) + * bug #20116 fixed AddConstraintValidatorsPass config (fabpot) + * bug #20078 Fix #19943 Make sure to process each interface metadata only once (lemoinem) + * bug #20080 [Form] compound forms without children should be considered rendered implicitly (backbone87) + * bug #20086 [VarDumper] Fix PHP 7.1 compat (nicolas-grekas) + * bug #20077 [Process] silent file operation to avoid open basedir issues (xabbuh) + * bug #20079 fixed Twig support for 1.26 and 2.0 (fabpot) + * bug #19951 [Finder] Trim trailing directory slash in ExcludeDirectoryFilterIterator (ro0NL) + * bug #20010 [DX] Fixed regression when exception message swallowed when logging it. (Koc) + * bug #19983 [TwigBridge] removed Twig null nodes (deprecated as of Twig 1.25) (fabpot) + * bug #19946 [Console] Fix parsing optionnal options with empty value in argv (chalasr) + * bug #19636 [Finder] no PHP warning on empty directory iteration (ggottwald) + * bug #19923 [bugfix] [Console] Set `Input::$interactive` to `false` when command is executed with `--quiet` as verbosity level (phansys) + * bug #19811 Fixed the nullable support for php 7.1 and below (2.7, 2.8, 3.0) (iltar) + * bug #19904 [Form] Fixed collapsed ChoiceType options attributes (HeahDude) + * bug #19908 [Config] Handle open_basedir restrictions in FileLocator (Nicofuma) + * bug #19922 [Yaml][TwigBridge] Use JSON_UNESCAPED_SLASHES for lint commands output (chalasr) + * bug #19928 [Validator] Update IpValidatorTest data set with a valid reserved IP (jakzal) + * bug #19813 [Console] fixed PHP7 Errors are now handled and converted to Exceptions (fonsecas72) + * bug #19879 [Form] Incorrect timezone with DateTimeLocalizedStringTransformer (mbeccati) + * 2.7.18 (2016-09-07) * bug #19859 [ClassLoader] Fix ClassCollectionLoader inlining with declare(strict_types=1) (nicolas-grekas) From 2a8cff9d7ad811024c37b53f412f4399b5f10943 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 3 Oct 2016 11:15:46 -0700 Subject: [PATCH 05/69] update CONTRIBUTORS for 2.7.19 --- CONTRIBUTORS.md | 67 +++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 7cbed979c4960..b0646cc1303cd 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -16,8 +16,8 @@ Symfony is the result of the work of many people who made the code better - Kris Wallsmith (kriswallsmith) - Jakub Zalas (jakubzalas) - Ryan Weaver (weaverryan) - - Javier Eguiluz (javier.eguiluz) - Kévin Dunglas (dunglas) + - Javier Eguiluz (javier.eguiluz) - Hugo Hamon (hhamon) - Abdellatif Ait boudad (aitboudad) - Pascal Borreli (pborreli) @@ -35,8 +35,8 @@ Symfony is the result of the work of many people who made the code better - Eriksen Costa (eriksencosta) - Sarah Khalil (saro0h) - Jules Pietri (heah) - - Jonathan Wage (jwage) - Maxime Steinhausser (ogizanagi) + - Jonathan Wage (jwage) - Diego Saint Esteben (dosten) - Alexandre Salomé (alexandresalome) - William Durand (couac) @@ -49,22 +49,22 @@ Symfony is the result of the work of many people who made the code better - Henrik Bjørnskov (henrikbjorn) - Miha Vrhovnik - Diego Saint Esteben (dii3g0) + - Ener-Getick (energetick) - Konstantin Kudryashov (everzet) - Bilal Amarni (bamarni) - Florin Patan (florinpatan) - - Ener-Getick (energetick) - Peter Rehm (rpet) - Iltar van der Berg (kjarli) + - Robin Chalas (chalas_r) - Kevin Bond (kbond) - Andrej Hudec (pulzarraider) - Gábor Egyed (1ed) - Michel Weimerskirch (mweimerskirch) - Eric Clemmons (ericclemmons) + - Charles Sarrazin (csarrazi) - Matthias Pigulla (mpdude) - Christian Raue - Arnout Boks (aboks) - - Charles Sarrazin (csarrazi) - - Robin Chalas (chalas_r) - Deni - Henrik Westphal (snc) - Dariusz Górecki (canni) @@ -72,22 +72,22 @@ Symfony is the result of the work of many people who made the code better - Lee McDermott - Brandon Turner - Luis Cordova (cordoval) + - Graham Campbell (graham) + - Titouan Galopin (tgalopin) - Daniel Holmes (dholmes) - Pierre du Plessis (pierredup) + - Konstantin Myakshin (koc) - Bart van den Burg (burgov) - Jordan Alliot (jalliot) - - Graham Campbell (graham) - John Wards (johnwards) - Toni Uebernickel (havvg) - Fran Moreno (franmomu) - Antoine Hérault (herzult) + - Paráda József (paradajozsef) - Arnaud Le Blanc (arnaud-lb) - Jérôme Tamarelle (gromnan) - - Paráda József (paradajozsef) - - Titouan Galopin (tgalopin) - Michal Piotrowski (eventhorizon) - Tim Nagel (merk) - - Konstantin Myakshin (koc) - Brice BERNARD (brikou) - Alexander M. Turek (derrabus) - Dariusz Ruminski @@ -105,6 +105,7 @@ Symfony is the result of the work of many people who made the code better - excelwebzone - Jacob Dreesen (jdreesen) - Jáchym Toušek (enumag) + - Roland Franssen (ro0) - Jérémy DERUSSÉ (jderusse) - Vladimir Reznichenko (kalessil) - Tomáš Votruba (tomas_votruba) @@ -112,6 +113,7 @@ Symfony is the result of the work of many people who made the code better - Gordon Franke (gimler) - Eric GELOEN (gelo) - David Buchmann (dbu) + - Tugdual Saunier (tucksaun) - Théo FIDRY (theofidry) - Robert Schönthal (digitalkaoz) - Florian Lonqueu-Brochard (florianlb) @@ -123,7 +125,6 @@ Symfony is the result of the work of many people who made the code better - Daniel Gomes (danielcsgomes) - Hidenori Goto (hidenorigoto) - Sebastiaan Stok (sstok) - - Tugdual Saunier (tucksaun) - Guilherme Blanco (guilhermeblanco) - Pablo Godel (pgodel) - Jérémie Augustin (jaugustin) @@ -133,6 +134,7 @@ Symfony is the result of the work of many people who made the code better - Joel Wurtz (brouznouf) - Philipp Wahala (hifi) - Vyacheslav Pavlov + - Javier Spagnoletti (phansys) - Richard Shank (iampersistent) - Thomas Rabaix (rande) - Vincent AUBERT (vincent) @@ -144,10 +146,10 @@ Symfony is the result of the work of many people who made the code better - Richard van Laak (rvanlaak) - Matthieu Ouellette-Vachon (maoueh) - Michał Pipa (michal.pipa) - - Javier Spagnoletti (phansys) - Amal Raghav (kertz) - Jonathan Ingram (jonathaningram) - Artur Kotyrba + - Teoh Han Hui (teohhanhui) - Warnar Boekkooi (boekkooi) - Dmitrii Chekaliuk (lazyhammer) - Clément JOBEILI (dator) @@ -158,11 +160,12 @@ Symfony is the result of the work of many people who made the code better - Mario A. Alvarez Garcia (nomack84) - Dennis Benkert (denderello) - Benjamin Dulau (dbenjamin) + - Mathieu Lemoine (lemoinem) - Andreas Hucks (meandmymonkey) - Noel Guilbert (noel) + - Yonel Ceruto González (yonelceruto) - Stepan Anchugov (kix) - bronze1man - - Roland Franssen (ro0) - sun (sun) - Larry Garfield (crell) - Martin Schuhfuß (usefulthink) @@ -188,14 +191,13 @@ Symfony is the result of the work of many people who made the code better - Dawid Nowak - Eugene Wissner - Julien Brochet (mewt) - - Yonel Ceruto González (yonelceruto) + - jeremyFreeAgent (jeremyfreeagent) - Sergey Linnik (linniksa) - Michaël Perrin (michael.perrin) - Marcel Beerta (mazen) - Loïc Faugeron - Jannik Zschiesche (apfelbox) - Marco Pivetta (ocramius) - - Teoh Han Hui (teohhanhui) - julien pauli (jpauli) - Michael Lee (zerustech) - Lorenz Schori @@ -216,6 +218,7 @@ Symfony is the result of the work of many people who made the code better - Xavier Perez - Arjen Brouwer (arjenjb) - Katsuhiro OGAWA + - James Halsall (jaitsu) - Alif Rachmawadi - Kristen Gilden (kgilden) - Pierre-Yves LEBECQ (pylebecq) @@ -226,10 +229,10 @@ Symfony is the result of the work of many people who made the code better - Joseph Rouff (rouffj) - Félix Labrecque (woodspire) - GordonsLondon - - jeremyFreeAgent (jeremyfreeagent) - Jan Sorgalla (jsor) - Ray - Grégoire Paris (greg0ire) + - Leo Feyer - Chekote - Tobias Nyholm (tobias) - Thomas Adam @@ -252,12 +255,14 @@ Symfony is the result of the work of many people who made the code better - Peter Kruithof (pkruithof) - Michael Holm (hollo) - Marc Weistroff (futurecat) + - SpacePossum - Hidde Wieringa (hiddewie) - Chris Smith (cs278) - Florian Klein (docteurklein) - Oleg Voronkovich - Manuel Kiessling (manuelkiessling) - Daniel Wehner + - Tristan Darricau (nicofuma) - Atsuhiro KUBO (iteman) - Andrew Moore (finewolf) - Bertrand Zuchuat (garfield-fr) @@ -266,7 +271,6 @@ Symfony is the result of the work of many people who made the code better - Thomas Tourlourat (armetiz) - Andrey Esaulov (andremaha) - Grégoire Passault (gregwar) - - Leo Feyer - Ismael Ambrosi (iambrosi) - Uwe Jäger (uwej711) - Aurelijus Valeiša (aurelijus) @@ -315,14 +319,11 @@ Symfony is the result of the work of many people who made the code better - JhonnyL - hossein zolfi (ocean) - Clément Gautier (clementgautier) - - James Halsall (jaitsu) - Eduardo Gulias (egulias) - giulio de donato (liuggio) - Stéphane PY (steph_py) - Philipp Kräutli (pkraeutli) - Kirill chEbba Chebunin (chebba) - - Tristan Darricau (nicofuma) - - SpacePossum - Greg Thornton (xdissent) - Costin Bereveanu (schniper) - Loïc Chardonnet (gnusat) @@ -390,13 +391,13 @@ Symfony is the result of the work of many people who made the code better - Christian Schmidt - Marcin Sikoń (marphi) - Dominik Zogg (dominik.zogg) + - Maxime STEINHAUSSER - Marek Pietrzak - Chad Sikorra (chadsikorra) - - Mathieu Lemoine - franek (franek) - Christian Wahler - - Mathieu Lemoine - Gintautas Miselis + - Rob Bast - David Badura (davidbadura) - Zander Baldwin - Adam Harvey @@ -414,6 +415,7 @@ Symfony is the result of the work of many people who made the code better - Sebastian Bergmann - Pablo Díez (pablodip) - Kevin McBride + - Sergio Santoro - Philipp Rieber (bicpi) - Manuel de Ruiter (manuel) - Eduardo Oliveira (entering) @@ -545,10 +547,10 @@ Symfony is the result of the work of many people who made the code better - Luc Vieillescazes (iamluc) - Johann Saunier (prophet777) - Antoine Corcy - - Rob Bast - Artur Eshenbrener - Arturs Vonda - Sascha Grossenbacher + - David Maicher (dmaicher) - Szijarto Tamas - Catalin Dan - Stephan Vock @@ -559,9 +561,10 @@ Symfony is the result of the work of many people who made the code better - Tristan Roussel - Cameron Porter - Hossein Bukhamsin + - Oliver Hoff - Disparity - origaminal - - Maxime STEINHAUSSER + - Matteo Beccati (matteobeccati) - Paweł Wacławczyk (pwc) - Oleg Zinchenko (cystbear) - Johannes Klauss (cloppy) @@ -581,7 +584,6 @@ Symfony is the result of the work of many people who made the code better - Michael Piecko - yclian - twifty - - Sergio Santoro - Peter Ward - Dominik Ritter (dritter) - Sebastian Grodzicki (sgrodzicki) @@ -604,6 +606,7 @@ Symfony is the result of the work of many people who made the code better - Andrew Tchircoff (andrewtch) - michaelwilliams - 1emming + - Victor Bocharsky (bocharsky_bw) - Leevi Graham (leevigraham) - Casper Valdemar Poulsen - Josiah (josiah) @@ -651,6 +654,7 @@ Symfony is the result of the work of many people who made the code better - Fabian Vogler (fabian) - Korvin Szanto - Alaattin Kahramanlar (alaattin) + - Sergey Zolotov (enleur) - Maksim Kotlyar (makasim) - Neil Ferreira - Nathanael Noblet (gnat) @@ -722,6 +726,7 @@ Symfony is the result of the work of many people who made the code better - Benoît Merlet (trompette) - Koen Kuipers - datibbaw + - Erik Saunier (snickers) - Rootie - Raul Fraile (raulfraile) - sensio @@ -731,6 +736,7 @@ Symfony is the result of the work of many people who made the code better - Mátyás Somfai (smatyas) - stefan.r - Valérian Galliat + - Rikijs Murgs - Alexandru Furculita (afurculita) - Ben Ramsey (ramsey) - Christian Jul Jensen @@ -810,6 +816,7 @@ Symfony is the result of the work of many people who made the code better - Benjamin Paap (benjaminpaap) - Christian - Sergii Smertin (nfx) + - hugofonseca (fonsecas72) - Bailey Parker - Eddie Jaoude - Haritz Iturbe (hizai) @@ -837,7 +844,6 @@ Symfony is the result of the work of many people who made the code better - Rodrigo Díez Villamuera (rodrigodiez) - e-ivanov - Jochen Bayer (jocl) - - Matteo Beccati (matteobeccati) - Jeremy Bush - wizhippo - Viacheslav Sychov @@ -887,7 +893,6 @@ Symfony is the result of the work of many people who made the code better - Christian Sciberras - Clement Herreman (clemherreman) - Dan Ionut Dumitriu (danionut90) - - David Maicher (dmaicher) - Nyro (nyro) - Marco - Marc Torres @@ -983,7 +988,6 @@ Symfony is the result of the work of many people who made the code better - Tadcka - Beth Binkovitz - Romain Geissler - - Oliver Hoff - Tomaz Ahlin - Benjamin Cremer (bcremer) - Marcus Stöhr (dafish) @@ -1012,6 +1016,7 @@ Symfony is the result of the work of many people who made the code better - BilgeXA - r1pp3rj4ck - Robert Queck + - Peter Bouwdewijn - mlively - Amine Matmati - Fabian Steiner (fabstei) @@ -1040,6 +1045,7 @@ Symfony is the result of the work of many people who made the code better - Konrad Mohrfeldt - Lance Chen - Andrey Astakhov (aast) + - Andrew (drew) - Nikolay Labinskiy (e-moe) - kor3k kor3k (kor3k) - Stelian Mocanita (stelian) @@ -1203,7 +1209,6 @@ Symfony is the result of the work of many people who made the code better - J Bruni - Alexey Prilipko - bertillon - - Victor Bocharsky (bocharsky_bw) - Yannick Bensacq (cibou) - Luca Genuzio (genuzio) - Hans Nilsson (hansnilsson) @@ -1236,6 +1241,7 @@ Symfony is the result of the work of many people who made the code better - Julien DIDIER (juliendidier) - Martin Mayer (martin) - Grzegorz Łukaszewicz (newicz) + - Götz Gottwald - Veres Lajos - grifx - Robert Campbell @@ -1462,8 +1468,8 @@ Symfony is the result of the work of many people who made the code better - Adel ELHAIBA (eadel) - Damián Nohales (eagleoneraptor) - Elliot Anderson (elliot) - - Sergey Zolotov (enleur) - Fabien D. (fabd) + - Fabien Bourigault (fbourigault) - Carsten Eilers (fnc) - Sorin Gitlan (forapathy) - Yohan Giarelli (frequence-web) @@ -1498,6 +1504,7 @@ Symfony is the result of the work of many people who made the code better - Paul Andrieux (paulandrieux) - Paweł Szczepanek (pauluz) - Philippe Degeeter (pdegeeter) + - Pedro Miguel Maymone de Resende (pedroresende) - Christian López Espínola (penyaskito) - Petr Jaroš (petajaros) - Philipp Hoffmann (philipphoffmann) @@ -1522,6 +1529,7 @@ Symfony is the result of the work of many people who made the code better - Moritz Kraft (userfriendly) - Víctor Mateo (victormateo) - Vincent (vincent1870) + - Valentin Udaltsov (vudaltsov) - Eugene Babushkin (warl) - Wouter Sioen (wouter_sioen) - Xavier Amado (xamado) @@ -1559,6 +1567,5 @@ Symfony is the result of the work of many people who made the code better - Pierre Geyer (ptheg) - Sam Fleming (sam_fleming) - Thomas BERTRAND (sevrahk) - - Erik Saunier (snickers) - Matej Žilák (teo_sk) - Vladislav Vlastovskiy (vlastv) From 70afffbbff537d77c26063d5b9c45e0814175c76 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 3 Oct 2016 11:15:49 -0700 Subject: [PATCH 06/69] updated VERSION for 2.7.19 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index c6586c02312aa..6d86705c87442 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -58,12 +58,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.7.19-DEV'; + const VERSION = '2.7.19'; const VERSION_ID = 20719; const MAJOR_VERSION = 2; const MINOR_VERSION = 7; const RELEASE_VERSION = 19; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '05/2018'; const END_OF_LIFE = '05/2019'; From 3086fd38e5295daa6af23222ccbc82506864b5c4 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 3 Oct 2016 11:42:03 -0700 Subject: [PATCH 07/69] bumped Symfony version to 2.7.20 --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 6d86705c87442..a4d715cad3665 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -58,12 +58,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.7.19'; - const VERSION_ID = 20719; + const VERSION = '2.7.20-DEV'; + const VERSION_ID = 20720; const MAJOR_VERSION = 2; const MINOR_VERSION = 7; - const RELEASE_VERSION = 19; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 20; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '05/2018'; const END_OF_LIFE = '05/2019'; From f433c13f3f1d948d24f558269cd42d3c324fe59f Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 3 Oct 2016 11:43:58 -0700 Subject: [PATCH 08/69] updated CHANGELOG for 2.8.12 --- CHANGELOG-2.8.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/CHANGELOG-2.8.md b/CHANGELOG-2.8.md index 482e20e17c7f9..edb544ab415a8 100644 --- a/CHANGELOG-2.8.md +++ b/CHANGELOG-2.8.md @@ -7,6 +7,39 @@ in 2.8 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/v2.8.0...v2.8.1 +* 2.8.12 (2016-10-03) + + * bug #20102 [Validator] Url validator not validating hosts ending in a number (gwkunze) + * bug #20132 Use "more entropy" option for uniqid() (javiereguiluz) + * bug #20122 [Validator] Reset constraint options (ro0NL) + * bug #20116 fixed AddConstraintValidatorsPass config (fabpot) + * bug #20078 Fix #19943 Make sure to process each interface metadata only once (lemoinem) + * bug #20080 [Form] compound forms without children should be considered rendered implicitly (backbone87) + * bug #20087 [VarDumper] Fix PHP 7.1 compat (nicolas-grekas) + * bug #20086 [VarDumper] Fix PHP 7.1 compat (nicolas-grekas) + * bug #20077 [Process] silent file operation to avoid open basedir issues (xabbuh) + * bug #20079 fixed Twig support for 1.26 and 2.0 (fabpot) + * bug #20051 Fix indexBy type extraction (lemoinem) + * bug #19951 [Finder] Trim trailing directory slash in ExcludeDirectoryFilterIterator (ro0NL) + * bug #20018 [VarDumper] Fix test (nicolas-grekas) + * bug #20011 Use UUID for error codes for Form validator. (Koc) + * bug #20010 [DX] Fixed regression when exception message swallowed when logging it. (Koc) + * bug #19983 [TwigBridge] removed Twig null nodes (deprecated as of Twig 1.25) (fabpot) + * bug #19946 [Console] Fix parsing optionnal options with empty value in argv (chalasr) + * bug #19636 [Finder] no PHP warning on empty directory iteration (ggottwald) + * bug #19923 [bugfix] [Console] Set `Input::$interactive` to `false` when command is executed with `--quiet` as verbosity level (phansys) + * bug #19811 Fixed the nullable support for php 7.1 and below (2.7, 2.8, 3.0) (iltar) + * bug #19853 [PropertyInfo] Make ReflectionExtractor compatible with ReflectionType changes in PHP 7.1 (teohhanhui) + * bug #19904 [Form] Fixed collapsed ChoiceType options attributes (HeahDude) + * bug #19908 [Config] Handle open_basedir restrictions in FileLocator (Nicofuma) + * bug #19924 [DoctrineBridge][PropertyInfo] Treat Doctrine decimal type as string (teohhanhui) + * bug #19932 Fixed bad merge (GrahamCampbell) + * bug #19922 [Yaml][TwigBridge] Use JSON_UNESCAPED_SLASHES for lint commands output (chalasr) + * bug #19928 [Validator] Update IpValidatorTest data set with a valid reserved IP (jakzal) + * bug #19813 [Console] fixed PHP7 Errors are now handled and converted to Exceptions (fonsecas72) + * bug #19879 [Form] Incorrect timezone with DateTimeLocalizedStringTransformer (mbeccati) + * bug #19878 Fix translation:update command count (tgalopin) + * 2.8.11 (2016-09-07) * bug #19859 [ClassLoader] Fix ClassCollectionLoader inlining with declare(strict_types=1) (nicolas-grekas) From 5cd057a938017fee83b261e38ed16006343fa312 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 3 Oct 2016 11:44:05 -0700 Subject: [PATCH 09/69] updated VERSION for 2.8.12 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 150d65e7cfd4a..f59efc51ecc76 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -59,12 +59,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.8.12-DEV'; + const VERSION = '2.8.12'; const VERSION_ID = 20812; const MAJOR_VERSION = 2; const MINOR_VERSION = 8; const RELEASE_VERSION = 12; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2018'; const END_OF_LIFE = '11/2019'; From 7f0ae275213e5b2c8119e38bb58a9c2538ee501b Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 3 Oct 2016 11:59:23 -0700 Subject: [PATCH 10/69] bumped Symfony version to 2.8.13 --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index f59efc51ecc76..f286285766815 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -59,12 +59,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.8.12'; - const VERSION_ID = 20812; + const VERSION = '2.8.13-DEV'; + const VERSION_ID = 20813; const MAJOR_VERSION = 2; const MINOR_VERSION = 8; - const RELEASE_VERSION = 12; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 13; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '11/2018'; const END_OF_LIFE = '11/2019'; From 70a620dfca5d260faac6cc7a154afdc6a12b80a3 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 3 Oct 2016 12:15:50 -0700 Subject: [PATCH 11/69] bumped Symfony version to 3.1.6 --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index f3a22fa06ab57..965c8e1556140 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -59,12 +59,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '3.1.5'; - const VERSION_ID = 30105; + const VERSION = '3.1.6-DEV'; + const VERSION_ID = 30106; const MAJOR_VERSION = 3; const MINOR_VERSION = 1; - const RELEASE_VERSION = 5; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 6; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '01/2017'; const END_OF_LIFE = '07/2017'; From a8b910bec2c5193b6f43c82e4af78ea51f4c815a Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Mon, 3 Oct 2016 19:29:11 +0200 Subject: [PATCH 12/69] [Console] Fix validation of null values using SymfonyStyle::ask() --- .../Component/Console/Helper/SymfonyQuestionHelper.php | 10 +++++----- .../Console/Tests/Helper/SymfonyQuestionHelperTest.php | 10 ++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Console/Helper/SymfonyQuestionHelper.php b/src/Symfony/Component/Console/Helper/SymfonyQuestionHelper.php index 8abec46007e49..9c5c4b7c88e77 100644 --- a/src/Symfony/Component/Console/Helper/SymfonyQuestionHelper.php +++ b/src/Symfony/Component/Console/Helper/SymfonyQuestionHelper.php @@ -34,11 +34,11 @@ public function ask(InputInterface $input, OutputInterface $output, Question $qu $question->setValidator(function ($value) use ($validator) { if (null !== $validator) { $value = $validator($value); - } - - // make required - if (!is_array($value) && !is_bool($value) && 0 === strlen($value)) { - throw new \Exception('A value is required.'); + } else { + // make required + if (!is_array($value) && !is_bool($value) && 0 === strlen($value)) { + throw new \Exception('A value is required.'); + } } return $value; diff --git a/src/Symfony/Component/Console/Tests/Helper/SymfonyQuestionHelperTest.php b/src/Symfony/Component/Console/Tests/Helper/SymfonyQuestionHelperTest.php index 032e153f068f1..27e0abd79d30d 100644 --- a/src/Symfony/Component/Console/Tests/Helper/SymfonyQuestionHelperTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/SymfonyQuestionHelperTest.php @@ -6,6 +6,7 @@ use Symfony\Component\Console\Helper\HelperSet; use Symfony\Component\Console\Helper\SymfonyQuestionHelper; use Symfony\Component\Console\Output\StreamOutput; +use Symfony\Component\Console\Question\Question; use Symfony\Component\Console\Question\ChoiceQuestion; /** @@ -73,6 +74,15 @@ public function testAskChoice() $this->assertOutputContains('What is your favorite superhero? [Superman, Batman]', $output); } + public function testAskReturnsNullIfValidatorAllowsIt() + { + $questionHelper = new SymfonyQuestionHelper(); + $questionHelper->setInputStream($this->getInputStream("\n")); + $question = new Question('What is your favorite superhero?'); + $question->setValidator(function ($value) { return $value; }); + $this->assertNull($questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + } + protected function getInputStream($input) { $stream = fopen('php://memory', 'r+', false); From 2ac1586984ee6e451ecb42d4790a3c2bfdf11445 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 4 Oct 2016 11:12:14 +0200 Subject: [PATCH 13/69] [travis] Use hhvm-stable instead of discontinued hhvm-3.12 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index bbf7547445fb9..62917b9c6b846 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ env: matrix: include: # Use the newer stack for HHVM as HHVM does not support Precise anymore since a long time and so Precise has an outdated version - - php: hhvm-3.12 + - php: hhvm-stable sudo: required dist: trusty group: edge From dda18df6de4822f6f0dbe90f538bab9e294cc139 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 4 Oct 2016 14:01:35 +0200 Subject: [PATCH 14/69] [VarDumper] Fix ReflectionNamedType->getName() detection --- .../Component/VarDumper/Caster/ReflectionCaster.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php b/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php index b7c7a8abbbf28..e772c246b2ff2 100644 --- a/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php @@ -115,7 +115,8 @@ public static function castFunctionAbstract(\ReflectionFunctionAbstract $c, arra )); if (isset($a[$prefix.'returnType'])) { - $a[$prefix.'returnType'] = method_exists('ReflectionType', 'getName') ? $a[$prefix.'returnType']->getName() : $a[$prefix.'returnType']->__toString(); + $v = $a[$prefix.'returnType']; + $a[$prefix.'returnType'] = $v instanceof \ReflectionNamedType ? $v->getName() : $v->__toString(); } if (isset($a[$prefix.'this'])) { $a[$prefix.'this'] = new CutStub($a[$prefix.'this']); @@ -168,9 +169,9 @@ public static function castParameter(\ReflectionParameter $c, array $a, Stub $st )); try { - if (method_exists($c, 'hasType')) { - if ($c->hasType()) { - $a[$prefix.'typeHint'] = method_exists('ReflectionType', 'getName') ? $c->getType()->getName() : $c->getType()->__toString(); + if (method_exists($c, 'getType')) { + if ($v = $c->getType()) { + $a[$prefix.'typeHint'] = $v instanceof \ReflectionNamedType ? $v->getName() : $v->__toString(); } } else { $v = explode(' ', $c->__toString(), 6); @@ -196,7 +197,7 @@ public static function castParameter(\ReflectionParameter $c, array $a, Stub $st unset($a[$prefix.'allowsNull']); } } catch (\ReflectionException $e) { - if (isset($a[$prefix.'typeHint']) && $c->allowsNull() && !method_exists('ReflectionType', 'getName')) { + if (isset($a[$prefix.'typeHint']) && $c->allowsNull() && !class_exists('ReflectionNamedType', false)) { $a[$prefix.'default'] = null; unset($a[$prefix.'allowsNull']); } From 73c96939cdaccf047a59eaddecd952ce1969d21d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 4 Oct 2016 09:25:27 +0200 Subject: [PATCH 15/69] [FrameworkBundle] Alter container class instead of kernel name in cache:clear command --- .../Command/CacheClearCommand.php | 37 +++++++------------ .../FrameworkExtension.php | 2 +- .../CacheClearCommandTest.php | 2 +- .../FrameworkExtensionTest.php | 1 + 4 files changed, 17 insertions(+), 25 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php index 5e98e1d58f752..84c2fae7d4db8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php @@ -157,22 +157,13 @@ protected function warmup($warmupDir, $realCacheDir, $enableOptionalWarmers = tr file_put_contents($file, $content); } - // fix references to kernel/container related classes - $fileSearch = $tempKernel->getName().ucfirst($tempKernel->getEnvironment()).'*'; - $search = array( - $tempKernel->getName().ucfirst($tempKernel->getEnvironment()), - sprintf('\'kernel.name\' => \'%s\'', $tempKernel->getName()), - sprintf('key="kernel.name">%s<', $tempKernel->getName()), - ); - $replace = array( - $realKernel->getName().ucfirst($realKernel->getEnvironment()), - sprintf('\'kernel.name\' => \'%s\'', $realKernel->getName()), - sprintf('key="kernel.name">%s<', $realKernel->getName()), - ); - foreach (Finder::create()->files()->name($fileSearch)->in($warmupDir) as $file) { - $content = str_replace($search, $replace, file_get_contents($file)); - file_put_contents(str_replace($search, $replace, $file), $content); - unlink($file); + // fix references to container's class + $tempContainerClass = get_class($tempKernel->getContainer()); + $realContainerClass = get_class($realKernel->getContainer()); + foreach (Finder::create()->files()->name($tempContainerClass.'*')->in($warmupDir) as $file) { + $content = str_replace($tempContainerClass, $realContainerClass, file_get_contents($file)); + file_put_contents($file, $content); + rename($file, str_replace(DIRECTORY_SEPARATOR.$tempContainerClass, DIRECTORY_SEPARATOR.$realContainerClass, $file)); } // remove temp kernel file after cache warmed up @@ -195,8 +186,8 @@ protected function getTempKernel(KernelInterface $parent, $namespace, $parentCla // the temp kernel class name must have the same length than the real one // to avoid the many problems in serialized resources files $class = substr($parentClass, 0, -1).'_'; - // the temp kernel name must be changed too - $name = var_export(substr($parent->getName(), 0, -1).'_', true); + // the temp container class must be changed too + $containerClass = var_export(substr(get_class($parent->getContainer()), 0, -1).'_', true); $code = <<load('routing.xml'); $container->setParameter('router.resource', $config['resource']); - $container->setParameter('router.cache_class_prefix', $container->getParameter('kernel.name').ucfirst($container->getParameter('kernel.environment'))); + $container->setParameter('router.cache_class_prefix', $container->getParameter('kernel.container_class')); $router = $container->findDefinition('router.default'); $argument = $router->getArgument(2); $argument['strict_requirements'] = $config['strict_requirements']; diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php index c351a790ac07c..f1140e86bb378 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php @@ -83,6 +83,6 @@ public function testCacheIsFreshAfterCacheClearedWithWarmup() } } $this->assertTrue($found, 'Kernel file should present as resource'); - $this->assertRegExp(sprintf('/\'kernel.name\'\s*=>\s*\'%s\'/', $this->kernel->getName()), file_get_contents($containerFile), 'kernel.name is properly set on the dumped container'); + $this->assertRegExp(sprintf('/\'kernel.container_class\'\s*=>\s*\'%s\'/', get_class($this->kernel->getContainer())), file_get_contents($containerFile), 'kernel.container_class is properly set on the dumped container'); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 92bd30832abf1..9d93263963f9b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -477,6 +477,7 @@ protected function createContainer(array $data = array()) 'kernel.environment' => 'test', 'kernel.name' => 'kernel', 'kernel.root_dir' => __DIR__, + 'kernel.container_class' => 'testContainer', ), $data))); } From 088451810736c3caab77e8af974ada820acc3c8d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 4 Oct 2016 13:53:34 +0200 Subject: [PATCH 16/69] [HttpKernel] Fix nullable types handling --- .../ArgumentResolver/DefaultValueResolver.php | 2 +- .../ControllerMetadata/ArgumentMetadata.php | 4 +-- .../ArgumentMetadataFactory.php | 30 +++++++------------ .../ArgumentMetadataFactoryTest.php | 2 +- 4 files changed, 15 insertions(+), 23 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/DefaultValueResolver.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/DefaultValueResolver.php index 0962dab885fe9..1af03651c3799 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/DefaultValueResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/DefaultValueResolver.php @@ -27,7 +27,7 @@ final class DefaultValueResolver implements ArgumentValueResolverInterface */ public function supports(Request $request, ArgumentMetadata $argument) { - return $argument->hasDefaultValue() || $argument->isNullable(); + return $argument->hasDefaultValue() || ($argument->isNullable() && !$argument->isVariadic()); } /** diff --git a/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadata.php b/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadata.php index 72c294f3a3d7c..32316a8d519e7 100644 --- a/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadata.php +++ b/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadata.php @@ -40,7 +40,7 @@ public function __construct($name, $type, $isVariadic, $hasDefaultValue, $defaul $this->isVariadic = $isVariadic; $this->hasDefaultValue = $hasDefaultValue; $this->defaultValue = $defaultValue; - $this->isNullable = (bool) $isNullable; + $this->isNullable = $isNullable || null === $type || ($hasDefaultValue && null === $defaultValue); } /** @@ -88,7 +88,7 @@ public function hasDefaultValue() } /** - * Returns whether the argument is nullable in PHP 7.1 or higher. + * Returns whether the argument accepts null values. * * @return bool */ diff --git a/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php b/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php index efe5966894495..ad6c395ee7d96 100644 --- a/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php +++ b/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php @@ -58,7 +58,7 @@ public function createArgumentMetadata($controller) } foreach ($reflection->getParameters() as $param) { - $arguments[] = new ArgumentMetadata($param->getName(), $this->getType($param), $this->isVariadic($param), $this->hasDefaultValue($param), $this->getDefaultValue($param), $this->isNullable($param)); + $arguments[] = new ArgumentMetadata($param->getName(), $this->getType($param), $this->isVariadic($param), $this->hasDefaultValue($param), $this->getDefaultValue($param), $param->allowsNull()); } return $arguments; @@ -88,23 +88,6 @@ private function hasDefaultValue(\ReflectionParameter $parameter) return $parameter->isDefaultValueAvailable(); } - /** - * Returns if the argument is allowed to be null but is still mandatory. - * - * @param \ReflectionParameter $parameter - * - * @return bool - */ - private function isNullable(\ReflectionParameter $parameter) - { - if ($this->supportsParameterType) { - return null !== ($type = $parameter->getType()) && $type->allowsNull(); - } - - // fallback for supported php 5.x versions - return $this->hasDefaultValue($parameter) && null === $this->getDefaultValue($parameter); - } - /** * Returns a default value if available. * @@ -127,7 +110,16 @@ private function getDefaultValue(\ReflectionParameter $parameter) private function getType(\ReflectionParameter $parameter) { if ($this->supportsParameterType) { - return $parameter->hasType() ? (string) $parameter->getType() : null; + if (!$type = $parameter->getType()) { + return; + } + $typeName = $type instanceof \ReflectionNamedType ? $type->getName() : $type->__toString(); + if ('array' === $typeName && !$type->isBuiltin()) { + // Special case for HHVM with variadics + return; + } + + return $typeName; } if ($parameter->isArray()) { diff --git a/src/Symfony/Component/HttpKernel/Tests/ControllerMetadata/ArgumentMetadataFactoryTest.php b/src/Symfony/Component/HttpKernel/Tests/ControllerMetadata/ArgumentMetadataFactoryTest.php index 49931f052c82e..1ca9a3c798947 100644 --- a/src/Symfony/Component/HttpKernel/Tests/ControllerMetadata/ArgumentMetadataFactoryTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/ControllerMetadata/ArgumentMetadataFactoryTest.php @@ -121,7 +121,7 @@ public function testNullableTypesSignature() new ArgumentMetadata('foo', 'string', false, false, null, true), new ArgumentMetadata('bar', \stdClass::class, false, false, null, true), new ArgumentMetadata('baz', 'string', false, true, 'value', true), - new ArgumentMetadata('mandatory', null, false, false, null), + new ArgumentMetadata('mandatory', null, false, false, null, true), ), $arguments); } From 384d0eeaf800406d110d92a58ac6ef17613a9e25 Mon Sep 17 00:00:00 2001 From: "Konstantin.Myakshin" Date: Tue, 4 Oct 2016 22:48:31 +0300 Subject: [PATCH 17/69] Fix event annotation for arguments resolving event --- src/Symfony/Component/HttpKernel/KernelEvents.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/KernelEvents.php b/src/Symfony/Component/HttpKernel/KernelEvents.php index fd5ec796a8433..3e961737b844e 100644 --- a/src/Symfony/Component/HttpKernel/KernelEvents.php +++ b/src/Symfony/Component/HttpKernel/KernelEvents.php @@ -73,10 +73,9 @@ final class KernelEvents * The CONTROLLER_ARGUMENTS event occurs once controller arguments have been resolved. * * This event allows you to change the arguments that will be passed to - * the controller. The event listener method receives a - * Symfony\Component\HttpKernel\Event\FilterControllerArgumentsEvent instance. + * the controller. * - * @Event + * @Event("Symfony\Component\HttpKernel\Event\FilterControllerArgumentsEvent") * * @var string */ From fbd73f08dc2d5d78865eee87a96411977844bdc2 Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Wed, 5 Oct 2016 14:10:52 +0200 Subject: [PATCH 18/69] Fixed a missing legacy groups --- .../HttpKernel/Tests/Controller/ControllerResolverTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php b/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php index a1b9a1c78d857..d09bad891102b 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php @@ -229,6 +229,7 @@ public function testCreateControllerCanReturnAnyCallable() /** * @requires PHP 7.1 + * @group legacy */ public function testGetNullableArguments() { @@ -244,6 +245,7 @@ public function testGetNullableArguments() /** * @requires PHP 7.1 + * @group legacy */ public function testGetNullableArgumentsWithDefaults() { From 32451b1a092181b793ee6bd186eeb7a3ca039491 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Wed, 5 Oct 2016 18:00:01 +0200 Subject: [PATCH 19/69] add missing use statement --- .../DependencyInjection/Compiler/AddConstraintValidatorsPass.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddConstraintValidatorsPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddConstraintValidatorsPass.php index 800a32e2f30df..497ea08a4bf4e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddConstraintValidatorsPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddConstraintValidatorsPass.php @@ -13,6 +13,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; class AddConstraintValidatorsPass implements CompilerPassInterface { From cc9a49948271fc6864003b65dfd2f5d888e8c443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 5 Oct 2016 19:21:13 +0200 Subject: [PATCH 20/69] Uniformize exception vars according to our CS --- .../Component/PropertyInfo/Extractor/PhpDocExtractor.php | 4 ++-- .../PropertyInfo/Extractor/ReflectionExtractor.php | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php index b1f323c0bd6ed..e60a623985d05 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php @@ -208,7 +208,7 @@ private function getDocBlockFromProperty($class, $property) // Use a ReflectionProperty instead of $class to get the parent class if applicable try { $reflectionProperty = new \ReflectionProperty($class, $property); - } catch (\ReflectionException $reflectionException) { + } catch (\ReflectionException $e) { return; } @@ -260,7 +260,7 @@ private function getDocBlockFromMethod($class, $ucFirstProperty, $type) ) { break; } - } catch (\ReflectionException $reflectionException) { + } catch (\ReflectionException $e) { // Try the next prefix if the method doesn't exist } } diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index 1d3d3a2083ca8..1bf56b9109418 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -51,7 +51,7 @@ public function getProperties($class, array $context = array()) { try { $reflectionClass = new \ReflectionClass($class); - } catch (\ReflectionException $reflectionException) { + } catch (\ReflectionException $e) { return; } @@ -261,7 +261,7 @@ private function isPublicProperty($class, $property) $reflectionProperty = new \ReflectionProperty($class, $property); return $reflectionProperty->isPublic(); - } catch (\ReflectionException $reflectionExcetion) { + } catch (\ReflectionException $e) { // Return false if the property doesn't exist } @@ -290,7 +290,7 @@ private function getAccessorMethod($class, $property) if (0 === $reflectionMethod->getNumberOfRequiredParameters()) { return array($reflectionMethod, $prefix); } - } catch (\ReflectionException $reflectionException) { + } catch (\ReflectionException $e) { // Return null if the property doesn't exist } } @@ -319,7 +319,7 @@ private function getMutatorMethod($class, $property) if ($reflectionMethod->getNumberOfParameters() >= 1) { return array($reflectionMethod, $prefix); } - } catch (\ReflectionException $reflectionException) { + } catch (\ReflectionException $e) { // Try the next prefix if the method doesn't exist } } From 29226ef1160dc2ab2c43dbb50f80c1d236653957 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 5 Oct 2016 12:47:52 +0200 Subject: [PATCH 21/69] [Console] Improved the explanation of the hasOption() method --- src/Symfony/Component/Console/Input/InputDefinition.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Symfony/Component/Console/Input/InputDefinition.php b/src/Symfony/Component/Console/Input/InputDefinition.php index 809baebd333e6..f7eafbd84f282 100644 --- a/src/Symfony/Component/Console/Input/InputDefinition.php +++ b/src/Symfony/Component/Console/Input/InputDefinition.php @@ -282,6 +282,9 @@ public function getOption($name) /** * Returns true if an InputOption object exists by name. * + * This method can't be used to check if the user included the option when + * executing the command (use getOption() instead). + * * @param string $name The InputOption name * * @return bool true if the InputOption object exists, false otherwise From 1159f8bba65d0e0f50d69f637dbed4308b959057 Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Mon, 3 Oct 2016 18:24:18 +0000 Subject: [PATCH 22/69] [HttpFoundation] JSONP callback validation --- .../Component/HttpFoundation/JsonResponse.php | 14 +++++++++++--- .../HttpFoundation/Tests/JsonResponseTest.php | 8 ++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/JsonResponse.php b/src/Symfony/Component/HttpFoundation/JsonResponse.php index 4672cdc8ded14..f370867aedc92 100644 --- a/src/Symfony/Component/HttpFoundation/JsonResponse.php +++ b/src/Symfony/Component/HttpFoundation/JsonResponse.php @@ -80,11 +80,19 @@ public static function create($data = null, $status = 200, $headers = array()) public function setCallback($callback = null) { if (null !== $callback) { - // taken from http://www.geekality.net/2011/08/03/valid-javascript-identifier/ - $pattern = '/^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*+$/u'; + // partially token from http://www.geekality.net/2011/08/03/valid-javascript-identifier/ + // partially token from https://github.com/willdurand/JsonpCallbackValidator + // JsonpCallbackValidator is released under the MIT License. See https://github.com/willdurand/JsonpCallbackValidator/blob/v1.1.0/LICENSE for details. + // (c) William Durand + $pattern = '/^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*(?:\[(?:"(?:\\\.|[^"\\\])*"|\'(?:\\\.|[^\'\\\])*\'|\d+)\])*?$/u'; + $reserved = array( + 'break', 'do', 'instanceof', 'typeof', 'case', 'else', 'new', 'var', 'catch', 'finally', 'return', 'void', 'continue', 'for', 'switch', 'while', + 'debugger', 'function', 'this', 'with', 'default', 'if', 'throw', 'delete', 'in', 'try', 'class', 'enum', 'extends', 'super', 'const', 'export', + 'import', 'implements', 'let', 'private', 'public', 'yield', 'interface', 'package', 'protected', 'static', 'null', 'true', 'false', + ); $parts = explode('.', $callback); foreach ($parts as $part) { - if (!preg_match($pattern, $part)) { + if (!preg_match($pattern, $part) || in_array($part, $reserved, true)) { throw new \InvalidArgumentException('The callback name is not valid.'); } } diff --git a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php index 60d27e4d5961c..0a0732f473219 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php @@ -213,6 +213,14 @@ public function testSetContentJsonSerializeError() JsonResponse::create($serializable); } + + public function testSetComplexCallback() + { + $response = JsonResponse::fromJsonString('{foo: "bar"}'); + $response->setCallback('ಠ_ಠ["foo"].bar[0]'); + + $this->assertEquals('/**/ಠ_ಠ["foo"].bar[0]({foo: "bar"});', $response->getContent()); + } } if (interface_exists('JsonSerializable')) { From 1427d3315378951540aecd6fef32065beb237cbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 5 Oct 2016 21:27:34 +0200 Subject: [PATCH 23/69] Correct a typo in the ReflectionExtractor's description --- .../Component/PropertyInfo/Extractor/ReflectionExtractor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index 1bf56b9109418..9b004b606bd1f 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -17,7 +17,7 @@ use Symfony\Component\PropertyInfo\Type; /** - * Extracts PHP informations using the reflection API. + * Extracts data using the reflection API. * * @author Kévin Dunglas */ From 4cae9c09471d500adaa3af54600334cc012b4f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 5 Oct 2016 22:47:52 +0200 Subject: [PATCH 24/69] [DependencyInjection] Add missing PHPDoc type --- src/Symfony/Component/DependencyInjection/Definition.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Definition.php b/src/Symfony/Component/DependencyInjection/Definition.php index 895b37459cd27..788eccebad869 100644 --- a/src/Symfony/Component/DependencyInjection/Definition.php +++ b/src/Symfony/Component/DependencyInjection/Definition.php @@ -850,7 +850,7 @@ public function isAutowired() /** * Sets autowired. * - * @param $autowired + * @param bool $autowired * * @return Definition The current instance */ From dcf601f3fafc8bbdf224948d476580b3758a45df Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 1 Sep 2016 17:15:52 +0200 Subject: [PATCH 25/69] Minor fixes & cleanups --- .../HttpFoundation/Tests/JsonResponseTest.php | 4 ++-- .../VarDumper/Caster/ReflectionCaster.php | 22 ++++++------------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php index 0a0732f473219..7b1c44674e362 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php @@ -216,10 +216,10 @@ public function testSetContentJsonSerializeError() public function testSetComplexCallback() { - $response = JsonResponse::fromJsonString('{foo: "bar"}'); + $response = JsonResponse::create(array('foo' => 'bar')); $response->setCallback('ಠ_ಠ["foo"].bar[0]'); - $this->assertEquals('/**/ಠ_ಠ["foo"].bar[0]({foo: "bar"});', $response->getContent()); + $this->assertEquals('/**/ಠ_ಠ["foo"].bar[0]({"foo":"bar"});', $response->getContent()); } } diff --git a/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php b/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php index e772c246b2ff2..dd07c08a470ba 100644 --- a/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php @@ -116,7 +116,8 @@ public static function castFunctionAbstract(\ReflectionFunctionAbstract $c, arra if (isset($a[$prefix.'returnType'])) { $v = $a[$prefix.'returnType']; - $a[$prefix.'returnType'] = $v instanceof \ReflectionNamedType ? $v->getName() : $v->__toString(); + $v = $v instanceof \ReflectionNamedType ? $v->getName() : $v->__toString(); + $a[$prefix.'returnType'] = $a[$prefix.'returnType']->allowsNull() ? '?'.$v : $v; } if (isset($a[$prefix.'this'])) { $a[$prefix.'this'] = new CutStub($a[$prefix.'this']); @@ -168,21 +169,12 @@ public static function castParameter(\ReflectionParameter $c, array $a, Stub $st 'allowsNull' => 'allowsNull', )); - try { - if (method_exists($c, 'getType')) { - if ($v = $c->getType()) { - $a[$prefix.'typeHint'] = $v instanceof \ReflectionNamedType ? $v->getName() : $v->__toString(); - } - } else { - $v = explode(' ', $c->__toString(), 6); - if (isset($v[5]) && 0 === strspn($v[4], '.&$')) { - $a[$prefix.'typeHint'] = $v[4]; - } - } - } catch (\ReflectionException $e) { - if (preg_match('/^Class ([^ ]++) does not exist$/', $e->getMessage(), $m)) { - $a[$prefix.'typeHint'] = $m[1]; + if (method_exists($c, 'getType')) { + if ($v = $c->getType()) { + $a[$prefix.'typeHint'] = $v instanceof \ReflectionNamedType ? $v->getName() : $v->__toString(); } + } elseif (preg_match('/^(?:[^ ]++ ){4}([a-zA-Z_\x7F-\xFF][^ ]++)/', $c, $v)) { + $a[$prefix.'typeHint'] = $v[1]; } if (!isset($a[$prefix.'typeHint'])) { unset($a[$prefix.'allowsNull']); From bffdfad41ec2c447883c5a0f7a0fe311438de138 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 4 Oct 2016 15:27:03 +0200 Subject: [PATCH 26/69] [PropertyInfo] Fix edge cases in ReflectionExtractor --- .../Extractor/ReflectionExtractor.php | 96 +++++++------------ .../Extractors/ReflectionExtractorTest.php | 1 + .../Tests/Fixtures/Php71Dummy.php | 4 + 3 files changed, 39 insertions(+), 62 deletions(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index 1d3d3a2083ca8..7643d8971ecb4 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -44,6 +44,13 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp */ public static $arrayMutatorPrefixes = array('add', 'remove'); + private $supportsParameterType; + + public function __construct() + { + $this->supportsParameterType = method_exists('ReflectionParameter', 'getType'); + } + /** * {@inheritdoc} */ @@ -134,68 +141,33 @@ private function extractFromMutator($class, $property) $reflectionParameters = $reflectionMethod->getParameters(); $reflectionParameter = $reflectionParameters[0]; - $arrayMutator = in_array($prefix, self::$arrayMutatorPrefixes); - - if (method_exists($reflectionParameter, 'getType') && $reflectionType = $reflectionParameter->getType()) { - $fromReflectionType = $this->extractFromReflectionType($reflectionType); - - if (!$arrayMutator) { - return array($fromReflectionType); + if ($this->supportsParameterType) { + if (!$reflectionType = $reflectionParameter->getType()) { + return; } + $type = $this->extractFromReflectionType($reflectionType); - $phpType = Type::BUILTIN_TYPE_ARRAY; - $collectionKeyType = new Type(Type::BUILTIN_TYPE_INT); - $collectionValueType = $fromReflectionType; - } - - if ($reflectionParameter->isArray()) { - $phpType = Type::BUILTIN_TYPE_ARRAY; - $collection = true; - } - - if ($arrayMutator) { - $collection = true; - $nullable = false; - $collectionNullable = $reflectionParameter->allowsNull(); - } else { - $nullable = $reflectionParameter->allowsNull(); - $collectionNullable = false; - } - - if (!isset($collection)) { - $collection = false; - } - - if (method_exists($reflectionParameter, 'isCallable') && $reflectionParameter->isCallable()) { - $phpType = Type::BUILTIN_TYPE_CALLABLE; - } - - if ($typeHint = $reflectionParameter->getClass()) { - if ($collection) { - $phpType = Type::BUILTIN_TYPE_ARRAY; - $collectionKeyType = new Type(Type::BUILTIN_TYPE_INT); - $collectionValueType = new Type(Type::BUILTIN_TYPE_OBJECT, $collectionNullable, $typeHint->name); + // HHVM reports variadics with "array" but not builtin type hints + if (!$reflectionType->isBuiltin() && Type::BUILTIN_TYPE_ARRAY === $type->getBuiltinType()) { + return; + } + } elseif (preg_match('/^(?:[^ ]++ ){4}([a-zA-Z_\x7F-\xFF][^ ]++)/', $reflectionParameter, $info)) { + if (Type::BUILTIN_TYPE_ARRAY === $info[1]) { + $type = new Type(Type::BUILTIN_TYPE_ARRAY, $reflectionParameter->allowsNull(), null, true); + } elseif (Type::BUILTIN_TYPE_CALLABLE === $info[1]) { + $type = new Type(Type::BUILTIN_TYPE_CALLABLE, $reflectionParameter->allowsNull()); } else { - $phpType = Type::BUILTIN_TYPE_OBJECT; - $typeClass = $typeHint->name; + $type = new Type(Type::BUILTIN_TYPE_OBJECT, $reflectionParameter->allowsNull(), $info[1]); } + } else { + return; } - // Nothing useful extracted - if (!isset($phpType)) { - return; + if (in_array($prefix, self::$arrayMutatorPrefixes)) { + $type = new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), $type); } - return array( - new Type( - $phpType, - $nullable, - isset($typeClass) ? $typeClass : null, - $collection, - isset($collectionKeyType) ? $collectionKeyType : null, - isset($collectionValueType) ? $collectionValueType : null - ), - ); + return array($type); } /** @@ -213,7 +185,7 @@ private function extractFromAccessor($class, $property) return; } - if (method_exists($reflectionMethod, 'getReturnType') && $reflectionType = $reflectionMethod->getReturnType()) { + if ($this->supportsParameterType && $reflectionType = $reflectionMethod->getReturnType()) { return array($this->extractFromReflectionType($reflectionType)); } @@ -231,15 +203,15 @@ private function extractFromAccessor($class, $property) */ private function extractFromReflectionType(\ReflectionType $reflectionType) { - $phpTypeOrClass = method_exists($reflectionType, 'getName') ? $reflectionType->getName() : (string) $reflectionType; + $phpTypeOrClass = $reflectionType instanceof \ReflectionNamedType ? $reflectionType->getName() : $reflectionType->__toString(); $nullable = $reflectionType->allowsNull(); - if ($reflectionType->isBuiltin()) { - if (Type::BUILTIN_TYPE_ARRAY === $phpTypeOrClass) { - $type = new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true); - } else { - $type = new Type($phpTypeOrClass, $nullable); - } + if (Type::BUILTIN_TYPE_ARRAY === $phpTypeOrClass) { + $type = new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true); + } elseif ('void' === $phpTypeOrClass) { + $type = new Type(Type::BUILTIN_TYPE_NULL, $nullable); + } elseif ($reflectionType->isBuiltin()) { + $type = new Type($phpTypeOrClass, $nullable); } else { $type = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $phpTypeOrClass); } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractors/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractors/ReflectionExtractorTest.php index 10b056220d539..8a828c21d66be 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractors/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractors/ReflectionExtractorTest.php @@ -107,6 +107,7 @@ public function php71TypesProvider() { return array( array('foo', array(new Type(Type::BUILTIN_TYPE_ARRAY, true, null, true))), + array('buz', array(new Type(Type::BUILTIN_TYPE_NULL))), array('bar', array(new Type(Type::BUILTIN_TYPE_INT, true))), array('baz', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING)))), array('donotexist', null), diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php71Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php71Dummy.php index d93c67a3d38bd..e72d376c492fa 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php71Dummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php71Dummy.php @@ -20,6 +20,10 @@ public function getFoo(): ?array { } + public function getBuz(): void + { + } + public function setBar(?int $bar) { } From c780978158c5c80b17e6e7e63dd6e1a368e8bba2 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 6 Oct 2016 11:12:13 +0200 Subject: [PATCH 27/69] [HttpKernel] Clean ArgumentMetadataFactory::getType() --- .../ArgumentMetadataFactory.php | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php b/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php index ad6c395ee7d96..d1e7af206804b 100644 --- a/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php +++ b/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php @@ -122,21 +122,8 @@ private function getType(\ReflectionParameter $parameter) return $typeName; } - if ($parameter->isArray()) { - return 'array'; + if (preg_match('/^(?:[^ ]++ ){4}([a-zA-Z_\x7F-\xFF][^ ]++)/', $parameter, $info)) { + return $info[1]; } - - if ($parameter->isCallable()) { - return 'callable'; - } - - try { - $refClass = $parameter->getClass(); - } catch (\ReflectionException $e) { - // mandatory; extract it from the exception message - return str_replace(array('Class ', ' does not exist'), '', $e->getMessage()); - } - - return $refClass ? $refClass->getName() : null; } } From a1bc96bf43d3a76feea1492e5e27f17da9e1bbbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 6 Oct 2016 16:04:11 +0200 Subject: [PATCH 28/69] [Serializer] minor: Remove an extra space in a YamlFileLoader error --- .../Component/Serializer/Mapping/Loader/YamlFileLoader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Serializer/Mapping/Loader/YamlFileLoader.php b/src/Symfony/Component/Serializer/Mapping/Loader/YamlFileLoader.php index f68807165d794..1063a334a65f1 100644 --- a/src/Symfony/Component/Serializer/Mapping/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/Serializer/Mapping/Loader/YamlFileLoader.php @@ -90,7 +90,7 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata) if (isset($data['max_depth'])) { if (!is_int($data['max_depth'])) { - throw new MappingException('The "max_depth" value must an integer in "%s" for the attribute "%s" of the class "%s".', $this->file, $attribute, $classMetadata->getName()); + throw new MappingException('The "max_depth" value must be an integer in "%s" for the attribute "%s" of the class "%s".', $this->file, $attribute, $classMetadata->getName()); } $attributeMetadata->setMaxDepth($data['max_depth']); From b1b21bf43dd9661a38091e6f6b6ac47095510e5f Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 7 Oct 2016 13:16:58 +0200 Subject: [PATCH 29/69] Improved the deprecation messages for service aliases --- .../Component/DependencyInjection/Loader/XmlFileLoader.php | 4 ++-- .../Component/DependencyInjection/Loader/YamlFileLoader.php | 2 +- .../DependencyInjection/Tests/Loader/XmlFileLoaderTest.php | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php index 6b1381b01201d..91bb2d071dd52 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php @@ -505,13 +505,13 @@ private function validateAlias(\DOMElement $alias, $file) { foreach ($alias->attributes as $name => $node) { if (!in_array($name, array('alias', 'id', 'public'))) { - @trigger_error(sprintf('Using the attribute "%s" is deprecated for alias definition "%s" in "%s". Allowed attributes are "alias", "id" and "public". The XmlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported attributes.', $name, $alias->getAttribute('id'), $file), E_USER_DEPRECATED); + @trigger_error(sprintf('Using the attribute "%s" is deprecated for the service "%s" which is defined as an alias in "%s". Allowed attributes for service aliases are "alias", "id" and "public". The XmlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported attributes.', $name, $alias->getAttribute('id'), $file), E_USER_DEPRECATED); } } foreach ($alias->childNodes as $child) { if ($child instanceof \DOMElement && $child->namespaceURI === self::NS) { - @trigger_error(sprintf('Using the element "%s" is deprecated for alias definition "%s" in "%s". The XmlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported elements.', $child->localName, $alias->getAttribute('id'), $file), E_USER_DEPRECATED); + @trigger_error(sprintf('Using the element "%s" is deprecated for the service "%s" which is defined as an alias in "%s". The XmlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported elements.', $child->localName, $alias->getAttribute('id'), $file), E_USER_DEPRECATED); } } } diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php index 82bbf901828d4..569c8f4e028b9 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php @@ -180,7 +180,7 @@ private function parseDefinition($id, $service, $file) foreach ($service as $key => $value) { if (!in_array($key, array('alias', 'public'))) { - @trigger_error(sprintf('The configuration key "%s" is unsupported for alias definition "%s" in "%s". Allowed configuration keys are "alias" and "public". The YamlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported attributes.', $key, $id, $file), E_USER_DEPRECATED); + @trigger_error(sprintf('The configuration key "%s" is unsupported for the service "%s" which is defined as an alias in "%s". Allowed configuration keys for service aliases are "alias" and "public". The YamlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported attributes.', $key, $id, $file), E_USER_DEPRECATED); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php index a351c62ebc881..04fad8b5815cd 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php @@ -563,9 +563,9 @@ public function testAutowire() public function testAliasDefinitionContainsUnsupportedElements() { $deprecations = array( - 'Using the attribute "class" is deprecated for alias definition "bar"', - 'Using the element "tag" is deprecated for alias definition "bar"', - 'Using the element "factory" is deprecated for alias definition "bar"', + 'Using the attribute "class" is deprecated for the service "bar" which is defined as an alias', + 'Using the element "tag" is deprecated for the service "bar" which is defined as an alias', + 'Using the element "factory" is deprecated for the service "bar" which is defined as an alias', ); ErrorAssert::assertDeprecationsAreTriggered($deprecations, function () { From f02b6876b4e875d1d766abd1c19a14f3663ef2ad Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Sat, 8 Oct 2016 11:54:03 +0200 Subject: [PATCH 30/69] [FrameworkBundle] Convert null prefix to an empty string in translation:update command --- .../FrameworkBundle/Command/TranslationUpdateCommand.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php index f310613d10315..920c50c1d793f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php @@ -118,8 +118,9 @@ protected function execute(InputInterface $input, OutputInterface $output) // load any messages from templates $extractedCatalogue = new MessageCatalogue($input->getArgument('locale')); $output->text('Parsing templates'); + $prefix = $input->getOption('prefix'); $extractor = $this->getContainer()->get('translation.extractor'); - $extractor->setPrefix($input->getOption('prefix')); + $extractor->setPrefix(null === $prefix ? '' : $prefix); foreach ($transPaths as $path) { $path .= 'views'; if (is_dir($path)) { From 7def83c0b1c7f1abde900c1fe7371d0f2e8f2571 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 11 Oct 2016 23:07:33 +0200 Subject: [PATCH 31/69] move tags from decorated to decorating service --- .../Compiler/DecoratorServicePass.php | 10 ++++++---- .../Compiler/DecoratorServicePassTest.php | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php index ef0a19c6a725c..c7a4ac89c1292 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php @@ -42,10 +42,12 @@ public function process(ContainerBuilder $container) $public = $alias->isPublic(); $container->setAlias($renamedId, new Alias((string) $alias, false)); } else { - $definition = $container->getDefinition($inner); - $public = $definition->isPublic(); - $definition->setPublic(false); - $container->setDefinition($renamedId, $definition); + $decoratedDefinition = $container->getDefinition($inner); + $definition->setTags($decoratedDefinition->getTags(), $definition->getTags()); + $public = $decoratedDefinition->isPublic(); + $decoratedDefinition->setPublic(false); + $decoratedDefinition->setTags(array()); + $container->setDefinition($renamedId, $decoratedDefinition); } $container->setAlias($inner, new Alias($id, $public)); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php index 7ddf44dfc0f1b..b197e422493a4 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php @@ -82,6 +82,24 @@ public function testProcessWithAlias() $this->assertNull($fooExtendedDefinition->getDecoratedService()); } + public function testProcessMovesTagsFromDecoratedDefinitionToDecoratingDefinition() + { + $container = new ContainerBuilder(); + $container + ->register('foo') + ->setTags(array('name' => 'bar')) + ; + $container + ->register('baz') + ->setDecoratedService('foo') + ; + + $this->process($container); + + $this->assertEmpty($container->getDefinition('baz.inner')->getTags()); + $this->assertEquals(array('name' => 'bar'), $container->getDefinition('baz')->getTags()); + } + protected function process(ContainerBuilder $container) { $repeatedPass = new DecoratorServicePass(); From e116d3d76d5381fe84be377ba27a1252342dcbf4 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Wed, 12 Oct 2016 18:58:41 +0200 Subject: [PATCH 32/69] [HttpFoundation] add missing upgrade entry --- UPGRADE-3.0.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md index 81b9a2a92675b..8f2bb48cc9812 100644 --- a/UPGRADE-3.0.md +++ b/UPGRADE-3.0.md @@ -1805,6 +1805,8 @@ UPGRADE FROM 2.x to 3.0 ### HttpFoundation + * The precedence of parameters returned from `Request::get()` changed from "GET, PATH, BODY" to "PATH, GET, BODY" + * `Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface` no longer implements the `IteratorAggregate` interface. Use the `all()` method instead of iterating over the flash bag. * Removed the feature that allowed finding deep items in `ParameterBag::get()`. From 3a458d3823b0f2f482317698ae836355901a867c Mon Sep 17 00:00:00 2001 From: Andre Smith Date: Tue, 11 Oct 2016 16:20:22 +0200 Subject: [PATCH 33/69] 3.0 Upgrade Guide: Added Table of Contents --- UPGRADE-3.0.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md index 8f2bb48cc9812..8d6ffdae9eae7 100644 --- a/UPGRADE-3.0.md +++ b/UPGRADE-3.0.md @@ -1,6 +1,35 @@ UPGRADE FROM 2.x to 3.0 ======================= +# Table of Contents + +- [ClassLoader](#classloader) +- [Config](#config) +- [Console](#console) +- [DependencyInjection](#dependencyinjection) +- [DoctrineBridge](#doctrinebridge) +- [DomCrawler](#domcrawler) +- [EventDispatcher](#eventdispatcher) +- [Form](#form) +- [FrameworkBundle](#frameworkbundle) +- [HttpFoundation](#httpfoundation) +- [HttpKernel](#httpkernel) +- [Locale](#locale) +- [Monolog Bridge](#monolog-bridge) +- [Process](#process) +- [PropertyAccess](#propertyaccess) +- [Routing](#routing) +- [Security](#security) +- [SecurityBundle](#securitybundle) +- [Serializer](#serializer) +- [Swiftmailer Bridge](#swiftmailer-bridge) +- [Translator](#translator) +- [Twig Bridge](#twig-bridge) +- [TwigBundle](#twigbundle) +- [Validator](#validator) +- [WebProfiler](#webprofiler) +- [Yaml](#yaml) + ### ClassLoader * The `UniversalClassLoader` class has been removed in favor of From 129694f6504d6bff001eae9f4bcce8a16b82cb22 Mon Sep 17 00:00:00 2001 From: Lin Lu Date: Sat, 8 Oct 2016 17:47:55 +0200 Subject: [PATCH 34/69] Remove unused variable --- src/Symfony/Component/EventDispatcher/EventDispatcher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/EventDispatcher/EventDispatcher.php b/src/Symfony/Component/EventDispatcher/EventDispatcher.php index f19ba1d24596f..9a68ef12d70a9 100644 --- a/src/Symfony/Component/EventDispatcher/EventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/EventDispatcher.php @@ -92,7 +92,7 @@ public function getListenerPriority($eventName, $listener) } foreach ($this->listeners[$eventName] as $priority => $listeners) { - if (false !== ($key = array_search($listener, $listeners, true))) { + if (false !== array_search($listener, $listeners, true)) { return $priority; } } From aaab30ea80934285772634c1b9c841a8c6ae3157 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 12 Oct 2016 18:43:15 -0700 Subject: [PATCH 35/69] simplified code --- src/Symfony/Component/EventDispatcher/EventDispatcher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/EventDispatcher/EventDispatcher.php b/src/Symfony/Component/EventDispatcher/EventDispatcher.php index 9a68ef12d70a9..bce44a142ba4a 100644 --- a/src/Symfony/Component/EventDispatcher/EventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/EventDispatcher.php @@ -92,7 +92,7 @@ public function getListenerPriority($eventName, $listener) } foreach ($this->listeners[$eventName] as $priority => $listeners) { - if (false !== array_search($listener, $listeners, true)) { + if (false !== in_array($listener, $listeners, true)) { return $priority; } } From 6602e21a9c2c0899b5c8bf7529db80b9114513d9 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 1 Sep 2016 17:15:52 +0200 Subject: [PATCH 36/69] [travis] Test on PHP 7.1 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 62917b9c6b846..5e8436f831284 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,7 +28,7 @@ matrix: - php: 5.6 - php: 7.0 env: deps=high - - php: 7.0 + - php: 7.1 env: deps=low fast_finish: true @@ -52,7 +52,7 @@ before_install: - if [[ ! $skip && $PHP = 5.* ]]; then echo extension = mongo.so >> $INI_FILE; fi - if [[ ! $skip && $PHP = 5.* ]]; then echo extension = memcache.so >> $INI_FILE; fi - if [[ ! $skip && $PHP = 5.* ]]; then (echo yes | pecl install -f apcu-4.0.11 && echo apc.enable_cli = 1 >> $INI_FILE); fi - - if [[ ! $skip && $PHP = 7.0 ]]; then (echo yes | pecl install -f apcu-5.1.5 && echo apc.enable_cli = 1 >> $INI_FILE); fi + - if [[ ! $skip && $PHP = 7.* ]]; then (echo yes | pecl install -f apcu-5.1.6 && echo apc.enable_cli = 1 >> $INI_FILE); fi - if [[ ! $deps && $PHP = 5.* ]]; then (cd src/Symfony/Component/Debug/Resources/ext && phpize && ./configure && make && echo extension = $(pwd)/modules/symfony_debug.so >> $INI_FILE); fi - if [[ ! $skip && $PHP = 5.* ]]; then pecl install -f memcached-2.1.0; fi - if [[ ! $skip && ! $PHP = hhvm* ]]; then echo extension = ldap.so >> $INI_FILE; fi From c1ae7b6ad7af213c7ecc21a1c68a72c41a6f397f Mon Sep 17 00:00:00 2001 From: Wesley Lancel Date: Tue, 4 Oct 2016 09:14:18 +0200 Subject: [PATCH 37/69] Prevent infinite loop in PropertyMetadata --- .../Component/Validator/Mapping/PropertyMetadata.php | 6 ++++++ .../Validator/Tests/Mapping/PropertyMetadataTest.php | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/Symfony/Component/Validator/Mapping/PropertyMetadata.php b/src/Symfony/Component/Validator/Mapping/PropertyMetadata.php index ac71be828541d..ebc83e1d6f59d 100644 --- a/src/Symfony/Component/Validator/Mapping/PropertyMetadata.php +++ b/src/Symfony/Component/Validator/Mapping/PropertyMetadata.php @@ -58,8 +58,14 @@ public function getPropertyValue($object) */ protected function newReflectionMember($objectOrClassName) { + $originalClass = is_string($objectOrClassName) ? $objectOrClassName : get_class($objectOrClassName); + while (!property_exists($objectOrClassName, $this->getName())) { $objectOrClassName = get_parent_class($objectOrClassName); + + if (false === $objectOrClassName) { + throw new ValidatorException(sprintf('Property "%s" does not exist in class "%s"', $this->getName(), $originalClass)); + } } $member = new \ReflectionProperty($objectOrClassName, $this->getName()); diff --git a/src/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php b/src/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php index f411d950e1708..e0ff920fe1ef3 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php @@ -42,4 +42,14 @@ public function testGetPropertyValueFromOverriddenPrivateProperty() $this->assertTrue($metadata->isPublic($entity)); $this->assertEquals('Overridden data', $metadata->getPropertyValue($entity)); } + + public function testGetPropertyValueFromRemovedProperty() + { + $entity = new Entity('foobar'); + $metadata = new PropertyMetadata(self::CLASSNAME, 'internal'); + $metadata->name = 'test'; + + $this->setExpectedException('Symfony\Component\Validator\Exception\ValidatorException'); + $metadata->getPropertyValue($entity); + } } From df138fb636867b396185e634263e310aaafbd75f Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 13 Oct 2016 07:02:27 -0700 Subject: [PATCH 38/69] fixed CS --- src/Symfony/Component/Validator/Mapping/PropertyMetadata.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/Mapping/PropertyMetadata.php b/src/Symfony/Component/Validator/Mapping/PropertyMetadata.php index ebc83e1d6f59d..d12701cb44aba 100644 --- a/src/Symfony/Component/Validator/Mapping/PropertyMetadata.php +++ b/src/Symfony/Component/Validator/Mapping/PropertyMetadata.php @@ -64,7 +64,7 @@ protected function newReflectionMember($objectOrClassName) $objectOrClassName = get_parent_class($objectOrClassName); if (false === $objectOrClassName) { - throw new ValidatorException(sprintf('Property "%s" does not exist in class "%s"', $this->getName(), $originalClass)); + throw new ValidatorException(sprintf('Property "%s" does not exist in class "%s".', $this->getName(), $originalClass)); } } From c43de7f21a587649bb42ca08bce9ad8d0c0e731d Mon Sep 17 00:00:00 2001 From: David Maicher Date: Thu, 13 Oct 2016 22:14:35 +0200 Subject: [PATCH 39/69] [HttpCache] fix: do not cache OPTIONS request --- .../Component/HttpFoundation/Request.php | 10 +++++++ .../HttpFoundation/Tests/RequestTest.php | 26 +++++++++++++++++++ .../HttpKernel/HttpCache/HttpCache.php | 2 +- .../Tests/HttpCache/HttpCacheTest.php | 15 +++++++++++ .../Component/HttpKernel/composer.json | 2 +- 5 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index dc32f4a39af92..00a16223b497f 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -1473,6 +1473,16 @@ public function isMethodSafe() return in_array($this->getMethod(), array('GET', 'HEAD', 'OPTIONS', 'TRACE')); } + /** + * Checks whether the method is cachaeble or not. + * + * @return bool + */ + public function isMethodCacheable() + { + return in_array($this->getMethod(), array('GET', 'HEAD')); + } + /** * Returns the request body content. * diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php index f90a368775a16..0c54c16b29cfc 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php @@ -1948,6 +1948,32 @@ public function methodSafeProvider() array('CONNECT', false), ); } + + /** + * @dataProvider methodCacheableProvider + */ + public function testMethodCacheable($method, $chacheable) + { + $request = new Request(); + $request->setMethod($method); + $this->assertEquals($chacheable, $request->isMethodCacheable()); + } + + public function methodCacheableProvider() + { + return array( + array('HEAD', true), + array('GET', true), + array('POST', false), + array('PUT', false), + array('PATCH', false), + array('DELETE', false), + array('PURGE', false), + array('OPTIONS', false), + array('TRACE', false), + array('CONNECT', false), + ); + } } class RequestContentProxy extends Request diff --git a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php index 253deb143a897..efb08d693c891 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php @@ -204,7 +204,7 @@ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQ if (!$request->isMethodSafe()) { $response = $this->invalidate($request, $catch); - } elseif ($request->headers->has('expect')) { + } elseif ($request->headers->has('expect') || !$request->isMethodCacheable()) { $response = $this->pass($request, $catch); } else { $response = $this->lookup($request, $catch); diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php index 68d2b88ed6a86..7751f6e0ccfdc 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php @@ -1264,6 +1264,21 @@ public function testEsiCacheRemoveValidationHeadersIfEmbeddedResponses() $this->assertNull($this->response->getETag()); $this->assertNull($this->response->getLastModified()); } + + public function testDoesNotCacheOptionsRequest() + { + $this->setNextResponse(200, array('Cache-Control' => 'public, s-maxage=60'), 'get'); + $this->request('GET', '/'); + $this->assertHttpKernelIsCalled(); + + $this->setNextResponse(200, array('Cache-Control' => 'public, s-maxage=60'), 'options'); + $this->request('OPTIONS', '/'); + $this->assertHttpKernelIsCalled(); + + $this->request('GET', '/'); + $this->assertHttpKernelIsNotCalled(); + $this->assertSame('get', $this->response->getContent()); + } } class TestKernel implements HttpKernelInterface diff --git a/src/Symfony/Component/HttpKernel/composer.json b/src/Symfony/Component/HttpKernel/composer.json index 1774b641e3b10..ec2333d9b4bb0 100644 --- a/src/Symfony/Component/HttpKernel/composer.json +++ b/src/Symfony/Component/HttpKernel/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=5.3.9", "symfony/event-dispatcher": "~2.6,>=2.6.7", - "symfony/http-foundation": "~2.7.15|~2.8.8", + "symfony/http-foundation": "~2.7.20|~2.8.13", "symfony/debug": "~2.6,>=2.6.2", "psr/log": "~1.0" }, From f76e77f924142a3c00023d23d1ff82bdb3ade1f1 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 13 Oct 2016 18:29:00 -0700 Subject: [PATCH 40/69] fixed typo --- src/Symfony/Component/HttpFoundation/Request.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index 00a16223b497f..5e07af3790c93 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -1474,7 +1474,7 @@ public function isMethodSafe() } /** - * Checks whether the method is cachaeble or not. + * Checks whether the method is cacheable or not. * * @return bool */ From d24c3402310036ac95c319a83b6e0ec1a7adcbff Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 14 Oct 2016 11:42:19 +0200 Subject: [PATCH 41/69] Fix deps merge --- src/Symfony/Component/HttpKernel/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/composer.json b/src/Symfony/Component/HttpKernel/composer.json index 7346264627c28..13a89b7184ddb 100644 --- a/src/Symfony/Component/HttpKernel/composer.json +++ b/src/Symfony/Component/HttpKernel/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=5.3.9", "symfony/event-dispatcher": "~2.6,>=2.6.7|~3.0.0", - "symfony/http-foundation": "~2.7.20|~2.8.13|~3.0.8", + "symfony/http-foundation": "~2.7.20|~2.8.13|~3.1.6", "symfony/debug": "~2.6,>=2.6.2", "psr/log": "~1.0" }, From 3d6b4502c80c1e616391beee6d618898abe1cd37 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 14 Oct 2016 13:10:27 +0200 Subject: [PATCH 42/69] no 304 response if method is not cacheable --- src/Symfony/Component/HttpFoundation/Response.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/Response.php b/src/Symfony/Component/HttpFoundation/Response.php index 9babc6345a468..7a05a03cdc795 100644 --- a/src/Symfony/Component/HttpFoundation/Response.php +++ b/src/Symfony/Component/HttpFoundation/Response.php @@ -1000,7 +1000,7 @@ public function setVary($headers, $replace = true) */ public function isNotModified(Request $request) { - if (!$request->isMethodSafe()) { + if (!$request->isMethodCacheable()) { return false; } From cd3206c5cba85bdef04ac1c0d015543064bf1ee8 Mon Sep 17 00:00:00 2001 From: Muhammed Akbulut Date: Fri, 29 Jul 2016 16:40:15 +0200 Subject: [PATCH 43/69] fixed Filesystem:makePathRelative and added 2 more testcases --- src/Symfony/Component/Filesystem/Filesystem.php | 8 ++++++-- src/Symfony/Component/Filesystem/Tests/FilesystemTest.php | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index f114a2de58bcd..79e8420688821 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -369,10 +369,14 @@ public function makePathRelative($endPath, $startPath) } // Determine how deep the start path is relative to the common path (ie, "web/bundles" = 2 levels) - $depth = count($startPathArr) - $index; + if (count($startPathArr) === 1 && $startPathArr[0] === '') { + $depth = 0; + } else { + $depth = count($startPathArr) - $index; + } // When we need to traverse from the start, and we are starting from a root path, don't add '../' - if ('/' === $startPath[0] && 0 === $index && 1 === $depth) { + if ('/' === $startPath[0] && 0 === $index && 0 === $depth) { $traverser = ''; } else { // Repeated "../" for each level need to reach the common path diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php index 0ca2904833f26..4f7457898b27a 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php @@ -840,6 +840,8 @@ public function providePathsForMakePathRelative() array('/a/aab/bb/', '/a/aa/', '../aab/bb/'), array('/a/aab/bb/', '/', 'a/aab/bb/'), array('/a/aab/bb/', '/b/aab', '../../a/aab/bb/'), + array('/aab/bb', '/aa', '../aab/bb/'), + array('/aab', '/aa', '../aab/'), ); if ('\\' === DIRECTORY_SEPARATOR) { From b69bd3f0ed94d9c8138d1cd379e734a67e7ce1bd Mon Sep 17 00:00:00 2001 From: Andre Smith Date: Tue, 11 Oct 2016 17:48:30 +0200 Subject: [PATCH 44/69] 3.0 Upgrade Guide: Added details describing how to pass data to a form through the options resolver --- UPGRADE-3.0.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md index b8b4a96223469..68e3780d8ab36 100644 --- a/UPGRADE-3.0.md +++ b/UPGRADE-3.0.md @@ -348,6 +348,58 @@ UPGRADE FROM 2.x to 3.0 $form = $this->createForm(MyType::class); ``` + * Passing custom data to forms now needs to be done + through the options resolver. + + In the controller: + + Before: + ```php + $form = $this->createForm(new MyType($variable), $entity, array( + 'action' => $this->generateUrl('action_route'), + 'method' => 'PUT', + )); + ``` + After: + ```php + $form = $this->createForm(MyType::class, $entity, array( + 'action' => $this->generateUrl('action_route'), + 'method' => 'PUT', + 'custom_value' => $variable, + )); + ``` + In the form type: + + Before: + ```php + class MyType extends AbstractType + { + private $value; + + public function __construct($variableValue) + { + $this->value = $value; + } + // ... + } + ``` + + After: + ```php + public function buildForm(FormBuilderInterface $builder, array $options) + { + $value = $options['custom_value']; + // ... + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults(array( + 'custom_value' => null, + )); + } + ``` + * The alias option of the `form.type_extension` tag was removed in favor of the `extended_type`/`extended-type` option. From b0df3a7eb9afd93bf07f875cc429cc05b1b7d12b Mon Sep 17 00:00:00 2001 From: Dariusz Ruminski Date: Sun, 16 Oct 2016 22:09:25 +0200 Subject: [PATCH 45/69] PHP CS Fixer: use php_unit_dedicate_assert --- .php_cs | 1 + .../Bundle/FrameworkBundle/Tests/Functional/ProfilerTest.php | 2 +- .../Bundle/TwigBundle/Tests/Functional/CacheWarmingTest.php | 4 ++-- .../Extension/Validator/Type/BaseValidatorExtensionTest.php | 4 ++-- .../Component/OptionsResolver/Tests/LegacyOptionsTest.php | 4 ++-- .../Component/Translation/Tests/Dumper/FileDumperTest.php | 4 ++-- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.php_cs b/.php_cs index 6043614819492..5a702adb3a838 100644 --- a/.php_cs +++ b/.php_cs @@ -6,6 +6,7 @@ return Symfony\CS\Config\Config::create() ->fixers(array( 'long_array_syntax', 'php_unit_construct', + 'php_unit_dedicate_assert', )) ->finder( Symfony\CS\Finder\DefaultFinder::create() diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ProfilerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ProfilerTest.php index a8741124fda7f..2d422b0292081 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ProfilerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ProfilerTest.php @@ -30,7 +30,7 @@ public function testProfilerIsDisabled($insulate) $client->enableProfiler(); $crawler = $client->request('GET', '/profiler'); $profile = $client->getProfile(); - $this->assertTrue(is_object($profile)); + $this->assertInternalType('object', $profile); $client->request('GET', '/profiler'); $this->assertFalse($client->getProfile()); diff --git a/src/Symfony/Bundle/TwigBundle/Tests/Functional/CacheWarmingTest.php b/src/Symfony/Bundle/TwigBundle/Tests/Functional/CacheWarmingTest.php index 0b04f81af0798..b51e619a9d285 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/Functional/CacheWarmingTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/Functional/CacheWarmingTest.php @@ -28,7 +28,7 @@ public function testCacheIsProperlyWarmedWhenTemplatingIsAvailable() $warmer->enableOptionalWarmers(); $warmer->warmUp($kernel->getCacheDir()); - $this->assertTrue(file_exists($kernel->getCacheDir().'/twig')); + $this->assertFileExists($kernel->getCacheDir().'/twig'); } public function testCacheIsNotWarmedWhenTemplatingIsDisabled() @@ -40,7 +40,7 @@ public function testCacheIsNotWarmedWhenTemplatingIsDisabled() $warmer->enableOptionalWarmers(); $warmer->warmUp($kernel->getCacheDir()); - $this->assertFalse(file_exists($kernel->getCacheDir().'/twig')); + $this->assertFileNotExists($kernel->getCacheDir().'/twig'); } protected function setUp() diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/Type/BaseValidatorExtensionTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/Type/BaseValidatorExtensionTest.php index 6a15bbfa9e6b6..01f20c4127cf1 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/Type/BaseValidatorExtensionTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/Type/BaseValidatorExtensionTest.php @@ -58,7 +58,7 @@ public function testValidationGroupsCanBeSetToCallback() 'validation_groups' => array($this, 'testValidationGroupsCanBeSetToCallback'), )); - $this->assertTrue(is_callable($form->getConfig()->getOption('validation_groups'))); + $this->assertInternalType('callable', $form->getConfig()->getOption('validation_groups')); } public function testValidationGroupsCanBeSetToClosure() @@ -67,7 +67,7 @@ public function testValidationGroupsCanBeSetToClosure() 'validation_groups' => function (FormInterface $form) { }, )); - $this->assertTrue(is_callable($form->getConfig()->getOption('validation_groups'))); + $this->assertInternalType('callable', $form->getConfig()->getOption('validation_groups')); } abstract protected function createForm(array $options = array()); diff --git a/src/Symfony/Component/OptionsResolver/Tests/LegacyOptionsTest.php b/src/Symfony/Component/OptionsResolver/Tests/LegacyOptionsTest.php index b65a09002eabe..fb4d25b5bcea5 100644 --- a/src/Symfony/Component/OptionsResolver/Tests/LegacyOptionsTest.php +++ b/src/Symfony/Component/OptionsResolver/Tests/LegacyOptionsTest.php @@ -275,7 +275,7 @@ public function testOverloadCannotBeEvaluatedLazilyWithoutExpectedClosureParams( }); $resolved = $this->options->resolve(); - $this->assertTrue(is_callable($resolved['foo'])); + $this->assertInternalType('callable', $resolved['foo']); } public function testOverloadCannotBeEvaluatedLazilyWithoutFirstParamTypeHint() @@ -287,7 +287,7 @@ public function testOverloadCannotBeEvaluatedLazilyWithoutFirstParamTypeHint() }); $resolved = $this->options->resolve(); - $this->assertTrue(is_callable($resolved['foo'])); + $this->assertInternalType('callable', $resolved['foo']); } public function testRemoveOptionAndNormalizer() diff --git a/src/Symfony/Component/Translation/Tests/Dumper/FileDumperTest.php b/src/Symfony/Component/Translation/Tests/Dumper/FileDumperTest.php index 96820890922a0..bb2d9166ef7cc 100644 --- a/src/Symfony/Component/Translation/Tests/Dumper/FileDumperTest.php +++ b/src/Symfony/Component/Translation/Tests/Dumper/FileDumperTest.php @@ -30,7 +30,7 @@ public function testDumpBackupsFileIfExisting() $dumper = new ConcreteFileDumper(); $dumper->dump($catalogue, array('path' => $tempDir)); - $this->assertTrue(file_exists($backupFile)); + $this->assertFileExists($backupFile); @unlink($file); @unlink($backupFile); @@ -49,7 +49,7 @@ public function testDumpCreatesNestedDirectoriesAndFile() $dumper->setRelativePathTemplate('test/translations/%domain%.%locale%.%extension%'); $dumper->dump($catalogue, array('path' => $tempDir)); - $this->assertTrue(file_exists($file)); + $this->assertFileExists($file); @unlink($file); @rmdir($translationsDir); From f0849d833118e69b0d630047594b046f0d4a34bc Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 15 Oct 2016 12:33:44 -0700 Subject: [PATCH 46/69] [TwigBridge] removed deprecations added in Twig 1.27 --- composer.json | 2 +- .../Bridge/Twig/Command/LintCommand.php | 2 +- .../Tests/Extension/RoutingExtensionTest.php | 2 +- .../Extension/TranslationExtensionTest.php | 2 +- .../Tests/NodeVisitor/TwigNodeProvider.php | 2 +- .../TokenParser/FormThemeTokenParserTest.php | 2 +- .../TokenParser/TransChoiceTokenParser.php | 2 +- .../Twig/TokenParser/TransTokenParser.php | 4 +-- .../Bridge/Twig/Translation/TwigExtractor.php | 6 ++--- src/Symfony/Bridge/Twig/composer.json | 2 +- .../Bundle/SecurityBundle/composer.json | 2 +- .../DependencyInjection/Configuration.php | 2 +- .../DependencyInjection/TwigExtensionTest.php | 2 +- .../LegacyRenderTokenParserTest.php | 2 +- src/Symfony/Bundle/TwigBundle/TwigEngine.php | 10 ++++---- src/Symfony/Bundle/TwigBundle/composer.json | 2 +- .../DataCollector/DumpDataCollector.php | 25 +++++++++++-------- 17 files changed, 37 insertions(+), 34 deletions(-) diff --git a/composer.json b/composer.json index 468b4f5b267f2..1a2e8c26b586f 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "paragonie/random_compat": "~1.0", "symfony/polyfill-apcu": "~1.1", "symfony/polyfill-mbstring": "~1.1", - "twig/twig": "~1.26|~2.0", + "twig/twig": "~1.27|~2.0", "psr/log": "~1.0" }, "replace": { diff --git a/src/Symfony/Bridge/Twig/Command/LintCommand.php b/src/Symfony/Bridge/Twig/Command/LintCommand.php index df603f93fddda..4ed63241b8d8c 100644 --- a/src/Symfony/Bridge/Twig/Command/LintCommand.php +++ b/src/Symfony/Bridge/Twig/Command/LintCommand.php @@ -146,7 +146,7 @@ private function validate(\Twig_Environment $twig, $template, $file) try { $temporaryLoader = new \Twig_Loader_Array(array((string) $file => $template)); $twig->setLoader($temporaryLoader); - $nodeTree = $twig->parse($twig->tokenize($template, (string) $file)); + $nodeTree = $twig->parse($twig->tokenize(new \Twig_Source($template, (string) $file))); $twig->compile($nodeTree); $twig->setLoader($realLoader); } catch (\Twig_Error $e) { diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/RoutingExtensionTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/RoutingExtensionTest.php index 1c1ac645c89f8..87b6052f6f792 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/RoutingExtensionTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/RoutingExtensionTest.php @@ -23,7 +23,7 @@ public function testEscaping($template, $mustBeEscaped) $twig = new \Twig_Environment($this->getMock('Twig_LoaderInterface'), array('debug' => true, 'cache' => false, 'autoescape' => 'html', 'optimizations' => 0)); $twig->addExtension(new RoutingExtension($this->getMock('Symfony\Component\Routing\Generator\UrlGeneratorInterface'))); - $nodes = $twig->parse($twig->tokenize($template)); + $nodes = $twig->parse($twig->tokenize(new \Twig_Source($template))); $this->assertSame($mustBeEscaped, $nodes->getNode('body')->getNode(0)->getNode('expr') instanceof \Twig_Node_Expression_Filter); } diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php index a02edc777a1bf..0235c4da327a0 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php @@ -36,7 +36,7 @@ public function testTrans($template, $expected, array $variables = array()) $twig = new \Twig_Environment($loader, array('debug' => true, 'cache' => false)); $twig->addExtension(new TranslationExtension(new Translator('en', new MessageSelector()))); - echo $twig->compile($twig->parse($twig->tokenize($twig->getLoader()->getSource('index'), 'index')))."\n\n"; + echo $twig->compile($twig->parse($twig->tokenize(new \Twig_Source($twig->getLoader()->getSource('index'), 'index'))))."\n\n"; $this->assertEquals($expected, $this->getTemplate($template)->render($variables)); } diff --git a/src/Symfony/Bridge/Twig/Tests/NodeVisitor/TwigNodeProvider.php b/src/Symfony/Bridge/Twig/Tests/NodeVisitor/TwigNodeProvider.php index 0e401f62ea8b9..a90b556c9e3fe 100644 --- a/src/Symfony/Bridge/Twig/Tests/NodeVisitor/TwigNodeProvider.php +++ b/src/Symfony/Bridge/Twig/Tests/NodeVisitor/TwigNodeProvider.php @@ -25,7 +25,7 @@ public static function getModule($content) new \Twig_Node_Expression_Array(array(), 0), new \Twig_Node_Expression_Array(array(), 0), null, - null + new \Twig_Source('') ); } diff --git a/src/Symfony/Bridge/Twig/Tests/TokenParser/FormThemeTokenParserTest.php b/src/Symfony/Bridge/Twig/Tests/TokenParser/FormThemeTokenParserTest.php index 2986cd1258d63..aa9913249833d 100644 --- a/src/Symfony/Bridge/Twig/Tests/TokenParser/FormThemeTokenParserTest.php +++ b/src/Symfony/Bridge/Twig/Tests/TokenParser/FormThemeTokenParserTest.php @@ -23,7 +23,7 @@ public function testCompile($source, $expected) { $env = new \Twig_Environment($this->getMock('Twig_LoaderInterface'), array('cache' => false, 'autoescape' => false, 'optimizations' => 0)); $env->addTokenParser(new FormThemeTokenParser()); - $stream = $env->tokenize($source); + $stream = $env->tokenize(new \Twig_Source($source)); $parser = new \Twig_Parser($env); $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)); diff --git a/src/Symfony/Bridge/Twig/TokenParser/TransChoiceTokenParser.php b/src/Symfony/Bridge/Twig/TokenParser/TransChoiceTokenParser.php index 7ea1a2c414647..e9e65ad46f896 100644 --- a/src/Symfony/Bridge/Twig/TokenParser/TransChoiceTokenParser.php +++ b/src/Symfony/Bridge/Twig/TokenParser/TransChoiceTokenParser.php @@ -64,7 +64,7 @@ public function parse(\Twig_Token $token) $body = $this->parser->subparse(array($this, 'decideTransChoiceFork'), true); if (!$body instanceof \Twig_Node_Text && !$body instanceof \Twig_Node_Expression) { - throw new \Twig_Error_Syntax('A message inside a transchoice tag must be a simple text.', $body->getLine(), $stream->getFilename()); + throw new \Twig_Error_Syntax('A message inside a transchoice tag must be a simple text.', $body->getLine(), $stream->getSourceContext()->getName()); } $stream->expect(\Twig_Token::BLOCK_END_TYPE); diff --git a/src/Symfony/Bridge/Twig/TokenParser/TransTokenParser.php b/src/Symfony/Bridge/Twig/TokenParser/TransTokenParser.php index 06472d0b42174..1493cf8bcfcd9 100644 --- a/src/Symfony/Bridge/Twig/TokenParser/TransTokenParser.php +++ b/src/Symfony/Bridge/Twig/TokenParser/TransTokenParser.php @@ -55,7 +55,7 @@ public function parse(\Twig_Token $token) $stream->next(); $locale = $this->parser->getExpressionParser()->parseExpression(); } elseif (!$stream->test(\Twig_Token::BLOCK_END_TYPE)) { - throw new \Twig_Error_Syntax('Unexpected token. Twig was looking for the "with", "from", or "into" keyword.', $stream->getCurrent()->getLine(), $stream->getFilename()); + throw new \Twig_Error_Syntax('Unexpected token. Twig was looking for the "with", "from", or "into" keyword.', $stream->getCurrent()->getLine(), $stream->getSourceContext()->getName()); } } @@ -64,7 +64,7 @@ public function parse(\Twig_Token $token) $body = $this->parser->subparse(array($this, 'decideTransFork'), true); if (!$body instanceof \Twig_Node_Text && !$body instanceof \Twig_Node_Expression) { - throw new \Twig_Error_Syntax('A message inside a trans tag must be a simple text.', $body->getLine(), $stream->getFilename()); + throw new \Twig_Error_Syntax('A message inside a trans tag must be a simple text.', $body->getLine(), $stream->getSourceContext()->getName()); } $stream->expect(\Twig_Token::BLOCK_END_TYPE); diff --git a/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php b/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php index 2a9450c885837..69ec1d9155000 100644 --- a/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php +++ b/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php @@ -62,9 +62,9 @@ public function extract($resource, MessageCatalogue $catalogue) $this->extractTemplate(file_get_contents($file->getPathname()), $catalogue); } catch (\Twig_Error $e) { if ($file instanceof SplFileInfo) { - $e->setTemplateFile($file->getRelativePathname()); + $e->setTemplateName($file->getRelativePathname()); } elseif ($file instanceof \SplFileInfo) { - $e->setTemplateFile($file->getRealPath()); + $e->setTemplateName($file->getRealPath()); } throw $e; @@ -85,7 +85,7 @@ protected function extractTemplate($template, MessageCatalogue $catalogue) $visitor = $this->twig->getExtension('Symfony\Bridge\Twig\Extension\TranslationExtension')->getTranslationNodeVisitor(); $visitor->enable(); - $this->twig->parse($this->twig->tokenize($template)); + $this->twig->parse($this->twig->tokenize(new \Twig_Source($template))); foreach ($visitor->getMessages() as $message) { $catalogue->set(trim($message[0]), $this->prefix.trim($message[0]), $message[1] ?: $this->defaultDomain); diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index c82e7b8cf4098..b83dc34c7fb8f 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": ">=5.3.9", - "twig/twig": "~1.26|~2.0" + "twig/twig": "~1.27|~2.0" }, "require-dev": { "symfony/asset": "~2.7", diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index 0ca847bc1b80b..5c80d97691403 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -37,7 +37,7 @@ "symfony/yaml": "~2.0,>=2.0.5", "symfony/expression-language": "~2.6", "doctrine/doctrine-bundle": "~1.2", - "twig/twig": "~1.26|~2.0", + "twig/twig": "~1.27|~2.0", "ircmaxell/password-compat": "~1.0" }, "autoload": { diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php index 52c70f33187d5..008f9b7e769dd 100644 --- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php @@ -167,7 +167,7 @@ private function addTwigOptions(ArrayNodeDefinition $rootNode) $rootNode ->fixXmlConfig('path') ->children() - ->variableNode('autoescape')->defaultValue('filename')->end() + ->variableNode('autoescape')->defaultValue('name')->end() ->scalarNode('autoescape_service')->defaultNull()->end() ->scalarNode('autoescape_service_method')->defaultNull()->end() ->scalarNode('base_template_class')->example('Twig_Template')->cannotBeEmpty()->end() diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php index cd3968034e109..fcfa38a4bb1a8 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php @@ -147,7 +147,7 @@ public function testLoadDefaultTemplateEscapingGuesserConfiguration($format) $this->compileContainer($container); $options = $container->getDefinition('twig')->getArgument(1); - $this->assertEquals('filename', $options['autoescape']); + $this->assertEquals('name', $options['autoescape']); } public function testGlobalsWithDifferentTypesAndValues() diff --git a/src/Symfony/Bundle/TwigBundle/Tests/TokenParser/LegacyRenderTokenParserTest.php b/src/Symfony/Bundle/TwigBundle/Tests/TokenParser/LegacyRenderTokenParserTest.php index e3d0a72a6c081..b1f81ec8eef5b 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/TokenParser/LegacyRenderTokenParserTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/TokenParser/LegacyRenderTokenParserTest.php @@ -27,7 +27,7 @@ public function testCompile($source, $expected) { $env = new \Twig_Environment($this->getMock('Twig_LoaderInterface'), array('cache' => false, 'autoescape' => false, 'optimizations' => 0)); $env->addTokenParser(new RenderTokenParser()); - $stream = $env->tokenize($source); + $stream = $env->tokenize(new \Twig_Source($source)); $parser = new \Twig_Parser($env); $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)); diff --git a/src/Symfony/Bundle/TwigBundle/TwigEngine.php b/src/Symfony/Bundle/TwigBundle/TwigEngine.php index 3092fe9c5d611..0d01648d57587 100644 --- a/src/Symfony/Bundle/TwigBundle/TwigEngine.php +++ b/src/Symfony/Bundle/TwigBundle/TwigEngine.php @@ -54,13 +54,13 @@ public function setDefaultEscapingStrategy($strategy) /** * @deprecated since version 2.7, to be removed in 3.0. - * Use the 'filename' strategy instead. + * Use the 'name' strategy instead. */ - public function guessDefaultEscapingStrategy($filename) + public function guessDefaultEscapingStrategy($name) { @trigger_error('The '.__METHOD__.' method is deprecated since version 2.7 and will be removed in 3.0. Use the Twig_FileExtensionEscapingStrategy::guess method instead.', E_USER_DEPRECATED); - return \Twig_FileExtensionEscapingStrategy::guess($filename); + return \Twig_FileExtensionEscapingStrategy::guess($name); } /** @@ -73,8 +73,8 @@ public function render($name, array $parameters = array()) } catch (\Twig_Error $e) { if ($name instanceof TemplateReference) { try { - // try to get the real file name of the template where the error occurred - $e->setTemplateFile(sprintf('%s', $this->locator->locate($this->parser->parse($e->getTemplateFile())))); + // try to get the real name of the template where the error occurred + $e->setTemplateName(sprintf('%s', $this->locator->locate($this->parser->parse($e->getTemplateName())))); } catch (\Exception $e2) { } } diff --git a/src/Symfony/Bundle/TwigBundle/composer.json b/src/Symfony/Bundle/TwigBundle/composer.json index dfee0d6e8089b..4714ddb2e06fc 100644 --- a/src/Symfony/Bundle/TwigBundle/composer.json +++ b/src/Symfony/Bundle/TwigBundle/composer.json @@ -19,7 +19,7 @@ "php": ">=5.3.9", "symfony/asset": "~2.7", "symfony/twig-bridge": "~2.7", - "twig/twig": "~1.26|~2.0", + "twig/twig": "~1.27|~2.0", "symfony/http-foundation": "~2.5", "symfony/http-kernel": "~2.7" }, diff --git a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php index 985db4b133b58..3a445f45bb89a 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php @@ -97,21 +97,24 @@ public function dump(Data $data) break; } elseif (isset($trace[$i]['object']) && $trace[$i]['object'] instanceof \Twig_Template) { - $info = $trace[$i]['object']; - $name = $info->getTemplateName(); - $src = method_exists($info, 'getSource') ? $info->getSource() : $info->getEnvironment()->getLoader()->getSource($name); - $info = $info->getDebugInfo(); + $template = $trace[$i]['object']; + $name = $template->getTemplateName(); + $file = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getPath() : false; + $src = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : false); + $info = $template->getDebugInfo(); if (null !== $src && isset($info[$trace[$i - 1]['line']])) { - $file = false; $line = $info[$trace[$i - 1]['line']]; - $src = explode("\n", $src); - $fileExcerpt = array(); - for ($i = max($line - 3, 1), $max = min($line + 3, count($src)); $i <= $max; ++$i) { - $fileExcerpt[] = ''.$this->htmlEncode($src[$i - 1]).''; - } + if ($src) { + $src = explode("\n", $src); + $fileExcerpt = array(); + + for ($i = max($line - 3, 1), $max = min($line + 3, count($src)); $i <= $max; ++$i) { + $fileExcerpt[] = ''.$this->htmlEncode($src[$i - 1]).''; + } - $fileExcerpt = '
    '.implode("\n", $fileExcerpt).'
'; + $fileExcerpt = '
    '.implode("\n", $fileExcerpt).'
'; + } } break; } From 5b26e332610ed665137d8b63f43a61ec9d8432b6 Mon Sep 17 00:00:00 2001 From: Klaus Purer Date: Sun, 16 Oct 2016 22:10:53 +0200 Subject: [PATCH 47/69] [DomCrawler] Allow pipe (|) character in link tags when using Xpath expressions --- src/Symfony/Component/DomCrawler/Crawler.php | 44 ++++++++++++++++++- .../DomCrawler/Tests/CrawlerTest.php | 5 ++- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/DomCrawler/Crawler.php b/src/Symfony/Component/DomCrawler/Crawler.php index 37822e53c2a00..a1ddffd797a1a 100644 --- a/src/Symfony/Component/DomCrawler/Crawler.php +++ b/src/Symfony/Component/DomCrawler/Crawler.php @@ -856,13 +856,12 @@ private function relativize($xpath) { $expressions = array(); - $unionPattern = '/\|(?![^\[]*\])/'; // An expression which will never match to replace expressions which cannot match in the crawler // We cannot simply drop $nonMatchingExpression = 'a[name() = "b"]'; // Split any unions into individual expressions. - foreach (preg_split($unionPattern, $xpath) as $expression) { + foreach ($this->splitUnionParts($xpath) as $expression) { $expression = trim($expression); $parenthesis = ''; @@ -912,6 +911,47 @@ private function relativize($xpath) return implode(' | ', $expressions); } + /** + * Splits the XPath into parts that are separated by the union operator. + * + * @param string $xpath + * + * @return string[] + */ + private function splitUnionParts($xpath) + { + // Split any unions into individual expressions. We need to iterate + // through the string to correctly parse opening/closing quotes and + // braces which is not possible with regular expressions. + $unionParts = array(); + $inSingleQuotedString = false; + $inDoubleQuotedString = false; + $openedBrackets = 0; + $lastUnion = 0; + $xpathLength = strlen($xpath); + for ($i = 0; $i < $xpathLength; ++$i) { + $char = $xpath[$i]; + + if ($char === "'" && !$inDoubleQuotedString) { + $inSingleQuotedString = !$inSingleQuotedString; + } elseif ($char === '"' && !$inSingleQuotedString) { + $inDoubleQuotedString = !$inDoubleQuotedString; + } elseif (!$inSingleQuotedString && !$inDoubleQuotedString) { + if ($char === '[') { + ++$openedBrackets; + } elseif ($char === ']') { + --$openedBrackets; + } elseif ($char === '|' && $openedBrackets === 0) { + $unionParts[] = substr($xpath, $lastUnion, $i - $lastUnion); + $lastUnion = $i + 1; + } + } + } + $unionParts[] = substr($xpath, $lastUnion); + + return $unionParts; + } + /** * @param int $position * diff --git a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php index 45bbb2f8e5992..65e2a90e87513 100755 --- a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php +++ b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php @@ -387,6 +387,7 @@ public function testFilterXpathComplexQueries() $this->assertCount(5, $crawler->filterXPath('(//a | //div)//img')); $this->assertCount(7, $crawler->filterXPath('((//a | //div)//img | //ul)')); $this->assertCount(7, $crawler->filterXPath('( ( //a | //div )//img | //ul )')); + $this->assertCount(1, $crawler->filterXPath("//a[./@href][((./@id = 'Klausi|Claudiu' or normalize-space(string(.)) = 'Klausi|Claudiu' or ./@title = 'Klausi|Claudiu' or ./@rel = 'Klausi|Claudiu') or .//img[./@alt = 'Klausi|Claudiu'])]")); } public function testFilterXPath() @@ -548,7 +549,7 @@ public function testFilterXPathWithSelfAxes() $this->assertCount(0, $crawler->filterXPath('self::a'), 'The fake root node has no "real" element name'); $this->assertCount(0, $crawler->filterXPath('self::a/img'), 'The fake root node has no "real" element name'); - $this->assertCount(9, $crawler->filterXPath('self::*/a')); + $this->assertCount(10, $crawler->filterXPath('self::*/a')); } public function testFilter() @@ -969,6 +970,8 @@ public function createTestCrawler($uri = null) GetLink + Klausi|Claudiu +
From 3c216176e85c5a4f6055d67994439fd5eec95179 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 6 Oct 2016 15:54:54 +0200 Subject: [PATCH 48/69] [HttpKernel] Fix source links with latests Twig versions --- .../Component/HttpKernel/DataCollector/DumpDataCollector.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php index 3a445f45bb89a..538d73c783ba3 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php @@ -99,11 +99,11 @@ public function dump(Data $data) } elseif (isset($trace[$i]['object']) && $trace[$i]['object'] instanceof \Twig_Template) { $template = $trace[$i]['object']; $name = $template->getTemplateName(); - $file = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getPath() : false; $src = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : false); $info = $template->getDebugInfo(); - if (null !== $src && isset($info[$trace[$i - 1]['line']])) { + if (isset($info[$trace[$i - 1]['line']])) { $line = $info[$trace[$i - 1]['line']]; + $file = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getPath() : false; if ($src) { $src = explode("\n", $src); From 17757d8114e255283ab131071b46293f2ff75a2e Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 18 Oct 2016 09:12:23 +0200 Subject: [PATCH 49/69] [DomCrawler] Optimize DomCrawler::relativize() --- src/Symfony/Component/DomCrawler/Crawler.php | 96 +++++++++----------- 1 file changed, 44 insertions(+), 52 deletions(-) diff --git a/src/Symfony/Component/DomCrawler/Crawler.php b/src/Symfony/Component/DomCrawler/Crawler.php index a1ddffd797a1a..6f329d3892bcd 100644 --- a/src/Symfony/Component/DomCrawler/Crawler.php +++ b/src/Symfony/Component/DomCrawler/Crawler.php @@ -860,18 +860,44 @@ private function relativize($xpath) // We cannot simply drop $nonMatchingExpression = 'a[name() = "b"]'; - // Split any unions into individual expressions. - foreach ($this->splitUnionParts($xpath) as $expression) { - $expression = trim($expression); - $parenthesis = ''; - - // If the union is inside some braces, we need to preserve the opening braces and apply - // the change only inside it. - if (preg_match('/^[\(\s*]+/', $expression, $matches)) { - $parenthesis = $matches[0]; - $expression = substr($expression, strlen($parenthesis)); + $xpathLen = strlen($xpath); + $openedBrackets = 0; + $startPosition = strspn($xpath, " \t\n\r\0\x0B"); + + for ($i = $startPosition; $i <= $xpathLen; ++$i) { + $i += strcspn($xpath, '"\'[]|', $i); + + if ($i < $xpathLen) { + switch ($xpath[$i]) { + case '"': + case "'": + if (false === $i = strpos($xpath, $xpath[$i], $i + 1)) { + return $xpath; // The XPath expression is invalid + } + continue 2; + case '[': + ++$openedBrackets; + continue 2; + case ']': + --$openedBrackets; + continue 2; + } + } + if ($openedBrackets) { + continue; } + if ($startPosition < $xpathLen && '(' === $xpath[$startPosition]) { + // If the union is inside some braces, we need to preserve the opening braces and apply + // the change only inside it. + $j = 1 + strspn($xpath, "( \t\n\r\0\x0B", $startPosition + 1); + $parenthesis = substr($xpath, $startPosition, $j); + $startPosition += $j; + } else { + $parenthesis = ''; + } + $expression = rtrim(substr($xpath, $startPosition, $i - $startPosition)); + // BC for Symfony 2.4 and lower were elements were adding in a fake _root parent if (0 === strpos($expression, '/_root/')) { $expression = './'.substr($expression, 7); @@ -880,7 +906,7 @@ private function relativize($xpath) } // add prefix before absolute element selector - if (empty($expression)) { + if ('' === $expression) { $expression = $nonMatchingExpression; } elseif (0 === strpos($expression, '//')) { $expression = 'descendant-or-self::'.substr($expression, 2); @@ -898,7 +924,7 @@ private function relativize($xpath) // '.' is the fake root element in Symfony 2.4 and lower, which is excluded from results $expression = $nonMatchingExpression; } elseif (0 === strpos($expression, 'descendant::')) { - $expression = 'descendant-or-self::'.substr($expression, strlen('descendant::')); + $expression = 'descendant-or-self::'.substr($expression, 12); } elseif (preg_match('/^(ancestor|ancestor-or-self|attribute|following|following-sibling|namespace|parent|preceding|preceding-sibling)::/', $expression)) { // the fake root has no parent, preceding or following nodes and also no attributes (even no namespace attributes) $expression = $nonMatchingExpression; @@ -906,50 +932,16 @@ private function relativize($xpath) $expression = 'self::'.$expression; } $expressions[] = $parenthesis.$expression; - } - return implode(' | ', $expressions); - } - - /** - * Splits the XPath into parts that are separated by the union operator. - * - * @param string $xpath - * - * @return string[] - */ - private function splitUnionParts($xpath) - { - // Split any unions into individual expressions. We need to iterate - // through the string to correctly parse opening/closing quotes and - // braces which is not possible with regular expressions. - $unionParts = array(); - $inSingleQuotedString = false; - $inDoubleQuotedString = false; - $openedBrackets = 0; - $lastUnion = 0; - $xpathLength = strlen($xpath); - for ($i = 0; $i < $xpathLength; ++$i) { - $char = $xpath[$i]; - - if ($char === "'" && !$inDoubleQuotedString) { - $inSingleQuotedString = !$inSingleQuotedString; - } elseif ($char === '"' && !$inSingleQuotedString) { - $inDoubleQuotedString = !$inDoubleQuotedString; - } elseif (!$inSingleQuotedString && !$inDoubleQuotedString) { - if ($char === '[') { - ++$openedBrackets; - } elseif ($char === ']') { - --$openedBrackets; - } elseif ($char === '|' && $openedBrackets === 0) { - $unionParts[] = substr($xpath, $lastUnion, $i - $lastUnion); - $lastUnion = $i + 1; - } + if ($i === $xpathLen) { + return implode(' | ', $expressions); } + + $i += strspn($xpath, " \t\n\r\0\x0B", $i + 1); + $startPosition = $i + 1; } - $unionParts[] = substr($xpath, $lastUnion); - return $unionParts; + return $xpath; // The XPath expression is invalid } /** From f3b09d9ca5de33886f03834685c41f9db1461f68 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 6 Oct 2016 16:01:55 +0200 Subject: [PATCH 50/69] [VarDumper] Fix source links with latests Twig versions --- .../VarDumper/Caster/ExceptionCaster.php | 18 ++-- .../Tests/Caster/ExceptionCasterTest.php | 85 +++++++++++++++++++ .../VarDumper/Tests/CliDumperTest.php | 23 ++--- .../VarDumper/Tests/Fixtures/Twig.php | 19 ++--- 4 files changed, 113 insertions(+), 32 deletions(-) create mode 100644 src/Symfony/Component/VarDumper/Tests/Caster/ExceptionCasterTest.php diff --git a/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php b/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php index 513352e374aa2..173d79dd41d64 100644 --- a/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php @@ -150,15 +150,19 @@ public static function castFrameStub(FrameStub $frame, array $a, Stub $stub, $is if (!empty($f['class']) && is_subclass_of($f['class'], 'Twig_Template') && method_exists($f['class'], 'getDebugInfo')) { $template = isset($f['object']) ? $f['object'] : new $f['class'](new \Twig_Environment(new \Twig_Loader_Filesystem())); - - try { - $templateName = $template->getTemplateName(); - $templateSrc = explode("\n", method_exists($template, 'getSource') ? $template->getSource() : $template->getEnvironment()->getLoader()->getSource($templateName)); - $templateInfo = $template->getDebugInfo(); - if (isset($templateInfo[$f['line']])) { + $templateName = $template->getTemplateName(); + $templateSrc = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : ''); + $templateInfo = $template->getDebugInfo(); + if (isset($templateInfo[$f['line']])) { + if (method_exists($template, 'getSourceContext')) { + $templateName = $template->getSourceContext()->getPath() ?: $templateName; + } + if ($templateSrc) { + $templateSrc = explode("\n", $templateSrc); $src[$templateName.':'.$templateInfo[$f['line']]] = self::extractSource($templateSrc, $templateInfo[$f['line']], self::$srcContext); + } else { + $src[$templateName] = $templateInfo[$f['line']]; } - } catch (\Twig_Error_Loader $e) { } } } else { diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/ExceptionCasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/ExceptionCasterTest.php new file mode 100644 index 0000000000000..4c72eb1f7529b --- /dev/null +++ b/src/Symfony/Component/VarDumper/Tests/Caster/ExceptionCasterTest.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Caster; + +use Symfony\Component\VarDumper\Caster\FrameStub; +use Symfony\Component\VarDumper\Test\VarDumperTestCase; + +class ExceptionCasterTest extends VarDumperTestCase +{ + /** + * @requires function Twig_Template::getSourceContext + */ + public function testFrameWithTwig() + { + require_once dirname(__DIR__).'/Fixtures/Twig.php'; + + $f = array( + new FrameStub(array( + 'file' => dirname(__DIR__).'/Fixtures/Twig.php', + 'line' => 19, + 'class' => '__TwigTemplate_VarDumperFixture_u75a09', + 'object' => new \__TwigTemplate_VarDumperFixture_u75a09(new \Twig_Environment(new \Twig_Loader_Filesystem())), + )), + new FrameStub(array( + 'file' => dirname(__DIR__).'/Fixtures/Twig.php', + 'line' => 19, + 'class' => '__TwigTemplate_VarDumperFixture_u75a09', + 'object' => new \__TwigTemplate_VarDumperFixture_u75a09(new \Twig_Environment(new \Twig_Loader_Filesystem()), null), + )), + ); + + $expectedDump = <<<'EODUMP' +array:2 [ + 0 => { + class: "__TwigTemplate_VarDumperFixture_u75a09" + object: __TwigTemplate_VarDumperFixture_u75a09 { + %A + } + src: { + %sTwig.php:19: """ + // line 2\n + throw new \Exception('Foobar');\n + }\n + """ + bar.twig:2: """ + foo bar\n + twig source\n + \n + """ + } + } + 1 => { + class: "__TwigTemplate_VarDumperFixture_u75a09" + object: __TwigTemplate_VarDumperFixture_u75a09 { + %A + } + src: { + %sTwig.php:19: """ + // line 2\n + throw new \Exception('Foobar');\n + }\n + """ + foo.twig:2: """ + foo bar\n + twig source\n + \n + """ + } + } +] + +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $f); + } +} diff --git a/src/Symfony/Component/VarDumper/Tests/CliDumperTest.php b/src/Symfony/Component/VarDumper/Tests/CliDumperTest.php index 11de511dd0db8..36d45b6b5bb11 100644 --- a/src/Symfony/Component/VarDumper/Tests/CliDumperTest.php +++ b/src/Symfony/Component/VarDumper/Tests/CliDumperTest.php @@ -201,6 +201,9 @@ public function testClosedResource() ); } + /** + * @requires function Twig_Template::getSourceContext + */ public function testThrowingCaster() { $out = fopen('php://memory', 'r+b'); @@ -235,19 +238,6 @@ public function testThrowingCaster() rewind($out); $out = stream_get_contents($out); - if (method_exists($twig, 'getSource')) { - $twig = <<assertStringMatchesFormat( <<displayWithErrorHandling() ==> __TwigTemplate_VarDumperFixture_u75a09->doDisplay(): { src: { diff --git a/src/Symfony/Component/VarDumper/Tests/Fixtures/Twig.php b/src/Symfony/Component/VarDumper/Tests/Fixtures/Twig.php index f25aac6553bba..7ffdd2bd54a63 100644 --- a/src/Symfony/Component/VarDumper/Tests/Fixtures/Twig.php +++ b/src/Symfony/Component/VarDumper/Tests/Fixtures/Twig.php @@ -3,14 +3,14 @@ /* foo.twig */ class __TwigTemplate_VarDumperFixture_u75a09 extends Twig_Template { - public function __construct(Twig_Environment $env) + private $filename; + + public function __construct(Twig_Environment $env, $filename = 'bar.twig') { parent::__construct($env); - $this->parent = false; - - $this->blocks = array( - ); + $this->blocks = array(); + $this->filename = $filename; } protected function doDisplay(array $context, array $blocks = array()) @@ -26,14 +26,11 @@ public function getTemplateName() public function getDebugInfo() { - return array (19 => 2); + return array(19 => 2); } - public function getSource() + public function getSourceContext() { - return " foo bar - twig source - -"; + return new Twig_Source(" foo bar\n twig source\n\n", 'foo.twig', $this->filename); } } From d367cfc6f218c306249ccd1ab82dd49afb3b4f63 Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Tue, 18 Oct 2016 19:16:23 +0200 Subject: [PATCH 51/69] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dca4c3cbdeec6..e1c2e3a7e666a 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Running Symfony Tests Information on how to run the Symfony test suite can be found in the [Running Symfony Tests][6] section. -[1]: https://symfony.com/get_started +[1]: https://symfony.com/doc/current/quick_tour/index.html [2]: https://symfony.com/doc/current/ [3]: https://symfony.com/doc/current/contributing/code/index.html [4]: https://symfony.com/doc/current/contributing/code/patches.html#check-list From 26b90e47c0b69ba4a910f390758c21baa9000db5 Mon Sep 17 00:00:00 2001 From: Jakub Zalas Date: Tue, 18 Oct 2016 06:32:56 +0100 Subject: [PATCH 52/69] [HttpKernel] Refactor a RequestDataCollector test case to use a data provider --- .../RequestDataCollectorTest.php | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php b/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php index eef00d4a024dd..6336fa4453e19 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php @@ -70,16 +70,28 @@ public function testKernelResponseDoesNotStartSession() } /** - * Test various types of controller callables. + * @dataProvider provideControllerCallables */ - public function testControllerInspection() + public function testControllerInspection($name, $callable, $expected) + { + $c = new RequestDataCollector(); + $request = $this->createRequest(); + $response = $this->createResponse(); + $this->injectController($c, $callable, $request); + $c->collect($request, $response); + + $this->assertSame($expected, $c->getController(), sprintf('Testing: %s', $name)); + } + + public function provideControllerCallables() { // make sure we always match the line number $r1 = new \ReflectionMethod($this, 'testControllerInspection'); $r2 = new \ReflectionMethod($this, 'staticControllerMethod'); $r3 = new \ReflectionClass($this); + // test name, callable, expected - $controllerTests = array( + return array( array( '"Regular" callable', array($this, 'testControllerInspection'), @@ -168,15 +180,6 @@ function () { return 'foo'; }, ), ), ); - - $c = new RequestDataCollector(); - $request = $this->createRequest(); - $response = $this->createResponse(); - foreach ($controllerTests as $controllerTest) { - $this->injectController($c, $controllerTest[1], $request); - $c->collect($request, $response); - $this->assertSame($controllerTest[2], $c->getController(), sprintf('Testing: %s', $controllerTest[0])); - } } protected function createRequest() From 57008ea42bd55f6d1378014961886b278468661e Mon Sep 17 00:00:00 2001 From: Jakub Zalas Date: Tue, 18 Oct 2016 06:32:56 +0100 Subject: [PATCH 53/69] [HttpKernel] Fix a regression in the RequestDataCollector --- .../DataCollector/RequestDataCollector.php | 2 +- .../RequestDataCollectorTest.php | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php index fd66b38cd2592..f274ac79c2c71 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php @@ -374,7 +374,7 @@ protected function parseController($controller) ); } - return (string) $controller ?: 'n/a'; + return is_string($controller) ? $controller : 'n/a'; } private function getCookieHeader($name, $value, $expires, $path, $domain, $secure, $httponly) diff --git a/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php b/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php index 6336fa4453e19..df5d974fd8c30 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\HttpKernel\Tests\DataCollector; +use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface; @@ -182,6 +183,17 @@ function () { return 'foo'; }, ); } + public function testItIgnoresInvalidCallables() + { + $request = $this->createRequestWithSession(); + $response = new RedirectResponse('/'); + + $c = new RequestDataCollector(); + $c->collect($request, $response); + + $this->assertSame('n/a', $c->getController()); + } + protected function createRequest() { $request = Request::create('http://test.com/foo?bar=baz'); @@ -194,6 +206,16 @@ protected function createRequest() return $request; } + private function createRequestWithSession() + { + $request = $this->createRequest(); + $request->attributes->set('_controller', 'Foo::bar'); + $request->setSession(new Session(new MockArraySessionStorage())); + $request->getSession()->start(); + + return $request; + } + protected function createResponse() { $response = new Response(); From 4f31dec580b10470b6c94cc0dcc615a869df1805 Mon Sep 17 00:00:00 2001 From: Abdellatif Ait boudad Date: Wed, 19 Oct 2016 09:54:02 +0100 Subject: [PATCH 54/69] [WebProfilerBundle][btn-link] add `cursor: pointer` --- .../WebProfilerBundle/Resources/views/Profiler/profiler.css.twig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig index a37879c7864d3..4d458d3242c97 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig @@ -133,6 +133,7 @@ button { outline: none; border: 0; padding: 0; + cursor: pointer; } .btn-link:hover { text-decoration: underline; From bb791d076444e016f7da768212233357eeac49de Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 19 Oct 2016 15:17:26 -0700 Subject: [PATCH 55/69] [TwigBridge] Use non-deprecated Twig_Node::getTemplateLine() --- src/Symfony/Bridge/Twig/Node/SearchAndRenderBlockNode.php | 2 +- src/Symfony/Bridge/Twig/Node/TransNode.php | 6 +++--- .../NodeVisitor/TranslationDefaultDomainNodeVisitor.php | 8 ++++---- .../Bridge/Twig/TokenParser/TransChoiceTokenParser.php | 2 +- src/Symfony/Bridge/Twig/TokenParser/TransTokenParser.php | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Node/SearchAndRenderBlockNode.php b/src/Symfony/Bridge/Twig/Node/SearchAndRenderBlockNode.php index 8c42bcd3c2650..9cb964865ea19 100644 --- a/src/Symfony/Bridge/Twig/Node/SearchAndRenderBlockNode.php +++ b/src/Symfony/Bridge/Twig/Node/SearchAndRenderBlockNode.php @@ -37,7 +37,7 @@ public function compile(\Twig_Compiler $compiler) // the variables in the third argument $label = $arguments[1]; $variables = isset($arguments[2]) ? $arguments[2] : null; - $lineno = $label->getLine(); + $lineno = $label->getTemplateLine(); if ($label instanceof \Twig_Node_Expression_Constant) { // If the label argument is given as a constant, we can either diff --git a/src/Symfony/Bridge/Twig/Node/TransNode.php b/src/Symfony/Bridge/Twig/Node/TransNode.php index 114b38c441123..7b2f9c090405f 100644 --- a/src/Symfony/Bridge/Twig/Node/TransNode.php +++ b/src/Symfony/Bridge/Twig/Node/TransNode.php @@ -109,18 +109,18 @@ protected function compileString(\Twig_Node $body, \Twig_Node_Expression_Array $ preg_match_all('/(?getLine()); + $key = new \Twig_Node_Expression_Constant('%'.$var.'%', $body->getTemplateLine()); if (!$vars->hasElement($key)) { if ('count' === $var && $this->hasNode('count')) { $vars->addElement($this->getNode('count'), $key); } else { - $varExpr = new \Twig_Node_Expression_Name($var, $body->getLine()); + $varExpr = new \Twig_Node_Expression_Name($var, $body->getTemplateLine()); $varExpr->setAttribute('ignore_strict_check', $ignoreStrictCheck); $vars->addElement($varExpr, $key); } } } - return array(new \Twig_Node_Expression_Constant(str_replace('%%', '%', trim($msg)), $body->getLine()), $vars); + return array(new \Twig_Node_Expression_Constant(str_replace('%%', '%', trim($msg)), $body->getTemplateLine()), $vars); } } diff --git a/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php b/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php index 3e850350fd144..b226d91adfe48 100644 --- a/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php +++ b/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php @@ -50,10 +50,10 @@ protected function doEnterNode(\Twig_Node $node, \Twig_Environment $env) return $node; } else { $var = $env->getParser()->getVarName(); - $name = new \Twig_Node_Expression_AssignName($var, $node->getLine()); - $this->scope->set('domain', new \Twig_Node_Expression_Name($var, $node->getLine())); + $name = new \Twig_Node_Expression_AssignName($var, $node->getTemplateLine()); + $this->scope->set('domain', new \Twig_Node_Expression_Name($var, $node->getTemplateLine())); - return new \Twig_Node_Set(false, new \Twig_Node(array($name)), new \Twig_Node(array($node->getNode('expr'))), $node->getLine()); + return new \Twig_Node_Set(false, new \Twig_Node(array($name)), new \Twig_Node(array($node->getNode('expr'))), $node->getTemplateLine()); } } @@ -71,7 +71,7 @@ protected function doEnterNode(\Twig_Node $node, \Twig_Environment $env) } else { if (!$arguments->hasNode($ind)) { if (!$arguments->hasNode($ind - 1)) { - $arguments->setNode($ind - 1, new \Twig_Node_Expression_Array(array(), $node->getLine())); + $arguments->setNode($ind - 1, new \Twig_Node_Expression_Array(array(), $node->getTemplateLine())); } $arguments->setNode($ind, $this->scope->get('domain')); diff --git a/src/Symfony/Bridge/Twig/TokenParser/TransChoiceTokenParser.php b/src/Symfony/Bridge/Twig/TokenParser/TransChoiceTokenParser.php index e9e65ad46f896..fa61a2f1486c5 100644 --- a/src/Symfony/Bridge/Twig/TokenParser/TransChoiceTokenParser.php +++ b/src/Symfony/Bridge/Twig/TokenParser/TransChoiceTokenParser.php @@ -64,7 +64,7 @@ public function parse(\Twig_Token $token) $body = $this->parser->subparse(array($this, 'decideTransChoiceFork'), true); if (!$body instanceof \Twig_Node_Text && !$body instanceof \Twig_Node_Expression) { - throw new \Twig_Error_Syntax('A message inside a transchoice tag must be a simple text.', $body->getLine(), $stream->getSourceContext()->getName()); + throw new \Twig_Error_Syntax('A message inside a transchoice tag must be a simple text.', $body->getTemplateLine(), $stream->getSourceContext()->getName()); } $stream->expect(\Twig_Token::BLOCK_END_TYPE); diff --git a/src/Symfony/Bridge/Twig/TokenParser/TransTokenParser.php b/src/Symfony/Bridge/Twig/TokenParser/TransTokenParser.php index 1493cf8bcfcd9..4c8e7d3eeea38 100644 --- a/src/Symfony/Bridge/Twig/TokenParser/TransTokenParser.php +++ b/src/Symfony/Bridge/Twig/TokenParser/TransTokenParser.php @@ -64,7 +64,7 @@ public function parse(\Twig_Token $token) $body = $this->parser->subparse(array($this, 'decideTransFork'), true); if (!$body instanceof \Twig_Node_Text && !$body instanceof \Twig_Node_Expression) { - throw new \Twig_Error_Syntax('A message inside a trans tag must be a simple text.', $body->getLine(), $stream->getSourceContext()->getName()); + throw new \Twig_Error_Syntax('A message inside a trans tag must be a simple text.', $body->getTemplateLine(), $stream->getSourceContext()->getName()); } $stream->expect(\Twig_Token::BLOCK_END_TYPE); From 8a420c554cbaebec5c8f9d2661335a99cbcdf2b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1chym=20Tou=C5=A1ek?= Date: Mon, 19 Sep 2016 19:50:59 +0200 Subject: [PATCH 56/69] [Validator] Fix annotation --- .../Validator/Validator/RecursiveContextualValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php b/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php index ebbc6a38837c9..4835c955097a2 100644 --- a/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php +++ b/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php @@ -790,7 +790,7 @@ private function validateGenericNode($value, $object, $cacheKey, MetadataInterfa * @param int $traversalStrategy The strategy used for * traversing the value * @param GroupSequence $groupSequence The group sequence - * @param string[]|null $cascadedGroup The group that should + * @param string|null $cascadedGroup The group that should * be passed to cascaded * objects instead of * the group sequence From 5735255467fd7315255c91854323924a7deed91a Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 20 Oct 2016 15:28:37 +0200 Subject: [PATCH 57/69] [3.1][PhpUnitBridge] Drop ErrorAssert in favor of @expectedDeprecation --- .../FrameworkExtensionTest.php | 14 ++++++------- .../Templating/TemplateNameParserTest.php | 13 +++++------- .../Tests/ContainerBuilderTest.php | 17 +++++++-------- .../Tests/Loader/XmlFileLoaderTest.php | 21 +++++++------------ .../Fragment/EsiFragmentRendererTest.php | 13 +++++------- .../Component/Yaml/Tests/InlineTest.php | 7 ++----- 6 files changed, 34 insertions(+), 51 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 8ad3ad418f582..6f3149f083957 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -11,7 +11,6 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection; -use Symfony\Bridge\PhpUnit\ErrorAssert; use Symfony\Bundle\FrameworkBundle\Tests\TestCase; use Symfony\Bundle\FrameworkBundle\DependencyInjection\FrameworkExtension; use Symfony\Component\Cache\Adapter\ApcuAdapter; @@ -547,16 +546,17 @@ public function testSerializerCacheDisabled() /** * @group legacy - * @requires function Symfony\Bridge\PhpUnit\ErrorAssert::assertDeprecationsAreTriggered + * @expectedDeprecation The "framework.serializer.cache" option is deprecated %s. */ public function testDeprecatedSerializerCacheOption() { - ErrorAssert::assertDeprecationsAreTriggered('The "framework.serializer.cache" option is deprecated', function () { - $container = $this->createContainerFromFile('serializer_legacy_cache', array('kernel.debug' => true, 'kernel.container_class' => __CLASS__)); + $container = $this->createContainerFromFile('serializer_legacy_cache', array('kernel.debug' => true, 'kernel.container_class' => __CLASS__)); - $this->assertFalse($container->hasDefinition('serializer.mapping.cache_class_metadata_factory')); - $this->assertEquals(new Reference('foo'), $container->getDefinition('serializer.mapping.class_metadata_factory')->getArgument(1)); - }); + $this->assertFalse($container->hasDefinition('serializer.mapping.cache_class_metadata_factory')); + $this->assertTrue($container->hasDefinition('serializer.mapping.class_metadata_factory')); + + $cache = $container->getDefinition('serializer.mapping.class_metadata_factory')->getArgument(1); + $this->assertEquals(new Reference('foo'), $cache); } public function testAssetHelperWhenAssetsAreEnabled() diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateNameParserTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateNameParserTest.php index 253d070561d4b..9c19087264425 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateNameParserTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateNameParserTest.php @@ -11,7 +11,6 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Templating; -use Symfony\Bridge\PhpUnit\ErrorAssert; use Symfony\Bundle\FrameworkBundle\Tests\TestCase; use Symfony\Bundle\FrameworkBundle\Templating\TemplateNameParser; use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference; @@ -86,17 +85,15 @@ public function testParseValidNameWithNotFoundBundle() /** * @group legacy * @dataProvider provideAbsolutePaths - * @requires function Symfony\Bridge\PhpUnit\ErrorAssert::assertDeprecationsAreTriggered + * @expectedDeprecation Absolute template path support is deprecated since Symfony 3.1 and will be removed in 4.0. */ public function testAbsolutePathsAreDeprecated($name, $logicalName, $path, $ref) { - ErrorAssert::assertDeprecationsAreTriggered('Absolute template path support is deprecated since Symfony 3.1 and will be removed in 4.0.', function () use ($name, $logicalName, $path, $ref) { - $template = $this->parser->parse($name); + $template = $this->parser->parse($name); - $this->assertSame($ref->getLogicalName(), $template->getLogicalName()); - $this->assertSame($logicalName, $template->getLogicalName()); - $this->assertSame($path, $template->getPath()); - }); + $this->assertSame($ref->getLogicalName(), $template->getLogicalName()); + $this->assertSame($logicalName, $template->getLogicalName()); + $this->assertSame($path, $template->getPath()); } public function provideAbsolutePaths() diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 71918229600a0..dab10132aec8c 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -14,7 +14,6 @@ require_once __DIR__.'/Fixtures/includes/classes.php'; require_once __DIR__.'/Fixtures/includes/ProjectExtension.php'; -use Symfony\Bridge\PhpUnit\ErrorAssert; use Symfony\Component\Config\Resource\ResourceInterface; use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -59,18 +58,18 @@ public function testDefinitions() } /** - * @requires function Symfony\Bridge\PhpUnit\ErrorAssert::assertDeprecationsAreTriggered + * @group legacy + * @expectedDeprecation The "deprecated_foo" service is deprecated. You should stop using it, as it will soon be removed. */ public function testCreateDeprecatedService() { - ErrorAssert::assertDeprecationsAreTriggered('The "deprecated_foo" service is deprecated. You should stop using it, as it will soon be removed.', function () { - $definition = new Definition('stdClass'); - $definition->setDeprecated(true); + $definition = new Definition('stdClass'); + $definition->setDeprecated(true); - $builder = new ContainerBuilder(); - $builder->setDefinition('deprecated_foo', $definition); - $builder->get('deprecated_foo'); - }); + $builder = new ContainerBuilder(); + $builder->setDefinition('deprecated_foo', $definition); + $builder->compile(); + $builder->get('deprecated_foo'); } public function testRegister() diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php index 04fad8b5815cd..9cf528d5ca9c9 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php @@ -11,7 +11,6 @@ namespace Symfony\Component\DependencyInjection\Tests\Loader; -use Symfony\Bridge\PhpUnit\ErrorAssert; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; @@ -558,23 +557,17 @@ public function testAutowire() /** * @group legacy - * @requires function Symfony\Bridge\PhpUnit\ErrorAssert::assertDeprecationsAreTriggered + * @expectedDeprecation Using the attribute "class" is deprecated for the service "bar" which is defined as an alias %s. + * @expectedDeprecation Using the element "tag" is deprecated for the service "bar" which is defined as an alias %s. + * @expectedDeprecation Using the element "factory" is deprecated for the service "bar" which is defined as an alias %s. */ public function testAliasDefinitionContainsUnsupportedElements() { - $deprecations = array( - 'Using the attribute "class" is deprecated for the service "bar" which is defined as an alias', - 'Using the element "tag" is deprecated for the service "bar" which is defined as an alias', - 'Using the element "factory" is deprecated for the service "bar" which is defined as an alias', - ); - - ErrorAssert::assertDeprecationsAreTriggered($deprecations, function () { - $container = new ContainerBuilder(); - $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); - $loader->load('legacy_invalid_alias_definition.xml'); + $loader->load('legacy_invalid_alias_definition.xml'); - $this->assertTrue($container->has('bar')); - }); + $this->assertTrue($container->has('bar')); } } diff --git a/src/Symfony/Component/HttpKernel/Tests/Fragment/EsiFragmentRendererTest.php b/src/Symfony/Component/HttpKernel/Tests/Fragment/EsiFragmentRendererTest.php index 9d08fa562ec21..0ac736f32eda5 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Fragment/EsiFragmentRendererTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Fragment/EsiFragmentRendererTest.php @@ -11,7 +11,6 @@ namespace Symfony\Component\HttpKernel\Tests\Fragment; -use Symfony\Bridge\PhpUnit\ErrorAssert; use Symfony\Component\HttpKernel\Controller\ControllerReference; use Symfony\Component\HttpKernel\Fragment\EsiFragmentRenderer; use Symfony\Component\HttpKernel\HttpCache\Esi; @@ -28,16 +27,14 @@ public function testRenderFallbackToInlineStrategyIfEsiNotSupported() /** * @group legacy - * @requires function Symfony\Bridge\PhpUnit\ErrorAssert::assertDeprecationsAreTriggered + * @expectedDeprecation Passing non-scalar values as part of URI attributes to the ESI and SSI rendering strategies is deprecated %s. */ public function testRenderFallbackWithObjectAttributesIsDeprecated() { - ErrorAssert::assertDeprecationsAreTriggered('Passing non-scalar values as part of URI attributes to the ESI and SSI rendering strategies is deprecated', function () { - $strategy = new EsiFragmentRenderer(new Esi(), $this->getInlineStrategy(true), new UriSigner('foo')); - $request = Request::create('/'); - $reference = new ControllerReference('main_controller', array('foo' => array('a' => array(), 'b' => new \stdClass())), array()); - $strategy->render($reference, $request); - }); + $strategy = new EsiFragmentRenderer(new Esi(), $this->getInlineStrategy(true), new UriSigner('foo')); + $request = Request::create('/'); + $reference = new ControllerReference('main_controller', array('foo' => array('a' => array(), 'b' => new \stdClass())), array()); + $strategy->render($reference, $request); } public function testRender() diff --git a/src/Symfony/Component/Yaml/Tests/InlineTest.php b/src/Symfony/Component/Yaml/Tests/InlineTest.php index 859a03e8014d8..e6e09084c5d6e 100644 --- a/src/Symfony/Component/Yaml/Tests/InlineTest.php +++ b/src/Symfony/Component/Yaml/Tests/InlineTest.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Yaml\Tests; -use Symfony\Bridge\PhpUnit\ErrorAssert; use Symfony\Component\Yaml\Inline; use Symfony\Component\Yaml\Yaml; @@ -255,14 +254,12 @@ public function getScalarIndicators() /** * @group legacy - * @requires function Symfony\Bridge\PhpUnit\ErrorAssert::assertDeprecationsAreTriggered + * @expectedDeprecation Not quoting the scalar "%bar " starting with the "%" indicator character is deprecated since Symfony 3.1 and will throw a ParseException in 4.0. * throws \Symfony\Component\Yaml\Exception\ParseException in 4.0 */ public function testParseUnquotedScalarStartingWithPercentCharacter() { - ErrorAssert::assertDeprecationsAreTriggered('Not quoting the scalar "%foo " starting with the "%" indicator character is deprecated since Symfony 3.1 and will throw a ParseException in 4.0.', function () { - Inline::parse('{ foo: %foo }'); - }); + Inline::parse('{ foo: %bar }'); } /** From 5d5f7045630b392c8411c85d90e9423e1a08a193 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 21 Oct 2016 22:59:10 +0200 Subject: [PATCH 58/69] [2.8][PhpUnitBridge] Drop ErrorAssert in favor of @expectedDeprecation --- .../Tests/ContainerBuilderTest.php | 14 ++++++-------- src/Symfony/Component/Yaml/Tests/ParserTest.php | 12 ++++-------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 5e15715d4c39e..63221485205e9 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -14,7 +14,6 @@ require_once __DIR__.'/Fixtures/includes/classes.php'; require_once __DIR__.'/Fixtures/includes/ProjectExtension.php'; -use Symfony\Bridge\PhpUnit\ErrorAssert; use Symfony\Component\Config\Resource\ResourceInterface; use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -61,17 +60,16 @@ public function testDefinitions() } /** - * @requires function Symfony\Bridge\PhpUnit\ErrorAssert::assertDeprecationsAreTriggered + * @group legacy + * @expectedDeprecation The "deprecated_foo" service is deprecated. You should stop using it, as it will soon be removed. */ public function testCreateDeprecatedService() { - ErrorAssert::assertDeprecationsAreTriggered('The "deprecated_foo" service is deprecated. You should stop using it, as it will soon be removed.', function () { - $definition = new Definition('stdClass'); - $definition->setDeprecated(true); + $definition = new Definition('stdClass'); + $definition->setDeprecated(true); - $builder = new ContainerBuilder(); - $builder->createService($definition, 'deprecated_foo'); - }); + $builder = new ContainerBuilder(); + $builder->createService($definition, 'deprecated_foo'); } public function testRegister() diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index 9e9a715ad167c..82c7e19334559 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Yaml\Tests; -use Symfony\Bridge\PhpUnit\ErrorAssert; use Symfony\Component\Yaml\Yaml; use Symfony\Component\Yaml\Parser; @@ -927,19 +926,16 @@ public function testFloatKeys() /** * @group legacy + * @expectedDeprecation Using a colon in the unquoted mapping value "bar: baz" in line 1 is deprecated since Symfony 2.8 and will throw a ParseException in 3.0. * throw ParseException in Symfony 3.0 - * @requires function Symfony\Bridge\PhpUnit\ErrorAssert::assertDeprecationsAreTriggered */ public function testColonInMappingValueException() { - $parser = $this->parser; - - ErrorAssert::assertDeprecationsAreTriggered('Using a colon in the unquoted mapping value "bar: baz" in line 1 is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', function () use ($parser) { - $yaml = <<parse($yaml); - }); + + $this->parser->parse($yaml); } public function testColonInMappingValueExceptionNotTriggeredByColonInComment() From b9a4586b24d671a43160cebd58f51bcc278af139 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 21 Oct 2016 18:08:29 -0700 Subject: [PATCH 59/69] [TwigBridge] fixed Twig_Source required argument --- .../Bridge/Twig/Tests/Extension/RoutingExtensionTest.php | 2 +- src/Symfony/Bridge/Twig/Tests/NodeVisitor/TwigNodeProvider.php | 2 +- .../Bridge/Twig/Tests/TokenParser/FormThemeTokenParserTest.php | 2 +- src/Symfony/Bridge/Twig/Translation/TwigExtractor.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/RoutingExtensionTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/RoutingExtensionTest.php index 87b6052f6f792..9733cd7b8ace6 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/RoutingExtensionTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/RoutingExtensionTest.php @@ -23,7 +23,7 @@ public function testEscaping($template, $mustBeEscaped) $twig = new \Twig_Environment($this->getMock('Twig_LoaderInterface'), array('debug' => true, 'cache' => false, 'autoescape' => 'html', 'optimizations' => 0)); $twig->addExtension(new RoutingExtension($this->getMock('Symfony\Component\Routing\Generator\UrlGeneratorInterface'))); - $nodes = $twig->parse($twig->tokenize(new \Twig_Source($template))); + $nodes = $twig->parse($twig->tokenize(new \Twig_Source($template, ''))); $this->assertSame($mustBeEscaped, $nodes->getNode('body')->getNode(0)->getNode('expr') instanceof \Twig_Node_Expression_Filter); } diff --git a/src/Symfony/Bridge/Twig/Tests/NodeVisitor/TwigNodeProvider.php b/src/Symfony/Bridge/Twig/Tests/NodeVisitor/TwigNodeProvider.php index a90b556c9e3fe..502cad38dec0b 100644 --- a/src/Symfony/Bridge/Twig/Tests/NodeVisitor/TwigNodeProvider.php +++ b/src/Symfony/Bridge/Twig/Tests/NodeVisitor/TwigNodeProvider.php @@ -25,7 +25,7 @@ public static function getModule($content) new \Twig_Node_Expression_Array(array(), 0), new \Twig_Node_Expression_Array(array(), 0), null, - new \Twig_Source('') + new \Twig_Source('', '') ); } diff --git a/src/Symfony/Bridge/Twig/Tests/TokenParser/FormThemeTokenParserTest.php b/src/Symfony/Bridge/Twig/Tests/TokenParser/FormThemeTokenParserTest.php index aa9913249833d..6b6a92abf1434 100644 --- a/src/Symfony/Bridge/Twig/Tests/TokenParser/FormThemeTokenParserTest.php +++ b/src/Symfony/Bridge/Twig/Tests/TokenParser/FormThemeTokenParserTest.php @@ -23,7 +23,7 @@ public function testCompile($source, $expected) { $env = new \Twig_Environment($this->getMock('Twig_LoaderInterface'), array('cache' => false, 'autoescape' => false, 'optimizations' => 0)); $env->addTokenParser(new FormThemeTokenParser()); - $stream = $env->tokenize(new \Twig_Source($source)); + $stream = $env->tokenize(new \Twig_Source($source, '')); $parser = new \Twig_Parser($env); $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)); diff --git a/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php b/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php index 69ec1d9155000..917687ad34eee 100644 --- a/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php +++ b/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php @@ -85,7 +85,7 @@ protected function extractTemplate($template, MessageCatalogue $catalogue) $visitor = $this->twig->getExtension('Symfony\Bridge\Twig\Extension\TranslationExtension')->getTranslationNodeVisitor(); $visitor->enable(); - $this->twig->parse($this->twig->tokenize(new \Twig_Source($template))); + $this->twig->parse($this->twig->tokenize(new \Twig_Source($template, ''))); foreach ($visitor->getMessages() as $message) { $catalogue->set(trim($message[0]), $this->prefix.trim($message[0]), $message[1] ?: $this->defaultDomain); From c9ca322825582dcb904a656e31e2e37067fabaef Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 22 Oct 2016 11:15:06 +0200 Subject: [PATCH 60/69] move test to the HttpKernel component --- .../Compiler/AddConsoleCommandPassTest.php | 20 ------------------- .../HttpKernel/Tests/Bundle/BundleTest.php | 15 ++++++++++++++ 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddConsoleCommandPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddConsoleCommandPassTest.php index 9750744859966..97427034f5a8a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddConsoleCommandPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddConsoleCommandPassTest.php @@ -88,26 +88,6 @@ public function testProcessThrowAnExceptionIfTheServiceIsNotASubclassOfCommand() $container->compile(); } - - public function testHttpKernelRegisterCommandsIngoreCommandAsAService() - { - $container = new ContainerBuilder(); - $container->addCompilerPass(new AddConsoleCommandPass()); - $definition = new Definition('Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler\MyCommand'); - $definition->addTag('console.command'); - $container->setDefinition('my-command', $definition); - $container->compile(); - - $application = $this->getMock('Symfony\Component\Console\Application'); - // Never called, because it's the - // Symfony\Bundle\FrameworkBundle\Console\Application that register - // commands as a service - $application->expects($this->never())->method('add'); - - $bundle = new ExtensionPresentBundle(); - $bundle->setContainer($container); - $bundle->registerCommands($application); - } } class MyCommand extends Command diff --git a/src/Symfony/Component/HttpKernel/Tests/Bundle/BundleTest.php b/src/Symfony/Component/HttpKernel/Tests/Bundle/BundleTest.php index 26dae365db6ed..6320c0e8b22a3 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Bundle/BundleTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Bundle/BundleTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\HttpKernel\Tests\Bundle; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Tests\Fixtures\ExtensionNotValidBundle\ExtensionNotValidBundle; use Symfony\Component\HttpKernel\Tests\Fixtures\ExtensionPresentBundle\ExtensionPresentBundle; use Symfony\Component\HttpKernel\Tests\Fixtures\ExtensionAbsentBundle\ExtensionAbsentBundle; @@ -41,4 +42,18 @@ public function testGetContainerExtensionWithInvalidClass() $bundle = new ExtensionNotValidBundle(); $bundle->getContainerExtension(); } + + public function testHttpKernelRegisterCommandsIgnoresCommandsThatAreRegisteredAsServices() + { + $container = new ContainerBuilder(); + $container->register('console.command.Symfony_Component_HttpKernel_Tests_Fixtures_ExtensionPresentBundle_Command_FooCommand', 'Symfony\Component\HttpKernel\Tests\Fixtures\ExtensionPresentBundle\Command\FooCommand'); + + $application = $this->getMock('Symfony\Component\Console\Application'); + // add() is never called when the found command classes are already registered as services + $application->expects($this->never())->method('add'); + + $bundle = new ExtensionPresentBundle(); + $bundle->setContainer($container); + $bundle->registerCommands($application); + } } From f09e6218f8fffe96608b768676a07ec6a2088d8a Mon Sep 17 00:00:00 2001 From: Lars Strojny Date: Wed, 19 Oct 2016 20:16:43 +0200 Subject: [PATCH 61/69] Trim constant values in XmlFileLoader --- .../Component/DependencyInjection/Loader/XmlFileLoader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php index 4336eced018eb..e60c2f7df76c1 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php @@ -391,7 +391,7 @@ private function getArgumentsAsPhp(\DOMElement $node, $name, $lowercase = true) $arguments[$key] = $arg->nodeValue; break; case 'constant': - $arguments[$key] = constant($arg->nodeValue); + $arguments[$key] = constant(trim($arg->nodeValue)); break; default: $arguments[$key] = XmlUtils::phpize($arg->nodeValue); From 317d46f249893dbb5b0f7b7f4acf2243d3da9127 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 21 Oct 2016 18:11:17 -0700 Subject: [PATCH 62/69] [TwigBundle] fixed usage of getSource in tests --- .../Tests/Loader/FilesystemLoaderTest.php | 6 +++--- .../LegacyRenderTokenParserTest.php | 2 +- .../Profiler/TemplateManager.php | 6 +++++- .../Tests/Profiler/TemplateManagerTest.php | 20 +++++++------------ 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php b/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php index 269e029a0858b..9804c08a1923b 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php @@ -17,7 +17,7 @@ class FilesystemLoaderTest extends TestCase { - public function testGetSource() + public function testGetSourceContext() { $parser = $this->getMock('Symfony\Component\Templating\TemplateNameParserInterface'); $locator = $this->getMock('Symfony\Component\Config\FileLocatorInterface'); @@ -30,10 +30,10 @@ public function testGetSource() $loader->addPath(__DIR__.'/../DependencyInjection/Fixtures/Resources/views', 'namespace'); // Twig-style - $this->assertEquals("This is a layout\n", $loader->getSource('@namespace/layout.html.twig')); + $this->assertEquals("This is a layout\n", $loader->getSourceContext('@namespace/layout.html.twig')->getCode()); // Symfony-style - $this->assertEquals("This is a layout\n", $loader->getSource('TwigBundle::layout.html.twig')); + $this->assertEquals("This is a layout\n", $loader->getSourceContext('TwigBundle::layout.html.twig')->getCode()); } public function testExists() diff --git a/src/Symfony/Bundle/TwigBundle/Tests/TokenParser/LegacyRenderTokenParserTest.php b/src/Symfony/Bundle/TwigBundle/Tests/TokenParser/LegacyRenderTokenParserTest.php index b1f81ec8eef5b..6a5806cd7a965 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/TokenParser/LegacyRenderTokenParserTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/TokenParser/LegacyRenderTokenParserTest.php @@ -27,7 +27,7 @@ public function testCompile($source, $expected) { $env = new \Twig_Environment($this->getMock('Twig_LoaderInterface'), array('cache' => false, 'autoescape' => false, 'optimizations' => 0)); $env->addTokenParser(new RenderTokenParser()); - $stream = $env->tokenize(new \Twig_Source($source)); + $stream = $env->tokenize(new \Twig_Source($source, '')); $parser = new \Twig_Parser($env); $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)); diff --git a/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php b/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php index 5d0fd277c51dc..415034a9f80c6 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php @@ -126,7 +126,11 @@ protected function templateExists($template) } try { - $loader->getSource($template); + if ($loader instanceof \Twig_SourceContextLoaderInterface) { + $loader->getSourceContext($template); + } else { + $loader->getSource($template); + } return true; } catch (\Twig_Error_Loader $e) { diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/Profiler/TemplateManagerTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/Profiler/TemplateManagerTest.php index 29238a21c439b..c9b199ea18b93 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Tests/Profiler/TemplateManagerTest.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/Profiler/TemplateManagerTest.php @@ -31,11 +31,6 @@ class TemplateManagerTest extends TestCase */ protected $profiler; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $profile; - /** * @var \Symfony\Bundle\WebProfilerBundle\Profiler\TemplateManager */ @@ -129,11 +124,7 @@ public function profileHasCollectorCallback($panel) protected function mockProfile() { - $this->profile = $this->getMockBuilder('Symfony\Component\HttpKernel\Profiler\Profile') - ->disableOriginalConstructor() - ->getMock(); - - return $this->profile; + return $this->getMockBuilder('Symfony\Component\HttpKernel\Profiler\Profile')->disableOriginalConstructor()->getMock(); } protected function mockTwigEnvironment() @@ -144,9 +135,12 @@ protected function mockTwigEnvironment() ->method('loadTemplate') ->will($this->returnValue('loadedTemplate')); - $this->twigEnvironment->expects($this->any()) - ->method('getLoader') - ->will($this->returnValue($this->getMock('\Twig_LoaderInterface'))); + if (interface_exists('\Twig_SourceContextLoaderInterface')) { + $loader = $this->getMock('\Twig_SourceContextLoaderInterface'); + } else { + $loader = $this->getMock('\Twig_LoaderInterface'); + } + $this->twigEnvironment->expects($this->any())->method('getLoader')->will($this->returnValue($loader)); return $this->twigEnvironment; } From c333eb70b67e1531de0131e3a14ea3c71eb92442 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sun, 23 Oct 2016 08:49:28 +0200 Subject: [PATCH 63/69] merge tags instead of completely replacing them --- .../DependencyInjection/Compiler/DecoratorServicePass.php | 2 +- .../Tests/Compiler/DecoratorServicePassTest.php | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php index c7a4ac89c1292..f0ac7ff9453c1 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php @@ -43,7 +43,7 @@ public function process(ContainerBuilder $container) $container->setAlias($renamedId, new Alias((string) $alias, false)); } else { $decoratedDefinition = $container->getDefinition($inner); - $definition->setTags($decoratedDefinition->getTags(), $definition->getTags()); + $definition->setTags(array_merge($decoratedDefinition->getTags(), $definition->getTags())); $public = $decoratedDefinition->isPublic(); $decoratedDefinition->setPublic(false); $decoratedDefinition->setTags(array()); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php index b197e422493a4..10781e255e376 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php @@ -87,17 +87,18 @@ public function testProcessMovesTagsFromDecoratedDefinitionToDecoratingDefinitio $container = new ContainerBuilder(); $container ->register('foo') - ->setTags(array('name' => 'bar')) + ->setTags(array('bar' => array('attr' => 'baz'))) ; $container ->register('baz') + ->setTags(array('foobar' => array('attr' => 'bar'))) ->setDecoratedService('foo') ; $this->process($container); $this->assertEmpty($container->getDefinition('baz.inner')->getTags()); - $this->assertEquals(array('name' => 'bar'), $container->getDefinition('baz')->getTags()); + $this->assertEquals(array('bar' => array('attr' => 'baz'), 'foobar' => array('attr' => 'bar')), $container->getDefinition('baz')->getTags()); } protected function process(ContainerBuilder $container) From 5951378727ae4f26107899282f5ff9b89a3aa277 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Fri, 21 Oct 2016 20:02:07 +0200 Subject: [PATCH 64/69] A decorated service should not keep the autowiring types --- .../Compiler/DecoratorServicePass.php | 2 ++ .../Compiler/DecoratorServicePassTest.php | 21 +++++++++++++++++++ .../ResolveDefinitionTemplatesPassTest.php | 7 +++++-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php index 285beda21cb00..391357a1fa3ac 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php @@ -54,9 +54,11 @@ public function process(ContainerBuilder $container) } else { $decoratedDefinition = $container->getDefinition($inner); $definition->setTags($decoratedDefinition->getTags(), $definition->getTags()); + $definition->setAutowiringTypes(array_merge($decoratedDefinition->getAutowiringTypes(), $definition->getAutowiringTypes())); $public = $decoratedDefinition->isPublic(); $decoratedDefinition->setPublic(false); $decoratedDefinition->setTags(array()); + $decoratedDefinition->setAutowiringTypes(array()); $container->setDefinition($renamedId, $decoratedDefinition); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php index a8b741e568d98..8459298268e9b 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php @@ -142,6 +142,27 @@ public function testProcessMovesTagsFromDecoratedDefinitionToDecoratingDefinitio $this->assertEquals(array('name' => 'bar'), $container->getDefinition('baz')->getTags()); } + public function testProcessMergesAutowiringTypesInDecoratingDefinitionAndRemoveThemFromDecoratedDefinition() + { + $container = new ContainerBuilder(); + + $container + ->register('parent') + ->addAutowiringType('Bar') + ; + + $container + ->register('child') + ->setDecoratedService('parent') + ->addAutowiringType('Foo') + ; + + $this->process($container); + + $this->assertEquals(array('Bar', 'Foo'), $container->getDefinition('child')->getAutowiringTypes()); + $this->assertEmpty($container->getDefinition('child.inner')->getAutowiringTypes()); + } + protected function process(ContainerBuilder $container) { $repeatedPass = new DecoratorServicePass(); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php index dd23e162cd52b..15392fbdc18cb 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php @@ -360,8 +360,11 @@ public function testProcessMergeAutowiringTypes() $this->process($container); - $def = $container->getDefinition('child'); - $this->assertEquals(array('Foo', 'Bar'), $def->getAutowiringTypes()); + $childDef = $container->getDefinition('child'); + $this->assertEquals(array('Foo', 'Bar'), $childDef->getAutowiringTypes()); + + $parentDef = $container->getDefinition('parent'); + $this->assertSame(array('Foo'), $parentDef->getAutowiringTypes()); } protected function process(ContainerBuilder $container) From 7b56cc08767bfaa2b1a53f211fd657a8a8328c0f Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 23 Oct 2016 22:48:00 -0700 Subject: [PATCH 65/69] removed usage of Twig_Compiler::addIndentation --- src/Symfony/Bridge/Twig/Node/DumpNode.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/Twig/Node/DumpNode.php b/src/Symfony/Bridge/Twig/Node/DumpNode.php index a7c152944618f..a66781e36550a 100644 --- a/src/Symfony/Bridge/Twig/Node/DumpNode.php +++ b/src/Symfony/Bridge/Twig/Node/DumpNode.php @@ -65,7 +65,7 @@ public function compile(\Twig_Compiler $compiler) ->write('\Symfony\Component\VarDumper\VarDumper::dump(array('."\n") ->indent(); foreach ($values as $node) { - $compiler->addIndentation(); + $compiler->write(''); if ($node->hasAttribute('name')) { $compiler ->string($node->getAttribute('name')) From a79991f44aac63950c6406545ef9461cfb3fbc7c Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Mon, 24 Oct 2016 16:19:10 +0200 Subject: [PATCH 66/69] Fix edge case with StreamedResponse where headers are sent twice --- .../HttpFoundation/StreamedResponse.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/Symfony/Component/HttpFoundation/StreamedResponse.php b/src/Symfony/Component/HttpFoundation/StreamedResponse.php index 4b936a150e19c..8274dc43a0aeb 100644 --- a/src/Symfony/Component/HttpFoundation/StreamedResponse.php +++ b/src/Symfony/Component/HttpFoundation/StreamedResponse.php @@ -28,6 +28,7 @@ class StreamedResponse extends Response { protected $callback; protected $streamed; + private $headersSent; /** * Constructor. @@ -44,6 +45,7 @@ public function __construct($callback = null, $status = 200, $headers = array()) $this->setCallback($callback); } $this->streamed = false; + $this->headersSent = false; } /** @@ -75,6 +77,22 @@ public function setCallback($callback) $this->callback = $callback; } + /** + * {@inheritdoc} + * + * This method only sends the headers once. + */ + public function sendHeaders() + { + if ($this->headersSent) { + return; + } + + $this->headersSent = true; + + parent::sendHeaders(); + } + /** * {@inheritdoc} * From 89b78f21ebbe730e6ef948ef3e2c96e87d9049e0 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 24 Oct 2016 20:31:12 +0200 Subject: [PATCH 67/69] [Yaml] Fix 7.1 compat --- src/Symfony/Component/Yaml/Inline.php | 7 +++++-- src/Symfony/Component/Yaml/Tests/InlineTest.php | 10 +++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/Yaml/Inline.php b/src/Symfony/Component/Yaml/Inline.php index 6853e5a0ba2cc..68ff14983f3ae 100644 --- a/src/Symfony/Component/Yaml/Inline.php +++ b/src/Symfony/Component/Yaml/Inline.php @@ -317,7 +317,7 @@ public static function parseScalar($scalar, $flags = 0, $delimiters = null, $str } if ($output && '%' === $output[0]) { - @trigger_error(sprintf('Not quoting the scalar "%s" starting with the "%%" indicator character is deprecated since Symfony 3.1 and will throw a ParseException in 4.0.' , $output), E_USER_DEPRECATED); + @trigger_error(sprintf('Not quoting the scalar "%s" starting with the "%%" indicator character is deprecated since Symfony 3.1 and will throw a ParseException in 4.0.', $output), E_USER_DEPRECATED); } if ($evaluate) { @@ -606,7 +606,10 @@ private static function evaluateScalar($scalar, $flags, $references = array()) return (float) str_replace(',', '', $scalar); case preg_match(self::getTimestampRegex(), $scalar): if (Yaml::PARSE_DATETIME & $flags) { - return new \DateTime($scalar, new \DateTimeZone('UTC')); + $date = new \DateTime($scalar); + $date->setTimeZone(new \DateTimeZone('UTC')); + + return $date; } $timeZone = date_default_timezone_get(); diff --git a/src/Symfony/Component/Yaml/Tests/InlineTest.php b/src/Symfony/Component/Yaml/Tests/InlineTest.php index e6e09084c5d6e..d6d7790dda413 100644 --- a/src/Symfony/Component/Yaml/Tests/InlineTest.php +++ b/src/Symfony/Component/Yaml/Tests/InlineTest.php @@ -507,7 +507,7 @@ public function testParseTimestampAsDateTimeObject($yaml, $year, $month, $day, $ $expected = new \DateTime($yaml); $expected->setTimeZone(new \DateTimeZone('UTC')); $expected->setDate($year, $month, $day); - $expected->setTime($hour, $minute, $second); + @$expected->setTime($hour, $minute, $second, 1000000 * ($second - (int) $second)); $this->assertEquals($expected, Inline::parse($yaml, Yaml::PARSE_DATETIME)); } @@ -515,9 +515,9 @@ public function testParseTimestampAsDateTimeObject($yaml, $year, $month, $day, $ public function getTimestampTests() { return array( - 'canonical' => array('2001-12-15T02:59:43.1Z', 2001, 12, 15, 2, 59, 43), - 'ISO-8601' => array('2001-12-15t21:59:43.10-05:00', 2001, 12, 16, 2, 59, 43), - 'spaced' => array('2001-12-15 21:59:43.10 -5', 2001, 12, 16, 2, 59, 43), + 'canonical' => array('2001-12-15T02:59:43.1Z', 2001, 12, 15, 2, 59, 43.1), + 'ISO-8601' => array('2001-12-15t21:59:43.10-05:00', 2001, 12, 16, 2, 59, 43.1), + 'spaced' => array('2001-12-15 21:59:43.10 -5', 2001, 12, 16, 2, 59, 43.1), 'date' => array('2001-12-15', 2001, 12, 15, 0, 0, 0), ); } @@ -530,7 +530,7 @@ public function testParseNestedTimestampListAsDateTimeObject($yaml, $year, $mont $expected = new \DateTime($yaml); $expected->setTimeZone(new \DateTimeZone('UTC')); $expected->setDate($year, $month, $day); - $expected->setTime($hour, $minute, $second); + @$expected->setTime($hour, $minute, $second, 1000000 * ($second - (int) $second)); $expectedNested = array('nested' => array($expected)); $yamlNested = "{nested: [$yaml]}"; From 27ce7bf6575dda204f782f6cc7d9ce845a727a55 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 26 Oct 2016 19:38:08 -0700 Subject: [PATCH 68/69] updated CHANGELOG for 3.1.6 --- CHANGELOG-3.1.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/CHANGELOG-3.1.md b/CHANGELOG-3.1.md index 33ad4d31965d3..07d0350ddfada 100644 --- a/CHANGELOG-3.1.md +++ b/CHANGELOG-3.1.md @@ -7,6 +7,36 @@ in 3.1 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v3.1.0...v3.1.1 +* 3.1.6 (2016-10-27) + + * bug #20291 [Yaml] Fix 7.1 compat (nicolas-grekas) + * bug #20289 Fix edge case with StreamedResponse where headers are sent twice (Nicofuma) + * bug #20267 [DependencyInjection] A decorated service should not keep the autowiring types (chalasr) + * bug #20278 [DependencyInjection] merge tags instead of completely replacing them (xabbuh) + * bug #20271 Changes related to Twig 1.27 (fabpot) + * bug #20252 Trim constant values in XmlFileLoader (lstrojny) + * bug #20239 [HttpKernel] Fix a regression in the RequestDataCollector (jakzal) + * bug #20253 [TwigBridge] Use non-deprecated Twig_Node::getTemplateLine() (fabpot) + * bug #20243 [WebProfilerBundle][btn-link] add `cursor: pointer` (aitboudad) + * bug #20175 [VarDumper] Fix source links with latests Twig versions (nicolas-grekas) + * bug #20235 [DomCrawler] Allow pipe (|) character in link tags when using Xpath expressions (klausi, nicolas-grekas) + * bug #20224 [Twig] removed deprecations added in Twig 1.27 (fabpot) + * bug #19478 fixed Filesystem:makePathRelative and added 2 more testcases (muhammedeminakbulut) + * bug #20218 [HttpFoundation] no 304 response if method is not cacheable (xabbuh) + * bug #20207 [DependencyInjection] move tags from decorated to decorating service (xabbuh) + * bug #20205 [HttpCache] fix: do not cache OPTIONS request (dmaicher) + * bug #20146 [Validator] Prevent infinite loop in PropertyMetadata (wesleylancel) + * bug #20184 [FrameworkBundle] Convert null prefix to an empty string in translation:update (chalasr) + * bug #20154 [PropertyInfo] Fix edge cases in ReflectionExtractor (nicolas-grekas) + * bug #19725 [Security] $attributes can be anything, but RoleVoter assumes strings (Jonatan Männchen) + * bug #20127 [HttpFoundation] JSONP callback validation (ro0NL) + * bug #20163 add missing use statement (xabbuh) + * bug #19961 [Console] Escape question text and default value in SymfonyStyle::ask() (chalasr) + * bug #20141 [Console] Fix validation of empty values using SymfonyQuestionHelper::ask() (chalasr) + * bug #20147 [FrameworkBundle] Alter container class instead of kernel name in cache:clear command (nicolas-grekas) + * bug #20156 Fix event annotation for arguments resolving event (Koc) + * bug #20152 [HttpKernel] Fix nullable types handling (nicolas-grekas) + * 3.1.5 (2016-10-03) * bug #20102 [Validator] Url validator not validating hosts ending in a number (gwkunze) From c1a76dad1a13c149de13339c62c4d4e54749f158 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 26 Oct 2016 19:38:31 -0700 Subject: [PATCH 69/69] updated VERSION for 3.1.6 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 965c8e1556140..e6f9f4ab3da40 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -59,12 +59,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '3.1.6-DEV'; + const VERSION = '3.1.6'; const VERSION_ID = 30106; const MAJOR_VERSION = 3; const MINOR_VERSION = 1; const RELEASE_VERSION = 6; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '01/2017'; const END_OF_LIFE = '07/2017';