Console.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: yunwuxin <448901948@qq.com>
  10. // +----------------------------------------------------------------------
  11. namespace think\console\output\descriptor;
  12. use think\Console as ThinkConsole;
  13. use think\console\Command;
  14. class Console
  15. {
  16. const GLOBAL_NAMESPACE = '_global';
  17. /**
  18. * @var ThinkConsole
  19. */
  20. private $console;
  21. /**
  22. * @var null|string
  23. */
  24. private $namespace;
  25. /**
  26. * @var array
  27. */
  28. private $namespaces;
  29. /**
  30. * @var Command[]
  31. */
  32. private $commands;
  33. /**
  34. * @var Command[]
  35. */
  36. private $aliases;
  37. /**
  38. * 构造方法
  39. * @param ThinkConsole $console
  40. * @param string|null $namespace
  41. */
  42. public function __construct(ThinkConsole $console, $namespace = null)
  43. {
  44. $this->console = $console;
  45. $this->namespace = $namespace;
  46. }
  47. /**
  48. * @return array
  49. */
  50. public function getNamespaces()
  51. {
  52. if (null === $this->namespaces) {
  53. $this->inspectConsole();
  54. }
  55. return $this->namespaces;
  56. }
  57. /**
  58. * @return Command[]
  59. */
  60. public function getCommands()
  61. {
  62. if (null === $this->commands) {
  63. $this->inspectConsole();
  64. }
  65. return $this->commands;
  66. }
  67. /**
  68. * @param string $name
  69. * @return Command
  70. * @throws \InvalidArgumentException
  71. */
  72. public function getCommand($name)
  73. {
  74. if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) {
  75. throw new \InvalidArgumentException(sprintf('Command %s does not exist.', $name));
  76. }
  77. return isset($this->commands[$name]) ? $this->commands[$name] : $this->aliases[$name];
  78. }
  79. private function inspectConsole()
  80. {
  81. $this->commands = [];
  82. $this->namespaces = [];
  83. $all = $this->console->all($this->namespace ? $this->console->findNamespace($this->namespace) : null);
  84. foreach ($this->sortCommands($all) as $namespace => $commands) {
  85. $names = [];
  86. /** @var Command $command */
  87. foreach ($commands as $name => $command) {
  88. if (is_string($command)) {
  89. $command = new $command();
  90. }
  91. if (!$command->getName()) {
  92. continue;
  93. }
  94. if ($command->getName() === $name) {
  95. $this->commands[$name] = $command;
  96. } else {
  97. $this->aliases[$name] = $command;
  98. }
  99. $names[] = $name;
  100. }
  101. $this->namespaces[$namespace] = ['id' => $namespace, 'commands' => $names];
  102. }
  103. }
  104. /**
  105. * @param array $commands
  106. * @return array
  107. */
  108. private function sortCommands(array $commands)
  109. {
  110. $namespacedCommands = [];
  111. foreach ($commands as $name => $command) {
  112. $key = $this->console->extractNamespace($name, 1);
  113. if (!$key) {
  114. $key = self::GLOBAL_NAMESPACE;
  115. }
  116. $namespacedCommands[$key][$name] = $command;
  117. }
  118. ksort($namespacedCommands);
  119. foreach ($namespacedCommands as &$commandsSet) {
  120. ksort($commandsSet);
  121. }
  122. // unset reference to keep scope clear
  123. unset($commandsSet);
  124. return $namespacedCommands;
  125. }
  126. }