Passed
Push — master ( f34cda...bfcca5 )
by 世昌
01:57
created

NameFinder::getFullName()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 4
nop 1
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
namespace nebula\application;
3
4
/**
5
 * 模块命名处理器
6
 */
7
class NameFinder
8
{
9
    /**
10
     * 已知全部全名
11
     *
12
     * @var array
13
     */
14
    protected $knownsFullName = [];
15
16
    /**
17
     * 默认名
18
     *
19
     * @var string
20
     */
21
    protected $default = '*:';
22
23
    protected static $instance;
24
25
    /**
26
     * 返回实例
27
     *
28
     * @return self
29
     */
30
    public static function instance()
31
    {
32
        if (isset(static::$instance)) {
33
            return static::$instance;
34
        }
35
        return static::$instance = new static;
36
    }
37
38
    public function add(string $name, string $version)
39
    {
40
        $version = $this->formatVersion($version);
41
        if (!\in_array($name, $this->knownsFullName)) {
42
            $this->knownsFullName[$name][$version] = $name.':'.$version;
43
            uksort($this->knownsFullName[$name], [$this, 'sort']);
44
        }
45
    }
46
47
    /**
48
     * 拆分名称
49
     * [namespace/]name[:version]:data -> [namespace/name:version,data]
50
     *
51
     * @param string $name
52
     * @param string|null $default
53
     * @return array
54
     */
55
    public function info(string $name, ?string $default = null):array
56
    {
57
        $rpos = \strrpos($name, ':');
58
        if ($rpos > 0) {
59
            $module = substr($name, 0, $rpos);
60
            $name = \substr($name, $rpos+1);
61
            $moduleFull  = $this->getFullName($module);
62
            return [$moduleFull, $name];
63
        }
64
        if ($rpos === 0) {
65
            return [$default, substr($name, 1)];
66
        }
67
        return [$default, $name];
68
    }
69
70
    public function getFullName(string $name):string
71
    {
72
        $version = null;
73
        if (\strpos($name, ':')) {
74
            list($name, $version) = \explode(':', $name, 2);
75
        }
76
        $name = $this->getLikeName($name);
77
        if (\array_key_exists($version, $this->knownsFullName[$name])) {
78
            return $this->knownsFullName[$name][$version];
79
        }
80
        return end($this->knownsFullName[$name]);
81
    }
82
    
83
    protected function getLikeName(string $name):string
84
    {
85
        foreach (array_keys($this->knownsFullName) as $keyName) {
86
            if (\strpos($keyName, $name) !== false) {
87
                $names[] = $keyName;
88
            }
89
        }
90
        if (count($names) === 0) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $names does not seem to be defined for all execution paths leading up to this point.
Loading history...
91
            throw new \Exception(__('name %s not exist', $name));
0 ignored issues
show
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

91
            throw new \Exception(/** @scrutinizer ignore-call */ __('name %s not exist', $name));
Loading history...
92
        }
93
        if (count($names) > 1) {
94
            throw new \Exception(__('conflict name %s', $name));
95
        }
96
        return $names[0];
97
    }
98
99
100
    protected function sort(string $a, string $b)
101
    {
102
        return \version_compare($a, $b);
103
    }
104
105
    protected function formatVersion(string $version)
106
    {
107
        $version = \strtolower($version);
108
        if (\strpos($version, 'v') === 0) {
109
            return substr($version, 1);
110
        }
111
        return $version;
112
    }
113
}
114