Bläddra i källkod

[ZF-2736] Zend_Translate:

- FEATURE: added routing for translations

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@22181 44c647ce-9c0f-0410-b52a-842ac1e357ba
thomas 15 år sedan
förälder
incheckning
4bff381e6b

+ 53 - 0
documentation/manual/en/module_specs/Zend_Translate-Additional.xml

@@ -194,6 +194,20 @@ $translate->addTranslation(
                     </row>
 
                     <row>
+                        <entry>route</entry>
+                        <entry>all</entry>
+
+                        <entry>
+                            This option allows to use reroute from non existing translations to
+                            other languages. See the <link
+                                linkend="zend.translate.additional.rerouting">Rerouting
+                                Section</linkend> for details about this option.
+                        </entry>
+
+                        <entry><emphasis><constant>NULL</constant></emphasis></entry>
+                    </row>
+
+                    <row>
                         <entry>scan</entry>
                         <entry>all</entry>
 
@@ -855,6 +869,45 @@ $translate = new Zend_Translate(
         </sect3>
     </sect2>
 
+    <sect2 id="zend.translate.additional.rerouting">
+        <title>Routing for translations</title>
+
+        <para>
+            Not every message ID can be translated. But sometimes is can be useful to output the
+            translation from another language instead of returning the message ID itself. You can
+            archive this by using the <property>route</property> option.
+        </para>
+
+        <para>
+            You can add one route for every language. See the following example:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$translate = new Zend_Translate(
+    array(
+        'adapter' => $adapter,
+        'content' => $content,
+        'locale'  => $locale,
+        'route'   => array('fr' => 'en', 'de' => 'fr')
+    )
+);
+]]></programlisting>
+
+        <para>
+            The above returns a english translation for all messages which can not be translated to
+            french. And it returns a french translation for all messages which can not be translated
+            to german. It will even return an english translation for all messages which can wether
+            be translated to german nor to french. So you can even define a complete translation
+            chain.
+        </para>
+
+        <para>
+            This feature seems ot be interesting for anyone. But be aware that returning
+            translations for wrong or other languages can be problematic when the user does not
+            understand this language. So you should always use this feature sparingly.
+        </para>
+    </sect2>
+
     <sect2 id="zend.translate.additional.combination">
         <title>Combining multiple translation sources</title>
 

+ 29 - 0
library/Zend/Translate/Adapter.php

@@ -47,6 +47,12 @@ abstract class Zend_Translate_Adapter {
     private $_automatic = true;
 
     /**
+     * Internal value to see already routed languages
+     * @var array()
+     */
+    private $_routed = array();
+
+    /**
      * Internal cache for all adapters
      * @var Zend_Cache_Core
      */
@@ -89,6 +95,7 @@ abstract class Zend_Translate_Adapter {
         'logMessage'      => "Untranslated message within '%locale%': %message%",
         'logUntranslated' => false,
         'reload'          => false,
+        'route'           => null,
         'scan'            => null
     );
 
@@ -670,6 +677,17 @@ abstract class Zend_Translate_Adapter {
             if (!Zend_Locale::isLocale($locale, false, false)) {
                 // language does not exist, return original string
                 $this->_log($messageId, $locale);
+                // use rerouting when enabled
+                if (!empty($this->_options['route'])) {
+                    if (array_key_exists($locale, $this->_options['route']) &&
+                        !array_key_exists($locale, $this->_routed)) {
+                        $this->_routed[$locale] = true;
+                        return $this->translate($messageId, $this->_options['route'][$locale]);
+                    }
+
+                    $this->_routed = array();
+                }
+
                 if ($plural === null) {
                     return $messageId;
                 }
@@ -714,6 +732,17 @@ abstract class Zend_Translate_Adapter {
         }
 
         $this->_log($messageId, $locale);
+        // use rerouting when enabled
+        if (!empty($this->_options['route'])) {
+            if (array_key_exists($locale, $this->_options['route']) &&
+                !array_key_exists($locale, $this->_routed)) {
+                $this->_routed[$locale] = true;
+                return $this->translate($messageId, $this->_options['route'][$locale]);
+            }
+
+            $this->_routed = array();
+        }
+
         if ($plural === null) {
             return $messageId;
         }

+ 68 - 1
tests/Zend/TranslateTest.php

@@ -680,7 +680,7 @@ class Zend_TranslateTest extends PHPUnit_Framework_TestCase
     /**
      * @group ZF-9489
      */
-    public function testAddingAdapterToSourcealsUsingOwnRule()
+    public function testAddingAdapterToSourceUsingOwnRule()
     {
         $translate = new Zend_Translate(
             Zend_Translate::AN_ARRAY,
@@ -744,6 +744,73 @@ class Zend_TranslateTest extends PHPUnit_Framework_TestCase
     }
 
     /**
+     * @group ZF-2736
+     */
+    public function testReroutingForTranslations()
+    {
+        $translate = new Zend_Translate(
+            array(
+                'adapter' => Zend_Translate::AN_ARRAY,
+                'content' => dirname(__FILE__) . '/Translate/Adapter/_files/testArray/',
+                'locale'  => 'auto',
+                'scan'    => Zend_Translate::LOCALE_FILENAME,
+                'ignore'  => array('.', 'ignoreme', 'LC_TEST'),
+                'route'   => array('ja' => 'de_AT'),
+            )
+        );
+
+        $translate2 = new Zend_Translate(
+            array(
+                'adapter' => Zend_Translate::AN_CSV,
+                'content' => dirname(__FILE__) . '/Translate/Adapter/_files/translation_en.csv',
+                'locale'  => 'en_US',
+            )
+        );
+
+        $translate->addTranslation($translate2);
+
+        $langs = $translate->getList();
+        $this->assertFalse(array_key_exists('de_DE', $langs));
+        $this->assertTrue(array_key_exists('ja', $langs));
+        $this->assertTrue(array_key_exists('en_US', $langs));
+        $this->assertEquals('Message 5 (en)', $translate->translate('Message 5', 'ja'));
+    }
+
+    /**
+     * @group ZF-2736
+     */
+    public function testCircleReroutingForTranslations()
+    {
+        $translate = new Zend_Translate(
+            array(
+                'adapter' => Zend_Translate::AN_ARRAY,
+                'content' => dirname(__FILE__) . '/Translate/Adapter/_files/testArray/',
+                'locale'  => 'auto',
+                'scan'    => Zend_Translate::LOCALE_FILENAME,
+                'ignore'  => array('.', 'ignoreme', 'LC_TEST'),
+                'route'   => array('ja' => 'de_AT', 'de_AT' => 'ja'),
+            )
+        );
+
+        $translate2 = new Zend_Translate(
+            array(
+                'adapter' => Zend_Translate::AN_CSV,
+                'content' => dirname(__FILE__) . '/Translate/Adapter/_files/translation_en.csv',
+                'locale'  => 'en_US',
+            )
+        );
+
+        $translate->addTranslation($translate2);
+
+        $langs = $translate->getList();
+        $this->assertFalse(array_key_exists('de_DE', $langs));
+        $this->assertTrue(array_key_exists('ja', $langs));
+        $this->assertTrue(array_key_exists('en_US', $langs));
+        $this->assertEquals('Message 5 (en)', $translate->translate('Message 5', 'ja'));
+        $this->assertEquals('Message 10', $translate->translate('Message 10', 'ja'));
+    }
+
+    /**
      * Ignores a raised PHP error when in effect, but throws a flag to indicate an error occurred
      *
      * @param  integer $errno