mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-05-10 04:24:14 +09:00
commit
97a1b578a2
2 changed files with 218 additions and 147 deletions
|
|
@ -108,70 +108,52 @@ class Lang
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the language file.
|
// Initialize variables.
|
||||||
$lang = $this->getPluginLang($dir);
|
$filename = null;
|
||||||
|
$lang = new \stdClass;
|
||||||
|
$result = true;
|
||||||
|
|
||||||
// Load the default language file.
|
// Find a suitable language file in the given directory.
|
||||||
|
if (file_exists($dir . '/' . $this->_language . '.php'))
|
||||||
|
{
|
||||||
|
$filename = $dir . '/' . $this->_language . '.php';
|
||||||
|
}
|
||||||
|
elseif (($hyphen = strpos($this->_language, '-')) !== false && file_exists($dir . '/' . substr($this->_language, 0, $hyphen) . '.php'))
|
||||||
|
{
|
||||||
|
$filename = $dir . '/' . substr($this->_language, 0, $hyphen) . '.php';
|
||||||
|
}
|
||||||
|
elseif (file_exists("$dir/lang.xml"))
|
||||||
|
{
|
||||||
|
$filename = Parsers\LangParser::compileXMLtoPHP("$dir/lang.xml", $this->_language === 'ja' ? 'jp' : $this->_language);
|
||||||
|
}
|
||||||
|
elseif (file_exists($dir . '/' . ($this->_language === 'ja' ? 'jp' : $this->_language) . '.lang.php'))
|
||||||
|
{
|
||||||
|
$filename = $dir . '/' . ($this->_language === 'ja' ? 'jp' : $this->_language) . '.lang.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the language file.
|
||||||
|
if ($filename)
|
||||||
|
{
|
||||||
|
include $filename;
|
||||||
|
array_unshift($this->_search_priority, $plugin_name);
|
||||||
|
$result = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark this directory and plugin as loaded.
|
||||||
|
$this->_loaded_directories[$dir] = true;
|
||||||
|
$this->_loaded_plugins[$plugin_name] = $lang;
|
||||||
|
|
||||||
|
// Load the same directory in the default language, too.
|
||||||
if ($this->_language !== 'en')
|
if ($this->_language !== 'en')
|
||||||
{
|
{
|
||||||
self::getInstance('en')->loadDirectory($dir, $plugin_name);
|
self::getInstance('en')->loadDirectory($dir, $plugin_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($lang))
|
return $result;
|
||||||
{
|
|
||||||
$this->_loaded_directories[$dir] = true;
|
|
||||||
$this->_loaded_plugins[$plugin_name] = $lang;
|
|
||||||
array_unshift($this->_search_priority, $plugin_name);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->_loaded_directories[$dir] = true;
|
|
||||||
$this->_loaded_plugins[$plugin_name] = new \stdClass;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the language file from plugin.
|
|
||||||
*
|
|
||||||
* @param string $dir
|
|
||||||
* @param string $language
|
|
||||||
* @return object
|
|
||||||
*/
|
|
||||||
public function getPluginLang($dir, $language = null)
|
|
||||||
{
|
|
||||||
if (!$language)
|
|
||||||
{
|
|
||||||
$language = $this->_language;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file_exists($dir . '/' . $language . '.php'))
|
|
||||||
{
|
|
||||||
$filename = $dir . '/' . $language . '.php';
|
|
||||||
}
|
|
||||||
elseif (($hyphen = strpos($language, '-')) !== false && file_exists($dir . '/' . substr($language, 0, $hyphen) . '.php'))
|
|
||||||
{
|
|
||||||
$filename = $dir . '/' . substr($language, 0, $hyphen) . '.php';
|
|
||||||
}
|
|
||||||
elseif (file_exists("$dir/lang.xml"))
|
|
||||||
{
|
|
||||||
$filename = Parsers\LangParser::compileXMLtoPHP("$dir/lang.xml", $language === 'ja' ? 'jp' : $language);
|
|
||||||
}
|
|
||||||
elseif (file_exists($dir . '/' . ($language === 'ja' ? 'jp' : $language) . '.lang.php'))
|
|
||||||
{
|
|
||||||
$filename = $dir . '/' . ($language === 'ja' ? 'jp' : $language) . '.lang.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$filename)
|
|
||||||
{
|
|
||||||
return new \stdClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
$lang = new \stdClass;
|
|
||||||
include $filename;
|
|
||||||
|
|
||||||
return $lang;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -194,7 +176,19 @@ class Lang
|
||||||
{
|
{
|
||||||
$args = func_get_args();
|
$args = func_get_args();
|
||||||
array_shift($args);
|
array_shift($args);
|
||||||
return $this->__call($key, $args);
|
if (count($args) === 1 && is_array($args[0]))
|
||||||
|
{
|
||||||
|
$args = $args[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the translation.
|
||||||
|
$translation = $this->__get($key);
|
||||||
|
|
||||||
|
// If there are no arguments, return the translation.
|
||||||
|
if (!count($args)) return $translation;
|
||||||
|
|
||||||
|
// If there are arguments, interpolate them into the translation and return the result.
|
||||||
|
return vsprintf($translation, $args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -209,6 +203,24 @@ class Lang
|
||||||
$this->__set($key, $value);
|
$this->__set($key, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fallback method for getting the default translation.
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getFromDefaultLang($key)
|
||||||
|
{
|
||||||
|
if ($this->_language === 'en')
|
||||||
|
{
|
||||||
|
return $key;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return self::getInstance('en')->__get($key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Magic method for translations without arguments.
|
* Magic method for translations without arguments.
|
||||||
*
|
*
|
||||||
|
|
@ -217,51 +229,45 @@ class Lang
|
||||||
*/
|
*/
|
||||||
public function __get($key)
|
public function __get($key)
|
||||||
{
|
{
|
||||||
// Get default language
|
// Load a dot-separated key (prefixed by plugin name).
|
||||||
if ($this->_language !== 'en')
|
if (preg_match('/^[a-z0-9_.-]+$/i', $key) && ($keys = explode('.', $key)) && count($keys) >= 2)
|
||||||
{
|
{
|
||||||
$lang_en = self::getInstance('en')->{$key};
|
// Attempt to load the plugin.
|
||||||
}
|
$plugin_name = array_shift($keys);
|
||||||
|
|
||||||
// Separate the plugin name from the key.
|
|
||||||
if (preg_match('/^[a-z0-9_.-]+$/i', $key) && ($keys = explode('.', $key, 2)) && count($keys) === 2)
|
|
||||||
{
|
|
||||||
list($plugin_name, $lang_key) = $keys;
|
|
||||||
if (!isset($this->_loaded_plugins[$plugin_name]))
|
if (!isset($this->_loaded_plugins[$plugin_name]))
|
||||||
{
|
{
|
||||||
$this->loadPlugin($plugin_name);
|
$this->loadPlugin($plugin_name);
|
||||||
}
|
}
|
||||||
|
if (!isset($this->_loaded_plugins[$plugin_name]))
|
||||||
if (isset($this->_loaded_plugins[$plugin_name]->{$lang_key}))
|
|
||||||
{
|
{
|
||||||
$lang = $this->_loaded_plugins[$plugin_name]->{$lang_key};
|
return $this->getFromDefaultLang($key);
|
||||||
if (is_array($lang) && is_array($lang_en) && count($lang_en, COUNT_RECURSIVE) > count($lang, COUNT_RECURSIVE))
|
|
||||||
{
|
|
||||||
return $lang_en;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $lang;
|
// Find the given key.
|
||||||
|
$lang = $this->_loaded_plugins[$plugin_name];
|
||||||
|
foreach ($keys as $subkey)
|
||||||
|
{
|
||||||
|
if (is_object($lang) && isset($lang->{$subkey}))
|
||||||
|
{
|
||||||
|
$lang = $lang->{$subkey};
|
||||||
}
|
}
|
||||||
|
elseif (is_array($lang) && isset($lang[$subkey]))
|
||||||
|
{
|
||||||
|
$lang = $lang[$subkey];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
return $this->getFromDefaultLang($key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return is_array($lang) ? new \ArrayObject($lang, 3) : $lang;
|
||||||
|
}
|
||||||
|
|
||||||
// Search custom translations first.
|
// Search custom translations first.
|
||||||
if (isset($this->_loaded_plugins['_custom_']->{$key}))
|
if (isset($this->_loaded_plugins['_custom_']->{$key}))
|
||||||
{
|
{
|
||||||
$lang = $this->_loaded_plugins['_custom_']->{$key};
|
$lang = $this->_loaded_plugins['_custom_']->{$key};
|
||||||
if (is_array($lang))
|
return is_array($lang) ? new \ArrayObject($lang, 3) : $lang;
|
||||||
{
|
|
||||||
if (is_array($lang_en) && count($lang_en, COUNT_RECURSIVE) > count($lang, COUNT_RECURSIVE))
|
|
||||||
{
|
|
||||||
return new \ArrayObject($lang_en, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new \ArrayObject($lang, 3);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $lang;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search other plugins.
|
// Search other plugins.
|
||||||
|
|
@ -270,31 +276,12 @@ class Lang
|
||||||
if (isset($this->_loaded_plugins[$plugin_name]->{$key}))
|
if (isset($this->_loaded_plugins[$plugin_name]->{$key}))
|
||||||
{
|
{
|
||||||
$lang = $this->_loaded_plugins[$plugin_name]->{$key};
|
$lang = $this->_loaded_plugins[$plugin_name]->{$key};
|
||||||
if (is_array($lang))
|
return is_array($lang) ? new \ArrayObject($lang, 3) : $lang;
|
||||||
{
|
|
||||||
if (is_array($lang_en) && count($lang_en, COUNT_RECURSIVE) > count($lang, COUNT_RECURSIVE))
|
|
||||||
{
|
|
||||||
return new \ArrayObject($lang_en, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new \ArrayObject($lang, 3);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $lang;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search other language.
|
// If no translation is found, return the default language.
|
||||||
if (isset($lang_en))
|
return $this->getFromDefaultLang($key);
|
||||||
{
|
|
||||||
return $lang_en;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no translation is found, return the key.
|
|
||||||
return $key;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -306,6 +293,73 @@ class Lang
|
||||||
*/
|
*/
|
||||||
public function __set($key, $value)
|
public function __set($key, $value)
|
||||||
{
|
{
|
||||||
|
// Set a dot-separated key (prefixed by plugin name).
|
||||||
|
if (preg_match('/^[a-z0-9_.-]+$/i', $key) && ($keys = explode('.', $key)) && count($keys) >= 2)
|
||||||
|
{
|
||||||
|
// Attempt to load the plugin.
|
||||||
|
$plugin_name = array_shift($keys);
|
||||||
|
if (!isset($this->_loaded_plugins[$plugin_name]))
|
||||||
|
{
|
||||||
|
$this->loadPlugin($plugin_name);
|
||||||
|
}
|
||||||
|
if (!isset($this->_loaded_plugins[$plugin_name]))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the given key.
|
||||||
|
$count = count($keys);
|
||||||
|
$lang = $this->_loaded_plugins[$plugin_name];
|
||||||
|
foreach ($keys as $i => $subkey)
|
||||||
|
{
|
||||||
|
if (is_object($lang) && isset($lang->{$subkey}))
|
||||||
|
{
|
||||||
|
if ($i === $count - 1)
|
||||||
|
{
|
||||||
|
$lang->{$subkey} = $value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
elseif (is_array($lang->{$subkey}))
|
||||||
|
{
|
||||||
|
$lang = &$lang->{$subkey};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif (is_array($lang) && isset($lang[$subkey]))
|
||||||
|
{
|
||||||
|
if ($i === $count - 1)
|
||||||
|
{
|
||||||
|
$lang[$subkey] = $value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
elseif (is_array($lang[$subkey]))
|
||||||
|
{
|
||||||
|
$lang = &$lang[$subkey];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (is_object($lang))
|
||||||
|
{
|
||||||
|
$lang->{$subkey} = $value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$lang[$subkey] = $value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set a regular key.
|
||||||
$this->_loaded_plugins['_custom_']->{$key} = $value;
|
$this->_loaded_plugins['_custom_']->{$key} = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -335,13 +389,7 @@ class Lang
|
||||||
*/
|
*/
|
||||||
public function __unset($key)
|
public function __unset($key)
|
||||||
{
|
{
|
||||||
foreach ($this->_loaded_plugins as $plugin_name => $translations)
|
$this->set($key, null);
|
||||||
{
|
|
||||||
if (isset($translations->{$key}))
|
|
||||||
{
|
|
||||||
unset($translations->{$key});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -353,16 +401,6 @@ class Lang
|
||||||
*/
|
*/
|
||||||
public function __call($key, $args = array())
|
public function __call($key, $args = array())
|
||||||
{
|
{
|
||||||
// Remove a colon from the beginning of the string.
|
return $this->get($key, $args);
|
||||||
if ($key !== '' && $key[0] === ':') $key = substr($key, 1);
|
|
||||||
|
|
||||||
// Find the translation.
|
|
||||||
$translation = $this->__get($key);
|
|
||||||
|
|
||||||
// If there are no arguments, return the translation.
|
|
||||||
if (!count($args)) return $translation;
|
|
||||||
|
|
||||||
// If there are arguments, interpolate them into the translation and return the result.
|
|
||||||
return vsprintf($translation, $args);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,30 +4,63 @@ class LangTest extends \Codeception\TestCase\Test
|
||||||
{
|
{
|
||||||
public function testLang()
|
public function testLang()
|
||||||
{
|
{
|
||||||
|
// Test separation of languages.
|
||||||
$ko = Rhymix\Framework\Lang::getInstance('ko');
|
$ko = Rhymix\Framework\Lang::getInstance('ko');
|
||||||
$en = Rhymix\Framework\Lang::getInstance('en');
|
$en = Rhymix\Framework\Lang::getInstance('en');
|
||||||
$this->assertTrue($ko instanceof Rhymix\Framework\Lang);
|
$this->assertTrue($ko instanceof Rhymix\Framework\Lang);
|
||||||
$this->assertTrue($en instanceof Rhymix\Framework\Lang);
|
$this->assertTrue($en instanceof Rhymix\Framework\Lang);
|
||||||
$this->assertFalse($ko === $en);
|
$this->assertFalse($ko === $en);
|
||||||
|
|
||||||
|
// Test backward compatible language code for Japanese.
|
||||||
$ja = Rhymix\Framework\Lang::getInstance('ja');
|
$ja = Rhymix\Framework\Lang::getInstance('ja');
|
||||||
$jp = Rhymix\Framework\Lang::getInstance('jp');
|
$jp = Rhymix\Framework\Lang::getInstance('jp');
|
||||||
$this->assertTrue($ja === $jp);
|
$this->assertTrue($ja === $jp);
|
||||||
|
|
||||||
$this->assertEquals('도움말', $ko->get('common.help'));
|
// Test loading new plugins.
|
||||||
$this->assertEquals('Help', $en->get('common.help'));
|
$this->assertNotEquals('ヘルプ', $ja->help);
|
||||||
$this->assertEquals('도움말', $ko->help);
|
|
||||||
$this->assertEquals('Help', $en->help);
|
|
||||||
|
|
||||||
$this->assertEquals('common.nonexistent', $ko->get('common.nonexistent'));
|
|
||||||
$this->assertEquals('common.nonexistent', $ko->get('common.nonexistent', 'foo', 'bar'));
|
|
||||||
|
|
||||||
$this->assertEquals('admin.help', $ko->get('admin.help'));
|
|
||||||
$this->assertEquals('admin.help', $en->get('admin.help'));
|
|
||||||
|
|
||||||
$ja->loadPlugin('common');
|
$ja->loadPlugin('common');
|
||||||
$this->assertEquals('ヘルプ', $ja->help);
|
$this->assertEquals('ヘルプ', $ja->help);
|
||||||
|
|
||||||
|
// Test simple translations with namespacing.
|
||||||
|
$this->assertEquals('도움말', $ko->get('common.help'));
|
||||||
|
$this->assertEquals('Help', $en->get('common.help'));
|
||||||
|
|
||||||
|
// Test simple translations without namespacing.
|
||||||
|
$this->assertEquals('도움말', $ko->help);
|
||||||
|
$this->assertEquals('Help', $en->help);
|
||||||
|
|
||||||
|
// Test complex translations with multidimensional arrays.
|
||||||
|
$this->assertEquals('%d분 전', $ko->get('common.time_gap.min'));
|
||||||
|
$this->assertEquals('10분 전', $ko->get('common.time_gap.min', 10));
|
||||||
|
$this->assertTrue($ko->get('common.time_gap') instanceof \ArrayObject);
|
||||||
|
$this->assertEquals('%d분 전', $ko->get('common.time_gap')->min);
|
||||||
|
|
||||||
|
// Test nonexistent keys.
|
||||||
|
$this->assertEquals('common.nonexistent', $ko->get('common.nonexistent'));
|
||||||
|
$this->assertEquals('common.nonexistent', $ko->get('common.nonexistent', 'foo', 'bar'));
|
||||||
|
$this->assertEquals('admin.help', $ko->get('admin.help'));
|
||||||
|
$this->assertEquals('admin.help', $en->get('admin.help'));
|
||||||
|
|
||||||
|
// Test setting new keys with and without namespacing.
|
||||||
|
$ko->set('foo', 'FOO!');
|
||||||
|
$this->assertEquals('FOO!', $ko->get('foo'));
|
||||||
|
$ko->set('common.foobar', 'FOOBAR!');
|
||||||
|
$this->assertEquals('FOOBAR!', $ko->get('common.foobar'));
|
||||||
|
$this->assertEquals('FOOBAR!', $ko->get('foobar'));
|
||||||
|
|
||||||
|
// Test setting new keys with multidimensional arrays.
|
||||||
|
$ko->set('common.time_gap.foobar', 'FOOBAR!');
|
||||||
|
$this->assertEquals('FOOBAR!', $ko->get('common.time_gap.foobar'));
|
||||||
|
$ko->set('common.foobar.baz', 'BAZ!');
|
||||||
|
$this->assertNotEquals('BAZ!', $ko->get('common.foobar.baz'));
|
||||||
|
|
||||||
|
// Test fallback to English.
|
||||||
|
$en->only_in_english = 'Hello world';
|
||||||
|
$this->assertEquals('Hello world', $ko->only_in_english);
|
||||||
|
$this->assertEquals('Hello world', $en->only_in_english);
|
||||||
|
$this->assertEquals('Hello world', $ja->only_in_english);
|
||||||
|
|
||||||
|
// Test string interpolation.
|
||||||
$ko->foobartestlang = '%s님 안녕하세요?';
|
$ko->foobartestlang = '%s님 안녕하세요?';
|
||||||
$this->assertEquals('Travis님 안녕하세요?', $ko->foobartestlang('Travis'));
|
$this->assertEquals('Travis님 안녕하세요?', $ko->foobartestlang('Travis'));
|
||||||
$en->foobartestlang = 'Hello, %s!';
|
$en->foobartestlang = 'Hello, %s!';
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue