Passed
Push — dev ( 4bc1ce...847377 )
by 世昌
02:56
created

ApplicationLoader::assignModuleToApplication()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 12
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 15
rs 9.8666

1 Method

Rating   Name   Duplication   Size   Complexity  
A ApplicationLoader::setModuleStatus() 0 6 1
1
<?php
2
namespace suda\application\loader;
3
4
use suda\framework\Config;
5
use suda\application\Module;
6
use suda\application\Resource;
7
use suda\application\ModuleBag;
8
use suda\application\Application;
9
use suda\application\database\Database;
10
use suda\database\exception\SQLException;
11
use suda\framework\filesystem\FileSystem;
12
use suda\application\builder\ModuleBuilder;
13
14
/**
15
 * 应用程序
16
 */
17
class ApplicationLoader
18
{
19
    /**
20
     * 应用程序
21
     *
22
     * @var Application
23
     */
24
    protected $application;
25
26
    /**
27
     * 模块加载器
28
     *
29
     * @var ModuleLoader[]
30
     */
31
    protected $moduleLoader;
32
33
34
    /**
35
     * @var array
36
     */
37
    protected $actionableModules;
38
39
    /**
40
     * @var array
41
     */
42
    protected $reachableModules;
43
44
    public function __construct(Application $application)
45
    {
46
        $this->application = $application;
47
        $this->actionableModules = [];
48
        $this->reachableModules = [];
49
    }
50
51
    public function load()
52
    {
53
        $this->loadVendorIfExist();
54
        $this->loadGlobalConfig();
55
        $this->registerModule();
56
        $this->setModuleStatus();
57
        $this->prepareModule();
58
        $this->activeModule();
59
    }
60
61
62
    public function loadRoute()
63
    {
64
        foreach ($this->application->getModules() as $name => $module) {
65
            if ($module->getStatus() === Module::REACHABLE) {
66
                call_user_func([$this->moduleLoader[$name],'toReachable']);
67
            }
68
        }
69
    }
70
71
72
    public function loadGlobalConfig()
73
    {
74
        $resource = $this->application->getResource();
75
        if ($configPath = $resource->getConfigResourcePath('config/config')) {
76
            $this->application->getConfig()->load($configPath);
77
        }
78
        if ($listenerPath = $resource->getConfigResourcePath('config/listener')) {
79
            $this->application->loadEvent($listenerPath);
80
        }
81
    }
82
83
    public function loadVendorIfExist()
84
    {
85
        $vendorAutoload = $this->application->getPath().'/vendor/autoload.php';
86
        if (FileSystem::exist($vendorAutoload)) {
87
            require_once $vendorAutoload;
88
        }
89
    }
90
91
    /**
92
     * @throws SQLException
93
     */
94
    public function loadDataSource()
95
    {
96
        Database::loadApplication($this->application);
97
        $dataSource = Database::getDefaultDataSource();
98
        $this->application->setDataSource($dataSource);
99
    }
100
101
102
103
    protected function prepareModule()
104
    {
105
        foreach ($this->application->getModules()->all() as $name => $module) {
106
            $this->moduleLoader[$name] = new ModuleLoader($this->application, $module);
107
            $this->moduleLoader[$name]->toLoad();
108
            $this->moduleLoader[$name]->loadExtraModuleResourceLibrary();
109
        }
110
    }
111
112
    protected function activeModule()
113
    {
114
        foreach ($this->application->getModules()->all() as $name => $module) {
115
            if ($module->getStatus() !== Module::LOADED) {
116
                $this->moduleLoader[$name]->toActive();
117
            }
118
        }
119
    }
120
121
    protected function registerModule()
122
    {
123
        $extractPath = $this->application->getDataPath() .'/extract-module';
124
        FileSystem::make($extractPath);
125
        foreach ($this->application->getModulePaths() as $path) {
126
            $this->registerModuleFrom($path, $extractPath);
127
        }
128
    }
129
130
    protected function setModuleStatus()
131
    {
132
        $active = $this->application->getManifest('module.active', $this->actionableModules);
133
        $reachable = $this->application->getManifest('module.reachable', $this->reachableModules);
134
        $this->setModuleActive($this->application->getModules(), $active);
135
        $this->setModuleReachable($this->application->getModules(), $reachable);
136
    }
137
138
    protected function registerModuleFrom(string $path, string $extractPath)
139
    {
140
        $modules = new ModuleBag;
141
        foreach (ModuleBuilder::scan($path, $extractPath) as $module) {
142
            $modules->add($module);
143
        }
144
        $this->prepareModuleConfig($path, $modules);
145
    }
146
147
    protected function prepareModuleConfig(string $path, ModuleBag $modules)
148
    {
149
        $config = $this->getModuleDirectoryConfig($path);
150
        if (is_array($config)) {
151
            $moduleNames = array_keys($modules->all());
152
            // 获取模块文件夹模块配置
153
            $load  = $config['load'] ?? $moduleNames;
154
            $active = $config['active'] ?? $load;
155
            $reachable = $config['reachable'] ?? $active;
156
            // 获取允许加载的模块
157
            $load = $this->application->getManifest('module.load', $load);
158
            $this->loadModuleFromBag($modules, $load);
159
            $this->actionableModules = array_merge($this->actionableModules, $active);
160
            $this->reachableModules = array_merge($this->reachableModules, $reachable);
161
        }
162
    }
163
164
    /**
165
     * @param string $path
166
     * @return array|null
167
     */
168
    protected function getModuleDirectoryConfig(string $path)
169
    {
170
        $resource = new Resource([$path]);
171
        $configPath = $resource->getConfigResourcePath('config');
172
        $config = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $config is dead and can be removed.
Loading history...
173
        if ($configPath) {
174
            return  Config::loadConfig($configPath, $this->application->getConfig());
175
        }
176
        return null;
177
    }
178
179
    protected function loadModuleFromBag(ModuleBag $bag, array $load)
180
    {
181
        foreach ($load as $moduleName) {
182
            if ($module = $bag->get($moduleName)) {
183
                $module->setStatus(Module::LOADED);
184
                $this->application->add($module);
185
            }
186
        }
187
    }
188
189
    protected function setModuleActive(ModuleBag $bag, array $active)
190
    {
191
        foreach ($active as $moduleName) {
192
            if ($module = $bag->get($moduleName)) {
193
                $module->setStatus(Module::ACTIVE);
194
            }
195
        }
196
    }
197
198
    protected function setModuleReachable(ModuleBag $bag, array $reachable)
199
    {
200
        foreach ($reachable as $moduleName) {
201
            if ($module = $bag->get($moduleName)) {
202
                $module->setStatus(Module::REACHABLE);
203
            }
204
        }
205
    }
206
}
207