ModuleBuilder::scan()   B
last analyzed

Complexity

Conditions 7
Paths 6

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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