* changed indexing order of the i18n __domains array to allow caching by domain+language (fixes #1085)

* adapted testcase

Signed-off-by: mark_story <mark@mark-story.com>
This commit is contained in:
0x20h 2010-09-18 17:34:46 +02:00 committed by mark_story
parent 729a45703b
commit ba8280423d
2 changed files with 45 additions and 54 deletions

View file

@ -155,19 +155,13 @@ class I18n extends Object {
} }
$_this->domain = $domain . '_' . $_this->l10n->locale; $_this->domain = $domain . '_' . $_this->l10n->locale;
if (!isset($_this->__domains[$_this->category][$_this->__lang][$domain])) { if (!isset($_this->__domains[$domain][$_this->__lang])) {
$_this->__domains[$_this->category][$_this->__lang][$domain] = Cache::read($_this->domain, '_cake_core_'); $_this->__domains[$domain][$_this->__lang] = Cache::read($_this->domain, '_cake_core_');
} }
if (empty($_this->__domains[$_this->category][$_this->__lang][$domain])) { if (empty($_this->__domains[$domain][$_this->__lang][$_this->category])) {
$_this->__bindTextDomain($domain); $_this->__bindTextDomain($domain);
$_this->__cache[] = array( $_this->__cache[] = array('key' => $_this->domain, 'lang' => $_this->__lang, 'domain' => $domain);
'key' => $_this->domain,
'category' => $_this->category,
'lang' => $_this->__lang,
'domain' => $domain,
'locale' => $_this->l10n->locale
);
} }
if ($_this->category == 'LC_TIME') { if ($_this->category == 'LC_TIME') {
@ -176,8 +170,8 @@ class I18n extends Object {
if (!isset($count)) { if (!isset($count)) {
$plurals = 0; $plurals = 0;
} elseif (!empty($_this->__domains[$_this->category][$_this->__lang][$domain]["%plural-c"]) && $_this->__noLocale === false) { } elseif (!empty($_this->__domains[$domain][$_this->__lang][$_this->category]["%plural-c"]) && $_this->__noLocale === false) {
$header = $_this->__domains[$_this->category][$_this->__lang][$domain]["%plural-c"]; $header = $_this->__domains[$domain][$_this->__lang][$_this->category]["%plural-c"];
$plurals = $_this->__pluralGuess($header, $count); $plurals = $_this->__pluralGuess($header, $count);
} else { } else {
if ($count != 1) { if ($count != 1) {
@ -187,8 +181,8 @@ class I18n extends Object {
} }
} }
if (!empty($_this->__domains[$_this->category][$_this->__lang][$domain][$singular])) { if (!empty($_this->__domains[$domain][$_this->__lang][$_this->category][$singular])) {
if (($trans = $_this->__domains[$_this->category][$_this->__lang][$domain][$singular]) || ($plurals) && ($trans = $_this->__domains[$_this->category][$_this->__lang][$domain][$plural])) { if (($trans = $_this->__domains[$domain][$_this->__lang][$_this->category][$singular]) || ($plurals) && ($trans = $_this->__domains[$domain][$_this->__lang][$_this->category][$plural])) {
if (is_array($trans)) { if (is_array($trans)) {
if (isset($trans[$plurals])) { if (isset($trans[$plurals])) {
$trans = $trans[$plurals]; $trans = $trans[$plurals];
@ -294,12 +288,12 @@ class I18n extends Object {
if (file_exists($fn = "$app.mo")) { if (file_exists($fn = "$app.mo")) {
$this->__loadMo($fn, $domain); $this->__loadMo($fn, $domain);
$this->__noLocale = false; $this->__noLocale = false;
$merge[$this->category][$this->__lang][$domain] = $this->__domains[$this->category][$this->__lang][$domain]; $merge[$domain][$this->__lang][$this->category] = $this->__domains[$domain][$this->__lang][$this->category];
$core = null; $core = null;
} elseif (file_exists($fn = "$app.po") && ($f = fopen($fn, "r"))) { } elseif (file_exists($fn = "$app.po") && ($f = fopen($fn, "r"))) {
$this->__loadPo($f, $domain); $this->__loadPo($f, $domain);
$this->__noLocale = false; $this->__noLocale = false;
$merge[$this->category][$this->__lang][$domain] = $this->__domains[$this->category][$this->__lang][$domain]; $merge[$domain][$this->__lang][$this->category] = $this->__domains[$domain][$this->__lang][$this->category];
$core = null; $core = null;
} }
} }
@ -320,27 +314,27 @@ class I18n extends Object {
} }
} }
if (empty($this->__domains[$this->category][$this->__lang][$domain])) { if (empty($this->__domains[$domain][$this->__lang][$this->category])) {
$this->__domains[$this->category][$this->__lang][$domain] = array(); $this->__domains[$domain][$this->__lang][$this->category] = array();
return $domain; return $domain;
} }
if ($head = $this->__domains[$this->category][$this->__lang][$domain][""]) { if ($head = $this->__domains[$domain][$this->__lang][$this->category][""]) {
foreach (explode("\n", $head) as $line) { foreach (explode("\n", $head) as $line) {
$header = strtok($line,":"); $header = strtok($line,":");
$line = trim(strtok("\n")); $line = trim(strtok("\n"));
$this->__domains[$this->category][$this->__lang][$domain]["%po-header"][strtolower($header)] = $line; $this->__domains[$domain][$this->__lang][$this->category]["%po-header"][strtolower($header)] = $line;
} }
if (isset($this->__domains[$this->category][$this->__lang][$domain]["%po-header"]["plural-forms"])) { if (isset($this->__domains[$domain][$this->__lang][$this->category]["%po-header"]["plural-forms"])) {
$switch = preg_replace("/(?:[() {}\\[\\]^\\s*\\]]+)/", "", $this->__domains[$this->category][$this->__lang][$domain]["%po-header"]["plural-forms"]); $switch = preg_replace("/(?:[() {}\\[\\]^\\s*\\]]+)/", "", $this->__domains[$domain][$this->__lang][$this->category]["%po-header"]["plural-forms"]);
$this->__domains[$this->category][$this->__lang][$domain]["%plural-c"] = $switch; $this->__domains[$domain][$this->__lang][$this->category]["%plural-c"] = $switch;
unset($this->__domains[$this->category][$this->__lang][$domain]["%po-header"]); unset($this->__domains[$domain][$this->__lang][$this->category]["%po-header"]);
} }
$this->__domains = Set::pushDiff($this->__domains, $merge); $this->__domains = Set::pushDiff($this->__domains, $merge);
if (isset($this->__domains[$this->category][$this->__lang][$domain][null])) { if (isset($this->__domains[$domain][$this->__lang][$this->category][null])) {
unset($this->__domains[$this->category][$this->__lang][$domain][null]); unset($this->__domains[$domain][$this->__lang][$this->category][null]);
} }
} }
return $domain; return $domain;
@ -376,10 +370,10 @@ class I18n extends Object {
if (strpos($msgstr, "\000")) { if (strpos($msgstr, "\000")) {
$msgstr = explode("\000", $msgstr); $msgstr = explode("\000", $msgstr);
} }
$this->__domains[$this->category][$this->__lang][$domain][$msgid] = $msgstr; $this->__domains[$domain][$this->__lang][$this->category][$msgid] = $msgstr;
if (isset($msgid_plural)) { if (isset($msgid_plural)) {
$this->__domains[$this->category][$this->__lang][$domain][$msgid_plural] =& $this->__domains[$this->category][$this->__lang][$domain][$msgid]; $this->__domains[$domain][$this->__lang][$this->category][$msgid_plural] =& $this->__domains[$domain][$this->__lang][$this->category][$msgid];
} }
} }
} }
@ -454,7 +448,7 @@ class I18n extends Object {
} while (!feof($file)); } while (!feof($file));
fclose($file); fclose($file);
$merge[""] = $header; $merge[""] = $header;
return $this->__domains[$this->category][$this->__lang][$domain] = array_merge($merge ,$translations); return $this->__domains[$domain][$this->__lang][$this->category] = array_merge($merge ,$translations);
} }
/** /**
@ -512,9 +506,9 @@ class I18n extends Object {
$value[$i] = $val; $value[$i] = $val;
} }
if (count($value) == 1) { if (count($value) == 1) {
$this->__domains[$this->category][$this->__lang][$domain][$currentToken] = array_pop($value); $this->__domains[$domain][$this->__lang][$this->category][$currentToken] = array_pop($value);
} else { } else {
$this->__domains[$this->category][$this->__lang][$domain][$currentToken] = $value; $this->__domains[$domain][$this->__lang][$this->category][$currentToken] = $value;
} }
} }
} }
@ -559,8 +553,8 @@ class I18n extends Object {
* @access private * @access private
*/ */
function __translateTime($format, $domain) { function __translateTime($format, $domain) {
if (!empty($this->__domains['LC_TIME'][$this->__lang][$domain][$format])) { if (!empty($this->__domains[$domain][$this->__lang]['LC_TIME'][$format])) {
if (($trans = $this->__domains[$this->category][$this->__lang][$domain][$format])) { if (($trans = $this->__domains[$domain][$this->__lang][$this->category][$format])) {
return $trans; return $trans;
} }
} }
@ -576,17 +570,9 @@ class I18n extends Object {
function __destruct() { function __destruct() {
if (!empty($this->__cache)) { if (!empty($this->__cache)) {
foreach($this->__cache as $entry) { foreach($this->__cache as $entry) {
if (empty($this->__domains[$entry['category']][$entry['lang']][$entry['domain']])) { if (empty($this->__domains[$entry['domain']][$entry['lang']])) continue;
continue; Cache::write($entry['key'], array_filter($this->__domains[$entry['domain']][$entry['lang']]), '_cake_core_');
}
Cache::write(
$entry['key'],
array_filter($this->__domains[$entry['category']][$entry['lang']][$entry['domain']]),
'_cake_core_'
);
} }
} }
$this->__cache = array();
$this->__domains = array();
} }
} }

View file

@ -58,9 +58,12 @@ class I18nTest extends CakeTestCase {
function testTranslationCaching() { function testTranslationCaching() {
Configure::write('Config.language', 'cache_test_po'); Configure::write('Config.language', 'cache_test_po');
$i18n =& i18n::getInstance(); $i18n =& i18n::getInstance();
// reset cache & i18n // reset cache & i18n
$i18n->__destruct(); $i18n->__destruct();
// reset internally stored entries
$i18n->__cache = array();
$i18n->__domains = array();
Cache::clear(false, '_cake_core_'); Cache::clear(false, '_cake_core_');
$lang = $i18n->l10n->locale; $lang = $i18n->l10n->locale;
@ -69,26 +72,28 @@ class I18nTest extends CakeTestCase {
// make some calls to translate using different domains // make some calls to translate using different domains
$this->assertEqual(i18n::translate('dom1.foo', false, 'dom1'), 'Dom 1 Foo'); $this->assertEqual(i18n::translate('dom1.foo', false, 'dom1'), 'Dom 1 Foo');
$this->assertEqual(i18n::translate('dom1.bar', false, 'dom1'), 'Dom 1 Bar'); $this->assertEqual(i18n::translate('dom1.bar', false, 'dom1'), 'Dom 1 Bar');
$this->assertEqual($i18n->__cache[0]['key'], 'dom1_' . $lang); $this->assertEqual($i18n->__cache[0]['key'], 'dom1_' . $lang);
$this->assertEqual($i18n->__cache[0]['domain'], 'dom1'); $this->assertEqual($i18n->__cache[0]['domain'], 'dom1');
$this->assertEqual($i18n->__domains['LC_MESSAGES']['cache_test_po']['dom1']['dom1.foo'], 'Dom 1 Foo'); $this->assertEqual($i18n->__domains['dom1']['cache_test_po']['LC_MESSAGES']['dom1.foo'], 'Dom 1 Foo');
// destruct -> writes to cache // destruct -> writes to cache
$i18n->__destruct(); $i18n->__destruct();
// reset internally stored entries
$i18n->__domains = array();
$i18n->__cache = array();
// now only dom1 should be in cache // now only dom1 should be in cache
$cachedDom1 = Cache::read('dom1_' . $lang, '_cake_core_'); $cachedDom1 = Cache::read('dom1_' . $lang, '_cake_core_');
$this->assertEqual($cachedDom1['dom1.foo'], 'Dom 1 Foo'); $this->assertEqual($cachedDom1['LC_MESSAGES']['dom1.foo'], 'Dom 1 Foo');
$this->assertEqual($cachedDom1['dom1.bar'], 'Dom 1 Bar'); $this->assertEqual($cachedDom1['LC_MESSAGES']['dom1.bar'], 'Dom 1 Bar');
// dom2 not in cache // dom2 not in cache
$this->assertFalse(Cache::read('dom2_' . $lang, '_cake_core_')); $this->assertFalse(Cache::read('dom2_' . $lang, '_cake_core_'));
// translate a item of dom2 (adds dom2 to cache) // translate a item of dom2 (adds dom2 to cache)
$this->assertEqual(i18n::translate('dom2.foo', false, 'dom2'), 'Dom 2 Foo'); $this->assertEqual(i18n::translate('dom2.foo', false, 'dom2'), 'Dom 2 Foo');
// modify cache entry to verify that dom1 entry is now read from cache // modify cache entry manually to verify that dom1 entry is now read from cache
$cachedDom1['dom1.foo'] = 'FOO'; $cachedDom1['LC_MESSAGES']['dom1.foo'] = 'FOO';
Cache::write('dom1_' . $lang, $cachedDom1, '_cake_core_'); Cache::write('dom1_' . $lang, $cachedDom1, '_cake_core_');
$this->assertEqual(i18n::translate('dom1.foo', false, 'dom1'), 'FOO'); $this->assertEqual(i18n::translate('dom1.foo', false, 'dom1'), 'FOO');
@ -101,8 +106,8 @@ class I18nTest extends CakeTestCase {
// verify caching through manual read from cache // verify caching through manual read from cache
$cachedDom2 = Cache::read('dom2_' . $lang, '_cake_core_'); $cachedDom2 = Cache::read('dom2_' . $lang, '_cake_core_');
$this->assertEqual($cachedDom2['dom2.foo'], 'Dom 2 Foo'); $this->assertEqual($cachedDom2['LC_MESSAGES']['dom2.foo'], 'Dom 2 Foo');
$this->assertEqual($cachedDom2['dom2.bar'], 'Dom 2 Bar'); $this->assertEqual($cachedDom2['LC_MESSAGES']['dom2.bar'], 'Dom 2 Bar');
} }