This repository has been archived by the owner. It is now read-only.

Gettext adapter cannot translate plurals when the target language has only one plural form #66

Closed
zfbot opened this Issue Apr 5, 2013 · 1 comment

Comments

Projects
None yet
2 participants
@zfbot

zfbot commented Apr 5, 2013

Jira Information

Original Issue:ZF-12547
Issue Type:Bug
Reporter:fisharebest
Created:03/22/13
Assignee:
Components:Zend_Translate

Description

When a target language only has one plural form, calls to {{Zend_Translate::plural()}} just return the first character of the string.

Consider these two translation files (French - 2 plural forms, Turkish - 1 plural form). Compile them with the command "msgfmt XX.po -o XX.mo"

msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"

msgid "There is %d fish"
msgid_plural "There are %d fishes"
msgstr[0] "Il ya %d poisson"
msgstr[1] "Il ya %d poissons"
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=1; plural=0;\n"

msgid "There is %d fish"
msgid_plural "There are %d fishes"
msgstr[0] "%d balıklar var"

Here is a test script

require 'Zend/Translate.php';

// A language with more than one plural form - works OK
$translate = new Zend_Translate('gettext', 'fr.mo', 'fr');
for ($i=0; $i<5; ++$i) {
    echo $translate->plural('There is %d fish', 'There are %d fishes', $i), PHP_EOL;
}

// A language with only one plural form - does not work
$translate = new Zend_Translate('gettext', 'tr.mo', 'tr');
for ($i=0; $i<5; ++$i) {
    echo $translate->plural('There is %d fish', 'There are %d fishes', $i), PHP_EOL;
}

The actual output is

Il ya %d poisson
Il ya %d poisson
Il ya %d poissons
Il ya %d poissons
Il ya %d poissons
%
%
%
%
%

Note that the turkish translations contain just the first character of the sring.

This comes from code in {{Zend_Translate_Adapter::plural()}} which assumes that plural translations are always arrays. The [0] operator is finding the first character of a string, not the first element of an array.

            $rule = Zend_Translate_Plural::getPlural($number, $locale);
            if (isset($this->_translate[$locale][$plural[0]][$rule])) {
                $this->_routed = array();
                return $this->_translate[$locale][$plural[0]][$rule];
            }

As far as I can tell, the bug comes from Zend_Translate_Adapter_Gettext, and can be fixed by the following patch

Index: Gettext.php
===================================================================
--- Gettext.php (revision 25275)
+++ Gettext.php (working copy)
@@ -122,7 +122,7 @@
                 fseek($this->_file, $transtemp[$count * 2 + 2]);
                 $translate = fread($this->_file, $transtemp[$count * 2 + 1]);
                 $translate = explode("\0", $translate);
-                if ((count($original) > 1) && (count($translate) > 1)) {
+                if (count($original) > 1) {
                     $this->_data[$locale][$original[0]] = $translate;
                     array_shift($original);
                     foreach ($original as $orig) {

An explanation for the patch is that a translation is defined as a plural if there are more than one ENGLISH forms. It does not matter whether there is only one TRANSLATED form.

With the patch, the test script outputs the expected values:

Il ya %d poisson
Il ya %d poisson
Il ya %d poissons
Il ya %d poissons
Il ya %d poissons
%d balıklar var
%d balıklar var
%d balıklar var
%d balıklar var
%d balıklar var
@zfbot

This comment has been minimized.

Show comment Hide comment
@zfbot

zfbot Apr 5, 2013

This issue was ported from the ZF2 Jira Issue Tracker at
http://framework.zend.com/issues/browse/ZF-12547

Known GitHub users mentioned in the original message or comment:

zfbot commented Apr 5, 2013

This issue was ported from the ZF2 Jira Issue Tracker at
http://framework.zend.com/issues/browse/ZF-12547

Known GitHub users mentioned in the original message or comment:

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.