Commit ddf4b81f authored by catch's avatar catch

Issue #1221276 by fietserwin, Gábor Hojtsy, sun, gumanist: Fixed...

Issue #1221276 by fietserwin, Gábor Hojtsy, sun, gumanist: Fixed locale_get_plural() only works for a single language within a request and does not work for English.
parent 004df891
......@@ -1723,7 +1723,8 @@ function format_plural($count, $singular, $plural, array $args = array(), array
// Get the plural index through the gettext formula.
$index = (function_exists('locale_get_plural')) ? locale_get_plural($count, isset($options['langcode']) ? $options['langcode'] : NULL) : -1;
// Backwards compatibility.
// If the index cannot be computed, use the plural as a fallback (which
// allows for most flexiblity with the replaceable @count value).
if ($index < 0) {
return t($plural, $args, $options);
}
......
......@@ -743,29 +743,46 @@ function locale_reset() {
* @param $langcode
* Optional language code to translate to a language other than
* what is used to display the page.
* @return
* The numeric index of the plural variant to use for this $langcode and
* $count combination or -1 if the language was not found or does not have a
* plural formula.
*/
function locale_get_plural($count, $langcode = NULL) {
global $language;
$locale_plurals = &drupal_static(__FUNCTION__, array());
$plurals = &drupal_static(__FUNCTION__ . ':plurals', array());
// Used to locally cache the plural formulas for all languages.
$plural_formulas = &drupal_static(__FUNCTION__, array());
// Used to store precomputed plural indexes corresponding to numbers
// individually for each language.
$plural_indexes = &drupal_static(__FUNCTION__ . ':plurals', array());
$langcode = $langcode ? $langcode : $language->langcode;
if (!isset($plurals[$langcode][$count])) {
if (empty($locale_plural_formulas)) {
$locale_plurals = variable_get('locale_translation_plurals', array());
if (!isset($plural_indexes[$langcode][$count])) {
// Retrieve and statically cache the plural formulas for all languages.
if (empty($plural_formulas)) {
$plural_formulas = variable_get('locale_translation_plurals', array());
}
if (!empty($locale_plurals[$langcode])) {
// If there is a plural formula for the language, evaluate it for the given
// $count and statically cache the result for the combination of language
// and count, since the result will always be identical.
if (!empty($plural_formulas[$langcode])) {
// $n is used inside the expression in the eval().
$n = $count;
$plurals[$langcode][$count] = @eval('return intval(' . $locale_plurals[$langcode]['formula'] . ');');
return $plurals[$langcode][$count];
$plural_indexes[$langcode][$count] = @eval('return intval(' . $plural_formulas[$langcode]['formula'] . ');');
}
// In case there is no plural formula for English (no imported translation
// for English), use a default formula.
elseif ($langcode == 'en') {
$plural_indexes[$langcode][$count] = (int) ($count != 1);
}
// Otherwise, return -1 (unknown).
else {
$plurals[$langcode][$count] = -1;
return -1;
$plural_indexes[$langcode][$count] = -1;
}
}
return $plurals[$langcode][$count];
return $plural_indexes[$langcode][$count];
}
......
......@@ -585,6 +585,129 @@ class LocaleTranslationFunctionalTest extends DrupalWebTestCase {
}
}
/**
* Tests plural index computation functionality.
*/
class LocalePluralFormatTest extends DrupalWebTestCase {
public static function getInfo() {
return array(
'name' => 'Plural formula evaluation',
'description' => 'Tests plural formula evaluation for various languages.',
'group' => 'Locale',
);
}
function setUp() {
parent::setUp('locale', 'locale_test');
$admin_user = $this->drupalCreateUser(array('administer languages', 'translate interface', 'access administration pages'));
$this->drupalLogin($admin_user);
}
/**
* Tests locale_get_plural() functionality.
*/
function testGetPluralFormat() {
// Import some .po files with formulas to set up the environment.
// These will also add the languages to the system and enable them.
$this->importPoFile($this->getPoFileWithSimplePlural(), array(
'langcode' => 'fr',
));
$this->importPoFile($this->getPoFileWithComplexPlural(), array(
'langcode' => 'hr',
));
// Reset static caches from locale_get_plural() to ensure we get fresh data.
drupal_static_reset('locale_get_plural');
drupal_static_reset('locale_get_plural:plurals');
// Test locale_get_plural() for English (no formula presnt).
$this->assertIdentical(locale_get_plural(1, 'en'), 0, t("Computed plural index for 'en' with count 1 is 0."));
$this->assertIdentical(locale_get_plural(0, 'en'), 1, t("Computed plural index for 'en' with count 0 is 1."));
$this->assertIdentical(locale_get_plural(5, 'en'), 1, t("Computed plural index for 'en' with count 5 is 1."));
// Test locale_get_plural() for French (simpler formula).
$this->assertIdentical(locale_get_plural(1, 'fr'), 0, t("Computed plural index for 'fr' with count 1 is 0."));
$this->assertIdentical(locale_get_plural(0, 'fr'), 0, t("Computed plural index for 'fr' with count 0 is 0."));
$this->assertIdentical(locale_get_plural(5, 'fr'), 1, t("Computed plural index for 'fr' with count 5 is 1."));
// Test locale_get_plural() for Croatian (more complex formula).
$this->assertIdentical(locale_get_plural( 1, 'hr'), 0, t("Computed plural index for 'hr' with count 1 is 0."));
$this->assertIdentical(locale_get_plural(21, 'hr'), 0, t("Computed plural index for 'hr' with count 21 is 0."));
$this->assertIdentical(locale_get_plural( 0, 'hr'), 2, t("Computed plural index for 'hr' with count 0 is 2."));
$this->assertIdentical(locale_get_plural( 2, 'hr'), 1, t("Computed plural index for 'hr' with count 2 is 1."));
$this->assertIdentical(locale_get_plural( 8, 'hr'), 2, t("Computed plural index for 'hr' with count 8 is 2."));
// Test locale_get_plural() for Hungarian (nonexistent language).
$this->assertIdentical(locale_get_plural( 1, 'hu'), -1, t("Computed plural index for 'hu' with count 1 is -1."));
$this->assertIdentical(locale_get_plural(21, 'hu'), -1, t("Computed plural index for 'hu' with count 21 is -1."));
$this->assertIdentical(locale_get_plural( 0, 'hu'), -1, t("Computed plural index for 'hu' with count 0 is -1."));
}
/**
* Imports a standalone .po file in a given language.
*
* @param $contents
* Contents of the .po file to import.
* @param $options
* Additional options to pass to the translation import form.
*/
function importPoFile($contents, array $options = array()) {
$name = tempnam('temporary://', "po_") . '.po';
file_put_contents($name, $contents);
$options['files[file]'] = $name;
$this->drupalPost('admin/config/regional/translate/import', $options, t('Import'));
drupal_unlink($name);
}
/**
* Returns a .po file with a simple plural formula.
*/
function getPoFileWithSimplePlural() {
return <<< EOF
msgid ""
msgstr ""
"Project-Id-Version: Drupal 7\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=UTF-8\\n"
"Content-Transfer-Encoding: 8bit\\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\\n"
msgid "1 hour"
msgid_plural "@count hours"
msgstr[0] "1 heure"
msgstr[1] "@count heures"
msgid "Monday"
msgstr "lundi"
EOF;
}
/**
* Returns a .po file with a complex plural formula.
*/
function getPoFileWithComplexPlural() {
return <<< EOF
msgid ""
msgstr ""
"Project-Id-Version: Drupal 7\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=UTF-8\\n"
"Content-Transfer-Encoding: 8bit\\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\\n"
msgid "1 hour"
msgid_plural "@count hours"
msgstr[0] "@count sat"
msgstr[1] "@count sata"
msgstr[2] "@count sati"
msgid "Monday"
msgstr "Ponedjeljak"
EOF;
}
}
/**
* Functional tests for the import of translation files.
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment