Quellcode durchsuchen

fixed fallback catalogue mechanism in Framework bundle

Fabien Potencier vor 13 Jahren
Ursprung
Commit
c13b4e2b55

+ 126 - 0
src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php

@@ -0,0 +1,126 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\FrameworkBundle\Tests\Translation;
+
+use Symfony\Bundle\FrameworkBundle\Translation\Translator;
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\HttpKernel\Util\Filesystem;
+
+class TranslatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $tmpDir;
+
+    public function setUp()
+    {
+        $this->tmpDir = sys_get_temp_dir().'/sf2_translation';
+        $this->deleteTmpDir();
+    }
+
+    public function tearDown()
+    {
+        $this->deleteTmpDir();
+    }
+
+    protected function deleteTmpDir()
+    {
+        if (!file_exists($dir = $this->tmpDir)) {
+            return;
+        }
+
+        $fs = new Filesystem();
+        $fs->remove($dir);
+    }
+
+    public function testTransWithoutCaching()
+    {
+        $translator = $this->getTranslator($this->getLoader());
+        $translator->setLocale('fr');
+        $translator->setFallbackLocale('en');
+
+        $this->assertEquals('foo (FR)', $translator->trans('foo'));
+        $this->assertEquals('bar (EN)', $translator->trans('bar'));
+    }
+
+    public function testTransWithCaching()
+    {
+        // prime the cache
+        $translator = $this->getTranslator($this->getLoader(), array('cache_dir' => $this->tmpDir));
+        $translator->setLocale('fr');
+        $translator->setFallbackLocale('en');
+
+        $this->assertEquals('foo (FR)', $translator->trans('foo'));
+        $this->assertEquals('bar (EN)', $translator->trans('bar'));
+
+        // do it another time as the cache is primed now
+        $loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
+        $translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir));
+        $translator->setLocale('fr');
+        $translator->setFallbackLocale('en');
+
+        $this->assertEquals('foo (FR)', $translator->trans('foo'));
+        $this->assertEquals('bar (EN)', $translator->trans('bar'));
+    }
+
+    protected function getCatalogue($locale, $messages)
+    {
+        $catalogue = new MessageCatalogue($locale);
+        foreach ($messages as $key => $translation) {
+            $catalogue->set($key, $translation);
+        }
+
+        return $catalogue;
+    }
+
+    protected function getLoader()
+    {
+        $loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
+        $loader
+            ->expects($this->at(0))
+            ->method('load')
+            ->will($this->returnValue($this->getCatalogue('fr', array('foo' => 'foo (FR)'))))
+        ;
+        $loader
+            ->expects($this->at(1))
+            ->method('load')
+            ->will($this->returnValue($this->getCatalogue('en', array('foo' => 'foo (EN)', 'bar' => 'bar (EN)'))))
+        ;
+
+        return $loader;
+    }
+
+    protected function getContainer($loader)
+    {
+        $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
+        $container
+            ->expects($this->any())
+            ->method('get')
+            ->will($this->returnValue($loader))
+        ;
+
+        return $container;
+    }
+
+    public function getTranslator($loader, $options = array())
+    {
+        $translator = new Translator(
+            $this->getContainer($loader),
+            $this->getMock('Symfony\Component\Translation\MessageSelector'),
+            array('loader' => 'loader'),
+            $options
+        );
+
+        $translator->addResource('loader', 'foo', 'fr');
+        $translator->addResource('loader', 'foo', 'en');
+
+        return $translator;
+    }
+}

+ 27 - 3
src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php

@@ -98,10 +98,34 @@ class Translator extends BaseTranslator
 
             parent::loadCatalogue($locale);
 
-            $content = sprintf(
-                "<?php use Symfony\Component\Translation\MessageCatalogue; return new MessageCatalogue('%s', %s);",
+            $fallbackContent = '';
+            $fallback = $this->computeFallbackLocale($locale);
+            if ($fallback && $fallback != $locale) {
+                $fallbackContent = sprintf(<<<EOF
+\$catalogue->addFallbackCatalogue(new MessageCatalogue('%s', %s));
+EOF
+                    ,
+                    $fallback,
+                    var_export($this->catalogues[$fallback]->all(), true)
+                );
+            }
+
+            $content = sprintf(<<<EOF
+<?php
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+\$catalogue = new MessageCatalogue('%s', %s);
+
+%s
+
+return \$catalogue;
+
+EOF
+                ,
                 $locale,
-                var_export($this->catalogues[$locale]->all(), true)
+                var_export($this->catalogues[$locale]->all(), true),
+                $fallbackContent
             );
 
             $cache->write($content, $this->catalogues[$locale]->getResources());

+ 11 - 11
src/Symfony/Component/Translation/Translator.php

@@ -167,10 +167,19 @@ class Translator implements TranslatorInterface
             }
         }
 
-        $this->optimizeCatalogue($locale);
+        $this->addFallbackCatalogue($locale);
     }
 
-    private function optimizeCatalogue($locale)
+    protected function computeFallbackLocale($locale)
+    {
+        if (strlen($locale) > 3) {
+            return substr($locale, 0, -strlen(strrchr($locale, '_')));
+        } else {
+            return $this->fallbackLocale;
+        }
+    }
+
+    private function addFallbackCatalogue($locale)
     {
         if (!$fallback = $this->computeFallbackLocale($locale)) {
             return;
@@ -184,13 +193,4 @@ class Translator implements TranslatorInterface
             $this->catalogues[$locale]->addFallbackCatalogue($this->catalogues[$fallback]);
         }
     }
-
-    private function computeFallbackLocale($locale)
-    {
-        if (strlen($locale) > 3) {
-            return substr($locale, 0, -strlen(strrchr($locale, '_')));
-        } else {
-            return $this->fallbackLocale;
-        }
-    }
 }