diff --git a/src/Console/Shell.php b/src/Console/Shell.php index 99b1f254ab4..4bdfb401f20 100644 --- a/src/Console/Shell.php +++ b/src/Console/Shell.php @@ -211,7 +211,7 @@ public function initialize() */ public function startup() { - if (!(bool)$this->param('requested')) { + if (!$this->param('requested')) { $this->_welcome(); } } @@ -300,22 +300,29 @@ public function hasMethod($name) * * `return $this->dispatchShell('schema', 'create', 'i18n', '--dry');` * + * With an array having two key / value pairs: + * - `command` can accept either a string or an array. Represents the command to dispatch + * - `extra` can accept an array of extra parameters to pass on to the dispatcher. This + * parameters will be available in the `param` property of the called `Shell` + * + * `return $this->dispatchShell([ + * 'command' => 'schema create DbAcl', + * 'extra' => ['param' => 'value'] + * ]);` + * + * or + * + * `return $this->dispatchShell([ + * 'command' => ['schema', 'create', 'DbAcl'], + * 'extra' => ['param' => 'value'] + * ]);` + * * @return mixed The return of the other shell. * @link http://book.cakephp.org/3.0/en/console-and-shells.html#invoking-other-shells-from-your-shell */ public function dispatchShell() { - $args = func_get_args(); - $extra = []; - if (is_array($args[0]) && isset($args[0]['command'])) { - if (!empty($args[0]['extra'])) { - $extra = $args[0]['extra']; - } - - $args = explode(' ', $args[0]['command']); - } elseif (is_string($args[0]) && count($args) === 1) { - $args = explode(' ', $args[0]); - } + list($args, $extra) = $this->parseDispatchArguments(func_get_args()); if (!isset($extra['requested'])) { $extra['requested'] = true; @@ -325,6 +332,39 @@ public function dispatchShell() return $dispatcher->dispatch($extra); } + /** + * Parses the arguments for the dispatchShell() method. + * + * @param array $args Arguments fetch from the dispatchShell() method with + * func_get_args() + * @return array First value has to be an array of the command arguments. + * Second value has to be an array of extra parameter to pass on to the dispatcher + */ + public function parseDispatchArguments($args) + { + $extra = []; + + if (is_string($args[0]) && count($args) === 1) { + $args = explode(' ', $args[0]); + return [$args, $extra]; + } + + if (is_array($args[0]) && !empty($args[0]['command'])) { + $command = $args[0]['command']; + if (is_string($command)) { + $command = explode(' ', $command); + } + + if (!empty($args[0]['extra'])) { + $extra = $args[0]['extra']; + } + + return [$command, $extra]; + } + + return [$args, $extra]; + } + /** * Runs the Shell with the provided argv. * diff --git a/tests/TestCase/Console/ShellTest.php b/tests/TestCase/Console/ShellTest.php index 749f099941b..a4dbf33f309 100644 --- a/tests/TestCase/Console/ShellTest.php +++ b/tests/TestCase/Console/ShellTest.php @@ -642,6 +642,52 @@ public function testRunCommandWithExtra() $Shell->runCommand(['slice', 'cakes'], false, ['requested' => true]); } + /** + * Test the dispatchShell() arguments parser + * + * @return void + */ + public function testDispatchShellArgsParser() + { + $Shell = new Shell(); + + $expected = [['schema', 'create', 'DbAcl'], []]; + // Shell::dispatchShell('schema create DbAcl'); + $result = $Shell->parseDispatchArguments(['schema create DbAcl']); + $this->assertEquals($expected, $result); + + // Shell::dispatchShell('schema', 'create', 'DbAcl'); + $result = $Shell->parseDispatchArguments(['schema', 'create', 'DbAcl']); + $this->assertEquals($expected, $result); + + // Shell::dispatchShell(['command' => 'schema create DbAcl']); + $result = $Shell->parseDispatchArguments([[ + 'command' => 'schema create DbAcl' + ]]); + $this->assertEquals($expected, $result); + + // Shell::dispatchShell(['command' => ['schema', 'create', 'DbAcl']]); + $result = $Shell->parseDispatchArguments([[ + 'command' => ['schema', 'create', 'DbAcl'] + ]]); + $this->assertEquals($expected, $result); + + $expected[1] = ['param' => 'value']; + // Shell::dispatchShell(['command' => 'schema create DbAcl', 'extra' => ['param' => 'value']]); + $result = $Shell->parseDispatchArguments([[ + 'command' => 'schema create DbAcl', + 'extra' => ['param' => 'value'] + ]]); + $this->assertEquals($expected, $result); + + // Shell::dispatchShell(['command' => ['schema', 'create', 'DbAcl'], 'extra' => ['param' => 'value']]); + $result = $Shell->parseDispatchArguments([[ + 'command' => ['schema', 'create', 'DbAcl'], + 'extra' => ['param' => 'value'] + ]]); + $this->assertEquals($expected, $result); + } + /** * Test that runCommand() doesn't call public methods when the second arg is false. *