diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php
index fba3dd4285..063b9359c7 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;
}
/**
diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php
index 6e16240d29..fe0ad19367 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;
/**
* Loads entities using a {@link QueryBuilder} instance.
@@ -43,7 +43,7 @@ class ORMQueryBuilderLoader implements EntityLoaderInterface
* deprecated and will not be
* supported anymore as of
* Symfony 3.0.
- * @param EntityManager $manager Deprecated.
+ * @param ObjectManager $manager Deprecated.
* @param string $class Deprecated.
*
* @throws UnexpectedTypeException
@@ -59,8 +59,8 @@ class ORMQueryBuilderLoader implements EntityLoaderInterface
if ($queryBuilder instanceof \Closure) {
@trigger_error('Passing a QueryBuilder closure to '.__CLASS__.'::__construct() is deprecated since version 2.7 and will be removed in 3.0.', E_USER_DEPRECATED);
- if (!$manager instanceof EntityManager) {
- throw new UnexpectedTypeException($manager, 'Doctrine\ORM\EntityManager');
+ if (!$manager instanceof ObjectManager) {
+ throw new UnexpectedTypeException($manager, 'Doctrine\Common\Persistence\ObjectManager');
}
@trigger_error('Passing an EntityManager to '.__CLASS__.'::__construct() is deprecated since version 2.7 and will be removed in 3.0.', E_USER_DEPRECATED);
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()
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;
+ }
+}
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);
}
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json
index d191b010e7..eafa086d4f 100644
--- a/src/Symfony/Bundle/FrameworkBundle/composer.json
+++ b/src/Symfony/Bundle/FrameworkBundle/composer.json
@@ -52,6 +52,7 @@
"symfony/console": "For using the console commands",
"symfony/finder": "For using the translation loader and cache warmer",
"symfony/form": "For using forms",
+ "symfony/serializer": "For using the serializer service",
"symfony/validator": "For using validation",
"symfony/yaml": "For using the debug:config and lint:yaml commands",
"doctrine/cache": "For using alternative cache drivers"
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 e4fea4b00b..53ca5591d3 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 %}