Selaa lähdekoodia

[Translation] fixed transchoice when used with a fallback

Fabien Potencier 13 vuotta sitten
vanhempi
commit
c50a3a194d

+ 11 - 8
src/Symfony/Component/Translation/MessageCatalogue.php

@@ -25,6 +25,7 @@ class MessageCatalogue implements MessageCatalogueInterface
     private $messages = array();
     private $locale;
     private $resources;
+    private $fallbackCatalogue;
 
     /**
      * Constructor.
@@ -102,7 +103,15 @@ class MessageCatalogue implements MessageCatalogueInterface
      */
     public function get($id, $domain = 'messages')
     {
-        return isset($this->messages[$domain][$id]) ? $this->messages[$domain][$id] : $id;
+        if (isset($this->messages[$domain][$id])) {
+            return $this->messages[$domain][$id];
+        }
+
+        if (null !== $this->fallbackCatalogue) {
+            return $this->fallbackCatalogue->get($id, $domain);
+        }
+
+        return $id;
     }
 
     /**
@@ -158,13 +167,7 @@ class MessageCatalogue implements MessageCatalogueInterface
      */
     public function addFallbackCatalogue(MessageCatalogueInterface $catalogue)
     {
-        foreach ($catalogue->getDomains() as $domain) {
-            foreach ($catalogue->all($domain) as $id => $translation) {
-                if (false === $this->has($id, $domain)) {
-                    $this->set($id, $translation, $domain);
-                }
-            }
-        }
+        $this->fallbackCatalogue = $catalogue;
 
         foreach ($catalogue->getResources() as $resource) {
             $this->addResource($resource);

+ 15 - 7
src/Symfony/Component/Translation/Translator.php

@@ -142,6 +142,11 @@ class Translator implements TranslatorInterface
             $this->loadCatalogue($locale);
         }
 
+        if (!$this->catalogues[$locale]->has((string) $id, $domain)) {
+            // we will use the fallback
+            $locale = $this->computeFallbackLocale($locale);
+        }
+
         return strtr($this->selector->choose($this->catalogues[$locale]->get((string) $id, $domain), (int) $number, $locale), $parameters);
     }
 
@@ -163,13 +168,7 @@ class Translator implements TranslatorInterface
 
     private function optimizeCatalogue($locale)
     {
-        if (strlen($locale) > 3) {
-            $fallback = substr($locale, 0, -strlen(strrchr($locale, '_')));
-        } else {
-            $fallback = $this->fallbackLocale;
-        }
-
-        if (!$fallback) {
+        if (!$fallback = $this->computeFallbackLocale($locale)) {
             return;
         }
 
@@ -179,4 +178,13 @@ 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;
+        }
+    }
 }

+ 10 - 0
tests/Symfony/Tests/Component/Translation/TranslatorTest.php

@@ -163,6 +163,16 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
             array('Il y a 0 pomme', new String('{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples'), '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''),
         );
     }
+
+    public function testTransChoiceFallback()
+    {
+        $translator = new Translator('ru', new MessageSelector());
+        $translator->setFallbackLocale('en');
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('some_message2' => 'one thing|%count% things'), 'en');
+
+        $this->assertEquals('10 things', $translator->transChoice('some_message2', 10, array('%count%' => 10)));
+    }
 }
 
 class String