Console::getCommands()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 7
ccs 0
cts 4
cp 0
crap 6
rs 10
c 0
b 0
f 0
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 <[email protected]>
10
// +----------------------------------------------------------------------
11
12
namespace think\console\output\descriptor;
13
14
use think\Console as ThinkConsole;
15
use think\console\Command;
16
17
class Console
18
{
19
20
    const GLOBAL_NAMESPACE = '_global';
21
22
    /**
23
     * @var ThinkConsole
24
     */
25
    private $console;
26
27
    /**
28
     * @var null|string
29
     */
30
    private $namespace;
31
32
    /**
33
     * @var array
34
     */
35
    private $namespaces;
36
37
    /**
38
     * @var Command[]
39
     */
40
    private $commands;
41
42
    /**
43
     * @var Command[]
44
     */
45
    private $aliases;
46
47
    /**
48
     * 构造方法
49
     * @param ThinkConsole $console
50
     * @param string|null  $namespace
51
     */
52
    public function __construct(ThinkConsole $console, $namespace = null)
53
    {
54
        $this->console   = $console;
55
        $this->namespace = $namespace;
56
    }
57
58
    /**
59
     * @return array
60
     */
61
    public function getNamespaces(): array
62
    {
63
        if (null === $this->namespaces) {
64
            $this->inspectConsole();
65
        }
66
67
        return $this->namespaces;
68
    }
69
70
    /**
71
     * @return Command[]
72
     */
73
    public function getCommands(): array
74
    {
75
        if (null === $this->commands) {
76
            $this->inspectConsole();
77
        }
78
79
        return $this->commands;
80
    }
81
82
    /**
83
     * @param string $name
84
     * @return Command
85
     * @throws \InvalidArgumentException
86
     */
87
    public function getCommand(string $name): Command
88
    {
89
        if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) {
90
            throw new \InvalidArgumentException(sprintf('Command %s does not exist.', $name));
91
        }
92
93
        return $this->commands[$name] ?? $this->aliases[$name];
94
    }
95
96
    private function inspectConsole(): void
97
    {
98
        $this->commands   = [];
99
        $this->namespaces = [];
100
101
        $all = $this->console->all($this->namespace ? $this->console->findNamespace($this->namespace) : null);
102
        foreach ($this->sortCommands($all) as $namespace => $commands) {
103
            $names = [];
104
105
            /** @var Command $command */
106
            foreach ($commands as $name => $command) {
107
                if (is_string($command)) {
108
                    $command = new $command();
109
                }
110
111
                if (!$command->getName()) {
112
                    continue;
113
                }
114
115
                if ($command->getName() === $name) {
116
                    $this->commands[$name] = $command;
117
                } else {
118
                    $this->aliases[$name] = $command;
119
                }
120
121
                $names[] = $name;
122
            }
123
124
            $this->namespaces[$namespace] = ['id' => $namespace, 'commands' => $names];
125
        }
126
    }
127
128
    /**
129
     * @param array $commands
130
     * @return array
131
     */
132
    private function sortCommands(array $commands): array
133
    {
134
        $namespacedCommands = [];
135
        foreach ($commands as $name => $command) {
136
            $key = $this->console->extractNamespace($name, 1);
137
            if (!$key) {
138
                $key = self::GLOBAL_NAMESPACE;
139
            }
140
141
            $namespacedCommands[$key][$name] = $command;
142
        }
143
        ksort($namespacedCommands);
144
145
        foreach ($namespacedCommands as &$commandsSet) {
146
            ksort($commandsSet);
147
        }
148
        // unset reference to keep scope clear
149
        unset($commandsSet);
150
151
        return $namespacedCommands;
152
    }
153
}
154