Commit 8f81e231 by Alexander Makarov

Fixes #4453: `yii message/extract` wasn't properly writing to po files in case…

Fixes #4453: `yii message/extract` wasn't properly writing to po files in case of multiple categories
parent ed533172
...@@ -72,6 +72,7 @@ Yii Framework 2 Change Log ...@@ -72,6 +72,7 @@ Yii Framework 2 Change Log
- Bug #4409: Upper case letters in subdirectory prefixes of controller IDs were not properly handled (qiangxue) - Bug #4409: Upper case letters in subdirectory prefixes of controller IDs were not properly handled (qiangxue)
- Bug #4412: Formatter used SI Prefixes for base 1024, now uses binary prefixes (kmindi) - Bug #4412: Formatter used SI Prefixes for base 1024, now uses binary prefixes (kmindi)
- Bug #4427: Formatter could do one division too much (kmindi) - Bug #4427: Formatter could do one division too much (kmindi)
- Bug #4453: `yii message/extract` wasn't properly writing to po files in case of multiple categories (samdark)
- Bug: Fixed inconsistent return of `\yii\console\Application::runAction()` (samdark) - Bug: Fixed inconsistent return of `\yii\console\Application::runAction()` (samdark)
- Bug: URL encoding for the route parameter added to `\yii\web\UrlManager` (klimov-paul) - Bug: URL encoding for the route parameter added to `\yii\web\UrlManager` (klimov-paul)
- Bug: Fixed the bug that requesting protected or private action methods would cause 500 error instead of 404 (qiangxue) - Bug: Fixed the bug that requesting protected or private action methods would cause 500 error instead of 404 (qiangxue)
......
...@@ -209,11 +209,11 @@ class MessageController extends Controller ...@@ -209,11 +209,11 @@ class MessageController extends Controller
} }
} }
echo $savedFlag ? "saved.\n" : "nothing new...skipped.\n"; echo $savedFlag ? "saved.\n" : "Nothing new...skipped.\n";
echo $removeUnused ? "Deleting obsoleted messages..." : "Updating obsoleted messages..."; echo $removeUnused ? "Deleting obsoleted messages..." : "Updating obsoleted messages...";
if (empty($obsolete)) { if (empty($obsolete)) {
echo "nothing obsoleted...skipped.\n"; echo "Nothing obsoleted...skipped.\n";
} else { } else {
if ($removeUnused) { if ($removeUnused) {
$db->createCommand() $db->createCommand()
...@@ -286,12 +286,10 @@ class MessageController extends Controller ...@@ -286,12 +286,10 @@ class MessageController extends Controller
foreach ($messages as $category => $msgs) { foreach ($messages as $category => $msgs) {
$file = str_replace("\\", '/', "$dirName/$category.php"); $file = str_replace("\\", '/', "$dirName/$category.php");
$path = dirname($file); $path = dirname($file);
if (!is_dir($path)) { FileHelper::createDirectory($path);
mkdir($path, 0755, true);
}
$msgs = array_values(array_unique($msgs)); $msgs = array_values(array_unique($msgs));
echo "Saving messages to $file...\n"; echo "Saving messages to $file...\n";
$this->saveMessagesCategoryToPHP($msgs, $file, $overwrite, $removeUnused, $sort); $this->saveMessagesCategoryToPHP($msgs, $file, $overwrite, $removeUnused, $sort, $category);
} }
} }
...@@ -303,23 +301,23 @@ class MessageController extends Controller ...@@ -303,23 +301,23 @@ class MessageController extends Controller
* @param boolean $overwrite if existing file should be overwritten without backup * @param boolean $overwrite if existing file should be overwritten without backup
* @param boolean $removeUnused if obsolete translations should be removed * @param boolean $removeUnused if obsolete translations should be removed
* @param boolean $sort if translations should be sorted * @param boolean $sort if translations should be sorted
* @param string $category message category
*/ */
protected function saveMessagesCategoryToPHP($messages, $fileName, $overwrite, $removeUnused, $sort) protected function saveMessagesCategoryToPHP($messages, $fileName, $overwrite, $removeUnused, $sort, $category)
{ {
if (is_file($fileName)) { if (is_file($fileName)) {
$translated = require($fileName); $existingMessages = require($fileName);
sort($messages); sort($messages);
ksort($translated); ksort($existingMessages);
if (array_keys($translated) == $messages) { if (array_keys($existingMessages) == $messages) {
echo "nothing new...skipped.\n"; echo "Nothing new in \"$category\" category... Nothing to save.\n";
return;
return self::EXIT_CODE_NORMAL;
} }
$merged = []; $merged = [];
$untranslated = []; $untranslated = [];
foreach ($messages as $message) { foreach ($messages as $message) {
if (array_key_exists($message, $translated) && strlen($translated[$message]) > 0) { if (array_key_exists($message, $existingMessages) && strlen($existingMessages[$message]) > 0) {
$merged[$message] = $translated[$message]; $merged[$message] = $existingMessages[$message];
} else { } else {
$untranslated[] = $message; $untranslated[] = $message;
} }
...@@ -330,10 +328,10 @@ class MessageController extends Controller ...@@ -330,10 +328,10 @@ class MessageController extends Controller
foreach ($untranslated as $message) { foreach ($untranslated as $message) {
$todo[$message] = ''; $todo[$message] = '';
} }
ksort($translated); ksort($existingMessages);
foreach ($translated as $message => $translation) { foreach ($existingMessages as $message => $translation) {
if (!isset($merged[$message]) && !isset($todo[$message]) && !$removeUnused) { if (!isset($merged[$message]) && !isset($todo[$message]) && !$removeUnused) {
if (substr_compare($translation, '@@', 0, 2) === 0 && substr_compare($translation, '@@', -2) === 0) { if (mb_strlen($translation, Yii::$app->charset) >= 2 && substr_compare($translation, '@@', 0, 2) === 0 && substr_compare($translation, '@@', -2) === 0) {
$todo[$message] = $translation; $todo[$message] = $translation;
} else { } else {
$todo[$message] = '@@' . $translation . '@@'; $todo[$message] = '@@' . $translation . '@@';
...@@ -355,7 +353,6 @@ class MessageController extends Controller ...@@ -355,7 +353,6 @@ class MessageController extends Controller
} }
ksort($merged); ksort($merged);
} }
echo "Saved.\n";
$array = VarDumper::export($merged); $array = VarDumper::export($merged);
...@@ -383,6 +380,7 @@ return $array; ...@@ -383,6 +380,7 @@ return $array;
EOD; EOD;
file_put_contents($fileName, $content); file_put_contents($fileName, $content);
echo "Saved.\n";
} }
/** /**
...@@ -398,10 +396,7 @@ EOD; ...@@ -398,10 +396,7 @@ EOD;
protected function saveMessagesToPO($messages, $dirName, $overwrite, $removeUnused, $sort, $catalog) protected function saveMessagesToPO($messages, $dirName, $overwrite, $removeUnused, $sort, $catalog)
{ {
$file = str_replace("\\", '/', "$dirName/$catalog.po"); $file = str_replace("\\", '/', "$dirName/$catalog.po");
$path = dirname($file); FileHelper::createDirectory(dirname($file));
if (!is_dir($path)) {
mkdir($path, 0755, true);
}
echo "Saving messages to $file...\n"; echo "Saving messages to $file...\n";
$poFile = new GettextPoFile(); $poFile = new GettextPoFile();
...@@ -411,6 +406,7 @@ EOD; ...@@ -411,6 +406,7 @@ EOD;
$notTranslatedYet = []; $notTranslatedYet = [];
$todos = []; $todos = [];
$hasSomethingToWrite = false;
foreach ($messages as $category => $msgs) { foreach ($messages as $category => $msgs) {
$msgs = array_values(array_unique($msgs)); $msgs = array_values(array_unique($msgs));
...@@ -420,8 +416,14 @@ EOD; ...@@ -420,8 +416,14 @@ EOD;
sort($msgs); sort($msgs);
ksort($existingMessages); ksort($existingMessages);
if (array_keys($existingMessages) == $msgs) { if (array_keys($existingMessages) == $msgs) {
echo "Nothing new... skipped.\n"; echo "Nothing new in \"$category\" category...\n";
return self::EXIT_CODE_NORMAL;
sort($msgs);
foreach ($msgs as $message) {
$merged[$category . chr(4) . $message] = '';
}
ksort($merged);
continue;
} }
// merge existing message translations with new message translations // merge existing message translations with new message translations
...@@ -443,7 +445,7 @@ EOD; ...@@ -443,7 +445,7 @@ EOD;
// add obsolete unused messages // add obsolete unused messages
foreach ($existingMessages as $message => $translation) { foreach ($existingMessages as $message => $translation) {
if (!isset($merged[$category . chr(4) . $message]) && !isset($todos[$category . chr(4) . $message]) && !$removeUnused) { if (!isset($merged[$category . chr(4) . $message]) && !isset($todos[$category . chr(4) . $message]) && !$removeUnused) {
if (substr($translation, 0, 2) === '@@' && substr($translation, -2) === '@@') { if (mb_strlen($translation, Yii::$app->charset) >= 2 && substr($translation, 0, 2) === '@@' && substr($translation, -2) === '@@') {
$todos[$category . chr(4) . $message] = $translation; $todos[$category . chr(4) . $message] = $translation;
} else { } else {
$todos[$category . chr(4) . $message] = '@@' . $translation . '@@'; $todos[$category . chr(4) . $message] = '@@' . $translation . '@@';
...@@ -459,8 +461,6 @@ EOD; ...@@ -459,8 +461,6 @@ EOD;
if ($overwrite === false) { if ($overwrite === false) {
$file .= '.merged'; $file .= '.merged';
} }
echo "Translation merged.\n";
} else { } else {
sort($msgs); sort($msgs);
foreach ($msgs as $message) { foreach ($msgs as $message) {
...@@ -468,8 +468,14 @@ EOD; ...@@ -468,8 +468,14 @@ EOD;
} }
ksort($merged); ksort($merged);
} }
echo "Category \"$category\" merged.\n";
$hasSomethingToWrite = true;
}
if ($hasSomethingToWrite) {
$poFile->save($file, $merged);
echo "Saved.\n";
} else {
echo "Nothing to save.\n";
} }
$poFile->save($file, $merged);
echo "Saved.\n";
} }
} }
...@@ -15,8 +15,6 @@ return [ ...@@ -15,8 +15,6 @@ return [
// with the existing ones. Defaults to false, which means the new (untranslated) // with the existing ones. Defaults to false, which means the new (untranslated)
// messages will be separated from the old (translated) ones. // messages will be separated from the old (translated) ones.
'sort' => false, 'sort' => false,
// boolean, whether the message file should be overwritten with the merged messages
'overwrite' => true,
// boolean, whether to remove messages that no longer appear in the source code. // boolean, whether to remove messages that no longer appear in the source code.
// Defaults to false, which means each of these messages will be enclosed with a pair of '@@' marks. // Defaults to false, which means each of these messages will be enclosed with a pair of '@@' marks.
'removeUnused' => false, 'removeUnused' => false,
...@@ -47,6 +45,8 @@ return [ ...@@ -47,6 +45,8 @@ return [
'format' => 'php', 'format' => 'php',
// Root directory containing message translations. // Root directory containing message translations.
'messagePath' => __DIR__ . DIRECTORY_SEPARATOR . 'messages', 'messagePath' => __DIR__ . DIRECTORY_SEPARATOR . 'messages',
// boolean, whether the message file should be overwritten with the merged messages
'overwrite' => true,
/* /*
...@@ -67,5 +67,7 @@ return [ ...@@ -67,5 +67,7 @@ return [
'messagePath' => __DIR__ . DIRECTORY_SEPARATOR . 'messages', 'messagePath' => __DIR__ . DIRECTORY_SEPARATOR . 'messages',
// Name of the file that will be used for translations. // Name of the file that will be used for translations.
'catalog' => 'messages', 'catalog' => 'messages',
// boolean, whether the message file should be overwritten with the merged messages
'overwrite' => true,
*/ */
]; ];
<?php
namespace yiiunit\framework\console\controllers;
use Yii;
use yii\helpers\FileHelper;
use yii\helpers\VarDumper;
/**
* Tests that [[\yii\console\controllers\MessageController]] works as expected with PHP message format.
*/
class PHPMessageControllerTest extends BaseMessageControllerTest
{
protected $messagePath;
public function setUp()
{
parent::setUp();
$this->messagePath = Yii::getAlias('@yiiunit/runtime/test_messages');
FileHelper::createDirectory($this->messagePath, 0777);
}
public function tearDown()
{
parent::tearDown();
FileHelper::removeDirectory($this->messagePath);
}
/**
* @inheritdoc
*/
protected function getDefaultConfig()
{
return [
'format' => 'php',
'languages' => [$this->language],
'sourcePath' => $this->sourcePath,
'messagePath' => $this->messagePath,
'overwrite' => true,
];
}
/**
* @param string $category
* @return string message file path
*/
protected function getMessageFilePath($category)
{
return $this->messagePath . '/' . $this->language . '/' . $category . '.php';
}
/**
* @inheritdoc
*/
protected function saveMessages($messages, $category)
{
$fileName = $this->getMessageFilePath($category);
if (file_exists($fileName)) {
unlink($fileName);
} else {
$dirName = dirname($fileName);
if (!file_exists($dirName)) {
mkdir($dirName, 0777, true);
}
}
$fileContent = '<?php return ' . VarDumper::export($messages) . ';';
file_put_contents($fileName, $fileContent);
}
/**
* @inheritdoc
*/
protected function loadMessages($category)
{
if (defined('HHVM_VERSION')) {
// https://github.com/facebook/hhvm/issues/1447
$this->markTestSkipped('Can not test on HHVM because require is cached.');
}
$messageFilePath = $this->getMessageFilePath($category);
$this->assertTrue(file_exists($messageFilePath), "There's no message file $messageFilePath!");
return require $messageFilePath;
}
}
\ No newline at end of file
<?php
namespace yiiunit\framework\console\controllers;
use Yii;
use yii\helpers\FileHelper;
use yii\i18n\GettextPoFile;
/**
* Tests that [[\yii\console\controllers\MessageController]] works as expected with PO message format.
*/
class POMessageControllerTest extends BaseMessageControllerTest
{
protected $messagePath;
protected $catalog = 'messages';
public function setUp()
{
parent::setUp();
$this->messagePath = Yii::getAlias('@yiiunit/runtime/test_messages');
FileHelper::createDirectory($this->messagePath, 0777);
}
public function tearDown()
{
parent::tearDown();
FileHelper::removeDirectory($this->messagePath);
}
/**
* @inheritdoc
*/
protected function getDefaultConfig()
{
return [
'format' => 'po',
'languages' => [$this->language],
'sourcePath' => $this->sourcePath,
'messagePath' => $this->messagePath,
'overwrite' => true,
];
}
/**
* @return string message file path
*/
protected function getMessageFilePath()
{
return $this->messagePath . '/' . $this->language . '/' . $this->catalog . '.po';
}
/**
* @inheritdoc
*/
protected function saveMessages($messages, $category)
{
$messageFilePath = $this->getMessageFilePath();
FileHelper::createDirectory(dirname($messageFilePath), 0777);
$gettext = new GettextPoFile();
$data = [];
foreach ($messages as $message => $translation) {
$data[$category . chr(4) . $message] = $translation;
}
$gettext->save($messageFilePath, $data);
}
/**
* @inheritdoc
*/
protected function loadMessages($category)
{
$messageFilePath = $this->getMessageFilePath();
$this->assertTrue(file_exists($messageFilePath), "There's no message file $messageFilePath!");
$gettext = new GettextPoFile();
return $gettext->load($messageFilePath, $category);
}
}
\ No newline at end of file
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