diff --git a/.travis.yml b/.travis.yml index 5e8436f831284..70e364f8f960d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -47,6 +47,7 @@ before_install: # A sigchild-enabled-PHP is used to test the Process component on the lowest PHP matrix line - if [[ ! $deps && $PHP = ${MIN_PHP%.*} && ! -d php-$MIN_PHP/sapi ]]; then wget http://museum.php.net/php5/php-$MIN_PHP.tar.bz2 -O - | tar -xj; (cd php-$MIN_PHP; ./configure --enable-sigchild --enable-pcntl; make -j2); fi - if [[ ! $PHP = hhvm* ]]; then INI_FILE=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; else INI_FILE=/etc/hhvm/php.ini; fi + - if [[ ! $skip ]]; then echo date.timezone = Europe/Paris >> $INI_FILE; fi - if [[ ! $skip ]]; then echo memory_limit = -1 >> $INI_FILE; fi - if [[ ! $skip ]]; then echo session.gc_probability = 0 >> $INI_FILE; fi - if [[ ! $skip && $PHP = 5.* ]]; then echo extension = mongo.so >> $INI_FILE; fi diff --git a/CHANGELOG-2.7.md b/CHANGELOG-2.7.md index c6f63e1b6c2b5..fd12d3a03612e 100644 --- a/CHANGELOG-2.7.md +++ b/CHANGELOG-2.7.md @@ -7,6 +7,24 @@ 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.21 (2016-11-21) + + * bug #20543 [DI] Fix error when trying to resolve a DefinitionDecorator (nicolas-grekas) + * bug #20484 bumped min version of Twig to 1.28 (fabpot) + * bug #20519 [Debug] Remove GLOBALS from exception context to avoid endless recursion (Seldaek) + * bug #20455 [ClassLoader] Fix ClassCollectionLoader inlining with __halt_compiler (giosh94mhz) + * bug #20307 [Form] Fix Date\TimeType marked as invalid on request with single_text and zero seconds (LuisDeimos) + * bug #20466 [Translation] fixed nested fallback catalogue using multiple locales. (aitboudad) + * bug #20465 [#18637][TranslationDebug] workaround for getFallbackLocales. (aitboudad) + * bug #20440 [TwigBridge][TwigBundle][HttpKernel] prefer getSourceContext() over getSource() (xabbuh) + * bug #20422 [Translation][fallback] add missing resources in parent catalogues. (aitboudad) + * bug #20378 [Form] Fixed show float values as choice value in ChoiceType (yceruto) + * bug #20375 [HttpFoundation][Session] Fix memcache session handler (klandaika) + * bug #20377 [Console] Fix infinite loop on missing input (chalasr) + * bug #20342 [Form] Fix UrlType transforms valid protocols (ogizanagi) + * bug #20292 Enhance GAE compat by removing some realpath() (nicolas-grekas) + * bug #20321 Compatibility with Twig 1.27 (xkobal) + * 2.7.20 (2016-10-27) * bug #20289 Fix edge case with StreamedResponse where headers are sent twice (Nicofuma) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 41c883159c8e2..c5fb26e0e91d8 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -22,16 +22,16 @@ Symfony is the result of the work of many people who made the code better - Abdellatif Ait boudad (aitboudad) - Pascal Borreli (pborreli) - Wouter De Jong (wouterj) - - Joseph Bielawski (stloyd) - Romain Neutron (romain) + - Joseph Bielawski (stloyd) - Karma Dordrak (drak) - Lukas Kahwe Smith (lsmith) - Martin Hasoň (hason) - Jeremy Mikola (jmikola) - Jean-François Simon (jfsimon) + - Grégoire Pineau (lyrixx) - Benjamin Eberlei (beberlei) - Igor Wiedler (igorw) - - Grégoire Pineau (lyrixx) - Eriksen Costa (eriksencosta) - Jules Pietri (heah) - Sarah Khalil (saro0h) @@ -45,11 +45,11 @@ Symfony is the result of the work of many people who made the code better - stealth35 ‏ (stealth35) - Alexander Mols (asm89) - Bulat Shakirzyanov (avalanche123) + - Robin Chalas (chalas_r) - Saša Stamenković (umpirsky) - Henrik Bjørnskov (henrikbjorn) - Miha Vrhovnik - Diego Saint Esteben (dii3g0) - - Robin Chalas (chalas_r) - Ener-Getick (energetick) - Konstantin Kudryashov (everzet) - Bilal Amarni (bamarni) @@ -84,19 +84,19 @@ Symfony is the result of the work of many people who made the code better - Fran Moreno (franmomu) - Antoine Hérault (herzult) - Paráda József (paradajozsef) + - Roland Franssen (ro0) + - Dariusz Ruminski - Jáchym Toušek (enumag) - Arnaud Le Blanc (arnaud-lb) - Jérôme Tamarelle (gromnan) - Michal Piotrowski (eventhorizon) - Tim Nagel (merk) - - Dariusz Ruminski - Brice BERNARD (brikou) - Alexander M. Turek (derrabus) - marc.weistroff - Issei Murasawa (issei_m) - lenar - Włodzimierz Gajda (gajdaw) - - Roland Franssen (ro0) - Baptiste Clavié (talus) - Alexander Schwenn (xelaris) - Florian Voutzinos (florianv) @@ -132,6 +132,7 @@ Symfony is the result of the work of many people who made the code better - Rafael Dohms (rdohms) - Arnaud Kleinpeter (nanocom) - jwdeitch + - Tobias Nyholm (tobias) - Joel Wurtz (brouznouf) - Philipp Wahala (hifi) - Vyacheslav Pavlov @@ -145,12 +146,14 @@ Symfony is the result of the work of many people who made the code better - Clemens Tolboom - Helmer Aaviksoo - Hiromi Hishida (77web) + - Yonel Ceruto González (yonelceruto) - Richard van Laak (rvanlaak) - Matthieu Ouellette-Vachon (maoueh) - Michał Pipa (michal.pipa) - Amal Raghav (kertz) - Jonathan Ingram (jonathaningram) - Artur Kotyrba + - jeremyFreeAgent (Jérémy Romey) (jeremyfreeagent) - Warnar Boekkooi (boekkooi) - Dmitrii Chekaliuk (lazyhammer) - Clément JOBEILI (dator) @@ -160,13 +163,12 @@ Symfony is the result of the work of many people who made the code better - Richard Miller (mr_r_miller) - Mario A. Alvarez Garcia (nomack84) - Dennis Benkert (denderello) - - jeremyFreeAgent (Jérémy Romey) (jeremyfreeagent) - Benjamin Dulau (dbenjamin) - Mathieu Lemoine (lemoinem) - Andreas Hucks (meandmymonkey) - Noel Guilbert (noel) - Lars Strojny (lstrojny) - - Yonel Ceruto González (yonelceruto) + - Maxime STEINHAUSSER - Stepan Anchugov (kix) - bronze1man - sun (sun) @@ -236,7 +238,6 @@ Symfony is the result of the work of many people who made the code better - Grégoire Paris (greg0ire) - Leo Feyer - Chekote - - Tobias Nyholm (tobias) - Thomas Adam - Albert Casademont (acasademont) - Jhonny Lidfors (jhonne) @@ -245,6 +246,7 @@ Symfony is the result of the work of many people who made the code better - Nikita Konstantinov - Wodor Wodorski - Thomas Lallement (raziel057) + - Giorgio Premi - Matthieu Napoli (mnapoli) - Beau Simensen (simensen) - Michael Hirschler (mvhirsch) @@ -295,7 +297,6 @@ Symfony is the result of the work of many people who made the code better - Mark Challoner (markchalloner) - Gregor Harlan (gharlan) - Gennady Telegin (gtelegin) - - Giorgio Premi - Ben Davies (bendavies) - Erin Millard - Artur Melo (restless) @@ -393,7 +394,6 @@ 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) - franek (franek) @@ -439,6 +439,7 @@ Symfony is the result of the work of many people who made the code better - Vicent Soria Durá (vicentgodella) - Nicolas Dewez (nicolas_dewez) - Anthony Ferrara + - Victor Bocharsky (bocharsky_bw) - Ioan Negulescu - Jakub Škvára (jskvara) - Andrew Udvare (audvare) @@ -611,7 +612,6 @@ 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) - Jordan Deitch - Casper Valdemar Poulsen @@ -769,6 +769,7 @@ Symfony is the result of the work of many people who made the code better - fabios - Sander Coolen (scoolen) - Nicolas Le Goff (nlegoff) + - Andreas Braun - Ben Oman - Manuele Menozzi - Anton Babenko (antonbabenko) @@ -858,6 +859,7 @@ Symfony is the result of the work of many people who made the code better - rpg600 - Péter Buri (burci) - Davide Borsatto (davide.borsatto) + - Indra Gunawan (guind) - kaiwa - Charles Sanquer (csanquer) - Albert Ganiev (helios-ag) @@ -969,6 +971,7 @@ Symfony is the result of the work of many people who made the code better - Sandro Hopf - Łukasz Makuch - George Giannoulopoulos + - Luis Ramirez (luisdeimos) - Daniel Richter (richtermeister) - ChrisC - Ilya Biryukov @@ -985,6 +988,7 @@ Symfony is the result of the work of many people who made the code better - Pete Mitchell (peterjmit) - Tom Corrigan (tomcorrigan) - Martin Pärtel + - Noah Heck (myesain) - Patrick Daley (padrig) - Xavier Briand (xavierbriand) - Max Summe @@ -1041,6 +1045,7 @@ Symfony is the result of the work of many people who made the code better - Sebastian Ionescu - Thomas Ploch - Simon Neidhold + - Xavier HAUSHERR - Valentin VALCIU - Kevin Dew - James Cowgill @@ -1163,6 +1168,7 @@ Symfony is the result of the work of many people who made the code better - Koalabaerchen - michalmarcinkowski - Warwick + - VJ - Chris - JakeFr - Simon Sargeant @@ -1236,6 +1242,7 @@ Symfony is the result of the work of many people who made the code better - Joel Marcey - David Christmann - root + - Wouter J - James Hudson - Tom Maguire - David Zuelke @@ -1312,6 +1319,7 @@ Symfony is the result of the work of many people who made the code better - Jelle Bekker (jbekker) - Ian Jenkins (jenkoian) - Jorge Martin (jorgemartind) + - Julien Falque (julienfalque) - Kevin Herrera (kherge) - Luis Ramón López López (lrlopez) - Muriel (metalmumu) @@ -1379,6 +1387,7 @@ Symfony is the result of the work of many people who made the code better - Jörg Rühl - wesleyh - sergey + - Karim Miladi - Michael Genereux - patrick-mcdougle - Dariusz Czech @@ -1559,6 +1568,7 @@ Symfony is the result of the work of many people who made the code better - Sergey Fedotov - Michael - fh-github@fholzhauer.de + - Jan Emrich - Mark Topper - Xavier REN - Zander Baldwin diff --git a/UPGRADE-2.7.md b/UPGRADE-2.7.md index 5de67ebede36c..1cf3d3df7f4dc 100644 --- a/UPGRADE-2.7.md +++ b/UPGRADE-2.7.md @@ -40,7 +40,7 @@ Form ---- * In form types and extension overriding the "setDefaultOptions" of the - AbstractType or AbstractExtensionType has been deprecated in favor of + AbstractType or AbstractTypeExtension has been deprecated in favor of overriding the new "configureOptions" method. The method "setDefaultOptions(OptionsResolverInterface $resolver)" will diff --git a/appveyor.yml b/appveyor.yml index adf63a1539493..f8162c0689ff0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -33,7 +33,7 @@ install: - cd .. - copy /Y php.ini-development php.ini-min - echo max_execution_time=1200 >> php.ini-min - - echo date.timezone="UTC" >> php.ini-min + - echo date.timezone="America/Los_Angeles" >> php.ini-min - echo extension_dir=ext >> php.ini-min - copy /Y php.ini-min php.ini-max - echo extension=php_openssl.dll >> php.ini-max diff --git a/composer.json b/composer.json index 1a2e8c26b586f..34dfa896e3b45 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.27|~2.0", + "twig/twig": "~1.28|~2.0", "psr/log": "~1.0" }, "replace": { diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php index e1cbbbfb1a36e..940ca6fdf9fbd 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php @@ -134,10 +134,7 @@ protected function setMappingDriverConfig(array $mappingConfig, $mappingName) throw new \InvalidArgumentException(sprintf('Invalid Doctrine mapping path given. Cannot load Doctrine mapping/bundle named "%s".', $mappingName)); } - if (substr($mappingDirectory, 0, 7) !== 'phar://') { - $mappingDirectory = realpath($mappingDirectory); - } - $this->drivers[$mappingConfig['type']][$mappingConfig['prefix']] = $mappingDirectory; + $this->drivers[$mappingConfig['type']][$mappingConfig['prefix']] = realpath($mappingDirectory) ?: $mappingDirectory; } /** diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/DoctrineValidationPass.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/DoctrineValidationPass.php index 96f05eb5b60c9..f8382ed2ebfb8 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/DoctrineValidationPass.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/DoctrineValidationPass.php @@ -61,7 +61,7 @@ private function updateValidatorMappingFiles(ContainerBuilder $container, $mappi foreach ($container->getParameter('kernel.bundles') as $bundle) { $reflection = new \ReflectionClass($bundle); if (is_file($file = dirname($reflection->getFileName()).'/'.$validationPath)) { - $files[] = realpath($file); + $files[] = $file; $container->addResource(new FileResource($file)); } } diff --git a/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php b/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php index 324611fba1ced..2dd139750c7bd 100644 --- a/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php +++ b/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php @@ -138,7 +138,6 @@ public function configureOptions(OptionsResolver $resolver) $type = $this; $choiceLoader = function (Options $options) use ($choiceListFactory, &$choiceLoaders, $type) { - // Unless the choices are given explicitly, load them on demand if (null === $options['choices']) { $hash = null; diff --git a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php index 760c0fada0fab..f917f73eaa15b 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php @@ -44,7 +44,7 @@ protected function setUp() $this->extension->expects($this->any()) ->method('getObjectManagerElementName') ->will($this->returnCallback(function ($name) { - return 'doctrine.orm.'.$name; + return 'doctrine.orm.'.$name; })); } diff --git a/src/Symfony/Bridge/Twig/Command/DebugCommand.php b/src/Symfony/Bridge/Twig/Command/DebugCommand.php index 898e0e2233bb6..39b910d6b4f61 100644 --- a/src/Symfony/Bridge/Twig/Command/DebugCommand.php +++ b/src/Symfony/Bridge/Twig/Command/DebugCommand.php @@ -60,7 +60,7 @@ protected function configure() new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (text or json)', 'text'), )) ->setDescription('Shows a list of twig functions, filters, globals and tests') - ->setHelp(<<setHelp(<<<'EOF' The %command.name% command outputs a list of twig functions, filters, globals and tests. Output can be filtered with an optional argument. diff --git a/src/Symfony/Bridge/Twig/Command/LintCommand.php b/src/Symfony/Bridge/Twig/Command/LintCommand.php index 4ed63241b8d8c..83f4e1948c4c5 100644 --- a/src/Symfony/Bridge/Twig/Command/LintCommand.php +++ b/src/Symfony/Bridge/Twig/Command/LintCommand.php @@ -61,7 +61,7 @@ protected function configure() ->setDescription('Lints a template and outputs encountered errors') ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt') ->addArgument('filename', InputArgument::IS_ARRAY) - ->setHelp(<<setHelp(<<<'EOF' The %command.name% command lints a template and outputs to STDOUT the first encountered syntax error. diff --git a/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php b/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php index b226d91adfe48..e64d6eae2347d 100644 --- a/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php +++ b/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php @@ -49,7 +49,7 @@ protected function doEnterNode(\Twig_Node $node, \Twig_Environment $env) return $node; } else { - $var = $env->getParser()->getVarName(); + $var = $this->getVarName(); $name = new \Twig_Node_Expression_AssignName($var, $node->getTemplateLine()); $this->scope->set('domain', new \Twig_Node_Expression_Name($var, $node->getTemplateLine())); @@ -123,4 +123,9 @@ private function isNamedArguments($arguments) return false; } + + private function getVarName() + { + return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false)); + } } diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php index 0235c4da327a0..e96bd4f9a3bef 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(new \Twig_Source($twig->getLoader()->getSource('index'), 'index'))))."\n\n"; + echo $twig->compile($twig->parse($twig->tokenize($twig->getLoader()->getSourceContext('index'))))."\n\n"; $this->assertEquals($expected, $this->getTemplate($template)->render($variables)); } diff --git a/src/Symfony/Bridge/Twig/Tests/Node/DumpNodeTest.php b/src/Symfony/Bridge/Twig/Tests/Node/DumpNodeTest.php index 5d8ea6f0868ab..035dc4f671431 100644 --- a/src/Symfony/Bridge/Twig/Tests/Node/DumpNodeTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Node/DumpNodeTest.php @@ -80,7 +80,13 @@ public function testOneVar() } EOTXT; - $expected = preg_replace('/%(.*?)%/', PHP_VERSION_ID >= 50400 ? '(isset($context["$1"]) ? $context["$1"] : null)' : '$this->getContext($context, "$1")', $expected); + if (PHP_VERSION_ID >= 70000) { + $expected = preg_replace('/%(.*?)%/', '($context["$1"] ?? null)', $expected); + } elseif (PHP_VERSION_ID >= 50400) { + $expected = preg_replace('/%(.*?)%/', '(isset($context["$1"]) ? $context["$1"] : null)', $expected); + } else { + $expected = preg_replace('/%(.*?)%/', '$this->getContext($context, "$1")', $expected); + } $this->assertSame($expected, $compiler->compile($node)->getSource()); } @@ -106,7 +112,14 @@ public function testMultiVars() } EOTXT; - $expected = preg_replace('/%(.*?)%/', PHP_VERSION_ID >= 50400 ? '(isset($context["$1"]) ? $context["$1"] : null)' : '$this->getContext($context, "$1")', $expected); + + if (PHP_VERSION_ID >= 70000) { + $expected = preg_replace('/%(.*?)%/', '($context["$1"] ?? null)', $expected); + } elseif (PHP_VERSION_ID >= 50400) { + $expected = preg_replace('/%(.*?)%/', '(isset($context["$1"]) ? $context["$1"] : null)', $expected); + } else { + $expected = preg_replace('/%(.*?)%/', '$this->getContext($context, "$1")', $expected); + } $this->assertSame($expected, $compiler->compile($node)->getSource()); } diff --git a/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php b/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php index f407afdcd6968..590b9ef75c617 100644 --- a/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php @@ -66,6 +66,10 @@ public function testCompile() protected function getVariableGetter($name) { + if (PHP_VERSION_ID >= 70000) { + return sprintf('($context["%s"] ?? null)', $name, $name); + } + if (PHP_VERSION_ID >= 50400) { return sprintf('(isset($context["%s"]) ? $context["%s"] : null)', $name, $name); } diff --git a/src/Symfony/Bridge/Twig/Tests/Node/SearchAndRenderBlockNodeTest.php b/src/Symfony/Bridge/Twig/Tests/Node/SearchAndRenderBlockNodeTest.php index ad76e25e8ee7a..0a3d30bdd5e5e 100644 --- a/src/Symfony/Bridge/Twig/Tests/Node/SearchAndRenderBlockNodeTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Node/SearchAndRenderBlockNodeTest.php @@ -263,6 +263,10 @@ public function testCompileLabelWithLabelThatEvaluatesToNullAndAttributes() protected function getVariableGetter($name) { + if (PHP_VERSION_ID >= 70000) { + return sprintf('($context["%s"] ?? null)', $name, $name); + } + if (PHP_VERSION_ID >= 50400) { return sprintf('(isset($context["%s"]) ? $context["%s"] : null)', $name, $name); } diff --git a/src/Symfony/Bridge/Twig/Tests/Node/TransNodeTest.php b/src/Symfony/Bridge/Twig/Tests/Node/TransNodeTest.php index 032975a8f2897..cbd21fc46edd2 100644 --- a/src/Symfony/Bridge/Twig/Tests/Node/TransNodeTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Node/TransNodeTest.php @@ -39,6 +39,10 @@ public function testCompileStrict() protected function getVariableGetterWithoutStrictCheck($name) { + if (PHP_VERSION_ID >= 70000) { + return sprintf('($context["%s"] ?? null)', $name, $name); + } + if (PHP_VERSION_ID >= 50400) { return sprintf('(isset($context["%s"]) ? $context["%s"] : null)', $name, $name); } @@ -48,10 +52,14 @@ protected function getVariableGetterWithoutStrictCheck($name) protected function getVariableGetterWithStrictCheck($name) { - if (version_compare(\Twig_Environment::VERSION, '2.0.0-DEV', '>=')) { + if (\Twig_Environment::MAJOR_VERSION >= 2) { return sprintf('(isset($context["%s"]) || array_key_exists("%s", $context) ? $context["%s"] : $this->notFound("%s", 0))', $name, $name, $name, $name); } + if (PHP_VERSION_ID >= 70000) { + return sprintf('($context["%s"] ?? $this->getContext($context, "%s"))', $name, $name, $name); + } + if (PHP_VERSION_ID >= 50400) { return sprintf('(isset($context["%s"]) ? $context["%s"] : $this->getContext($context, "%s"))', $name, $name, $name); } diff --git a/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php b/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php index 917687ad34eee..950c4d0810db0 100644 --- a/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php +++ b/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php @@ -64,7 +64,7 @@ public function extract($resource, MessageCatalogue $catalogue) if ($file instanceof SplFileInfo) { $e->setTemplateName($file->getRelativePathname()); } elseif ($file instanceof \SplFileInfo) { - $e->setTemplateName($file->getRealPath()); + $e->setTemplateName($file->getRealPath() ?: $file->getPathname()); } throw $e; diff --git a/src/Symfony/Bridge/Twig/TwigEngine.php b/src/Symfony/Bridge/Twig/TwigEngine.php index 3e3257e7fa0f5..1ac9d0102e63b 100644 --- a/src/Symfony/Bridge/Twig/TwigEngine.php +++ b/src/Symfony/Bridge/Twig/TwigEngine.php @@ -75,14 +75,14 @@ public function exists($name) $loader = $this->environment->getLoader(); - if ($loader instanceof \Twig_ExistsLoaderInterface) { + if ($loader instanceof \Twig_ExistsLoaderInterface || method_exists($loader, 'exists')) { return $loader->exists((string) $name); } try { // cast possible TemplateReferenceInterface to string because the // EngineInterface supports them but Twig_LoaderInterface does not - $loader->getSource((string) $name); + $loader->getSourceContext((string) $name)->getCode(); } catch (\Twig_Error_Loader $e) { return false; } diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index b83dc34c7fb8f..74c98e93a50e8 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.27|~2.0" + "twig/twig": "~1.28|~2.0" }, "require-dev": { "symfony/asset": "~2.7", diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php index 20deffcc3339f..9059905e04f54 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php @@ -39,7 +39,7 @@ protected function configure() new InputArgument('name', InputArgument::OPTIONAL, 'The bundle name or the extension alias'), )) ->setDescription('Dumps the current configuration for an extension') - ->setHelp(<<setHelp(<<<'EOF' The %command.name% command dumps the current configuration for an extension/bundle. diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php index f30b59cf62ac8..f9bc810d0fa27 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php @@ -38,7 +38,7 @@ protected function configure() new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw description'), )) ->setDescription('Displays configured listeners for an application') - ->setHelp(<<setHelp(<<<'EOF' The %command.name% command displays all configured listeners: php %command.full_name% diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ServerStartCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ServerStartCommand.php index 04906317fa944..2c45de91680f9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ServerStartCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ServerStartCommand.php @@ -39,7 +39,7 @@ protected function configure() )) ->setName('server:start') ->setDescription('Starts PHP built-in web server in the background') - ->setHelp(<<setHelp(<<<'EOF' The %command.name% runs PHP's built-in web server: php %command.full_name% diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ServerStopCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ServerStopCommand.php index 9b0656c220b66..84ed54c41e7a6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ServerStopCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ServerStopCommand.php @@ -33,7 +33,7 @@ protected function configure() )) ->setName('server:stop') ->setDescription('Stops PHP\'s built-in web server that was started with the server:start command') - ->setHelp(<<setHelp(<<<'EOF' The %command.name% stops PHP's built-in web server: php %command.full_name% diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php index 30d44493d4c4b..be4696adfd806 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php @@ -19,6 +19,8 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Translation\MessageCatalogue; use Symfony\Component\Translation\Translator; +use Symfony\Component\Translation\DataCollectorTranslator; +use Symfony\Component\Translation\LoggingTranslator; /** * Helps finding unused or missing translation messages in a given locale @@ -50,7 +52,7 @@ protected function configure() new InputOption('only-unused', null, InputOption::VALUE_NONE, 'Displays only unused messages'), )) ->setDescription('Displays translation messages information') - ->setHelp(<<setHelp(<<<'EOF' The %command.name% command helps finding unused or missing translation messages and comparing them with the fallback ones by inspecting the templates and translation files of a given bundle or the app folder. @@ -157,7 +159,7 @@ protected function execute(InputInterface $input, OutputInterface $output) // Load the fallback catalogues $fallbackCatalogues = array(); $translator = $this->getContainer()->get('translator'); - if ($translator instanceof Translator) { + if ($translator instanceof Translator || $translator instanceof DataCollectorTranslator || $translator instanceof LoggingTranslator) { foreach ($translator->getFallbackLocales() as $fallbackLocale) { if ($fallbackLocale === $locale) { continue; diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php index 920c50c1d793f..f310613d10315 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php @@ -118,9 +118,8 @@ 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(null === $prefix ? '' : $prefix); + $extractor->setPrefix($input->getOption('prefix')); foreach ($transPaths as $path) { $path .= 'views'; if (is_dir($path)) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/YamlLintCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/YamlLintCommand.php index b41f5f3479ebe..ca39257462dd3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/YamlLintCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/YamlLintCommand.php @@ -34,7 +34,7 @@ protected function configure() ->setDescription('Lints a file and outputs encountered errors') ->addArgument('filename', null, 'A file or a directory or STDIN') ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt') - ->setHelp(<<setHelp(<<<'EOF' The %command.name% command lints a YAML file and outputs to STDOUT the first encountered syntax error. diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index c8e105cddcc41..278b8b9b7d672 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -52,7 +52,7 @@ class FrameworkExtension extends Extension */ public function load(array $configs, ContainerBuilder $container) { - $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader = new XmlFileLoader($container, new FileLocator(dirname(__DIR__).'/Resources/config')); $loader->load('web.xml'); $loader->load('services.xml'); @@ -689,7 +689,7 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder if (class_exists('Symfony\Component\Security\Core\Exception\AuthenticationException')) { $r = new \ReflectionClass('Symfony\Component\Security\Core\Exception\AuthenticationException'); - $dirs[] = dirname($r->getFileName()).'/../Resources/translations'; + $dirs[] = dirname(dirname($r->getFileName())).'/Resources/translations'; } $rootDir = $container->getParameter('kernel.root_dir'); foreach ($container->getParameter('kernel.bundles') as $bundle => $class) { @@ -811,21 +811,21 @@ private function getValidatorMappingFiles(ContainerBuilder $container) $dirname = dirname($reflection->getFileName()); if (is_file($file = $dirname.'/Resources/config/validation.xml')) { - $files[0][] = realpath($file); + $files[0][] = $file; $container->addResource(new FileResource($file)); } if (is_file($file = $dirname.'/Resources/config/validation.yml')) { - $files[1][] = realpath($file); + $files[1][] = $file; $container->addResource(new FileResource($file)); } if (is_dir($dir = $dirname.'/Resources/config/validation')) { foreach (Finder::create()->files()->in($dir)->name('*.xml') as $file) { - $files[0][] = $file->getRealPath(); + $files[0][] = $file->getPathname(); } foreach (Finder::create()->files()->in($dir)->name('*.yml') as $file) { - $files[1][] = $file->getRealPath(); + $files[1][] = $file->getPathname(); } $container->addResource(new DirectoryResource($dir)); @@ -926,7 +926,7 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder $dirname = dirname($reflection->getFileName()); if (is_file($file = $dirname.'/Resources/config/serialization.xml')) { - $definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader', array(realpath($file))); + $definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader', array($file)); $definition->setPublic(false); $serializerLoaders[] = $definition; @@ -934,7 +934,7 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder } if (is_file($file = $dirname.'/Resources/config/serialization.yml')) { - $definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader', array(realpath($file))); + $definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader', array($file)); $definition->setPublic(false); $serializerLoaders[] = $definition; @@ -943,13 +943,13 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder if (is_dir($dir = $dirname.'/Resources/config/serialization')) { foreach (Finder::create()->files()->in($dir)->name('*.xml') as $file) { - $definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader', array($file->getRealPath())); + $definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader', array($file->getPathname())); $definition->setPublic(false); $serializerLoaders[] = $definition; } foreach (Finder::create()->files()->in($dir)->name('*.yml') as $file) { - $definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader', array($file->getRealPath())); + $definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader', array($file->getPathname())); $definition->setPublic(false); $serializerLoaders[] = $definition; @@ -996,7 +996,7 @@ private function getKernelRootHash(ContainerBuilder $container) */ public function getXsdValidationBasePath() { - return __DIR__.'/../Resources/config/schema'; + return dirname(__DIR__).'/Resources/config/schema'; } public function getNamespace() diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php index 324eb4782c2cc..bf4a4c478502b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php @@ -1 +1 @@ -block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'text')) ?> +block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'text')) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php index 4390687a69330..ec96cfb46b24c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php @@ -1 +1 @@ -block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'password')) ?> +block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'password')) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php index 59b29f4cbcfaa..8519da429b188 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php @@ -1 +1 @@ -block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'text')) ?> % +block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'text')) ?> % diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/reset_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/reset_widget.html.php index 1575e8292801e..e8fa18e488df8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/reset_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/reset_widget.html.php @@ -1 +1 @@ -block($form, 'button_widget', array('type' => isset($type) ? $type : 'reset')) ?> +block($form, 'button_widget', array('type' => isset($type) ? $type : 'reset')) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php index 4e442f6ef47ae..48a33f4aa2dbc 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php @@ -1 +1 @@ -block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'search')) ?> +block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'search')) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/submit_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/submit_widget.html.php index d42bb2a78ffe9..6bf71f5a1e1c9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/submit_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/submit_widget.html.php @@ -1 +1 @@ -block($form, 'button_widget', array('type' => isset($type) ? $type : 'submit')) ?> +block($form, 'button_widget', array('type' => isset($type) ? $type : 'submit')) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/url_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/url_widget.html.php index 0ce4ed2ca79fd..9e26318497b3c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/url_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/url_widget.html.php @@ -1 +1 @@ -block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'url')) ?> +block($form, 'form_widget_simple', array('type' => isset($type) ? $type : 'url')) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php b/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php index c0b68a2d17a46..4ef5f0a4bd1c4 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php +++ b/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php @@ -164,7 +164,6 @@ private function resolve($value) gettype($resolved) ) ); - }, $value); return str_replace('%%', '%', $escapedValue); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/RouterMatchCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/RouterMatchCommandTest.php index 93c2468dc15ae..fc7e2155537fe 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/RouterMatchCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/RouterMatchCommandTest.php @@ -88,7 +88,6 @@ private function getContainer() ->will($this->returnValueMap(array( array('router', 1, $router), array('controller_name_converter', 1, $loader), - ))); return $container; diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationDebugCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationDebugCommandTest.php index c99c0ace2ac77..27f61c4383f24 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationDebugCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationDebugCommandTest.php @@ -136,7 +136,7 @@ private function getContainer($extractedMessages = array(), $loadedMessages = ar ->method('extract') ->will( $this->returnCallback(function ($path, $catalogue) use ($extractedMessages) { - $catalogue->add($extractedMessages); + $catalogue->add($extractedMessages); }) ); @@ -146,7 +146,7 @@ private function getContainer($extractedMessages = array(), $loadedMessages = ar ->method('loadMessages') ->will( $this->returnCallback(function ($path, $catalogue) use ($loadedMessages) { - $catalogue->add($loadedMessages); + $catalogue->add($loadedMessages); }) ); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationUpdateCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationUpdateCommandTest.php index a04a0cccad77c..24a4f625f6db5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationUpdateCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationUpdateCommandTest.php @@ -74,7 +74,7 @@ private function getContainer($extractedMessages = array(), $loadedMessages = ar ->method('extract') ->will( $this->returnCallback(function ($path, $catalogue) use ($extractedMessages) { - $catalogue->add($extractedMessages); + $catalogue->add($extractedMessages); }) ); @@ -84,7 +84,7 @@ private function getContainer($extractedMessages = array(), $loadedMessages = ar ->method('loadMessages') ->will( $this->returnCallback(function ($path, $catalogue) use ($loadedMessages) { - $catalogue->add($loadedMessages); + $catalogue->add($loadedMessages); }) ); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/AbstractDescriptorTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/AbstractDescriptorTest.php index 192ba44bf737c..46249c8e7c153 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/AbstractDescriptorTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/AbstractDescriptorTest.php @@ -141,6 +141,7 @@ public function getDescribeCallableTestData() } abstract protected function getDescriptor(); + abstract protected function getFormat(); private function assertDescription($expectedDescription, $describedObject, array $options = array()) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php index 52a6665416923..d6fc8b24ad264 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php @@ -191,9 +191,11 @@ class CallableClass public function __invoke() { } + public static function staticMethod() { } + public function method() { } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 9d93263963f9b..922d6f95738f6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -363,11 +363,11 @@ public function testValidationPaths() // Testing symfony/framework-bundle with deps=high $this->assertStringEndsWith('symfony'.DIRECTORY_SEPARATOR.'form/Resources/config/validation.xml', $xmlMappings[0]); } - $this->assertStringEndsWith('TestBundle'.DIRECTORY_SEPARATOR.'Resources'.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'validation.xml', $xmlMappings[1]); + $this->assertStringEndsWith('TestBundle/Resources/config/validation.xml', $xmlMappings[1]); $yamlMappings = $calls[4][1][0]; $this->assertCount(1, $yamlMappings); - $this->assertStringEndsWith('TestBundle'.DIRECTORY_SEPARATOR.'Resources'.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'validation.yml', $yamlMappings[0]); + $this->assertStringEndsWith('TestBundle/Resources/config/validation.yml', $yamlMappings[0]); } public function testValidationNoStaticMethod() diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/translation.html.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/translation.html.php index 04df261863f48..c0ae6ec5c6604 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/translation.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Resources/views/translation.html.php @@ -1,7 +1,7 @@ This template is used for translation message extraction tests trans('single-quoted key') ?> trans('double-quoted key') ?> -trans(<<trans(<<<'EOF' heredoc key EOF ) ?> diff --git a/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php b/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php index bd81d4927142b..092c627fa9862 100644 --- a/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php +++ b/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php @@ -81,7 +81,7 @@ public function collect(Request $request, Response $response, \Exception $except 'authenticated' => $token->isAuthenticated(), 'token_class' => get_class($token), 'user' => $token->getUsername(), - 'roles' => array_map(function (RoleInterface $role) { return $role->getRole();}, $assignedRoles), + 'roles' => array_map(function (RoleInterface $role) { return $role->getRole(); }, $assignedRoles), 'inherited_roles' => array_map(function (RoleInterface $role) { return $role->getRole(); }, $inheritedRoles), 'supports_role_hierarchy' => null !== $this->roleHierarchy, ); diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php index 36dbcdf89a1bd..a3e5e233f9d71 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php @@ -407,11 +407,10 @@ private function addEncodersSection(ArrayNodeDefinition $rootNode) ->children() ->arrayNode('encoders') ->example(array( - 'Acme\DemoBundle\Entity\User1' => 'sha512', - 'Acme\DemoBundle\Entity\User2' => array( - 'algorithm' => 'sha512', - 'encode_as_base64' => 'true', - 'iterations' => 5000, + 'AppBundle\Entity\User1' => 'bcrypt', + 'AppBundle\Entity\User2' => array( + 'algorithm' => 'bcrypt', + 'cost' => 13, ), )) ->requiresAtLeastOneElement() diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php index 2b3310c61aae4..028e885246f61 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php @@ -25,7 +25,7 @@ interface SecurityFactoryInterface * Configures the container services required to use the authentication listener. * * @param ContainerBuilder $container - * @param string $id The unique id of the firewall + * @param string $id The unique id of the firewall * @param array $config The options array for the listener * @param string $userProvider The service id of the user provider * @param string $defaultEntryPoint @@ -48,7 +48,7 @@ public function getPosition(); /** * Defines the configuration key used to reference the provider * in the firewall configuration. - * + * * @return string */ public function getKey(); diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index ee1faf659a260..64dfae228be08 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.27|~2.0", + "twig/twig": "~1.28|~2.0", "ircmaxell/password-compat": "~1.0" }, "autoload": { diff --git a/src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.php b/src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.php index 3eec8d6be92ec..b6972fc6354cd 100644 --- a/src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.php +++ b/src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.php @@ -131,12 +131,12 @@ protected function templateExists($template) $template = (string) $template; $loader = $this->twig->getLoader(); - if ($loader instanceof \Twig_ExistsLoaderInterface) { + if ($loader instanceof \Twig_ExistsLoaderInterface || method_exists($loader, 'exists')) { return $loader->exists($template); } try { - $loader->getSource($template); + $loader->getSourceContext($template)->getCode(); return true; } catch (\Twig_Error_Loader $e) { diff --git a/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php b/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php index 4e0bef365ebbb..53fe300e29a62 100644 --- a/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php +++ b/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php @@ -58,6 +58,7 @@ public function exists($name) * Otherwise the template is located using the locator from the twig library. * * @param string|TemplateReferenceInterface $template The template + * @param bool $throw When true, a \Twig_Error_Loader exception will be thrown if a template could not be found * * @return string The path to the template file * @@ -87,7 +88,11 @@ protected function findTemplate($template, $throw = true) } if (false === $file || null === $file) { - throw $twigLoaderException; + if ($throw) { + throw $twigLoaderException; + } + + return false; } return $this->cache[$logicalName] = $file; diff --git a/src/Symfony/Bundle/TwigBundle/Tests/Controller/PreviewErrorControllerTest.php b/src/Symfony/Bundle/TwigBundle/Tests/Controller/PreviewErrorControllerTest.php index 7bef647a7e283..e4a47a07694b5 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/Controller/PreviewErrorControllerTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/Controller/PreviewErrorControllerTest.php @@ -34,7 +34,6 @@ public function testForwardRequestToConfiguredController() ->method('handle') ->with( $this->callback(function (Request $request) use ($self, $logicalControllerName, $code) { - $self->assertEquals($logicalControllerName, $request->attributes->get('_controller')); $exception = $request->attributes->get('exception'); diff --git a/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php b/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php index 9804c08a1923b..64ba490388f9f 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php @@ -115,4 +115,17 @@ public function testTwigErrorIfTemplateDoesNotExist() $method->setAccessible(true); $method->invoke($loader, 'name.format.engine'); } + + public function testTwigSoftErrorIfTemplateDoesNotExist() + { + $parser = $this->getMock('Symfony\Component\Templating\TemplateNameParserInterface'); + $locator = $this->getMock('Symfony\Component\Config\FileLocatorInterface'); + + $loader = new FilesystemLoader($locator, $parser); + $loader->addPath(__DIR__.'/../DependencyInjection/Fixtures/Resources/views'); + + $method = new \ReflectionMethod('Symfony\Bundle\TwigBundle\Loader\FilesystemLoader', 'findTemplate'); + $method->setAccessible(true); + $this->assertFalse($method->invoke($loader, 'name.format.engine', false)); + } } diff --git a/src/Symfony/Bundle/TwigBundle/composer.json b/src/Symfony/Bundle/TwigBundle/composer.json index 4714ddb2e06fc..8c4947db65f27 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.27|~2.0", + "twig/twig": "~1.28|~2.0", "symfony/http-foundation": "~2.5", "symfony/http-kernel": "~2.7" }, diff --git a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php index 2748910a19ae8..24c83d5e1d8c6 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php @@ -106,7 +106,7 @@ public function panelAction(Request $request, $token) 'panel' => $panel, 'page' => $page, 'request' => $request, - 'templates' => $this->getTemplateManager()->getTemplates($profile), + 'templates' => $this->getTemplateManager()->getNames($profile), 'is_ajax' => $request->isXmlHttpRequest(), )), 200, array('Content-Type' => 'text/html')); } @@ -200,7 +200,7 @@ public function toolbarAction(Request $request, $token) return new Response($this->twig->render('@WebProfiler/Profiler/toolbar.html.twig', array( 'position' => $position, 'profile' => $profile, - 'templates' => $this->getTemplateManager()->getTemplates($profile), + 'templates' => $this->getTemplateManager()->getNames($profile), 'profiler_url' => $url, 'token' => $token, )), 200, array('Content-Type' => 'text/html')); diff --git a/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php b/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php index 415034a9f80c6..91938e9be5395 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Profiler/TemplateManager.php @@ -67,7 +67,9 @@ public function getName(Profile $profile, $panel) * * @param Profile $profile * - * @return array + * @return Twig_Template[] + * + * @deprecated not used anymore internally */ public function getTemplates(Profile $profile) { @@ -88,7 +90,7 @@ public function getTemplates(Profile $profile) * * @throws \UnexpectedValueException */ - protected function getNames(Profile $profile) + public function getNames(Profile $profile) { $templates = array(); diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig index 6be34406e6196..bcf97ddcbfb46 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig @@ -36,7 +36,11 @@ {% if templates is defined %}