Passed
Push — master ( c78fe7...2b585c )
by 世昌
02:13
created

ModuleBuilder::getModuleProperty()   A

Complexity

Conditions 5
Paths 9

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 12
nc 9
nop 2
dl 0
loc 18
rs 9.5555
c 0
b 0
f 0
1
<?php
2
namespace suda\application\builder;
3
4
use Iterator;
5
use ZipArchive;
6
use suda\framework\Config;
7
use suda\application\Module;
8
use suda\application\Resource;
9
use suda\framework\config\PathResolver;
10
use suda\framework\filesystem\FileSystem;
11
12
/**
13
 * 模块构建工具
14
 */
15
class ModuleBuilder
16
{
17
    /**
18
     * 从配置文件构建模块
19
     *
20
     * @param string $path
21
     * @param string $propertyPath
22
     * @return Module
23
     */
24
    public static function build(string $path, string $propertyPath):Module
25
    {
26
        list($name, $version, $resource, $property) = static::getModuleProperty($path, $propertyPath);
27
        $module = new Module($name, $version, $path, $property);
28
        $module->getResource()->addResourcePath(Resource::getPathByRelativePath($resource, $path));
29
        $path = $module->getResource()->getConfigResourcePath('config/config');
30
        if ($path !== null && ($config = Config::loadConfig($path, $property)) !== null) {
31
            $module->setConfig($config);
32
        }
33
        return $module;
34
    }
35
36
    /**
37
     * 获取模块属性
38
     *
39
     * @param string $path
40
     * @param string $propertyPath
41
     * @return array
42
     */
43
    protected static function getModuleProperty(string $path, string $propertyPath)
44
    {
45
        $property = Config::loadConfig($propertyPath, ['path' => $path]) ?? [];
46
        $name = dirname($path);
47
        $version = '1.0.0';
48
        $resource = './resource';
49
        if ($property) {
50
            if (array_key_exists('name', $property)) {
51
                $name = $property['name'];
52
            }
53
            if (array_key_exists('version', $property)) {
54
                $version = $property['version'];
55
            }
56
            if (array_key_exists('resource', $property)) {
57
                $resource = $property['resource'];
58
            }
59
        }
60
        return [$name, $version, $resource, $property];
61
    }
62
63
    /**
64
     * 检查模块配置
65
     *
66
     * @param string $path
67
     * @return string|null
68
     */
69
    public static function check(string $path): ?string
70
    {
71
        return PathResolver::resolve($path.'/module');
72
    }
73
74
    /**
75
     * 检查ZIP包
76
     *
77
     * @param string $path
78
     * @param string $unpackPath
79
     * @return string|null
80
     */
81
    public static function checkPack(string $path, string $unpackPath): ?string
82
    {
83
        $extension = pathinfo($path, PATHINFO_EXTENSION);
84
        if ($extension !== 'mod' && $extension !== 'module') {
85
            return null;
86
        }
87
        $zip = new ZipArchive;
88
        if ($zip->open($path, ZipArchive::CHECKCONS)) {
89
            $unzipPath = $unpackPath.'/'. pathinfo($path, PATHINFO_FILENAME) .'-'.substr(md5_file($path), 0, 8);
90
            $zip->extractTo($unzipPath);
91
            $zip->close();
92
            return PathResolver::resolve($unzipPath.'/module');
93
        }
94
        return null;
95
    }
96
97
    /**
98
     * 扫描模块
99
     *
100
     * @param string $modulesPath
101
     * @param string $extractPath
102
     * @return Iterator
103
     */
104
    public static function scan(string $modulesPath, string $extractPath): Iterator
105
    {
106
        $enabledPack = class_exists('ZipArchive');
107
        foreach (FileSystem::read($modulesPath) as $path) {
108
            if (is_file($path) && $enabledPack) {
109
                if ($configPath = static::checkPack($path, $extractPath)) {
110
                    yield static::build($path, $configPath);
111
                }
112
            } elseif (is_dir($path)) {
113
                if ($configPath = static::check($path)) {
114
                    yield static::build($path, $configPath);
115
                }
116
            }
117
        }
118
    }
119
}
120