diff --git a/src/I18n/ChainMessagesLoader.php b/src/I18n/ChainMessagesLoader.php new file mode 100644 index 00000000000..1404e2a2bf0 --- /dev/null +++ b/src/I18n/ChainMessagesLoader.php @@ -0,0 +1,61 @@ +_loaders = $loaders; + } + + public function __invoke() { + foreach ($this->_loaders as $k => $loader) { + if (!is_callable($loader)) { + throw new \RuntimeException( + sprintf('Loader "%s" in the chain is not a valid callable'), + $k + ); + } + + $package = $loader(); + + if (!$package) { + continue; + } + + if (!($package instanceof Package)) { + throw new \RuntimeException( + sprintf('Loader "%s" in the chain did not return a valid Package object'), + $k + ); + } + + if (count($package->getMessages())) { + return $package; + } + } + + return new Package; + } + +} diff --git a/src/I18n/I18n.php b/src/I18n/I18n.php index edb5971220f..533473c76a1 100644 --- a/src/I18n/I18n.php +++ b/src/I18n/I18n.php @@ -64,11 +64,19 @@ public static function translator($package = 'default', $locale = null, callable try { return static::translators()->get($package); } catch (LoadException $e) { - static::translator($package, $locale, new MessagesFileLoader($package, $locale)); - return static::translators()->get($package); + return static::_fallbackTranslator($package, $locale); } } + protected static function _fallbackTranslator($package, $locale) { + $chain = new ChainMessagesLoader([ + new MessagesFileLoader($package, $locale, 'mo'), + new MessagesFileLoader($package, $locale, 'po') + ]); + static::translator($package, $locale, $chain); + return static::translators()->get($package); + } + /** * Used by the translation functions in basics.php * Returns a translated string based on current language and translation files stored in locale folder diff --git a/tests/TestCase/I18n/I18nTest.php b/tests/TestCase/I18n/I18nTest.php index 02eb91161f5..a78a4d3993f 100644 --- a/tests/TestCase/I18n/I18nTest.php +++ b/tests/TestCase/I18n/I18nTest.php @@ -37,4 +37,13 @@ public function testDefaultTranslator() { $this->assertEquals('%d is 1 (po translated)', $translator->translate('%d = 1')); } +/** + * Tests that the translator can automatically load messages from a .mo file + * + * @return void + */ + public function testTranslatorLoadMoFile() { + $translator = I18n::translator('default', 'es_ES'); + $this->assertEquals('Plural Rule 6 (translated)', $translator->translate('Plural Rule 1')); + } } diff --git a/tests/test_app/TestApp/Locale/rule_6_mo/LC_MESSAGES/default.mo b/tests/test_app/TestApp/Locale/es/LC_MESSAGES/default.mo similarity index 100% rename from tests/test_app/TestApp/Locale/rule_6_mo/LC_MESSAGES/default.mo rename to tests/test_app/TestApp/Locale/es/LC_MESSAGES/default.mo