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

Commit

Permalink
Merge branch 'feature/i18n-translator-ini' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
weierophinney committed Dec 10, 2012
2 parents 215be48 + fd6f1d5 commit 9e59ae6
Show file tree
Hide file tree
Showing 9 changed files with 258 additions and 1 deletion.
86 changes: 86 additions & 0 deletions src/Translator/Loader/Ini.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_I18n
*/

namespace Zend\I18n\Translator\Loader;

use Zend\Config\Reader\Ini as IniReader;
use Zend\I18n\Exception;
use Zend\I18n\Translator\Plural\Rule as PluralRule;
use Zend\I18n\Translator\TextDomain;

/**
* PHP INI format loader.
*
* @category Zend
* @package Zend_I18n
* @subpackage Translator
*/
class Ini implements FileLoaderInterface
{
/**
* load(): defined by FileLoaderInterface.
*
* @see FileLoaderInterface::load()
* @param string $locale
* @param string $filename
* @return TextDomain|null
* @throws Exception\InvalidArgumentException
*/
public function load($locale, $filename)
{
if (!is_file($filename) || !is_readable($filename)) {
throw new Exception\InvalidArgumentException(sprintf(
'Could not open file %s for reading',
$filename
));
}

$messages = array();
$iniReader = new IniReader();
$messagesNamespaced = $iniReader->fromFile($filename);

$list = $messagesNamespaced;
if (isset($messagesNamespaced['translation'])) {
$list = $messagesNamespaced['translation'];
}

foreach ($list as $message) {
if (!is_array($message) || count($message) < 2) {
throw new Exception\InvalidArgumentException(
'Each INI row must be an array with message and translation'
);
}
if (isset($message['message']) && isset($message['translation'])) {
$messages[$message['message']] = $message['translation'];
continue;
}
$messages[array_shift($message)] = array_shift($message);
}

if (!is_array($messages)) {
throw new Exception\InvalidArgumentException(sprintf(
'Expected an array, but received %s',
gettype($messages)
));
}

$textDomain = new TextDomain($messages);

if (array_key_exists('plural', $messagesNamespaced)
&& isset($messagesNamespaced['plural']['plural_forms'])
) {
$textDomain->setPluralRule(
PluralRule::fromString($messagesNamespaced['plural']['plural_forms'])
);
}

return $textDomain;
}
}
3 changes: 2 additions & 1 deletion src/Translator/LoaderPluginManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ class LoaderPluginManager extends AbstractPluginManager
* @var array
*/
protected $invokableClasses = array(
'phparray' => 'Zend\I18n\Translator\Loader\PhpArray',
'gettext' => 'Zend\I18n\Translator\Loader\Gettext',
'ini' => 'Zend\I18n\Translator\Loader\Ini',
'phparray' => 'Zend\I18n\Translator\Loader\PhpArray',
);

/**
Expand Down
94 changes: 94 additions & 0 deletions test/Translator/Loader/IniTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_I18n
*/

namespace ZendTest\I18n\Translator\Loader;

use PHPUnit_Framework_TestCase as TestCase;
use Locale;
use Zend\I18n\Translator\Loader\Ini as IniLoader;

class IniTest extends TestCase
{
protected $testFilesDir;
protected $originalLocale;

public function setUp()
{
$this->testFilesDir = realpath(__DIR__ . '/../_files');
}

public function testLoaderFailsToLoadMissingFile()
{
$loader = new IniLoader();
$this->setExpectedException('Zend\I18n\Exception\InvalidArgumentException', 'Could not open file');
$loader->load('en_EN', 'missing');
}

public function testLoaderLoadsEmptyFile()
{
$loader = new IniLoader();
$textDomain = $loader->load('en_EN', $this->testFilesDir . '/translation_empty.ini');
$this->assertInstanceOf('Zend\I18n\Translator\TextDomain', $textDomain);
}

public function testLoaderFailsToLoadNonArray()
{
$loader = new IniLoader();
$this->setExpectedException('Zend\I18n\Exception\InvalidArgumentException',
'Each INI row must be an array with message and translation');
$loader->load('en_EN', $this->testFilesDir . '/failed.ini');
}

public function testLoaderFailsToLoadBadSyntax()
{
$loader = new IniLoader();
$this->setExpectedException('Zend\I18n\Exception\InvalidArgumentException',
'Each INI row must be an array with message and translation');
$loader->load('en_EN', $this->testFilesDir . '/failed_syntax.ini');
}

public function testLoaderReturnsValidTextDomain()
{
$loader = new IniLoader();
$textDomain = $loader->load('en_EN', $this->testFilesDir . '/translation_en.ini');

$this->assertEquals('Message 1 (en)', $textDomain['Message 1']);
$this->assertEquals('Message 4 (en)', $textDomain['Message 4']);
}

public function testLoaderReturnsValidTextDomainWithFileWithoutPlural()
{
$loader = new IniLoader();
$textDomain = $loader->load('en_EN', $this->testFilesDir . '/translation_en_without_plural.ini');

$this->assertEquals('Message 1 (en)', $textDomain['Message 1']);
$this->assertEquals('Message 4 (en)', $textDomain['Message 4']);
}

public function testLoaderReturnsValidTextDomainWithSimpleSyntax()
{
$loader = new IniLoader();
$textDomain = $loader->load('en_EN', $this->testFilesDir . '/translation_en_simple_syntax.ini');

$this->assertEquals('Message 1 (en)', $textDomain['Message 1']);
$this->assertEquals('Message 4 (en)', $textDomain['Message 4']);
}

public function testLoaderLoadsPluralRules()
{
$loader = new IniLoader();
$textDomain = $loader->load('en_EN', $this->testFilesDir . '/translation_en.ini');

$this->assertEquals(2, $textDomain->getPluralRule()->evaluate(0));
$this->assertEquals(0, $textDomain->getPluralRule()->evaluate(1));
$this->assertEquals(1, $textDomain->getPluralRule()->evaluate(2));
$this->assertEquals(2, $textDomain->getPluralRule()->evaluate(10));
}
}
1 change: 1 addition & 0 deletions test/Translator/_files/failed.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
identifier1 = "Message 1"
1 change: 1 addition & 0 deletions test/Translator/_files/failed_syntax.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
identifier1[] = "Message 1"
Empty file.
26 changes: 26 additions & 0 deletions test/Translator/_files/translation_en.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[plural]
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);'

[translation]
identifier1.message = "Message 1"
identifier1.translation = "Message 1 (en)"

identifier2.message = "Message 2"
identifier2.translation = "Message 2 (en)"

identifier3.message = "Message 3"
identifier3.translation = "Message 3 (en)"

identifier4.message = "Message 4"
identifier4.translation = "Message 4 (en)"

identifier5.message = "Message 5"
identifier5.translation.0 = "Message 5 (en) Plural 0"
identifier5.translation.1 = "Message 5 (en) Plural 1"
identifier5.translation.2 = "Message 5 (en) Plural 2"

identifier6.message = "Cooking furniture"
identifier6.translation = "Küchen Möbel (en)"

identifier7.message = "Küchen Möbel"
identifier7.translation = "Cooking furniture (en)"
26 changes: 26 additions & 0 deletions test/Translator/_files/translation_en_simple_syntax.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[plural]
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);'

[translation]
identifier1[] = "Message 1"
identifier1[] = "Message 1 (en)"

identifier2[] = "Message 2"
identifier2[] = "Message 2 (en)"

identifier3[] = "Message 3"
identifier3[] = "Message 3 (en)"

identifier4[] = "Message 4"
identifier4[] = "Message 4 (en)"

identifier5.message = "Message 5"
identifier5.translation.0 = "Message 5 (en) Plural 0"
identifier5.translation.1 = "Message 5 (en) Plural 1"
identifier5.translation.2 = "Message 5 (en) Plural 2"

identifier6[] = "Cooking furniture"
identifier6[] = "Küchen Möbel (en)"

identifier7[] = "Küchen Möbel"
identifier7[] = "Cooking furniture (en)"
22 changes: 22 additions & 0 deletions test/Translator/_files/translation_en_without_plural.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
identifier1.message = "Message 1"
identifier1.translation = "Message 1 (en)"

identifier2.message = "Message 2"
identifier2.translation = "Message 2 (en)"

identifier3.message = "Message 3"
identifier3.translation = "Message 3 (en)"

identifier4.message = "Message 4"
identifier4.translation = "Message 4 (en)"

identifier5.message = "Message 5"
identifier5.translation.0 = "Message 5 (en) Plural 0"
identifier5.translation.1 = "Message 5 (en) Plural 1"
identifier5.translation.2 = "Message 5 (en) Plural 2"

identifier6.message = "Cooking furniture"
identifier6.translation = "Küchen Möbel (en)"

identifier7.message = "Küchen Möbel"
identifier7.translation = "Cooking furniture (en)"

0 comments on commit 9e59ae6

Please sign in to comment.