diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 2669d36bb6..a4ee3964c1 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -81,6 +81,7 @@ Yii Framework 2 Change Log - Enh #10264: Generation of HTML tags in Yii's JavaScript now uses jQuery style (silverfire) - Enh #10267: `yii.js` - added original event passing to `pjaxOptions` for links with `data-method` and `data-pjax` (servocoder, silverfire) - Enh #10319: `yii\helpers\VarDumper::dump()` now respects PHP magic method `__debugInfo()` (klimov-paul) +- Enh #10359: Support wildcard category name in `yii/console/controllers/MessageController` (rmrevin) - Enh: Added last resort measure for `FileHelper::removeDirectory()` fail to unlink symlinks under Windows (samdark) - Chg #9369: `Yii::$app->user->can()` now returns `false` instead of erroring in case `authManager` component is not configured (creocoder) - Chg #9411: `DetailView` now automatically sets container tag ID in case it's not specified (samdark) diff --git a/framework/console/controllers/MessageController.php b/framework/console/controllers/MessageController.php index 10b4ebf89c..f8e10329b2 100644 --- a/framework/console/controllers/MessageController.php +++ b/framework/console/controllers/MessageController.php @@ -130,7 +130,8 @@ class MessageController extends Controller */ public $catalog = 'messages'; /** - * @var array message categories to ignore. For example, 'yii'. + * @var array message categories to ignore. For example, 'yii', 'app*', 'widgets/menu', etc. + * @see isCategoryIgnored */ public $ignoreCategories = []; @@ -478,7 +479,7 @@ EOD; $category = stripcslashes($buffer[0][1]); $category = mb_substr($category, 1, mb_strlen($category) - 2); - if (!in_array($category, $ignoreCategories, true)) { + if (!$this->isCategoryIgnored($category, $ignoreCategories)) { $message = stripcslashes($buffer[2][1]); $message = mb_substr($message, 1, mb_strlen($message) - 2); @@ -520,6 +521,37 @@ EOD; return $messages; } + /** + * The method checks, whether the $category is ignored according to $ignoreCategories array. + * Examples: + * + * - `myapp` - will be ignored only `myapp` category; + * - `myapp*` - will be ignored by all categories beginning with `myapp` (`myapp`, `myapplication`, `myapprove`, `myapp/widgets`, `myapp.widgets`, etc). + * + * @param string $category category that is checked + * @param array $ignoreCategories message categories to ignore. + * @return boolean + */ + protected function isCategoryIgnored($category, array $ignoreCategories) + { + $result = false; + + if (!empty($ignoreCategories)) { + if (in_array($category, $ignoreCategories, true)) { + $result = true; + } else { + foreach ($ignoreCategories as $pattern) { + if (strpos($pattern, '*') > 0 && strpos($category, rtrim($pattern, '*')) === 0) { + $result = true; + break; + } + } + } + } + + return $result; + } + /** * Finds out if two PHP tokens are equal * diff --git a/tests/framework/console/controllers/BaseMessageControllerTest.php b/tests/framework/console/controllers/BaseMessageControllerTest.php index 802daab421..6e309bf6ee 100644 --- a/tests/framework/console/controllers/BaseMessageControllerTest.php +++ b/tests/framework/console/controllers/BaseMessageControllerTest.php @@ -155,7 +155,7 @@ abstract class BaseMessageControllerTest extends TestCase { $category = 'test_category2'; $message = 'test message'; - $sourceFileContent = "Yii::t('{$category}', '{$message}')"; + $sourceFileContent = "Yii::t('{$category}', '{$message}');"; $this->createSourceFile($sourceFileContent); $this->saveConfigFile($this->getConfig()); @@ -256,9 +256,9 @@ abstract class BaseMessageControllerTest extends TestCase ], $category); $newMessage = 'test new message'; - $sourceFileContent = "Yii::t('{$category}', '{$zeroMessage}')"; - $sourceFileContent .= "Yii::t('{$category}', '{$falseMessage}')"; - $sourceFileContent .= "Yii::t('{$category}', '{$newMessage}')"; + $sourceFileContent = "Yii::t('{$category}', '{$zeroMessage}');"; + $sourceFileContent .= "Yii::t('{$category}', '{$falseMessage}');"; + $sourceFileContent .= "Yii::t('{$category}', '{$newMessage}');"; $this->createSourceFile($sourceFileContent); $this->saveConfigFile($this->getConfig()); @@ -345,25 +345,29 @@ abstract class BaseMessageControllerTest extends TestCase { $category1 = 'category1'; $category2 = 'category2'; + $category3_wildcard = 'category3*'; + $category3_test = 'category3-test'; $message1 = 'message1'; $message2 = 'message2'; $message3 = 'message3'; - $this->saveConfigFile($this->getConfig(['ignoreCategories' => ['category2']])); + $this->saveConfigFile($this->getConfig(['ignoreCategories' => [$category2, $category3_wildcard]])); // Generate initial translation - $sourceFileContent = "Yii::t('{$category1}', '{$message1}'); Yii::t('{$category2}', '{$message2}');"; + $sourceFileContent = "Yii::t('{$category1}', '{$message1}'); Yii::t('{$category2}', '{$message2}'); Yii::t('{$category3_test}', '{$message3}');"; $source = $this->createSourceFile($sourceFileContent); $out = $this->runMessageControllerAction('extract', [$this->configFileName]); unlink($source); $messages1 = $this->loadMessages($category1); - $messages2 = $this->loadMessages($category2, false); + $messages2 = $this->loadMessages($category2); + $messages3 = $this->loadMessages($category3_test); - $this->assertArrayHasKey($message1, $messages1, "message1 not found in category1. Command output:\n\n" . $out); - $this->assertArrayNotHasKey($message2, $messages2, "message2 found in category2. Command output:\n\n" . $out); - $this->assertArrayNotHasKey($message3, $messages2, "message3 found in category2. Command output:\n\n" . $out); + $this->assertArrayHasKey($message1, $messages1, "{$message1} not found in {$category1}. Command output:\n\n" . $out); + $this->assertArrayNotHasKey($message2, $messages2, "{$message2} found in {$category2}. Command output:\n\n" . $out); + $this->assertArrayNotHasKey($message3, $messages2, "{$message3} found in {$category2}. Command output:\n\n" . $out); + $this->assertArrayNotHasKey($message3, $messages3, "{$message3} found in {$category3_test}. Command output:\n\n" . $out); // Change source code, run translation again $sourceFileContent = "Yii::t('{$category1}', '{$message1}'); Yii::t('{$category2}', '{$message3}');"; @@ -372,10 +376,10 @@ abstract class BaseMessageControllerTest extends TestCase unlink($source); $messages1 = $this->loadMessages($category1); - $messages2 = $this->loadMessages($category2, false); - $this->assertArrayHasKey($message1, $messages1, "message1 not found in category1. Command output:\n\n" . $out); - $this->assertArrayNotHasKey($message3, $messages2, "message3 not found in category2. Command output:\n\n" . $out); - $this->assertArrayNotHasKey($message2, $messages2, "message2 found in category2. Command output:\n\n" . $out); + $messages2 = $this->loadMessages($category2); + $this->assertArrayHasKey($message1, $messages1, "{$message1} not found in {$category1}. Command output:\n\n" . $out); + $this->assertArrayNotHasKey($message2, $messages2, "{$message2} found in {$category2}. Command output:\n\n" . $out); + $this->assertArrayNotHasKey($message3, $messages2, "{$message3} not found in {$category2}. Command output:\n\n" . $out); } /**