From 1f3ea0f8af641782ab1a1e58f4c9ffc53e0f36c0 Mon Sep 17 00:00:00 2001 From: "Nathanael d. Noblet" Date: Thu, 27 Aug 2015 13:00:40 -0600 Subject: [PATCH 01/19] Use ObjectManager interface instead of EntityManager If you use the EntityManager Decorator pattern that doctrine provides then simply specifying a query_builder closure where your decorated em is used fails as it isn't an instance of Doctrine\ORM\EntityManager. Testing against the ObjectManager interface fixes the issue. --- .../Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php index 8f135d6258..30263ea7e3 100644 --- a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php +++ b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php @@ -14,7 +14,7 @@ namespace Symfony\Bridge\Doctrine\Form\ChoiceList; use Symfony\Component\Form\Exception\UnexpectedTypeException; use Doctrine\ORM\QueryBuilder; use Doctrine\DBAL\Connection; -use Doctrine\ORM\EntityManager; +use Doctrine\Common\Persistence\ObjectManager; /** * Getting Entities through the ORM QueryBuilder. @@ -35,7 +35,7 @@ class ORMQueryBuilderLoader implements EntityLoaderInterface * Construct an ORM Query Builder Loader. * * @param QueryBuilder|\Closure $queryBuilder - * @param EntityManager $manager + * @param ObjectManager $manager * @param string $class * * @throws UnexpectedTypeException @@ -49,8 +49,8 @@ class ORMQueryBuilderLoader implements EntityLoaderInterface } if ($queryBuilder instanceof \Closure) { - if (!$manager instanceof EntityManager) { - throw new UnexpectedTypeException($manager, 'Doctrine\ORM\EntityManager'); + if (!$manager instanceof ObjectManager) { + throw new UnexpectedTypeException($manager, 'Doctrine\Common\Persistence\ObjectManager'); } $queryBuilder = $queryBuilder($manager->getRepository($class)); From 232f6fd534956bf9738489691ad1d2070adbc4c5 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Thu, 3 Sep 2015 15:05:21 +0800 Subject: [PATCH 02/19] [framework-bundle] Add Test for TranslationUpdateCommand Added the test script as per the discussion in PR #15562 | Q | A | ------------- | --- | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | n/a | License | MIT | Doc PR | n/a --- .../Command/TranslationUpdateCommandTest.php | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationUpdateCommandTest.php diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationUpdateCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationUpdateCommandTest.php new file mode 100644 index 0000000000..a04a0cccad --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationUpdateCommandTest.php @@ -0,0 +1,141 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Command; + +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Tester\CommandTester; +use Symfony\Bundle\FrameworkBundle\Command\TranslationUpdateCommand; +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\DependencyInjection; +use Symfony\Component\HttpKernel; + +class TranslationUpdateCommandTest extends \PHPUnit_Framework_TestCase +{ + private $fs; + private $translationDir; + + public function testDumpMessagesAndClean() + { + $tester = $this->createCommandTester($this->getContainer(array('foo' => 'foo'))); + $tester->execute(array('command' => 'translation:update', 'locale' => 'en', 'bundle' => 'foo', '--dump-messages' => true, '--clean' => true)); + $this->assertRegExp('/foo/', $tester->getDisplay()); + } + + protected function setUp() + { + $this->fs = new Filesystem(); + $this->translationDir = sys_get_temp_dir().'/'.uniqid('sf2_translation', true); + $this->fs->mkdir($this->translationDir.'/Resources/translations'); + $this->fs->mkdir($this->translationDir.'/Resources/views'); + } + + protected function tearDown() + { + $this->fs->remove($this->translationDir); + } + + /** + * @return CommandTester + */ + private function createCommandTester(DependencyInjection\ContainerInterface $container) + { + $command = new TranslationUpdateCommand(); + $command->setContainer($container); + + $application = new Application(); + $application->add($command); + + return new CommandTester($application->find('translation:update')); + } + + private function getContainer($extractedMessages = array(), $loadedMessages = array(), HttpKernel\KernelInterface $kernel = null) + { + $translator = $this->getMockBuilder('Symfony\Component\Translation\Translator') + ->disableOriginalConstructor() + ->getMock(); + + $translator + ->expects($this->any()) + ->method('getFallbackLocales') + ->will($this->returnValue(array('en'))); + + $extractor = $this->getMock('Symfony\Component\Translation\Extractor\ExtractorInterface'); + $extractor + ->expects($this->any()) + ->method('extract') + ->will( + $this->returnCallback(function ($path, $catalogue) use ($extractedMessages) { + $catalogue->add($extractedMessages); + }) + ); + + $loader = $this->getMock('Symfony\Bundle\FrameworkBundle\Translation\TranslationLoader'); + $loader + ->expects($this->any()) + ->method('loadMessages') + ->will( + $this->returnCallback(function ($path, $catalogue) use ($loadedMessages) { + $catalogue->add($loadedMessages); + }) + ); + + $writer = $this->getMock('Symfony\Component\Translation\Writer\TranslationWriter'); + $writer + ->expects($this->any()) + ->method('getFormats') + ->will( + $this->returnValue(array('xlf', 'yml')) + ); + + if (null === $kernel) { + $kernel = $this->getMock('Symfony\Component\HttpKernel\KernelInterface'); + $kernel + ->expects($this->any()) + ->method('getBundle') + ->will($this->returnValueMap(array( + array('foo', true, $this->getBundle($this->translationDir)), + array('test', true, $this->getBundle('test')), + ))); + } + + $kernel + ->expects($this->any()) + ->method('getRootDir') + ->will($this->returnValue($this->translationDir)); + + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $container + ->expects($this->any()) + ->method('get') + ->will($this->returnValueMap(array( + array('translation.extractor', 1, $extractor), + array('translation.loader', 1, $loader), + array('translation.writer', 1, $writer), + array('translator', 1, $translator), + array('kernel', 1, $kernel), + ))); + + return $container; + } + + private function getBundle($path) + { + $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\BundleInterface'); + $bundle + ->expects($this->any()) + ->method('getPath') + ->will($this->returnValue($path)) + ; + + return $bundle; + } +} From cade65191531dc6fb30600f274554905b712b85a Mon Sep 17 00:00:00 2001 From: Abdellatif Ait boudad Date: Wed, 12 Aug 2015 10:54:13 +0000 Subject: [PATCH 03/19] [Translator][warmup][fallback locales] fixed missing cache file generation. --- .../FrameworkBundle/Tests/Translation/TranslatorTest.php | 3 ++- .../Bundle/FrameworkBundle/Translation/Translator.php | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php index c7b61cb881..043cd11518 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php @@ -273,7 +273,7 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase // prime the cache $translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir, 'resource_files' => $resourceFiles), 'yml'); - $translator->setLocale('fr'); + $translator->setFallbackLocales(array('fr')); $translator->warmup($this->tmpDir); $loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface'); @@ -283,6 +283,7 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase $translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir, 'resource_files' => $resourceFiles), 'yml'); $translator->setLocale('fr'); + $translator->setFallbackLocales(array('fr')); $this->assertEquals('répertoire', $translator->trans('folder')); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php index 9cc92f9c2d..fba6d70d69 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php @@ -82,7 +82,13 @@ class Translator extends BaseTranslator implements WarmableInterface return; } - foreach ($this->resourceLocales as $locale) { + $locales = array_merge($this->getFallbackLocales(), array($this->getLocale()), $this->resourceLocales); + foreach (array_unique($locales) as $locale) { + // reset catalogue in case it's already loaded during the dump of the other locales. + if (isset($this->catalogues[$locale])) { + unset($this->catalogues[$locale]); + } + $this->loadCatalogue($locale); } } From b95b5e217f4731107e8e966f4c04deae7ebde6f1 Mon Sep 17 00:00:00 2001 From: David Badura Date: Thu, 10 Sep 2015 09:43:17 +0200 Subject: [PATCH 04/19] missing "YAML" in the exception message. --- .../Component/Validator/Mapping/Loader/YamlFileLoader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php index ea4e2641a6..cf6dd92dca 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php @@ -121,7 +121,7 @@ class YamlFileLoader extends FileLoader try { $classes = $this->yamlParser->parse(file_get_contents($path)); } catch (ParseException $e) { - throw new \InvalidArgumentException(sprintf('The file "%s" does not contain valid.', $path), 0, $e); + throw new \InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML.', $path), 0, $e); } // empty file From 53cdb1a420aca8eeac76abb6dc9960d56b42fc57 Mon Sep 17 00:00:00 2001 From: AlberT Date: Tue, 9 Jun 2015 13:04:59 +0200 Subject: [PATCH 05/19] [WebProfilerBundle] Added tabindex="-1" to not interfer with normal UX --- .../Resources/views/Profiler/toolbar.html.twig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig index 9e96dc6d1a..f0bcd9eeed 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig @@ -1,7 +1,7 @@ {% if 'normal' != position %}
- validate($configuration, $file); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/bad_format.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/bad_format.yml new file mode 100644 index 0000000000..1f58cac6ac --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/bad_format.yml @@ -0,0 +1,2 @@ +parameters: + FOO: bar diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php index a6fbbd68bc..7d6b76bce9 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php @@ -87,6 +87,7 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase array('bad_services'), array('bad_service'), array('bad_calls'), + array('bad_format'), ); } diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/bad_format.yml b/src/Symfony/Component/Routing/Tests/Fixtures/bad_format.yml new file mode 100644 index 0000000000..8ba50e2e42 --- /dev/null +++ b/src/Symfony/Component/Routing/Tests/Fixtures/bad_format.yml @@ -0,0 +1,3 @@ +blog_show: + path: /blog/{slug} + defaults: { _controller: "MyBundle:Blog:show" } diff --git a/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php index 167fab00d3..9cc27628ed 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php @@ -51,7 +51,15 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase public function getPathsToInvalidFiles() { - return array(array('nonvalid.yml'), array('nonvalid2.yml'), array('incomplete.yml'), array('nonvalidkeys.yml'), array('nonesense_resource_plus_path.yml'), array('nonesense_type_without_resource.yml')); + return array( + array('nonvalid.yml'), + array('nonvalid2.yml'), + array('incomplete.yml'), + array('nonvalidkeys.yml'), + array('nonesense_resource_plus_path.yml'), + array('nonesense_type_without_resource.yml'), + array('bad_format.yml'), + ); } public function testLoadSpecialRouteName() diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php index c5b39173e5..47961c7c12 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php @@ -31,15 +31,26 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase $this->assertFalse($loader->loadClassMetadata($metadata)); } - public function testLoadClassMetadataThrowsExceptionIfNotAnArray() + /** + * @dataProvider provideInvalidYamlFiles + * @expectedException \InvalidArgumentException + */ + public function testInvalidYamlFiles($path) { - $loader = new YamlFileLoader(__DIR__.'/nonvalid-mapping.yml'); + $loader = new YamlFileLoader(__DIR__.'/'.$path); $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity'); - $this->setExpectedException('\InvalidArgumentException'); $loader->loadClassMetadata($metadata); } + public function provideInvalidYamlFiles() + { + return array( + array('nonvalid-mapping.yml'), + array('bad-format.yml'), + ); + } + /** * @see https://github.com/symfony/symfony/pull/12158 */ diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/bad-format.yml b/src/Symfony/Component/Validator/Tests/Mapping/Loader/bad-format.yml new file mode 100644 index 0000000000..d2b4ad2654 --- /dev/null +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/bad-format.yml @@ -0,0 +1,9 @@ +namespaces: + custom: Symfony\Component\Validator\Tests\Fixtures\ + +Symfony\Component\Validator\Tests\Fixtures\Entity: + constraints: + # Custom constraint + - Symfony\Component\Validator\Tests\Fixtures\ConstraintA: ~ + # Custom constraint with namespaces prefix + - "custom:ConstraintB": ~ From 92e50a3b14fca600933f73dd2f8201f86182dd1b Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 11 Sep 2015 14:29:54 +0200 Subject: [PATCH 09/19] [HttpKernel] fix DumpDataCollector compat with Twig 2.0 --- .../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 efb0bb3e6e..e0d7d50f6b 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php @@ -98,9 +98,9 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface } elseif (isset($trace[$i]['object']) && $trace[$i]['object'] instanceof \Twig_Template) { $info = $trace[$i]['object']; $name = $info->getTemplateName(); - $src = $info->getEnvironment()->getLoader()->getSource($name); + $src = method_exists($info, 'getSource') ? $info->getSource() : $info->getEnvironment()->getLoader()->getSource($name); $info = $info->getDebugInfo(); - if (isset($info[$trace[$i - 1]['line']])) { + if (null !== $src && isset($info[$trace[$i - 1]['line']])) { $file = false; $line = $info[$trace[$i - 1]['line']]; $src = explode("\n", $src); From f3d844434b2ad4d88273266fff388854406ec5af Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 12 Sep 2015 19:34:25 +0100 Subject: [PATCH 10/19] [Console] Ensure the console output is only detected as decorated when both stderr and stdout support colors --- src/Symfony/Component/Console/Output/ConsoleOutput.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Symfony/Component/Console/Output/ConsoleOutput.php b/src/Symfony/Component/Console/Output/ConsoleOutput.php index 50ef4df900..04bd51b782 100644 --- a/src/Symfony/Component/Console/Output/ConsoleOutput.php +++ b/src/Symfony/Component/Console/Output/ConsoleOutput.php @@ -48,7 +48,12 @@ class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface { parent::__construct($this->openOutputStream(), $verbosity, $decorated, $formatter); + $actualDecorated = $this->isDecorated(); $this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated, $this->getFormatter()); + + if (null === $decorated) { + $this->setDecorated($actualDecorated && $this->stderr->isDecorated()); + } } /** From 520bd26642cec313daac2fd3f51259d6fb96f3ca Mon Sep 17 00:00:00 2001 From: Jose Gonzalez Date: Sat, 12 Sep 2015 16:58:59 +0100 Subject: [PATCH 11/19] [Yaml] Fix the parsing of float keys --- src/Symfony/Component/Yaml/Parser.php | 5 +++++ .../Component/Yaml/Tests/ParserTest.php | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index 3c20c8662f..fd7ded094f 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -133,6 +133,11 @@ class Parser throw $e; } + // Convert float keys to strings, to avoid being converted to integers by PHP + if (is_float($key)) { + $key = (string) $key; + } + if ('<<' === $key) { if (isset($values['value']) && 0 === strpos($values['value'], '*')) { $isInPlace = substr($values['value'], 1); diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index d74bf18c1b..3054c807fd 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -685,6 +685,24 @@ bar: 2 EOF; $this->assertEquals(array('foo' => 1, 'bar' => 2), $this->parser->parse($yaml)); } + + public function testFloatKeys() + { + $yaml = << array( + '1.2' => 'bar', + '1.3' => 'baz', + ), + ); + + $this->assertEquals($expected, $this->parser->parse($yaml)); + } } class B From c7acde8024b4ada67c98e6b7a98defab7256b2f5 Mon Sep 17 00:00:00 2001 From: Lukas Kahwe Smith Date: Thu, 13 Aug 2015 16:33:53 +0200 Subject: [PATCH 12/19] [FrameworkBundle] add a suggest for the serializer component --- src/Symfony/Bundle/FrameworkBundle/composer.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 1ef5af58a1..68c03a912e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -45,10 +45,11 @@ "symfony/yaml": "~2.0,>=2.0.5" }, "suggest": { - "symfony/console": "", - "symfony/finder": "", - "symfony/form": "", - "symfony/validator": "" + "symfony/console": "For using the console commands", + "symfony/finder": "For using the translation loader and cache warmer", + "symfony/form": "For using forms", + "symfony/validator": "For using validation", + "symfony/serializer": "For using the serializer service", }, "autoload": { "psr-0": { "Symfony\\Bundle\\FrameworkBundle\\": "" } From 92ad5df5675393f5ddaf0b277b56894d45c0e87e Mon Sep 17 00:00:00 2001 From: Kirill Saksin Date: Wed, 3 Jun 2015 00:50:45 +0300 Subject: [PATCH 13/19] [DoctrineBridge] Fixed #14840 --- .../DependencyInjection/AbstractDoctrineExtension.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php index 1518361c79..7247bd5798 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php @@ -129,11 +129,15 @@ abstract class AbstractDoctrineExtension extends Extension */ protected function setMappingDriverConfig(array $mappingConfig, $mappingName) { - if (!is_dir($mappingConfig['dir'])) { + $mappingDirectory = $mappingConfig['dir']; + if (!is_dir($mappingDirectory)) { throw new \InvalidArgumentException(sprintf('Invalid Doctrine mapping path given. Cannot load Doctrine mapping/bundle named "%s".', $mappingName)); } - $this->drivers[$mappingConfig['type']][$mappingConfig['prefix']] = realpath($mappingConfig['dir']); + if (substr($mappingDirectory, 0, 7) !== 'phar://') { + $mappingDirectory = realpath($mappingDirectory); + } + $this->drivers[$mappingConfig['type']][$mappingConfig['prefix']] = $mappingDirectory; } /** From 06f97bfbd175ad681492176533cfe5611259b6b8 Mon Sep 17 00:00:00 2001 From: Sebastiaan Stok Date: Sun, 31 May 2015 13:21:21 +0200 Subject: [PATCH 14/19] [HttpKernel] fix broken multiline --- .../Component/HttpKernel/HttpCache/Esi.php | 4 ++-- .../HttpKernel/Tests/HttpCache/EsiTest.php | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/HttpCache/Esi.php b/src/Symfony/Component/HttpKernel/HttpCache/Esi.php index 58b6265656..8242bfadcf 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/Esi.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/Esi.php @@ -162,8 +162,8 @@ class Esi // we don't use a proper XML parser here as we can have ESI tags in a plain text response $content = $response->getContent(); - $content = preg_replace('#.*?#', '', $content); - $content = preg_replace('#]*(?:/|#', '', $content); + $content = preg_replace('#.*?#s', '', $content); + $content = preg_replace('#]+>#s', '', $content); $chunks = preg_split('##', $content, -1, PREG_SPLIT_DELIM_CAPTURE); $chunks[0] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[0]); diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/EsiTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/EsiTest.php index d1411f016b..e83996c2e2 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/EsiTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/EsiTest.php @@ -92,6 +92,28 @@ class EsiTest extends \PHPUnit_Framework_TestCase $this->assertFalse($response->headers->has('x-body-eval')); } + public function testMultilineEsiRemoveTagsAreRemoved() + { + $esi = new Esi(); + + $request = Request::create('/'); + $response = new Response(' www.example.com Keep this'."\n www.example.com And this"); + $esi->process($request, $response); + + $this->assertEquals(' Keep this And this', $response->getContent()); + } + + public function testCommentTagsAreRemoved() + { + $esi = new Esi(); + + $request = Request::create('/'); + $response = new Response(' Keep this'); + $esi->process($request, $response); + + $this->assertEquals(' Keep this', $response->getContent()); + } + public function testProcess() { $esi = new Esi(); From 18e9f45e8dd9753de5111471e5b4de698beb2fb6 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 14 Sep 2015 09:37:59 +0200 Subject: [PATCH 15/19] [Debug] Fix case mismatch detection --- .../Component/Debug/DebugClassLoader.php | 20 ++++++++++++++++--- .../Debug/Tests/DebugClassLoaderTest.php | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Debug/DebugClassLoader.php b/src/Symfony/Component/Debug/DebugClassLoader.php index c8e5d1a83f..37d15d1862 100644 --- a/src/Symfony/Component/Debug/DebugClassLoader.php +++ b/src/Symfony/Component/Debug/DebugClassLoader.php @@ -221,8 +221,22 @@ class DebugClassLoader throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file)); } - if (self::$caseCheck && preg_match('#(?:[/\\\\][a-zA-Z_\x7F-\xFF][a-zA-Z0-9_\x7F-\xFF]*+)++\.(?:php|hh)$#D', $file, $tail)) { - $tail = $tail[0]; + if (self::$caseCheck) { + $real = explode('\\', $class.strrchr($file, '.')); + $tail = explode(DIRECTORY_SEPARATOR, str_replace('/', DIRECTORY_SEPARATOR, $file)); + + $i = count($tail) - 1; + $j = count($real) - 1; + + while (isset($tail[$i], $real[$j]) && $tail[$i] === $real[$j]) { + --$i; + --$j; + } + + array_splice($tail, 0, $i + 1); + } + if (self::$caseCheck && $tail) { + $tail = DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $tail); $tailLen = strlen($tail); $real = $refl->getFileName(); @@ -289,7 +303,7 @@ class DebugClassLoader if (0 === substr_compare($real, $tail, -$tailLen, $tailLen, true) && 0 !== substr_compare($real, $tail, -$tailLen, $tailLen, false) ) { - throw new \RuntimeException(sprintf('Case mismatch between class and source file names: %s vs %s', $class, $real)); + throw new \RuntimeException(sprintf('Case mismatch between class and real file names: %s vs %s in %s', substr($tail, -$tailLen + 1), substr($real, -$tailLen + 1), substr($real, 0, -$tailLen + 1))); } } diff --git a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php index a368a7d257..1516dbedf9 100644 --- a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php +++ b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php @@ -136,7 +136,7 @@ class DebugClassLoaderTest extends \PHPUnit_Framework_TestCase /** * @expectedException \RuntimeException - * @expectedExceptionMessage Case mismatch between class and source file names + * @expectedExceptionMessage Case mismatch between class and real file names */ public function testFileCaseMismatch() { From c28796ed746cc5d61114cbd41e3cc2601b4311a8 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 8 Sep 2015 16:34:41 +0100 Subject: [PATCH 16/19] Use stderr by default when a specific output is not injected --- .../Bridge/Monolog/Handler/ConsoleHandler.php | 13 ++++----- .../Tests/Handler/ConsoleHandlerTest.php | 27 +------------------ 2 files changed, 8 insertions(+), 32 deletions(-) diff --git a/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php b/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php index a4c19cdb6a..592584ffa4 100644 --- a/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php @@ -120,7 +120,12 @@ class ConsoleHandler extends AbstractProcessingHandler implements EventSubscribe */ public function onCommand(ConsoleCommandEvent $event) { - $this->setOutput($event->getOutput()); + $output = $event->getOutput(); + if ($output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + + $this->setOutput($output); } /** @@ -149,11 +154,7 @@ class ConsoleHandler extends AbstractProcessingHandler implements EventSubscribe */ protected function write(array $record) { - if ($record['level'] >= Logger::ERROR && $this->output instanceof ConsoleOutputInterface) { - $this->output->getErrorOutput()->write((string) $record['formatted']); - } else { - $this->output->write((string) $record['formatted']); - } + $this->output->write((string) $record['formatted']); } /** diff --git a/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php b/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php index 65f259693b..6cb315967e 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php @@ -110,7 +110,7 @@ class ConsoleHandlerTest extends \PHPUnit_Framework_TestCase public function testWritingAndFormatting() { - $output = $this->getMock('Symfony\Component\Console\Output\ConsoleOutputInterface'); + $output = $this->getMock('Symfony\Component\Console\Output\OutputInterface'); $output ->expects($this->any()) ->method('getVerbosity') @@ -122,19 +122,6 @@ class ConsoleHandlerTest extends \PHPUnit_Framework_TestCase ->with('[2013-05-29 16:21:54] app.INFO: My info message '."\n") ; - $errorOutput = $this->getMock('Symfony\Component\Console\Output\OutputInterface'); - $errorOutput - ->expects($this->once()) - ->method('write') - ->with('[2013-05-29 16:21:54] app.ERROR: My error message '."\n") - ; - - $output - ->expects($this->any()) - ->method('getErrorOutput') - ->will($this->returnValue($errorOutput)) - ; - $handler = new ConsoleHandler(null, false); $handler->setOutput($output); @@ -149,18 +136,6 @@ class ConsoleHandlerTest extends \PHPUnit_Framework_TestCase ); $this->assertTrue($handler->handle($infoRecord), 'The handler finished handling the log as bubble is false.'); - - $errorRecord = array( - 'message' => 'My error message', - 'context' => array(), - 'level' => Logger::ERROR, - 'level_name' => Logger::getLevelName(Logger::ERROR), - 'channel' => 'app', - 'datetime' => new \DateTime('2013-05-29 16:21:54'), - 'extra' => array(), - ); - - $this->assertTrue($handler->handle($errorRecord), 'The handler finished handling the log as bubble is false.'); } public function testLogsFromListeners() From 50afff16471e8c829279548ae5c2b7ab1098bf4a Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Mon, 14 Sep 2015 14:10:47 +0200 Subject: [PATCH 17/19] [Console] fix typo in OutputInterface --- src/Symfony/Component/Console/Output/OutputInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Console/Output/OutputInterface.php b/src/Symfony/Component/Console/Output/OutputInterface.php index f7f30636fe..edffb9ca8e 100644 --- a/src/Symfony/Component/Console/Output/OutputInterface.php +++ b/src/Symfony/Component/Console/Output/OutputInterface.php @@ -48,7 +48,7 @@ interface OutputInterface /** * Writes a message to the output and adds a newline at the end. * - * @param string|array $messages The message as an array of lines of a single string + * @param string|array $messages The message as an array of lines or a single string * @param int $type The type of output (one of the OUTPUT constants) * * @throws \InvalidArgumentException When unknown output type is given From c0363524a987c624f2b1627696c60d77c8bba313 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Mon, 14 Sep 2015 14:22:54 +0200 Subject: [PATCH 18/19] [Console] update param type phpdoc for StreamOutput --- src/Symfony/Component/Console/Output/StreamOutput.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Console/Output/StreamOutput.php b/src/Symfony/Component/Console/Output/StreamOutput.php index 6a8305c709..86fe1827e9 100644 --- a/src/Symfony/Component/Console/Output/StreamOutput.php +++ b/src/Symfony/Component/Console/Output/StreamOutput.php @@ -35,7 +35,7 @@ class StreamOutput extends Output /** * Constructor. * - * @param mixed $stream A stream resource + * @param resource $stream A stream resource * @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface) * @param bool|null $decorated Whether to decorate messages (null for auto-guessing) * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter) From dc57a7a5a7670b3103f1882845bfdb07138422db Mon Sep 17 00:00:00 2001 From: Daniel Tschinder Date: Wed, 25 Feb 2015 22:18:34 +0100 Subject: [PATCH 19/19] [DomCrawler] Invalid uri created from forms if base tag present --- src/Symfony/Component/DomCrawler/Crawler.php | 2 +- src/Symfony/Component/DomCrawler/Form.php | 13 ++++++++++++- .../Component/DomCrawler/Tests/CrawlerTest.php | 3 +++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/DomCrawler/Crawler.php b/src/Symfony/Component/DomCrawler/Crawler.php index 823f135239..84ce8f3f8d 100644 --- a/src/Symfony/Component/DomCrawler/Crawler.php +++ b/src/Symfony/Component/DomCrawler/Crawler.php @@ -755,7 +755,7 @@ class Crawler extends \SplObjectStorage throw new \InvalidArgumentException('The current node list is empty.'); } - $form = new Form($this->getNode(0), $this->uri, $method); + $form = new Form($this->getNode(0), $this->uri, $method, $this->baseHref); if (null !== $values) { $form->setValues($values); diff --git a/src/Symfony/Component/DomCrawler/Form.php b/src/Symfony/Component/DomCrawler/Form.php index b0462f098f..a447c830d5 100644 --- a/src/Symfony/Component/DomCrawler/Form.php +++ b/src/Symfony/Component/DomCrawler/Form.php @@ -33,20 +33,27 @@ class Form extends Link implements \ArrayAccess */ private $fields; + /** + * @var string + */ + private $baseHref; + /** * Constructor. * * @param \DOMNode $node A \DOMNode instance * @param string $currentUri The URI of the page where the form is embedded * @param string $method The method to use for the link (if null, it defaults to the method defined by the form) + * @param string $baseHref The URI of the used for relative links, but not for empty action * * @throws \LogicException if the node is not a button inside a form tag * * @api */ - public function __construct(\DOMNode $node, $currentUri, $method = null) + public function __construct(\DOMNode $node, $currentUri, $method = null, $baseHref = null) { parent::__construct($node, $currentUri, $method); + $this->baseHref = $baseHref; $this->initialize(); } @@ -442,6 +449,10 @@ class Form extends Link implements \ArrayAccess $this->addField($node); } } + + if ($this->baseHref && '' !== $this->node->getAttribute('action')) { + $this->currentUri = $this->baseHref; + } } private function addField(\DOMNode $node) diff --git a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php index 9906fedc7e..ca7802d45d 100644 --- a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php +++ b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php @@ -853,9 +853,12 @@ HTML; public function getBaseTagWithFormData() { return array( + array('https://base.com/', 'link/', 'https://base.com/link/', 'https://base.com/link/', ' tag does work with a path and relative form action'), array('/basepath', '/registration', 'http://domain.com/registration', 'http://domain.com/registration', ' tag does work with a path and form action'), array('/basepath', '', 'http://domain.com/registration', 'http://domain.com/registration', ' tag does work with a path and empty form action'), + array('http://base.com/', '/registration', 'http://base.com/registration', 'http://domain.com/registration', ' tag does work with a URL and form action'), array('http://base.com', '', 'http://domain.com/path/form', 'http://domain.com/path/form', ' tag does work with a URL and an empty form action'), + array('http://base.com/path', '/registration', 'http://base.com/registration', 'http://domain.com/path/form', ' tag does work with a URL and form action'), ); }