CommandTask.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP(tm) Project
  12. * @since CakePHP(tm) v 2.5
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. App::uses('AppShell', 'Console/Command');
  16. /**
  17. * Base class for Shell Command reflection.
  18. *
  19. * @package Cake.Console.Command.Task
  20. */
  21. class CommandTask extends AppShell {
  22. /**
  23. * Gets the shell command listing.
  24. *
  25. * @return array
  26. */
  27. public function getShellList() {
  28. $skipFiles = array('AppShell');
  29. $plugins = CakePlugin::loaded();
  30. $shellList = array_fill_keys($plugins, null) + array('CORE' => null, 'app' => null);
  31. $corePath = App::core('Console/Command');
  32. $shells = App::objects('file', $corePath[0]);
  33. $shells = array_diff($shells, $skipFiles);
  34. $this->_appendShells('CORE', $shells, $shellList);
  35. $appShells = App::objects('Console/Command', null, false);
  36. $appShells = array_diff($appShells, $shells, $skipFiles);
  37. $this->_appendShells('app', $appShells, $shellList);
  38. foreach ($plugins as $plugin) {
  39. $pluginShells = App::objects($plugin . '.Console/Command');
  40. $this->_appendShells($plugin, $pluginShells, $shellList);
  41. }
  42. return array_filter($shellList);
  43. }
  44. /**
  45. * Scan the provided paths for shells, and append them into $shellList
  46. *
  47. * @param string $type The type of object.
  48. * @param array $shells The shell name.
  49. * @param array &$shellList List of shells.
  50. * @return void
  51. */
  52. protected function _appendShells($type, $shells, &$shellList) {
  53. foreach ($shells as $shell) {
  54. $shellList[$type][] = Inflector::underscore(str_replace('Shell', '', $shell));
  55. }
  56. }
  57. /**
  58. * Return a list of all commands
  59. *
  60. * @return array
  61. */
  62. public function commands() {
  63. $shellList = $this->getShellList();
  64. $options = array();
  65. foreach ($shellList as $type => $commands) {
  66. $prefix = '';
  67. if (!in_array(strtolower($type), array('app', 'core'))) {
  68. $prefix = $type . '.';
  69. }
  70. foreach ($commands as $shell) {
  71. $options[] = $prefix . $shell;
  72. }
  73. }
  74. return $options;
  75. }
  76. /**
  77. * Return a list of subcommands for a given command
  78. *
  79. * @param string $commandName The command you want subcommands from.
  80. * @return array
  81. */
  82. public function subCommands($commandName) {
  83. $Shell = $this->getShell($commandName);
  84. if (!$Shell) {
  85. return array();
  86. }
  87. $taskMap = TaskCollection::normalizeObjectArray((array)$Shell->tasks);
  88. $return = array_keys($taskMap);
  89. $return = array_map('Inflector::underscore', $return);
  90. $ShellReflection = new ReflectionClass('AppShell');
  91. $shellMethods = $ShellReflection->getMethods(ReflectionMethod::IS_PUBLIC);
  92. $shellMethodNames = array('main', 'help');
  93. foreach ($shellMethods as $method) {
  94. $shellMethodNames[] = $method->getName();
  95. }
  96. $Reflection = new ReflectionClass($Shell);
  97. $methods = $Reflection->getMethods(ReflectionMethod::IS_PUBLIC);
  98. $methodNames = array();
  99. foreach ($methods as $method) {
  100. $methodNames[] = $method->getName();
  101. }
  102. $return += array_diff($methodNames, $shellMethodNames);
  103. sort($return);
  104. return $return;
  105. }
  106. /**
  107. * Get Shell instance for the given command
  108. *
  109. * @param mixed $commandName The command you want.
  110. * @return mixed
  111. */
  112. public function getShell($commandName) {
  113. list($pluginDot, $name) = pluginSplit($commandName, true);
  114. if (in_array(strtolower($pluginDot), array('app.', 'core.'))) {
  115. $commandName = $name;
  116. $pluginDot = '';
  117. }
  118. if (!in_array($commandName, $this->commands())) {
  119. return false;
  120. }
  121. $name = Inflector::camelize($name);
  122. $pluginDot = Inflector::camelize($pluginDot);
  123. $class = $name . 'Shell';
  124. App::uses($class, $pluginDot . 'Console/Command');
  125. $Shell = new $class();
  126. $Shell->plugin = trim($pluginDot, '.');
  127. $Shell->initialize();
  128. return $Shell;
  129. }
  130. /**
  131. * Get Shell instance for the given command
  132. *
  133. * @param mixed $commandName The command to get options for.
  134. * @return array
  135. */
  136. public function options($commandName) {
  137. $Shell = $this->getShell($commandName);
  138. if (!$Shell) {
  139. $parser = new ConsoleOptionParser();
  140. } else {
  141. $parser = $Shell->getOptionParser();
  142. }
  143. $options = array();
  144. $array = $parser->options();
  145. foreach ($array as $name => $obj) {
  146. $options[] = "--$name";
  147. $short = $obj->short();
  148. if ($short) {
  149. $options[] = "-$short";
  150. }
  151. }
  152. return $options;
  153. }
  154. }