1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15: namespace Cake\Command;
16:
17: use Cake\Console\Arguments;
18: use Cake\Console\Command;
19: use Cake\Console\CommandCollection;
20: use Cake\Console\CommandCollectionAwareInterface;
21: use Cake\Console\ConsoleIo;
22: use Cake\Console\ConsoleOptionParser;
23: use Cake\Console\ConsoleOutput;
24: use SimpleXMLElement;
25:
26: 27: 28:
29: class HelpCommand extends Command implements CommandCollectionAwareInterface
30: {
31: 32: 33: 34: 35:
36: protected $commands;
37:
38: 39: 40:
41: public function setCommandCollection(CommandCollection $commands)
42: {
43: $this->commands = $commands;
44: }
45:
46: 47: 48: 49: 50: 51: 52:
53: public function execute(Arguments $args, ConsoleIo $io)
54: {
55: if (!$args->getOption('xml')) {
56: $io->out('<info>Current Paths:</info>', 2);
57: $io->out('* app: ' . APP_DIR . DIRECTORY_SEPARATOR);
58: $io->out('* root: ' . ROOT . DIRECTORY_SEPARATOR);
59: $io->out('* core: ' . CORE_PATH);
60: $io->out('');
61:
62: $io->out('<info>Available Commands:</info>', 2);
63: }
64:
65: $commands = $this->commands->getIterator();
66: $commands->ksort();
67:
68: if ($args->getOption('xml')) {
69: $this->asXml($io, $commands);
70:
71: return static::CODE_SUCCESS;
72: }
73: $this->asText($io, $commands);
74:
75: return static::CODE_SUCCESS;
76: }
77:
78: 79: 80: 81: 82: 83: 84:
85: protected function asText($io, $commands)
86: {
87: $invert = [];
88: foreach ($commands as $name => $class) {
89: if (is_object($class)) {
90: $class = get_class($class);
91: }
92: if (!isset($invert[$class])) {
93: $invert[$class] = [];
94: }
95: $invert[$class][] = $name;
96: }
97:
98: foreach ($commands as $name => $class) {
99: if (is_object($class)) {
100: $class = get_class($class);
101: }
102: if (count($invert[$class]) == 1) {
103: $io->out('- ' . $name);
104: }
105:
106: if (count($invert[$class]) > 1) {
107:
108: usort($invert[$class], function ($a, $b) {
109: return strlen($a) - strlen($b);
110: });
111: $io->out('- ' . array_shift($invert[$class]));
112:
113:
114: $invert[$class] = [];
115: }
116: }
117: $io->out('');
118:
119: $io->out('To run a command, type <info>`cake command_name [args|options]`</info>');
120: $io->out('To get help on a specific command, type <info>`cake command_name --help`</info>', 2);
121: }
122:
123: 124: 125: 126: 127: 128: 129:
130: protected function asXml($io, $commands)
131: {
132: $shells = new SimpleXMLElement('<shells></shells>');
133: foreach ($commands as $name => $class) {
134: if (is_object($class)) {
135: $class = get_class($class);
136: }
137: $shell = $shells->addChild('shell');
138: $shell->addAttribute('name', $name);
139: $shell->addAttribute('call_as', $name);
140: $shell->addAttribute('provider', $class);
141: $shell->addAttribute('help', $name . ' -h');
142: }
143: $io->setOutputAs(ConsoleOutput::RAW);
144: $io->out($shells->saveXML());
145: }
146:
147: 148: 149: 150: 151: 152:
153: protected function buildOptionParser(ConsoleOptionParser $parser)
154: {
155: $parser->setDescription(
156: 'Get the list of available commands for this application.'
157: )->addOption('xml', [
158: 'help' => 'Get the listing as XML.',
159: 'boolean' => true
160: ]);
161:
162: return $parser;
163: }
164: }
165: