Also support dot notation when setting new language keys

This commit is contained in:
Kijin Sung 2016-03-17 14:52:05 +09:00
parent ef30f0fa40
commit 15e3360609
2 changed files with 90 additions and 26 deletions

View file

@ -247,30 +247,27 @@ class Lang
$lang = $this->_loaded_plugins[$plugin_name]; $lang = $this->_loaded_plugins[$plugin_name];
foreach ($keys as $subkey) foreach ($keys as $subkey)
{ {
if (isset($lang->{$subkey})) if (is_object($lang) && isset($lang->{$subkey}))
{ {
$lang = is_scalar($lang->{$subkey}) ? $lang->{$subkey} : new \ArrayObject($lang->{$subkey}, 3); $lang = $lang->{$subkey};
}
elseif (is_array($lang) && isset($lang[$subkey]))
{
$lang = $lang[$subkey];
} }
else else
{ {
return $this->getFromDefaultLang($key); return $this->getFromDefaultLang($key);
} }
} }
return $lang; 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;
{
return new \ArrayObject($lang, 3);
}
else
{
return $lang;
}
} }
// Search other plugins. // Search other plugins.
@ -279,14 +276,7 @@ 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;
{
return new \ArrayObject($lang, 3);
}
else
{
return $lang;
}
} }
} }
@ -303,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;
} }
@ -332,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});
}
}
} }
/** /**

View file

@ -41,6 +41,19 @@ class LangTest extends \Codeception\TestCase\Test
$this->assertEquals('admin.help', $ko->get('admin.help')); $this->assertEquals('admin.help', $ko->get('admin.help'));
$this->assertEquals('admin.help', $en->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. // Test fallback to English.
$en->only_in_english = 'Hello world'; $en->only_in_english = 'Hello world';
$this->assertEquals('Hello world', $ko->only_in_english); $this->assertEquals('Hello world', $ko->only_in_english);