Passed
Push — master ( f081ea...af57fd )
by 世昌
04:00
created

Manager::buildLoadingOrder()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 3
nop 2
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
namespace nebula\application\module;
3
4
use nebula\Context;
5
use nebula\application\Route;
6
use nebula\application\Application;
7
use nebula\application\module\Module;
8
use nebula\application\module\Builder;
9
use nebula\application\module\NameFinder;
10
use nebula\application\filesystem\FileSystem;
11
12
/**
13
 * 模板管理器
14
 */
15
class Manager
16
{
17
    /**
18
     * Nebula
19
     *
20
     * @var Context
21
     */
22
    protected $context;
23
24
    /**
25
     * 模块名称管理器
26
     *
27
     * @var NameFinder
28
     */
29
    protected $finder;
30
31
    /**
32
     * 当前运行的模块
33
     *
34
     * @var string
35
     */
36
    protected $active;
37
38
    /**
39
     * 可访问的模块
40
     *
41
     * @var array
42
     */
43
    protected $reachable;
44
45
    /**
46
     * 激活的模块
47
     *
48
     * @var array
49
     */
50
    protected $alive;
51
52
    /**
53
     * 注册的模块
54
     *
55
     * @var Module[]
56
     */
57
    protected $module;
58
59
    /**
60
     * 加载顺序
61
     *
62
     * @var array
63
     */
64
    protected $loadingOrder;
65
66
    /**
67
     * 路由加载顺序
68
     *
69
     * @var array
70
     */
71
    protected $routeLoadingOrder;
72
73
    /**
74
     * 构建管理器
75
     *
76
     * @param Context $app
77
     */
78
    public function __construct(Context $context)
79
    {
80
        $this->context = $context;
81
        $this->reachable = $context->getConfig()->get('app.module.reachable');
82
        $this->alive = $context->getConfig()->get('app.module.alive');
83
        $this->finder = new NameFinder;
84
    }
85
86
    /**
87
     * Get 激活的模块
88
     *
89
     * @return  string
90
     */
91
    public function getActive()
92
    {
93
        return $this->active;
94
    }
95
96
    /**
97
     * Set 激活的模块
98
     *
99
     * @param  string  $active  激活的模块
100
     *
101
     * @return  self
102
     */
103
    public function setActive(string $active)
104
    {
105
        $this->active = $active;
106
107
        return $this;
108
    }
109
110
    /**
111
     * Get 可访问的模块
112
     *
113
     * @return  array
114
     */
115
    public function getReachable()
116
    {
117
        return $this->reachable;
118
    }
119
120
    /**
121
     * Set 可访问的模块
122
     *
123
     * @param  array  $reachable  可访问的模块
124
     *
125
     * @return  self
126
     */
127
    public function setReachable(array $reachable)
128
    {
129
        $this->reachable = $reachable;
130
131
        return $this;
132
    }
133
134
135
    /**
136
     * 注册模块
137
     *
138
     * @return void
139
     */
140
    public function registerModule()
141
    {
142
        $scan = $this->getContext()->getConfig()->get('app.module.scan-path', []);
143
        $cache = $this->getContext()->getApplication()->getDataPath() .'/module-cache';
144
        FileSystem::makes($cache);
145
        // 扫描加载
146
        foreach (Builder::scan($scan, $cache) as $module) {
147
            $this->finder->add($module->getName(), $module->getVersion());
148
            $this->module[$module->getFullName()] = $module;
149
            $this->getContext()->getDebugger()->info('register module {name} at {path}', ['name'=>$module->getFullName(), 'path'=>$module->getPath()]);
150
        }
151
       $this->buildLoadingOrder('alive', 'loadingOrder');
152
       $this->buildLoadingOrder('reachable', 'routeLoadingOrder');
153
    }
154
    
155
    /**
156
     * 注册资源路径
157
     *
158
     * @return void
159
     */
160
    public function registerResource() {
161
        foreach ($this->loadingOrder as $name) {
162
            $this->module[$name]->registerResource();
163
        }
164
    }
165
166
    public function loadRoute(string $group, Route  $route)
167
    {
168
        foreach ($this->routeLoadingOrder as $name) {
169
            $route->addGroupRoute($group, $this->module[$name]->getRoute($group));
170
        }
171
    }
172
173
    protected function buildLoadingOrder(string $from, string $target) {
174
        // 构建加载顺序
175
        foreach ($this->{$from} as $index => $name) {
176
            if ($module = $this->find($name)) {
177
                $this->{$target}[$module->getFullName()] = $module->getPriority();
178
                $this->{$from}[$index] = $module->getFullName();
179
            }
180
        }
181
        // 数组从大到小排序
182
        arsort($this->{$target}, SORT_NUMERIC);
183
        $this->{$target} = \array_keys($this->{$target});
184
    }
185
186
    
187
    /**
188
     * 查找模块
189
     *
190
     * @param string $name
191
     * @return Module|null
192
     */
193
    public function find(string $name):?Module
194
    {
195
        $fullName = $this->finder->getFullName($name);
196
        return $this->module[$fullName] ?? null;
197
    }
198
199
200
    /**
201
     * 检测模块是否存在
202
     *
203
     * @param string $name
204
     * @return boolean
205
     */
206
    public function exist(string $name) :bool
207
    {
208
        return $this->find($name) !== null;
209
    }
210
211
    /**
212
     * Get nebula
213
     *
214
     * @return  Context
215
     */
216
    public function getContext()
217
    {
218
        return $this->context;
219
    }
220
}
221