123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- <?php
- namespace yii\console;
- use yii\console\controllers\HelpController;
- class UnknownCommandException extends Exception
- {
-
- public $command;
-
- protected $application;
-
- public function __construct($route, $application, $code = 0, \Exception $previous = null)
- {
- $this->command = $route;
- $this->application = $application;
- parent::__construct("Unknown command \"$route\".", $code, $previous);
- }
-
- public function getName()
- {
- return 'Unknown command';
- }
-
- public function getSuggestedAlternatives()
- {
- $help = $this->application->createController('help');
- if ($help === false || $this->command === '') {
- return [];
- }
-
- list($helpController, $actionID) = $help;
- $availableActions = [];
- foreach ($helpController->getCommands() as $command) {
- $result = $this->application->createController($command);
- if ($result === false) {
- continue;
- }
-
- $availableActions[] = $command;
-
-
- list($controller, $actionID) = $result;
- $actions = $helpController->getActions($controller);
- if (!empty($actions)) {
- $prefix = $controller->getUniqueId();
- foreach ($actions as $action) {
- $availableActions[] = $prefix . '/' . $action;
- }
- }
- }
- return $this->filterBySimilarity($availableActions, $this->command);
- }
-
- private function filterBySimilarity($actions, $command)
- {
- $alternatives = [];
-
- foreach ($actions as $action) {
- if (strpos($action, $command) === 0) {
- $alternatives[] = $action;
- }
- }
-
- $distances = array_map(function ($action) use ($command) {
- $action = strlen($action) > 255 ? substr($action, 0, 255) : $action;
- $command = strlen($command) > 255 ? substr($command, 0, 255) : $command;
- return levenshtein($action, $command);
- }, array_combine($actions, $actions));
-
- $relevantTypos = array_filter($distances, function ($distance) {
- return $distance <= 3;
- });
- asort($relevantTypos);
- $alternatives = array_merge($alternatives, array_flip($relevantTypos));
- return array_unique($alternatives);
- }
- }
|