Complex classes like HelpController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use HelpController, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
38 | class HelpController extends Controller |
||
39 | { |
||
40 | /** |
||
41 | * Displays available commands or the detailed information |
||
42 | * about a particular command. |
||
43 | * |
||
44 | * @param string $command The name of the command to show help about. |
||
45 | * If not provided, all available commands will be displayed. |
||
46 | * @return int the exit status |
||
47 | * @throws Exception if the command for help is unknown |
||
48 | */ |
||
49 | 3 | public function actionIndex($command = null) |
|
50 | { |
||
51 | 3 | if ($command !== null) { |
|
52 | 2 | $result = Yii::$app->createController($command); |
|
53 | 2 | if ($result === false) { |
|
54 | $name = $this->ansiFormat($command, Console::FG_YELLOW); |
||
55 | throw new Exception("No help for unknown command \"$name\"."); |
||
56 | } |
||
57 | |||
58 | 2 | [$controller, $actionID] = $result; |
|
59 | |||
60 | 2 | $actions = $this->getActions($controller); |
|
61 | 2 | if ($actionID !== '' || count($actions) === 1 && $actions[0] === $controller->defaultAction) { |
|
62 | 2 | $this->getSubCommandHelp($controller, $actionID); |
|
63 | } else { |
||
64 | 2 | $this->getCommandHelp($controller); |
|
65 | } |
||
66 | } else { |
||
67 | 1 | $this->getDefaultHelp(); |
|
68 | } |
||
69 | 3 | } |
|
70 | |||
71 | /** |
||
72 | * List all available controllers and actions in machine readable format. |
||
73 | * This is used for shell completion. |
||
74 | * @since 2.0.11 |
||
75 | */ |
||
76 | 2 | public function actionList() |
|
96 | |||
97 | /** |
||
98 | * List all available options for the $action in machine readable format. |
||
99 | * This is used for shell completion. |
||
100 | * |
||
101 | * @param string $action route to action |
||
102 | * @since 2.0.11 |
||
103 | */ |
||
104 | 1 | public function actionListActionOptions($action) |
|
105 | { |
||
106 | 1 | $result = Yii::$app->createController($action); |
|
107 | |||
108 | 1 | if ($result === false || !($result[0] instanceof Controller)) { |
|
109 | return; |
||
110 | } |
||
111 | |||
112 | /** @var Controller $controller */ |
||
113 | 1 | [$controller, $actionID] = $result; |
|
114 | 1 | $action = $controller->createAction($actionID); |
|
115 | 1 | if ($action === null) { |
|
116 | return; |
||
117 | } |
||
118 | |||
119 | 1 | $arguments = $controller->getActionArgsHelp($action); |
|
120 | 1 | foreach ($arguments as $argument => $help) { |
|
121 | 1 | $description = str_replace("\n", '', addcslashes($help['comment'], ':')) ?: $argument; |
|
122 | 1 | $this->stdout($argument . ':' . $description . "\n"); |
|
123 | } |
||
124 | |||
125 | 1 | $this->stdout("\n"); |
|
126 | 1 | $options = $controller->getActionOptionsHelp($action); |
|
127 | 1 | foreach ($options as $argument => $help) { |
|
128 | 1 | $description = str_replace("\n", '', addcslashes($help['comment'], ':')); |
|
129 | 1 | $this->stdout('--' . $argument . ($description ? ':' . $description : '') . "\n"); |
|
130 | } |
||
131 | 1 | } |
|
132 | |||
133 | /** |
||
134 | * Displays usage information for $action. |
||
135 | * |
||
136 | * @param string $action route to action |
||
137 | * @since 2.0.11 |
||
138 | */ |
||
139 | 1 | public function actionUsage($action) |
|
140 | { |
||
141 | 1 | $result = Yii::$app->createController($action); |
|
142 | |||
143 | 1 | if ($result === false || !($result[0] instanceof Controller)) { |
|
144 | return; |
||
145 | } |
||
146 | |||
147 | /** @var Controller $controller */ |
||
148 | 1 | [$controller, $actionID] = $result; |
|
149 | 1 | $action = $controller->createAction($actionID); |
|
150 | 1 | if ($action === null) { |
|
151 | return; |
||
152 | } |
||
153 | |||
154 | 1 | $scriptName = $this->getScriptName(); |
|
155 | 1 | if ($action->id === $controller->defaultAction) { |
|
156 | $this->stdout($scriptName . ' ' . $this->ansiFormat($controller->getUniqueId(), Console::FG_YELLOW)); |
||
157 | } else { |
||
158 | 1 | $this->stdout($scriptName . ' ' . $this->ansiFormat($action->getUniqueId(), Console::FG_YELLOW)); |
|
159 | } |
||
160 | |||
161 | 1 | $args = $controller->getActionArgsHelp($action); |
|
162 | 1 | foreach ($args as $name => $arg) { |
|
163 | 1 | if ($arg['required']) { |
|
164 | 1 | $this->stdout(' <' . $name . '>', Console::FG_CYAN); |
|
165 | } else { |
||
166 | 1 | $this->stdout(' [' . $name . ']', Console::FG_CYAN); |
|
167 | } |
||
168 | } |
||
169 | |||
170 | 1 | $this->stdout("\n"); |
|
171 | 1 | } |
|
172 | |||
173 | /** |
||
174 | * Returns all available command names. |
||
175 | * @return array all available command names |
||
176 | */ |
||
177 | 18 | public function getCommands() |
|
183 | |||
184 | /** |
||
185 | * Returns an array of commands an their descriptions. |
||
186 | * @return array all available commands as keys and their description as values. |
||
187 | */ |
||
188 | 3 | protected function getCommandDescriptions() |
|
206 | |||
207 | /** |
||
208 | * Returns all available actions of the specified controller. |
||
209 | * @param Controller $controller the controller instance |
||
210 | * @return array all available action IDs. |
||
211 | */ |
||
212 | 20 | public function getActions($controller) |
|
226 | |||
227 | /** |
||
228 | * Returns available commands of a specified module. |
||
229 | * @param \yii\base\Module $module the module instance |
||
230 | * @return array the available command names |
||
231 | */ |
||
232 | 18 | protected function getModuleCommands($module) |
|
276 | |||
277 | /** |
||
278 | * Validates if the given class is a valid console controller class. |
||
279 | * @param string $controllerClass |
||
280 | * @return bool |
||
281 | */ |
||
282 | 1 | protected function validateControllerClass($controllerClass) |
|
291 | |||
292 | /** |
||
293 | * Displays all available commands. |
||
294 | */ |
||
295 | 1 | protected function getDefaultHelp() |
|
362 | |||
363 | /** |
||
364 | * Displays the overall information of the command. |
||
365 | * @param Controller $controller the controller instance |
||
366 | */ |
||
367 | protected function getCommandHelp($controller) |
||
408 | |||
409 | /** |
||
410 | * Displays the detailed information of a command action. |
||
411 | * @param Controller $controller the controller instance |
||
412 | * @param string $actionID action ID |
||
413 | * @throws Exception if the action does not exist |
||
414 | */ |
||
415 | 2 | protected function getSubCommandHelp($controller, $actionID) |
|
488 | |||
489 | /** |
||
490 | * Generates a well-formed string for an argument or option. |
||
491 | * @param string $name the name of the argument or option |
||
492 | * @param bool $required whether the argument is required |
||
493 | * @param string $type the type of the option or argument |
||
494 | * @param mixed $defaultValue the default value of the option or argument |
||
495 | * @param string $comment comment about the option or argument |
||
496 | * @return string the formatted string for the argument or option |
||
497 | */ |
||
498 | 2 | protected function formatOptionHelp($name, $required, $type, $defaultValue, $comment) |
|
534 | |||
535 | /** |
||
536 | * @param Controller $controller the controller instance |
||
537 | * @param string $option the option name |
||
538 | * @return string the formatted string for the alias argument or option |
||
539 | * @since 2.0.8 |
||
540 | */ |
||
541 | 2 | protected function formatOptionAliases($controller, $option) |
|
552 | |||
553 | /** |
||
554 | * @return string the name of the cli script currently running. |
||
555 | */ |
||
556 | 4 | protected function getScriptName() |
|
560 | |||
561 | /** |
||
562 | * Return a default help header. |
||
563 | * @return string default help header. |
||
564 | * @since 2.0.11 |
||
565 | */ |
||
566 | 1 | protected function getDefaultHelpHeader() |
|
570 | } |
||
571 |
This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.