-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #221 from resurtm/get-text-i18n
[WIP] Gettext support
- Loading branch information
Showing
9 changed files
with
728 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
msgid "" | ||
msgstr "" | ||
"Project-Id-Version: \n" | ||
"POT-Creation-Date: \n" | ||
"PO-Revision-Date: \n" | ||
"Last-Translator: resurtm <[email protected]>\n" | ||
"Language-Team: \n" | ||
"MIME-Version: 1.0\n" | ||
"Content-Type: text/plain; charset=UTF-8\n" | ||
"Content-Transfer-Encoding: 8bit\n" | ||
"X-Generator: Poedit 1.5.5\n" | ||
|
||
msgctxt "context1" | ||
msgid "" | ||
"Aliquam tempus elit vel purus molestie placerat. In sollicitudin tincidunt\n" | ||
"aliquet. Integer tincidunt gravida tempor. In convallis blandit dui vel " | ||
"malesuada.\n" | ||
"Nunc vel sapien nunc, a pretium nulla." | ||
msgstr "" | ||
"Олицетворение однократно. Представленный лексико-семантический анализ " | ||
"является\n" | ||
"психолингвистическим в своей основе, но механизм сочленений полидисперсен. " | ||
"Впечатление\n" | ||
"однократно. Различное расположение выбирает сюжетный механизм сочленений." | ||
|
||
msgctxt "context1" | ||
msgid "String number two." | ||
msgstr "Строка номер два." | ||
|
||
msgctxt "context2" | ||
msgid "" | ||
"The other\n" | ||
"\n" | ||
"context.\n" | ||
msgstr "" | ||
"Другой\n" | ||
"\n" | ||
"контекст.\n" | ||
|
||
msgctxt "context1" | ||
msgid "" | ||
"Missing\n" | ||
"\r\t\"translation." | ||
msgstr "" | ||
|
||
msgctxt "context1" | ||
msgid "" | ||
"Nunc vel sapien nunc, a pretium nulla.\n" | ||
"Pellentesque habitant morbi tristique senectus et netus et malesuada fames " | ||
"ac turpis egestas." | ||
msgstr "Короткий перевод." | ||
|
||
msgid "contextless" | ||
msgstr "" | ||
|
||
msgctxt "context2" | ||
msgid "" | ||
"test1\\ntest2\n" | ||
"\\\n" | ||
"test3" | ||
msgstr "" | ||
"тест1\\nтест2\n" | ||
"\\\n" | ||
"тест3" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<?php | ||
|
||
namespace yiiunit\framework\i18n; | ||
|
||
use yii\i18n\GettextMessageSource; | ||
use yiiunit\TestCase; | ||
|
||
class GettextMessageSourceTest extends TestCase | ||
{ | ||
public function testLoadMessages() | ||
{ | ||
$this->markTestSkipped(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
<?php | ||
|
||
namespace yiiunit\framework\i18n; | ||
|
||
use yii\i18n\GettextMoFile; | ||
use yiiunit\TestCase; | ||
|
||
class GettextMoFileTest extends TestCase | ||
{ | ||
public function testLoad() | ||
{ | ||
$moFile = new GettextMoFile(); | ||
$moFilePath = __DIR__ . '/../../data/i18n/test.mo'; | ||
$context1 = $moFile->load($moFilePath, 'context1'); | ||
$context2 = $moFile->load($moFilePath, 'context2'); | ||
|
||
// item count | ||
$this->assertCount(3, $context1); | ||
$this->assertCount(2, $context2); | ||
|
||
// original messages | ||
$this->assertArrayNotHasKey("Missing\n\r\t\"translation.", $context1); | ||
$this->assertArrayHasKey("Aliquam tempus elit vel purus molestie placerat. In sollicitudin tincidunt\naliquet. Integer tincidunt gravida tempor. In convallis blandit dui vel malesuada.\nNunc vel sapien nunc, a pretium nulla.", $context1); | ||
$this->assertArrayHasKey("String number two.", $context1); | ||
$this->assertArrayHasKey("Nunc vel sapien nunc, a pretium nulla.\nPellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.", $context1); | ||
|
||
$this->assertArrayHasKey("The other\n\ncontext.\n", $context2); | ||
$this->assertArrayHasKey("test1\\ntest2\n\\\ntest3", $context2); | ||
|
||
// translated messages | ||
$this->assertFalse(in_array("", $context1)); | ||
$this->assertTrue(in_array("Олицетворение однократно. Представленный лексико-семантический анализ является\nпсихолингвистическим в своей основе, но механизм сочленений полидисперсен. Впечатление\nоднократно. Различное расположение выбирает сюжетный механизм сочленений.", $context1)); | ||
$this->assertTrue(in_array('Строка номер два.', $context1)); | ||
$this->assertTrue(in_array('Короткий перевод.', $context1)); | ||
|
||
$this->assertTrue(in_array("Другой\n\nконтекст.\n", $context2)); | ||
$this->assertTrue(in_array("тест1\\nтест2\n\\\nтест3", $context2)); | ||
} | ||
|
||
public function testSave() | ||
{ | ||
// initial data | ||
$s = chr(4); | ||
$messages = array( | ||
'Hello!' => 'Привет!', | ||
"context1{$s}Hello?" => 'Привет?', | ||
'Hello!?' => '', | ||
"context1{$s}Hello!?!" => '', | ||
"context2{$s}\"Quotes\"" => '"Кавычки"', | ||
"context2{$s}\nNew lines\n" => "\nПереносы строк\n", | ||
"context2{$s}\tTabs\t" => "\tТабы\t", | ||
"context2{$s}\rCarriage returns\r" => "\rВозвраты кареток\r", | ||
); | ||
|
||
// create temporary directory and dump messages | ||
$poFileDirectory = __DIR__ . '/../../runtime/i18n'; | ||
if (!is_dir($poFileDirectory)) { | ||
mkdir($poFileDirectory); | ||
} | ||
if (is_file($poFileDirectory . '/test.mo')) { | ||
unlink($poFileDirectory . '/test.mo'); | ||
} | ||
|
||
$moFile = new GettextMoFile(); | ||
$moFile->save($poFileDirectory . '/test.mo', $messages); | ||
|
||
// load messages | ||
$context1 = $moFile->load($poFileDirectory . '/test.mo', 'context1'); | ||
$context2 = $moFile->load($poFileDirectory . '/test.mo', 'context2'); | ||
|
||
// context1 | ||
$this->assertCount(2, $context1); | ||
|
||
$this->assertArrayHasKey('Hello?', $context1); | ||
$this->assertTrue(in_array('Привет?', $context1)); | ||
|
||
$this->assertArrayHasKey('Hello!?!', $context1); | ||
$this->assertTrue(in_array('', $context1)); | ||
|
||
// context2 | ||
$this->assertCount(4, $context2); | ||
|
||
$this->assertArrayHasKey("\"Quotes\"", $context2); | ||
$this->assertTrue(in_array('"Кавычки"', $context2)); | ||
|
||
$this->assertArrayHasKey("\nNew lines\n", $context2); | ||
$this->assertTrue(in_array("\nПереносы строк\n", $context2)); | ||
|
||
$this->assertArrayHasKey("\tTabs\t", $context2); | ||
$this->assertTrue(in_array("\tТабы\t", $context2)); | ||
|
||
$this->assertArrayHasKey("\rCarriage returns\r", $context2); | ||
$this->assertTrue(in_array("\rВозвраты кареток\r", $context2)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
<?php | ||
|
||
namespace yiiunit\framework\i18n; | ||
|
||
use yii\i18n\GettextPoFile; | ||
use yiiunit\TestCase; | ||
|
||
class GettextPoFileTest extends TestCase | ||
{ | ||
public function testLoad() | ||
{ | ||
$poFile = new GettextPoFile(); | ||
$poFilePath = __DIR__ . '/../../data/i18n/test.po'; | ||
$context1 = $poFile->load($poFilePath, 'context1'); | ||
$context2 = $poFile->load($poFilePath, 'context2'); | ||
|
||
// item count | ||
$this->assertCount(4, $context1); | ||
$this->assertCount(2, $context2); | ||
|
||
// original messages | ||
$this->assertArrayHasKey("Missing\n\r\t\"translation.", $context1); | ||
$this->assertArrayHasKey("Aliquam tempus elit vel purus molestie placerat. In sollicitudin tincidunt\naliquet. Integer tincidunt gravida tempor. In convallis blandit dui vel malesuada.\nNunc vel sapien nunc, a pretium nulla.", $context1); | ||
$this->assertArrayHasKey("String number two.", $context1); | ||
$this->assertArrayHasKey("Nunc vel sapien nunc, a pretium nulla.\nPellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.", $context1); | ||
|
||
$this->assertArrayHasKey("The other\n\ncontext.\n", $context2); | ||
$this->assertArrayHasKey("test1\\\ntest2\n\\\\\ntest3", $context2); | ||
|
||
// translated messages | ||
$this->assertTrue(in_array("", $context1)); | ||
$this->assertTrue(in_array("Олицетворение однократно. Представленный лексико-семантический анализ является\nпсихолингвистическим в своей основе, но механизм сочленений полидисперсен. Впечатление\nоднократно. Различное расположение выбирает сюжетный механизм сочленений.", $context1)); | ||
$this->assertTrue(in_array('Строка номер два.', $context1)); | ||
$this->assertTrue(in_array('Короткий перевод.', $context1)); | ||
|
||
$this->assertTrue(in_array("Другой\n\nконтекст.\n", $context2)); | ||
$this->assertTrue(in_array("тест1\\\nтест2\n\\\\\nтест3", $context2)); | ||
} | ||
|
||
public function testSave() | ||
{ | ||
// initial data | ||
$s = chr(4); | ||
$messages = array( | ||
'Hello!' => 'Привет!', | ||
"context1{$s}Hello?" => 'Привет?', | ||
'Hello!?' => '', | ||
"context1{$s}Hello!?!" => '', | ||
"context2{$s}\"Quotes\"" => '"Кавычки"', | ||
"context2{$s}\nNew lines\n" => "\nПереносы строк\n", | ||
"context2{$s}\tTabs\t" => "\tТабы\t", | ||
"context2{$s}\rCarriage returns\r" => "\rВозвраты кареток\r", | ||
); | ||
|
||
// create temporary directory and dump messages | ||
$poFileDirectory = __DIR__ . '/../../runtime/i18n'; | ||
if (!is_dir($poFileDirectory)) { | ||
mkdir($poFileDirectory); | ||
} | ||
if (is_file($poFileDirectory . '/test.po')) { | ||
unlink($poFileDirectory . '/test.po'); | ||
} | ||
|
||
$poFile = new GettextPoFile(); | ||
$poFile->save($poFileDirectory . '/test.po', $messages); | ||
|
||
// load messages | ||
$context1 = $poFile->load($poFileDirectory . '/test.po', 'context1'); | ||
$context2 = $poFile->load($poFileDirectory . '/test.po', 'context2'); | ||
|
||
// context1 | ||
$this->assertCount(2, $context1); | ||
|
||
$this->assertArrayHasKey('Hello?', $context1); | ||
$this->assertTrue(in_array('Привет?', $context1)); | ||
|
||
$this->assertArrayHasKey('Hello!?!', $context1); | ||
$this->assertTrue(in_array('', $context1)); | ||
|
||
// context2 | ||
$this->assertCount(4, $context2); | ||
|
||
$this->assertArrayHasKey("\"Quotes\"", $context2); | ||
$this->assertTrue(in_array('"Кавычки"', $context2)); | ||
|
||
$this->assertArrayHasKey("\nNew lines\n", $context2); | ||
$this->assertTrue(in_array("\nПереносы строк\n", $context2)); | ||
|
||
$this->assertArrayHasKey("\tTabs\t", $context2); | ||
$this->assertTrue(in_array("\tТабы\t", $context2)); | ||
|
||
$this->assertArrayHasKey("\rCarriage returns\r", $context2); | ||
$this->assertTrue(in_array("\rВозвраты кареток\r", $context2)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<?php | ||
/** | ||
* @link http://www.yiiframework.com/ | ||
* @copyright Copyright (c) 2008 Yii Software LLC | ||
* @license http://www.yiiframework.com/license/ | ||
*/ | ||
|
||
namespace yii\i18n; | ||
|
||
use yii\base\Component; | ||
|
||
/** | ||
* GettextFile is the base class for representing a Gettext message file. | ||
* | ||
* @author Qiang Xue <[email protected]> | ||
* @since 2.0 | ||
*/ | ||
abstract class GettextFile extends Component | ||
{ | ||
/** | ||
* Loads messages from a file. | ||
* @param string $filePath file path | ||
* @param string $context message context | ||
* @return array message translations. Array keys are source messages and array values are translated messages: | ||
* source message => translated message. | ||
*/ | ||
abstract public function load($filePath, $context); | ||
|
||
/** | ||
* Saves messages to a file. | ||
* @param string $filePath file path | ||
* @param array $messages message translations. Array keys are source messages and array values are | ||
* translated messages: source message => translated message. Note if the message has a context, | ||
* the message ID must be prefixed with the context with chr(4) as the separator. | ||
*/ | ||
abstract public function save($filePath, $messages); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<?php | ||
/** | ||
* @link http://www.yiiframework.com/ | ||
* @copyright Copyright (c) 2008 Yii Software LLC | ||
* @license http://www.yiiframework.com/license/ | ||
*/ | ||
|
||
namespace yii\i18n; | ||
|
||
use Yii; | ||
|
||
class GettextMessageSource extends MessageSource | ||
{ | ||
const MO_FILE_EXT = '.mo'; | ||
const PO_FILE_EXT = '.po'; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
public $basePath = '@app/messages'; | ||
/** | ||
* @var string | ||
*/ | ||
public $catalog = 'messages'; | ||
/** | ||
* @var boolean | ||
*/ | ||
public $useMoFile = true; | ||
/** | ||
* @var boolean | ||
*/ | ||
public $useBigEndian = false; | ||
|
||
protected function loadMessages($category, $language) | ||
{ | ||
$messageFile = Yii::getAlias($this->basePath) . '/' . $language . '/' . $this->catalog; | ||
if ($this->useMoFile) { | ||
$messageFile .= static::MO_FILE_EXT; | ||
} else { | ||
$messageFile .= static::PO_FILE_EXT; | ||
} | ||
|
||
if (is_file($messageFile)) { | ||
if ($this->useMoFile) { | ||
$gettextFile = new GettextMoFile(array('useBigEndian' => $this->useBigEndian)); | ||
} else { | ||
$gettextFile = new GettextPoFile(); | ||
} | ||
$messages = $gettextFile->load($messageFile, $category); | ||
if (!is_array($messages)) { | ||
$messages = array(); | ||
} | ||
return $messages; | ||
} else { | ||
Yii::error("The message file for category '$category' does not exist: $messageFile", __METHOD__); | ||
return array(); | ||
} | ||
} | ||
} |
Oops, something went wrong.