From 6e2b1782e52f8122302b84c331b30deec8972041 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Alekseev" Date: Tue, 18 Dec 2018 01:26:41 +0300 Subject: [PATCH] Fix #16855: Ignore console commands that have no actions --- framework/CHANGELOG.md | 3 +- framework/console/UnknownCommandException.php | 21 ++- .../console/controllers/HelpController.php | 147 ++++++++---------- .../console/controllers/FakeController.php | 27 ++++ .../controllers/FakeEmptyController.php | 18 +++ .../controllers/FakeNoDefaultController.php | 23 +++ .../console/UnknownCommandExceptionTest.php | 4 + .../controllers/HelpControllerTest.php | 27 +++- 8 files changed, 174 insertions(+), 96 deletions(-) create mode 100644 tests/data/console/controllers/FakeController.php create mode 100644 tests/data/console/controllers/FakeEmptyController.php create mode 100644 tests/data/console/controllers/FakeNoDefaultController.php diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index a0088dd922..f610d23cf4 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -6,7 +6,7 @@ Yii Framework 2 Change Log - Bug #17549: Fix `yii\db\ExpressionInterface` not supported in `yii\db\conditions\SimpleConditionBuilder` (razvanphp) - Bug #17434: Fix regular expression illegal character; Repeated fix for Internet Explorer 11 AJAX redirect bug in case of 301 and 302 response codes (`XMLHttpRequest: Network Error 0x800c0008`) (kamarton) - +- Bug #16855: Ignore console commands that have no actions (alexeevdv) 2.0.26 September 03, 2019 ------------------------- @@ -255,6 +255,7 @@ Yii Framework 2 Change Log - Enh: `yii\helpers\UnsetArrayValue`, `yii\helpers\ReplaceArrayValue` object now can be restored after serialization using `var_export()` function (silvefire) - Chg #16192: `yii\db\Command::logQuery()` is now protected, extracted `getCacheKey()` from `queryInternal()` (drlibra) - Chg #16941: Set `yii\console\controllers\MigrateController::useTablePrefix` to true as default value (GHopperMSK) +- Bug #16687: Add missing translations for `nl-NL` durations used in `yii\i18n\Formatter::asDuration()` (alexeevdv) 2.0.15.1 March 21, 2018 diff --git a/framework/console/UnknownCommandException.php b/framework/console/UnknownCommandException.php index 6498215047..3dc4aed1bc 100644 --- a/framework/console/UnknownCommandException.php +++ b/framework/console/UnknownCommandException.php @@ -76,21 +76,18 @@ class UnknownCommandException extends Exception $availableActions = []; foreach ($helpController->getCommands() as $command) { $result = $this->application->createController($command); - if ($result === false) { - continue; - } - // add the command itself (default action) - $availableActions[] = $command; - - // add all actions of this controller /** @var $controller Controller */ list($controller, $actionID) = $result; + if ($controller->createAction($controller->defaultAction) !== null) { + // add the command itself (default action) + $availableActions[] = $command; + } + + // add all actions of this controller $actions = $helpController->getActions($controller); - if (!empty($actions)) { - $prefix = $controller->getUniqueId(); - foreach ($actions as $action) { - $availableActions[] = $prefix . '/' . $action; - } + $prefix = $controller->getUniqueId(); + foreach ($actions as $action) { + $availableActions[] = $prefix . '/' . $action; } } diff --git a/framework/console/controllers/HelpController.php b/framework/console/controllers/HelpController.php index 4d3252b48c..b4db783c15 100644 --- a/framework/console/controllers/HelpController.php +++ b/framework/console/controllers/HelpController.php @@ -77,18 +77,15 @@ class HelpController extends Controller { foreach ($this->getCommandDescriptions() as $command => $description) { $result = Yii::$app->createController($command); - if ($result === false || !($result[0] instanceof Controller)) { - continue; - } /** @var $controller Controller */ list($controller, $actionID) = $result; $actions = $this->getActions($controller); - if (!empty($actions)) { - $prefix = $controller->getUniqueId(); + $prefix = $controller->getUniqueId(); + if ($controller->createAction($controller->defaultAction) !== null) { $this->stdout("$prefix\n"); - foreach ($actions as $action) { - $this->stdout("$prefix/$action\n"); - } + } + foreach ($actions as $action) { + $this->stdout("$prefix/$action\n"); } } } @@ -174,7 +171,15 @@ class HelpController extends Controller { $commands = $this->getModuleCommands(Yii::$app); sort($commands); - return array_unique($commands); + return array_filter(array_unique($commands), function ($command) { + $result = Yii::$app->createController($command); + if ($result === false || !$result[0] instanceof Controller) { + return false; + } + list($controller, $actionID) = $result; + $actions = $this->getActions($controller); + return $actions !== []; + }); } /** @@ -185,16 +190,10 @@ class HelpController extends Controller { $descriptions = []; foreach ($this->getCommands() as $command) { - $description = ''; - $result = Yii::$app->createController($command); - if ($result !== false && $result[0] instanceof Controller) { - list($controller, $actionID) = $result; - /** @var Controller $controller */ - $description = $controller->getHelpSummary(); - } - - $descriptions[$command] = $description; + /** @var Controller $controller */ + list($controller, $actionID) = $result; + $descriptions[$command] = $controller->getHelpSummary(); } return $descriptions; @@ -292,68 +291,56 @@ class HelpController extends Controller { $commands = $this->getCommandDescriptions(); $this->stdout($this->getDefaultHelpHeader()); - if (!empty($commands)) { - $this->stdout("\nThe following commands are available:\n\n", Console::BOLD); - $len = 0; - foreach ($commands as $command => $description) { - $result = Yii::$app->createController($command); - if ($result !== false && $result[0] instanceof Controller) { - /** @var $controller Controller */ - list($controller, $actionID) = $result; - $actions = $this->getActions($controller); - if (!empty($actions)) { - $prefix = $controller->getUniqueId(); - foreach ($actions as $action) { - $string = $prefix . '/' . $action; - if ($action === $controller->defaultAction) { - $string .= ' (default)'; - } - if (($l = strlen($string)) > $len) { - $len = $l; - } - } - } - } elseif (($l = strlen($command)) > $len) { - $len = $l; - } - } - foreach ($commands as $command => $description) { - $this->stdout('- ' . $this->ansiFormat($command, Console::FG_YELLOW)); - $this->stdout(str_repeat(' ', $len + 4 - strlen($command))); - $this->stdout(Console::wrapText($description, $len + 4 + 2), Console::BOLD); - $this->stdout("\n"); - - $result = Yii::$app->createController($command); - if ($result !== false && $result[0] instanceof Controller) { - list($controller, $actionID) = $result; - $actions = $this->getActions($controller); - if (!empty($actions)) { - $prefix = $controller->getUniqueId(); - foreach ($actions as $action) { - $string = ' ' . $prefix . '/' . $action; - $this->stdout(' ' . $this->ansiFormat($string, Console::FG_GREEN)); - if ($action === $controller->defaultAction) { - $string .= ' (default)'; - $this->stdout(' (default)', Console::FG_YELLOW); - } - $summary = $controller->getActionHelpSummary($controller->createAction($action)); - if ($summary !== '') { - $this->stdout(str_repeat(' ', $len + 4 - strlen($string))); - $this->stdout(Console::wrapText($summary, $len + 4 + 2)); - } - $this->stdout("\n"); - } - } - $this->stdout("\n"); - } - } - $scriptName = $this->getScriptName(); - $this->stdout("\nTo see the help of each command, enter:\n", Console::BOLD); - $this->stdout("\n $scriptName " . $this->ansiFormat('help', Console::FG_YELLOW) . ' ' - . $this->ansiFormat('', Console::FG_CYAN) . "\n\n"); - } else { + if (empty($commands)) { $this->stdout("\nNo commands are found.\n\n", Console::BOLD); + return; } + + $this->stdout("\nThe following commands are available:\n\n", Console::BOLD); + $maxLength = 0; + foreach ($commands as $command => $description) { + $result = Yii::$app->createController($command); + /** @var $controller Controller */ + list($controller, $actionID) = $result; + $actions = $this->getActions($controller); + $prefix = $controller->getUniqueId(); + foreach ($actions as $action) { + $string = $prefix . '/' . $action; + if ($action === $controller->defaultAction) { + $string .= ' (default)'; + } + $maxLength = max($maxLength, strlen($string)); + } + } + foreach ($commands as $command => $description) { + $result = Yii::$app->createController($command); + list($controller, $actionID) = $result; + $actions = $this->getActions($controller); + $this->stdout('- ' . $this->ansiFormat($command, Console::FG_YELLOW)); + $this->stdout(str_repeat(' ', $maxLength + 4 - strlen($command))); + $this->stdout(Console::wrapText($description, $maxLength + 4 + 2), Console::BOLD); + $this->stdout("\n"); + $prefix = $controller->getUniqueId(); + foreach ($actions as $action) { + $string = ' ' . $prefix . '/' . $action; + $this->stdout(' ' . $this->ansiFormat($string, Console::FG_GREEN)); + if ($action === $controller->defaultAction) { + $string .= ' (default)'; + $this->stdout(' (default)', Console::FG_YELLOW); + } + $summary = $controller->getActionHelpSummary($controller->createAction($action)); + if ($summary !== '') { + $this->stdout(str_repeat(' ', $maxLength + 4 - strlen($string))); + $this->stdout(Console::wrapText($summary, $maxLength + 4 + 2)); + } + $this->stdout("\n"); + } + $this->stdout("\n"); + } + $scriptName = $this->getScriptName(); + $this->stdout("\nTo see the help of each command, enter:\n", Console::BOLD); + $this->stdout("\n $scriptName " . $this->ansiFormat('help', Console::FG_YELLOW) . ' ' + . $this->ansiFormat('', Console::FG_CYAN) . "\n\n"); } /** @@ -378,9 +365,7 @@ class HelpController extends Controller $maxlen = 5; foreach ($actions as $action) { $len = strlen($prefix . '/' . $action) + 2 + ($action === $controller->defaultAction ? 10 : 0); - if ($maxlen < $len) { - $maxlen = $len; - } + $maxlen = max($maxlen, $len); } foreach ($actions as $action) { $this->stdout('- ' . $this->ansiFormat($prefix . '/' . $action, Console::FG_YELLOW)); diff --git a/tests/data/console/controllers/FakeController.php b/tests/data/console/controllers/FakeController.php new file mode 100644 index 0000000000..a5f20899eb --- /dev/null +++ b/tests/data/console/controllers/FakeController.php @@ -0,0 +1,27 @@ + + * @since 2.0.16 + */ +class FakeController extends Controller +{ + public $defaultAction = 'default'; + + public function actionDefault() + { + } + + public function actionSecond() + { + } +} diff --git a/tests/data/console/controllers/FakeEmptyController.php b/tests/data/console/controllers/FakeEmptyController.php new file mode 100644 index 0000000000..ad2f3bf3ff --- /dev/null +++ b/tests/data/console/controllers/FakeEmptyController.php @@ -0,0 +1,18 @@ + + * @since 2.0.16 + */ +class FakeEmptyController extends Controller +{ +} diff --git a/tests/data/console/controllers/FakeNoDefaultController.php b/tests/data/console/controllers/FakeNoDefaultController.php new file mode 100644 index 0000000000..094fa26b2e --- /dev/null +++ b/tests/data/console/controllers/FakeNoDefaultController.php @@ -0,0 +1,23 @@ + + * @since 2.0.16 + */ +class FakeNoDefaultController extends Controller +{ + public $defaultAction = 'not-exist'; + + public function actionIndex() + { + } +} diff --git a/tests/framework/console/UnknownCommandExceptionTest.php b/tests/framework/console/UnknownCommandExceptionTest.php index 7b148662a2..bbecc50ac7 100644 --- a/tests/framework/console/UnknownCommandExceptionTest.php +++ b/tests/framework/console/UnknownCommandExceptionTest.php @@ -24,6 +24,9 @@ class UnknownCommandExceptionTest extends TestCase 'cache' => 'yii\console\controllers\CacheController', 'migrate' => 'yii\console\controllers\MigrateController', 'message' => 'yii\console\controllers\MessageController', + 'whatever' => 'yiiunit\data\console\controllers\FakeController', + 'whatever-empty' => 'yiiunit\data\console\controllers\FakeEmptyController', + 'whatever-no-default' => 'yiiunit\data\console\controllers\FakeNoDefaultController', ], ]); } @@ -49,6 +52,7 @@ class UnknownCommandExceptionTest extends TestCase [str_repeat('asdw1234', 31), []], [str_repeat('asdw1234', 32), []], [str_repeat('asdw1234', 33), []], + ['what', ['whatever', 'whatever/default', 'whatever/second', 'whatever-no-default/index']], ]; } diff --git a/tests/framework/console/controllers/HelpControllerTest.php b/tests/framework/console/controllers/HelpControllerTest.php index 917330c24c..5c43a21966 100644 --- a/tests/framework/console/controllers/HelpControllerTest.php +++ b/tests/framework/console/controllers/HelpControllerTest.php @@ -68,10 +68,8 @@ help/index help/list help/list-action-options help/usage -magic/e-tag magic/e-tag/delete magic/e-tag/list-e-tags -magic/subFolder/sub magic/subFolder/sub/test STRING @@ -187,6 +185,31 @@ STRING $this->assertContains('--port, -p: int (defaults to 8080)', $result); $this->assertContains('--router, -r: string', $result); } + + public function testActionListContainsNoEmptyCommands() + { + $this->mockApplication([ + 'enableCoreCommands' => false, + 'controllerNamespace' => 'yiiunit\data\console\controllers', + ]); + $result = Console::stripAnsiFormat($this->runControllerAction('list')); + $this->assertNotContains("fake-empty\n", $result); + $this->assertNotContains("fake-no-default\n", $result); + $this->assertContains("fake-no-default/index\n", $result); + } + + public function testActionIndexContainsNoEmptyCommands() + { + $this->mockApplication([ + 'enableCoreCommands' => false, + 'controllerNamespace' => 'yiiunit\data\console\controllers', + ]); + $result = Console::stripAnsiFormat($this->runControllerAction('index')); + $this->assertNotContains("- fake-empty", $result); + $this->assertContains("- fake-no-default", $result); + $this->assertContains(" fake-no-default/index", $result); + $this->assertNotContains(" fake-no-default/index (default)", $result); + } }