@@ -25,7 +25,12 @@ abstract class Controller extends AbstractCommand implements ControllerInterface
2525 /** @var array */
2626 private static $ commandAliases ;
2727
28- /** @var string */
28+ /** @var array */
29+ protected static $ globalOptions = [
30+ '--show-disabled ' => 'Whether display disabled commands ' ,
31+ ];
32+
33+ /** @var string Action name, no suffix. */
2934 private $ action ;
3035
3136 /** @var string */
@@ -43,6 +48,11 @@ abstract class Controller extends AbstractCommand implements ControllerInterface
4348 /** @var string */
4449 protected $ notFoundCallback = 'notFound ' ;
4550
51+ /**
52+ * @var array From disabledCommands()
53+ */
54+ protected $ disabledCommands = [];
55+
4656 /**
4757 * define command alias map
4858 * @return array
@@ -55,6 +65,16 @@ protected static function commandAliases(): array
5565 ];
5666 }
5767
68+ protected function init ()
69+ {
70+ $ list = $ this ->disabledCommands ();
71+ $ this ->disabledCommands = $ list ? array_flip ($ list ) : [];
72+
73+ if (!$ this ->actionSuffix ) {
74+ $ this ->actionSuffix = 'Command ' ;
75+ }
76+ }
77+
5878 /**
5979 * define disabled command list.
6080 * @return array
@@ -106,15 +126,38 @@ final protected function configure()
106126 protected function execute ($ input , $ output )
107127 {
108128 $ action = FormatUtil::camelCase (trim ($ this ->action ?: $ this ->defaultAction , $ this ->delimiter ));
129+
130+ if ($ this ->isDisabled ($ action )) {
131+ $ output ->liteError (sprintf (
132+ "Sorry, The command ' $ action' is invalid in the group '%s'! " ,
133+ static ::getName ()
134+ ));
135+
136+ return -1 ;
137+ }
138+
109139 $ method = $ this ->actionSuffix ? $ action . ucfirst ($ this ->actionSuffix ) : $ action ;
110140
111141 // the action method exists and only allow access public method.
112- if (method_exists ($ this , $ method ) && (($ rfm = new \ReflectionMethod ($ this , $ method )) && $ rfm ->isPublic ())) {
142+ if (\method_exists ($ this , $ method ) && (($ rfm = new \ReflectionMethod ($ this , $ method )) && $ rfm ->isPublic ())) {
143+ // before
144+ if (\method_exists ($ this , $ before = 'before ' . ucfirst ($ action ))) {
145+ $ this ->$ before ($ input , $ output );
146+ }
147+
113148 // run action
114149 $ status = $ this ->$ method ($ input , $ output );
115150
116- // if you defined the method '$this->notFoundCallback' , will call it
117- } elseif (($ notFoundCallback = $ this ->notFoundCallback ) && method_exists ($ this , $ notFoundCallback )) {
151+ // after
152+ if (\method_exists ($ this , $ after = 'after ' . ucfirst ($ action ))) {
153+ $ this ->$ after ($ input , $ output );
154+ }
155+
156+ return (int )$ status ;
157+ }
158+
159+ // if you defined the method '$this->notFoundCallback' , will call it
160+ if (($ notFoundCallback = $ this ->notFoundCallback ) && method_exists ($ this , $ notFoundCallback )) {
118161 $ status = $ this ->{$ notFoundCallback }($ action );
119162 } else {
120163 $ group = static ::getName ();
@@ -181,12 +224,19 @@ final public function helpCommand(): int
181224 return $ this ->showHelpByMethodAnnotations ($ method , $ action , $ aliases );
182225 }
183226
227+ protected function beforeShowCommandList ()
228+ {
229+ // do something ...
230+ }
231+
184232 /**
185233 * show command list of the controller class
186234 * @throws \ReflectionException
187235 */
188236 final public function showCommandList ()
189237 {
238+ $ this ->beforeShowCommandList ();
239+
190240 $ ref = new \ReflectionClass ($ this );
191241 $ sName = lcfirst (self ::getName () ?: $ ref ->getShortName ());
192242
@@ -195,21 +245,32 @@ final public function showCommandList()
195245 }
196246
197247 $ commands = [];
198- $ defCommandDes = 'No description message ' ;
248+ $ showDisabled = (bool )$ this ->getOpt ('show-disabled ' , false );
249+ $ defaultDes = 'No description message ' ;
199250
200251 foreach ($ this ->getAllCommandMethods ($ ref ) as $ cmd => $ m ) {
201- $ desc = Annotation::firstLine ($ m ->getDocComment ()) ?: $ defCommandDes ;
252+ if (!$ cmd ) {
253+ continue ;
254+ }
255+
256+ $ desc = Annotation::firstLine ($ m ->getDocComment ()) ?: $ defaultDes ;
202257
203258 // is a annotation tag
204259 if ($ desc [0 ] === '@ ' ) {
205- $ desc = $ defCommandDes ;
260+ $ desc = $ defaultDes ;
206261 }
207262
208- if ($ cmd ) {
209- $ aliases = self ::getCommandAliases ($ cmd );
210- $ extra = $ aliases ? Helper::wrapTag (' [alias: ' . implode (', ' , $ aliases ) . '] ' , 'info ' ) : '' ;
211- $ commands [$ cmd ] = $ desc . $ extra ;
263+ if ($ this ->isDisabled ($ cmd )) {
264+ if (!$ showDisabled ) {
265+ continue ;
266+ }
267+
268+ $ desc .= '[<red>DISABLED</red>] ' ;
212269 }
270+
271+ $ aliases = self ::getCommandAliases ($ cmd );
272+ $ desc .= $ aliases ? Helper::wrapTag (' [alias: ' . implode (', ' , $ aliases ) . '] ' , 'info ' ) : '' ;
273+ $ commands [$ cmd ] = $ desc ;
213274 }
214275
215276 // sort commands
@@ -236,7 +297,7 @@ final public function showCommandList()
236297 $ this ->output ->mList ([
237298 'Usage: ' => $ usage ,
238299 //'Group Name:' => "<info>$sName</info>",
239- 'Options: ' => FormatUtil::alignmentOptions (Application::getInternalOptions ()),
300+ 'Options: ' => FormatUtil::alignmentOptions (array_merge ( Application::getInternalOptions (), static :: $ globalOptions )),
240301 'Commands: ' => $ commands ,
241302 ], [
242303 'sepChar ' => ' ' ,
@@ -292,10 +353,27 @@ protected function getRealCommandName(string $name)
292353 return $ map [$ name ] ?? $ name ;
293354 }
294355
356+ /**
357+ * @param string $name
358+ * @return bool
359+ */
360+ public function isDisabled (string $ name ): bool
361+ {
362+ return isset ($ this ->disabledCommands [$ name ]);
363+ }
364+
295365 /**************************************************************************
296366 * getter/setter methods
297367 **************************************************************************/
298368
369+ /**
370+ * @return array
371+ */
372+ public function getDisabledCommands (): array
373+ {
374+ return $ this ->disabledCommands ;
375+ }
376+
299377 /**
300378 * @param string|null $name
301379 * @return array
@@ -345,7 +423,7 @@ public function getDefaultAction(): string
345423 /**
346424 * @param string $defaultAction
347425 */
348- public function setDefaultAction ($ defaultAction )
426+ public function setDefaultAction (string $ defaultAction )
349427 {
350428 $ this ->defaultAction = $ defaultAction ;
351429 }
@@ -361,7 +439,7 @@ public function getActionSuffix(): string
361439 /**
362440 * @param string $actionSuffix
363441 */
364- public function setActionSuffix ($ actionSuffix )
442+ public function setActionSuffix (string $ actionSuffix )
365443 {
366444 $ this ->actionSuffix = $ actionSuffix ;
367445 }
@@ -377,7 +455,7 @@ public function getNotFoundCallback()
377455 /**
378456 * @param string $notFoundCallback
379457 */
380- public function setNotFoundCallback ($ notFoundCallback )
458+ public function setNotFoundCallback (string $ notFoundCallback )
381459 {
382460 $ this ->notFoundCallback = $ notFoundCallback ;
383461 }
0 commit comments