Config   A
last analyzed

Complexity

Total Complexity 33

Size/Duplication

Total Lines 246
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 86
c 1
b 0
f 0
dl 0
loc 246
ccs 88
cts 88
cp 1
rs 9.76
wmc 33

10 Methods

Rating   Name   Duplication   Size   Complexity  
A write() 0 18 3
A set() 0 16 3
A get() 0 12 3
A getStrings() 0 8 2
A getString() 0 3 1
A newConfigFromText() 0 6 1
A addConfig() 0 13 3
A newConfig() 0 6 1
A parse() 0 5 2
C parseBuffer() 0 50 14
1
<?php
2
0 ignored issues
show
Coding Style introduced by
Missing file doc comment
Loading history...
3
declare(strict_types=1);
4
5
namespace Casbin\Config;
6
7
use Casbin\Exceptions\CasbinException;
8
9
/**
10
 * Class Config.
11
 *
12
 * @author [email protected]
0 ignored issues
show
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
13
 */
0 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @package tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @link tag in class comment
Loading history...
14
final class Config implements ConfigContract
15
{
16
    const DEFAULT_SECTION = 'default';
17
18
    const DEFAULT_COMMENT = '#';
19
20
    const DEFAULT_COMMENT_SEM = ';';
21
22
    const DEFAULT_MULTI_LINE_SEPARATOR = '\\';
23
24
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
25
     * @var array<string, array<string, string>>
26
     */
27
    public $data = [];
28
29
    /**
30
     * Create an empty configuration representation from file.
31
     *
32
     * @param string $confName
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
33
     *
34
     * @return ConfigContract
35
     * @throws CasbinException
36
     */
37 357
    public static function newConfig(string $confName): ConfigContract
38
    {
39 357
        $c = new static();
40 357
        $c->parse($confName);
41
42 357
        return $c;
43
    }
44
45
    /**
46
     * Create an empty configuration representation from text.
47
     *
48
     * @param string $text
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
49
     *
50
     * @return ConfigContract
51
     * @throws CasbinException
52
     */
53 9
    public static function newConfigFromText(string $text): ConfigContract
54
    {
55 9
        $c = new Config();
56 9
        $c->parseBuffer($text);
57
58 9
        return $c;
59
    }
60
61
    /**
62
     * Adds a new section->key:value to the configuration.
63
     *
64
     * @param string $section
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
65
     * @param string $option
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
66
     * @param string $value
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
67
     *
68
     * @return bool
69
     */
70 366
    public function addConfig(string $section, string $option, string $value): bool
71
    {
72 366
        if (empty($section)) {
73 6
            $section = self::DEFAULT_SECTION;
74
        }
75
76 366
        if (!isset($this->data[$section])) {
77 366
            $this->data[$section] = [];
78
        }
79
80 366
        $this->data[$section][$option] = $value;
81
82 366
        return true;
83
    }
84
85
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
86
     * @param string $fname
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
87
     *
88
     * @return bool
89
     *
90
     * @throws CasbinException
91
     */
92 357
    private function parse(string $fname): bool
0 ignored issues
show
Coding Style introduced by
Private method name "Config::parse" must be prefixed with an underscore
Loading history...
93
    {
94 357
        $buf = file_get_contents($fname);
95
96 357
        return $buf === false ? false : $this->parseBuffer($buf);
97
    }
98
99
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
100
     * @param string $buf
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
101
     *
102
     * @return bool
103
     *
104
     * @throws CasbinException
105
     */
106 366
    private function parseBuffer(string $buf): bool
0 ignored issues
show
Coding Style introduced by
Private method name "Config::parseBuffer" must be prefixed with an underscore
Loading history...
107
    {
108 366
        $section = '';
109 366
        $lineNum = 0;
110 366
        $buffer = '';
111 366
        $canWrite = null;
112
113 366
        $buf = preg_replace('/[\r\n]+/', PHP_EOL, $buf);
114 366
        $buf = explode(PHP_EOL, $buf == null ? "" : $buf);
115
116 366
        for ($i = 0, $len = \count($buf); $i <= $len; ++$i) {
117 366
            if ($canWrite) {
118 366
                $this->write($section, $lineNum, $buffer);
119 366
                $canWrite = false;
120
            }
121
122 366
            ++$lineNum;
123 366
            $line = isset($buf[$i]) ? $buf[$i] : '';
124 366
            if ($i == \count($buf)) {
125 366
                if (\strlen($buffer) > 0) {
126 6
                    $this->write($section, $lineNum, $buffer);
127
                }
128
129 366
                break;
130
            }
131 366
            $line = trim($line);
132
133 366
            if ('' == $line || self::DEFAULT_COMMENT == substr($line, 0, 1) || self::DEFAULT_COMMENT_SEM == substr($line, 0, 1)) {
134 51
                $canWrite = true;
135
136 51
                continue;
137 366
            } elseif ('[' == substr($line, 0, 1) && ']' == substr($line, -1)) {
138 366
                if (\strlen($buffer) > 0) {
139 6
                    $this->write($section, $lineNum, $buffer);
140 6
                    $canWrite = false;
141
                }
142 366
                $section = substr($line, 1, -1);
143
            } else {
144 366
                $p = '';
145 366
                if (self::DEFAULT_MULTI_LINE_SEPARATOR == substr($line, -1)) {
146 6
                    $p = trim(substr($line, 0, -1));
147
                } else {
148 366
                    $p = $line;
149 366
                    $canWrite = true;
150
                }
151 366
                $buffer .= $p;
152
            }
153
        }
154
155 366
        return true;
156
    }
157
158
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
159
     * @param string $section
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
160
     * @param int $lineNum
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 4 spaces after parameter type; 1 found
Loading history...
161
     * @param string $b
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
162
     *
163
     * @throws CasbinException
164
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
165 366
    private function write(string $section, int $lineNum, string &$b): void
0 ignored issues
show
Coding Style introduced by
Private method name "Config::write" must be prefixed with an underscore
Loading history...
166
    {
167 366
        if (\strlen($b) <= 0) {
168 51
            return;
169
        }
170
171 366
        $optionVal = explode('=', $b, 2);
172
173 366
        if (2 != \count($optionVal)) {
174 3
            throw new CasbinException(sprintf('parse the content error : line %d , %s = ?', $lineNum, current($optionVal)));
175
        }
176
177 366
        $option = trim($optionVal[0]);
178 366
        $value = trim($optionVal[1]);
179
180 366
        $this->addConfig($section, $option, $value);
181
182 366
        $b = '';
183 244
    }
184
185
    /**
186
     * Lookups up the value using the provided key and converts the value to a string.
187
     *
188
     * @param string $key
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
189
     *
190
     * @return string
191
     */
192 366
    public function getString(string $key): string
193
    {
194 366
        return $this->get($key);
195
    }
196
197
    /**
198
     * Lookups up the value using the provided key and converts the value to an array of string
199
     * by splitting the string by comma.
200
     *
201
     * @param string $key
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
202
     *
203
     * @return array
204
     */
205 6
    public function getStrings(string $key): array
206
    {
207 6
        $v = $this->get($key);
208 6
        if ('' == $v) {
209 6
            return [];
210
        }
211
212 6
        return explode(',', $v);
213
    }
214
215
    /**
216
     * Sets the value for the specific key in the Config.
217
     *
218
     * @param string $key
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
219
     * @param string $value
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
220
     *
221
     * @throws CasbinException
222
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
223 6
    public function set(string $key, string $value): void
224
    {
225 6
        if (0 == \strlen($key)) {
226 6
            throw new CasbinException('key is empty');
227
        }
228
229 6
        $section = '';
230
231 6
        $keys = explode('::', strtolower($key));
232 6
        if (\count($keys) >= 2) {
233 6
            $section = $keys[0];
234 6
            $option = $keys[1];
235
        } else {
236 6
            $option = $keys[0];
237
        }
238 6
        $this->addConfig($section, $option, $value);
239 4
    }
240
241
    /**
242
     * section.key or key.
0 ignored issues
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
243
     *
244
     * @param string $key
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
245
     *
246
     * @return string
247
     */
248 366
    public function get(string $key): string
249
    {
250 366
        $keys = explode('::', $key);
251 366
        if (\count($keys) >= 2) {
252 366
            $section = $keys[0];
253 366
            $option = $keys[1];
254
        } else {
255 6
            $section = self::DEFAULT_SECTION;
256 6
            $option = $keys[0];
257
        }
258
259 366
        return isset($this->data[$section][$option]) ? $this->data[$section][$option] : '';
260
    }
261
}
262