Passed
Push — sudav3 ( 1415e3...f8d1a2 )
by 世昌
02:31
created

FieldModifierParser::skipWhiteComment()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 6
nc 4
nop 0
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
namespace suda\orm\struct;
3
4
use suda\orm\struct\Field;
5
6
/**
7
 * 字段修饰符解析
8
 */
9
class FieldModifierParser
10
{
11
    /**
12
     * 判断位置
13
     *
14
     * @var int
15
     */
16
    protected $pos;
17
18
    /**
19
     * 长度
20
     *
21
     * @var int
22
     */
23
    protected $length;
24
25
26
    /**
27
     * Tokens
28
     *
29
     * @var array
30
     */
31
    protected $tokens;
32
33
    /**
34
     * 修饰符
35
     *
36
     * @var array
37
     */
38
    protected $modifier;
39
    
40
    /**
41
     * 解析
42
     *
43
     * @param string $modifier
44
     * @return string
45
     */
46
    public function parse(string $modifier)
47
    {
48
        $this->tokens = \token_get_all('<?php '. $modifier);
49
        $this->length = count($this->tokens);
50
        $this->pos = 1;
51
        $this->modifier = [];
52
        while ($this->isNotEnd()) {
53
            $token = $this->tokens[$this->pos];
54
            if (\is_array($token)) {
55
                if ($token[0] === T_STRING || $token[0] === T_DEFAULT) {
56
                    $name = $token[1];
57
                    $parameter = $this->getParameter();
58
                    $this->modifier[] = [$name, $parameter];
59
                }
60
            }
61
            $this->pos++;
62
        }
63
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type suda\orm\struct\FieldModifierParser which is incompatible with the documented return type string.
Loading history...
64
    }
65
66
    /**
67
     * 修改
68
     *
69
     * @param \suda\orm\struct\Field $field
70
     * @return void
71
     */
72
    public function modify(Field $field)
73
    {
74
        foreach ($this->modifier as $value) {
75
            list($name, $parameter) = $value;
76
            if (\method_exists($field, $name)) {
77
                \call_user_func_array([$field, $name], $parameter);
78
            }
79
        }
80
    }
81
82
    public function getModifier()
83
    {
84
        return $this->modifier;
85
    }
86
87
    protected function isNotEnd()
88
    {
89
        return $this->pos < $this->length;
90
    }
91
    
92
    protected function getParameter()
93
    {
94
        $this->skipWhiteComment();
95
        $paramter = [];
96
        if ($this->skipAfterLeftBorder()) {
97
            $token = $this->tokens[$this->pos];
98
            $paramter[] = $this->getValue($token);
99
            $this->pos++;
100
            while ($this->nextIsNotEnd() === true) {
101
                $token = $this->tokens[$this->pos];
102
                $paramter[] = $this->getValue($token);
103
                $this->pos++;
104
            }
105
        }
106
        return $paramter;
107
    }
108
109
    protected function skipWhiteComment()
110
    {
111
        for ($i = $this->pos + 1; $i < $this->length ; $i++) {
112
            if (is_array($this->tokens[$i])) {
113
                if (in_array($this->tokens[$i][0], [T_COMMENT, T_DOC_COMMENT, T_WHITESPACE])) {
114
                    $this->pos++;
115
                }
116
            } else {
117
                return;
118
            }
119
        }
120
    }
121
122
    protected function skipAfterLeftBorder()
123
    {
124
        $this->skipWhiteComment();
125
        if ($this->pos + 1 < $this->length && $this->tokens[$this->pos + 1][0] === '(') {
126
            $this->pos += 2;
127
            if ($this->pos < $this->length && $this->tokens[$this->pos] !== ')') {
128
                return true;
129
            } else {
130
                $this->pos++;
131
            }
132
        }
133
        return false;
134
    }
135
136
137
    protected function getValue($token)
138
    {
139
        if ($token[0] === T_STRING) {
140
            return $this->getConstValue($token[1]);
141
        } elseif ($token[0] === T_CONSTANT_ENCAPSED_STRING) {
142
            return $this->getStringValue($token[1]);
143
        } elseif ($token[0] === T_LNUMBER) {
144
            return $this->getNumberValue($token[1]);
145
        }
146
        return null;
147
    }
148
149
    protected function getConstValue(string $value)
150
    {
151
        $value = strtolower($value);
152
        if ($value === 'true') {
153
            return true;
154
        }
155
        if ($value === 'false') {
156
            return false;
157
        }
158
        return null;
159
    }
160
161
    protected function getStringValue(string $value)
162
    {
163
        $value = trim($value, '\'"');
164
        return stripslashes($value);
165
    }
166
167
168
    protected function getNumberValue(string $value)
169
    {
170
        return intval($value);
171
    }
172
173
    protected function nextIsNotEnd()
174
    {
175
        $this->skipWhiteComment();
176
177
        $token = $this->tokens[$this->pos];
178
        if (is_array($token)) {
179
            return false;
180
        }
181
        if ($token === ')') {
182
            $this->pos++;
183
            $this->skipWhiteComment();
184
            return false;
185
        }
186
        if ($token === ',') {
187
            $this->pos++;
188
            $this->skipWhiteComment();
189
            return true;
190
        }
191
    }
192
}
193