Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

Commit

Permalink
Merge branch 'hotfix/4053'
Browse files Browse the repository at this point in the history
Close zendframework/zendframework#4053
* hotfix/4053:
  Implement better text domain merging support
  • Loading branch information
Ryan Mauger committed Mar 16, 2013
2 parents 9092473 + c3e320e commit d680762
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 59 deletions.
10 changes: 10 additions & 0 deletions src/Translator/Plural/Rule.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ public function evaluate($number)
return $result;
}

/**
* Get number of possible plural forms.
*
* @return integer
*/
public function getNumPlurals()
{
return $this->numPlurals;
}

/**
* Evaluate a part of an ast.
*
Expand Down
28 changes: 28 additions & 0 deletions src/Translator/TextDomain.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace Zend\I18n\Translator;

use ArrayObject;
use Zend\I18n\Exception;
use Zend\I18n\Translator\Plural\Rule as PluralRule;

/**
Expand Down Expand Up @@ -51,4 +52,31 @@ public function getPluralRule()

return $this->pluralRule;
}

/**
* Merge another text domain with the current one.
*
* The plural rule of both text domains must be compatible for a successful
* merge. We are only validating the number of plural forms though, as the
* same rule could be made up with different expression.
*
* @param TextDomain $textDomain
* @return TextDomain
* @throws Exception\RuntimeException
*/
public function merge(TextDomain $textDomain)
{
if ($this->getPluralRule()->getNumPlurals() !== $textDomain->getPluralRule()->getNumPlurals()) {
throw new Exception\RuntimeException('Plural rule of merging text domain is not compatible with the current one');
}

$this->exchangeArray(
array_replace(
$this->getArrayCopy(),
$textDomain->getArrayCopy()
)
);

return $this;
}
}
70 changes: 16 additions & 54 deletions src/Translator/Translator.php
Original file line number Diff line number Diff line change
Expand Up @@ -347,9 +347,9 @@ public function translatePlural(
$locale = null
) {
$locale = $locale ?: $this->getLocale();
$translation = $this->getTranslatedMessage($singular, $locale, $textDomain, true);
$translation = $this->getTranslatedMessage($singular, $locale, $textDomain);

if ($translation === null || $translation['message'] === '') {
if ($translation === null || $translation === '') {
if (null !== ($fallbackLocale = $this->getFallbackLocale())
&& $locale !== $fallbackLocale
) {
Expand All @@ -365,31 +365,31 @@ public function translatePlural(
return ($number == 1 ? $singular : $plural);
}

$index = $translation['plural_rule']->evaluate($number);
$index = $this->messages[$textDomain][$locale]
->getPluralRule()
->evaluate($number);

if (!isset($translation['message'][$index])) {
if (!isset($translation[$index])) {
throw new Exception\OutOfBoundsException(sprintf(
'Provided index %d does not exist in plural array', $index
));
}

return $translation['message'][$index];
return $translation[$index];
}

/**
* Get a translated message.
*
* @param string $message
* @param string $locale
* @param string $textDomain
* @param boolean $returnPluralRule
* @param string $message
* @param string $locale
* @param string $textDomain
* @return string|null
*/
protected function getTranslatedMessage(
$message,
$locale = null,
$textDomain = 'default',
$returnPluralRule = false
$textDomain = 'default'
) {
if ($message === '') {
return '';
Expand All @@ -399,28 +399,8 @@ protected function getTranslatedMessage(
$this->loadMessages($textDomain, $locale);
}

if (is_array($this->messages[$textDomain][$locale])) {
foreach ($this->messages[$textDomain][$locale] as $textDomain) {
if (isset($textDomain[$message])) {
if ($returnPluralRule) {
return array(
'message' => $textDomain[$message],
'plural_rule' => $textDomain->getPluralRule()
);
} else {
return $textDomain[$message];
}
}
}
} elseif (isset($this->messages[$textDomain][$locale][$message])) {
if ($returnPluralRule) {
return array(
'message' => $this->messages[$textDomain][$locale][$message],
'plural_rule' => $this->messages[$textDomain][$locale]->getPluralRule()
);
} else {
return $this->messages[$textDomain][$locale][$message];
}
if (isset($this->messages[$textDomain][$locale][$message])) {
return $this->messages[$textDomain][$locale][$message];
}

return null;
Expand Down Expand Up @@ -559,13 +539,7 @@ protected function loadMessagesFromRemote($textDomain, $locale)
}

if (isset($this->messages[$textDomain][$locale])) {
if (!is_array($this->messages[$textDomain][$locale])) {
$this->messages[$textDomain][$locale] = array(
$this->messages[$textDomain][$locale]
);
}

$this->messages[$textDomain][$locale][] = $loader->load($locale, $textDomain);
$this->messages[$textDomain][$locale]->merge($loader->load($locale, $textDomain));
} else {
$this->messages[$textDomain][$locale] = $loader->load($locale, $textDomain);
}
Expand Down Expand Up @@ -601,13 +575,7 @@ protected function loadMessagesFromPatterns($textDomain, $locale)
}

if (isset($this->messages[$textDomain][$locale])) {
if (!is_array($this->messages[$textDomain][$locale])) {
$this->messages[$textDomain][$locale] = array(
$this->messages[$textDomain][$locale]
);
}

$this->messages[$textDomain][$locale][] = $loader->load($locale, $filename);
$this->messages[$textDomain][$locale]->merge($loader->load($locale, $filename));
} else {
$this->messages[$textDomain][$locale] = $loader->load($locale, $filename);
}
Expand Down Expand Up @@ -645,13 +613,7 @@ protected function loadMessagesFromFiles($textDomain, $locale)
}

if (isset($this->messages[$textDomain][$locale])) {
if (!is_array($this->messages[$textDomain][$locale])) {
$this->messages[$textDomain][$locale] = array(
$this->messages[$textDomain][$locale]
);
}

$this->messages[$textDomain][$locale][] = $loader->load($locale, $file['filename']);
$this->messages[$textDomain][$locale]->merge($loader->load($locale, $file['filename']));
} else {
$this->messages[$textDomain][$locale] = $loader->load($locale, $file['filename']);
}
Expand Down
6 changes: 6 additions & 0 deletions test/Translator/Plural/RuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,10 @@ public function testCompleteRules($rule, $expectedValues)
$this->assertEquals((int) $expectedValues[$i], $rule->evaluate($i));
}
}

public function testGetNumPlurals()
{
$rule = Rule::fromString('nplurals=9; plural=n');
$this->assertEquals(9, $rule->getNumPlurals());
}
}
22 changes: 22 additions & 0 deletions test/Translator/TextDomainTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,26 @@ public function testPluralRuleDefault()
$this->assertEquals(1, $domain->getPluralRule()->evaluate(1));
$this->assertEquals(0, $domain->getPluralRule()->evaluate(2));
}

public function testMerging()
{
$domainA = new TextDomain(array('foo' => 'bar', 'bar' => 'baz'));
$domainB = new TextDomain(array('baz' => 'bat', 'bar' => 'bat'));
$domainA->merge($domainB);

$this->assertEquals('bar', $domainA['foo']);
$this->assertEquals('bat', $domainA['bar']);
$this->assertEquals('bat', $domainA['baz']);
}

public function testMergingIncompatibleTextDomains()
{
$this->setExpectedException('Zend\I18n\Exception\RuntimeException', 'is not compatible');

$domainA = new TextDomain();
$domainB = new TextDomain();
$domainB->setPluralRule(PluralRule::fromString('nplurals=3; plural=n'));

$domainA->merge($domainB);
}
}
5 changes: 2 additions & 3 deletions test/Translator/TranslatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,8 @@ public function testTranslationFromSeveralTranslationFiles()
$this->assertEquals('Nachricht 9', $translator->translate('Message 9')); //translation-more-de_DE.php
$this->assertEquals('Nachricht 10 - 0', $translator->translatePlural('Message 10', 'Message 10', 1)); //translation-de_DE.php
$this->assertEquals('Nachricht 10 - 1', $translator->translatePlural('Message 10', 'Message 10', 2)); //translation-de_DE.php
$this->assertEquals('Nachricht 11 - 0', $translator->translatePlural('Message 11', 'Message 11', 0)); //translation-more-de_DE.php
$this->assertEquals('Nachricht 11 - 1', $translator->translatePlural('Message 11', 'Message 11', 1)); //translation-more-de_DE.php
$this->assertEquals('Nachricht 11 - 2', $translator->translatePlural('Message 11', 'Message 11', 2)); //translation-more-de_DE.php
$this->assertEquals('Nachricht 11 - 0', $translator->translatePlural('Message 11', 'Message 11', 1)); //translation-more-de_DE.php
$this->assertEquals('Nachricht 11 - 1', $translator->translatePlural('Message 11', 'Message 11', 2)); //translation-more-de_DE.php
}

public function testFactoryCreatesTranslatorWithCache()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link https://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_I18n
*/

return array(
'' => array(
'plural_forms' => 'nplurals=3; plural=(n==0 ? 0 : (n == 1 ? 1 : 2));'
),
'Message 2' => 'Nachricht 2',
'Message 9' => 'Nachricht 9',
'Message 11' => array(
'Nachricht 11 - 0',
'Nachricht 11 - 1',
'Nachricht 11 - 2',
),
);
3 changes: 1 addition & 2 deletions test/Translator/_files/testarray/translation-more-de_DE.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@

return array(
'' => array(
'plural_forms' => 'nplurals=3; plural=(n==0 ? 0 : (n == 1 ? 1 : 2));'
'plural_forms' => 'nplurals=2; plural=n!=1;'
),
'Message 2' => 'Nachricht 2',
'Message 9' => 'Nachricht 9',
'Message 11' => array(
'Nachricht 11 - 0',
'Nachricht 11 - 1',
'Nachricht 11 - 2',
),
);

0 comments on commit d680762

Please sign in to comment.