Passed
Push — master ( c547da...5d2787 )
by 世昌
02:10 queued 15s
created

Manager::getContext()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
namespace suda\application\module;
3
4
use suda\Context;
5
use suda\application\Route;
6
use suda\application\Application;
7
use suda\application\module\Module;
8
use suda\application\module\Builder;
9
use suda\application\module\NameFinder;
10
use suda\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
    {
162
        foreach ($this->loadingOrder as $name) {
163
            $this->module[$name]->registerResource();
164
        }
165
    }
166
167
    /**
168
     * 注册公有 ClassLoader
169
     *
170
     * @param Application $application
171
     * @return void
172
     */
173
    public function registerSharedClassLoader(Application $application)
174
    {
175
        foreach ($this->loadingOrder as $name) {
176
            $import = $this->module[$name]->getConfig()->get('import.share', []);
177
            $application->importClassLoader($import, $this->module[$name]->getPath());
178
        }
179
    }
180
181
    /**
182
     * 注册私有 ClassLoader
183
     *
184
     * @param string $module
185
     * @param Application $application
186
     * @return void
187
     */
188
    public function registerPrivateClassLoader(string $module, Application $application)
189
    {
190
        $import = $this->module[$module]->getConfig()->get('import.src', []);
191
        $application->importClassLoader($import, $this->module[$module]->getPath());
192
    }
193
194
    public function loadRoute(string $group, Route  $route)
195
    {
196
        foreach ($this->routeLoadingOrder as $name) {
197
            $route->addGroupRoute($group, $this->module[$name]->getRoute($group));
198
        }
199
    }
200
201
    protected function buildLoadingOrder(string $from, string $target)
202
    {
203
        // 构建加载顺序
204
        foreach ($this->{$from} as $index => $name) {
205
            if ($module = $this->find($name)) {
206
                $this->{$target}[$module->getFullName()] = $module->getPriority();
207
                $this->{$from}[$index] = $module->getFullName();
208
            }
209
        }
210
        // 数组从大到小排序
211
        arsort($this->{$target}, SORT_NUMERIC);
212
        $this->{$target} = \array_keys($this->{$target});
213
    }
214
215
    
216
    /**
217
     * 查找模块
218
     *
219
     * @param string $name
220
     * @return Module|null
221
     */
222
    public function find(string $name):?Module
223
    {
224
        $fullName = $this->finder->getFullName($name);
225
        return $this->module[$fullName] ?? null;
226
    }
227
228
229
    /**
230
     * 检测模块是否存在
231
     *
232
     * @param string $name
233
     * @return boolean
234
     */
235
    public function exist(string $name) :bool
236
    {
237
        return $this->find($name) !== null;
238
    }
239
240
    /**
241
     * Get suda
242
     *
243
     * @return  Context
244
     */
245
    public function getContext()
246
    {
247
        return $this->context;
248
    }
249
}
250