Details
-
Type:
Improvement
-
Status:
Resolved
-
Priority:
Minor
-
Resolution: Won't Fix
-
Affects Version/s: 1.9.0, 1.9.1, 1.9.2, 1.9.3, 1.9.4, 1.9.5, 1.9.6, 1.9.7, 1.10.0
-
Fix Version/s: 1.10.3
-
Component/s: Zend_Translate
-
Labels:None
Description
This issue has been raised multiple times and the solutions do not work as they misstate the problem.
When using plural() on already translated strings the .po and .mo files may not contain the strings stored as plurals. But they do contain translations of the original texts, when these are found only one letter is returned instead of a string.
$one = $t->_('One');
$two = $t->_('Two');
echo $t->plural($one, $two, $i);
This now returns 'O' or 'w' depending on the value $i when "translating" from English to English.
Now I understand this is not the correct use of plural, but it does seems a very common use. When using plural on two variables you have little choice, e.g. poEdit will not see 'One' and 'Two' as instances of plural.
However, we can make this case work without breaking the correct working of translate files by extending the Translate Adapter to check for the plural translation choosen being an array versus a string.
$locale = (string) $locale; if (isset($this->_translate[$locale][$messageId])) { // return original translation if ($plural === null) { return $this->_translate[$locale][$messageId]; } $rule = Zend_Translate_Plural::getPlural($number, $locale); // BUG FIX added: && is_array($this->_translate[$locale][$plural[0]]) if (isset($this->_translate[$locale][$plural[0]][$rule]) && is_array($this->_translate[$locale][$plural[0]])) { return $this->_translate[$locale][$plural[0]][$rule]; } elseif (isset($this->_translate[$locale][$plural[$rule]])) { // FIX Added return $this->_translate[$locale][$plural[$rule]]; // FIX Added } } else if (strlen($locale) != 2) { // faster than creating a new locale and separate the leading part $locale = substr($locale, 0, -strlen(strrchr($locale, '_'))); if (isset($this->_translate[$locale][$messageId])) { // return regionless translation (en_US -> en) if ($plural === null) { return $this->_translate[$locale][$messageId]; } $rule = Zend_Translate_Plural::getPlural($number, $locale); // BUG FIX added: && is_array($this->_translate[$locale][$plural[0]]) if (isset($this->_translate[$locale][$plural[0]][$rule]) && is_array($this->_translate[$locale][$plural[0]])) { return $this->_translate[$locale][$plural[0]][$rule]; } elseif (isset($this->_translate[$locale][$plural[$rule]])) { // FIX Added return $this->_translate[$locale][$plural[$rule]]; // FIX Added } } }
As this makes the translate tools more flexible there seems little reason no to include it.
Sorry, my first time reporting in, I assumed that cloning this issue I would be able to edit the original text.
This issue has been raised multiple times and the solutions do not work as they misstate the problem.
When using plural() on already translated strings the .po and .mo files may not contain the strings as plurals. But they do contain translations of the original texts, when these are found only one letter is returned.
Now maybe I misunderstand how I should use plural, but my use seems a very common one. Especially when using plural on two variable values.
A solution that does not break the correct workings of translate files is to replace th current code:
if (isset($this->_translate[$locale][$plural[0]][$rule])) { return $this->_translate[$locale][$plural[0]][$rule]; }
With this slightly long version that check for the _translate entry being a string versus an array:
if (isset($this->_translate[$locale][$plural[0]][$rule]) && is_array($this->_translate[$locale][$plural[0]])) { return $this->_translate[$locale][$plural[0]][$rule]; } } elseif (isset($this->_translate[$locale][$plural[$rule]])) { return $this->_translate[$locale][$plural[$rule]]; }
This has to haappen twice in plural() in Zend_Translate_adapter.php