Browse Source

set or disable fallback domain for i18n

Schlaefer 10 years ago
parent
commit
2676242641
3 changed files with 102 additions and 3 deletions
  1. 14 0
      src/I18n/I18n.php
  2. 34 3
      src/I18n/TranslatorRegistry.php
  3. 54 0
      tests/TestCase/I18n/I18nTest.php

+ 14 - 0
src/I18n/I18n.php

@@ -238,6 +238,20 @@ class I18n
     }
 
     /**
+     * Set default fallback domain. If a domain can't provide a translation
+     * messages from the fallback domain are used.
+     *
+     * Get the currently set domain if argument is null.
+     *
+     * @param string|null $name name of the fallback-translator
+     * @return string
+     */
+    public static function defaultFallbackDomain($name = null)
+    {
+        return static::translators()->defaultFallbackDomain($name);
+    }
+
+    /**
      * Sets the name of the default messages formatter to use for future
      * translator instances. By default the `default` and `sprintf` formatters
      * are available.

+ 34 - 3
src/I18n/TranslatorRegistry.php

@@ -43,6 +43,17 @@ class TranslatorRegistry extends TranslatorLocator
     protected $_defaultFormatter = 'default';
 
     /**
+     * Domain used used as fallback if translation isn't found in specified domain.
+     *
+     * - true: 'default'
+     * - false: disable translation fallback
+     * - string: fallback domain name
+     *
+     * @var string|bool
+     */
+    protected $_defaultFallbackDomain = 'default';
+
+    /**
      * A CacheEngine object that is used to remember translator across
      * requests.
      *
@@ -155,6 +166,22 @@ class TranslatorRegistry extends TranslatorLocator
     }
 
     /**
+     * Set fallback domain. Messages from the fallback domain are used if
+     * a domain can't provide a localization message.
+     *
+     * Get the currently set domain if argument is null.
+     *
+     * @param string|null $name fallback domain
+     * @return string
+     */
+    public function defaultFallbackDomain($name = null) {
+        if ($name === null) {
+            return $this->_defaultFallbackDomain;
+        }
+        return $this->_defaultFallbackDomain = $name;
+    }
+
+    /**
      * Returns a new translator instance for the given name and locale
      * based of conventions.
      *
@@ -226,11 +253,15 @@ class TranslatorRegistry extends TranslatorLocator
      * @return callable loader
      */
     public function setLoaderFallback($name, callable $loader) {
-        if ($name !== 'default') {
+        if ($name !== $this->_defaultFallbackDomain) {
             $loader = function () use ($loader) {
                 $package = $loader();
-                if (!$package->getFallback()) {
-                    $package->setFallback('default');
+                if ($this->_defaultFallbackDomain !== false && !$package->getFallback()) {
+                    $fallback = $this->_defaultFallbackDomain;
+                    if ($fallback === true) {
+                        $fallback = 'default';
+                    }
+                    $package->setFallback($fallback);
                 }
                 return $package;
             };

+ 54 - 0
tests/TestCase/I18n/I18nTest.php

@@ -514,6 +514,60 @@ class I18nTest extends TestCase
     }
 
     /**
+     * Test that the fallback translators can be disabled
+     *
+     * @return void
+     */
+    public function testFallbackTranslatorFallbackDisabled()
+    {
+        I18n::defaultFallbackDomain(false);
+        I18n::translator('default', 'en_US', function () {
+            $package = new Package('default');
+            $package->setMessages(['Dog' => 'bark']);
+
+            return $package;
+        });
+        I18n::translator('custom', 'en_US',
+            function () {
+                $package = new Package('default');
+                $package->setMessages([]);
+
+                return $package;
+            }
+        );
+        $result = __d('custom', 'Dog');
+        $this->assertEquals('Dog', $result);
+    }
+
+    /**
+     * Test that an arbitrary fallback domain can be set
+     *
+     * @return void
+     */
+    public function testFallbackTranslatorCustomDomain()
+    {
+        $customDomain = 'foo';
+        I18n::defaultFallbackDomain($customDomain);
+        I18n::translator($customDomain, 'en_US', function () {
+            $package = new Package('default');
+            $package->setMessages(['Dog' => 'bark']);
+
+            return $package;
+        });
+        I18n::translator('custom', 'en_US',
+            function () {
+                $package = new Package('default');
+                $package->setMessages([]);
+
+                return $package;
+            }
+        );
+        $result = __d('custom', 'Dog');
+        $this->assertEquals('bark', $result);
+    }
+
+
+    /**
      * Tests that it is possible to register a generic translators factory for a domain
      * instead of having to create them manually
      *