Passed
Push — master ( fe68ac...129b43 )
by Alexander
01:54
created

Parser::checkByKey()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 5

Importance

Changes 0
Metric Value
eloc 10
dl 0
loc 20
ccs 11
cts 11
cp 1
rs 9.6111
c 0
b 0
f 0
cc 5
nc 5
nop 2
crap 5
1
<?php
2
3
namespace CyberLine\SystemdState;
4
5
use CyberLine\SystemdState\Model\ExecCommand;
6
7
class Parser
8
{
9
    private static $arrayTypes = [
10
        'After',
11
        'Before',
12
        'Requires',
13
        'Conflicts',
14
        'WantedBy',
15
        'Names',
16
        'Wants',
17
        'RequiredBy',
18
        'RequiredByOverridable',
19
        'RequiresMountsFor',
20
        'ReadWritePaths',
21
        'ReadOnlyPaths',
22
        'DropInPaths',
23
        'ConflictedBy',
24
        'Documentation',
25
        'BindsTo',
26
        'Triggers',
27
        'Features',
28
        'UnitPath',
29
        'BoundBy',
30
    ];
31
32
    private static $execTypes = [
33
        'ExecReload',
34
        'ExecStartPre',
35
        'ExecStart',
36
        'ExecStartPost',
37
        'ExecStop',
38
        'ExecStopPost',
39
    ];
40
41
    /**
42
     * @param array $values
43
     * @return array|bool|ExecCommand|\DateTimeImmutable|int|mixed|null
44
     */
45 31
    public static function parseValueByContent(array $values)
46
    {
47 31
        if (!array_key_exists(1, $values)) {
48 1
            return null;
49
        }
50
51 30
        $key = $values[0];
52
53 30
        if (null !== ($value = self::checkByKey($key, $values))) {
0 ignored issues
show
introduced by
The condition null !== $value = self::checkByKey($key, $values) is always true.
Loading history...
54 23
            return $value;
55
        }
56
57 8
        if (null !== ($value = self::checkByValue($values[1]))) {
58 4
            return $value;
59
        }
60
61 4
        return $values[1];
62
    }
63
64
    /**
65
     * @param string $key
66
     * @param array $values
67
     * @return array|ExecCommand|\DateTimeImmutable|null
68
     */
69 30
    private static function checkByKey(string $key, array $values)
70
    {
71 30
        if ($key === 'Environment') {
72 1
            return self::parseEnvironmentLine($values);
73
        }
74
75 30
        if (in_array($key, self::$execTypes)) {
76 1
            array_shift($values);
77 1
            return self::parseExecLine(implode(' ', $values));
78
        }
79
80 29
        if (preg_match('/Timestamp$/', $key)) {
81 1
            return \date_create_immutable_from_format('* Y-m-d H:i:s e', $values[1]);
82
        }
83
84 28
        if (in_array($key, self::$arrayTypes)) {
85 20
            return explode(' ', $values[1]);
86
        }
87
88 8
        return null;
89
    }
90
91
    /**
92
     * @param string $value
93
     * @return bool|int|null
94
     */
95 8
    private static function checkByValue(string $value)
96
    {
97 8
        if ($value === '0') {
98 1
            return 0;
99
        }
100
101 7
        if ($value === 'yes') {
102 1
            return true;
103
        }
104
105 6
        if ($value === 'no') {
106 1
            return false;
107
        }
108
109 5
        if (preg_match('/^[1-9][0-9]*$/', $value) && $value < PHP_INT_MAX) {
110 1
            return (int)$value;
111
        }
112
113 4
        return null;
114
    }
115
116
    /**
117
     * @param string $line
118
     * @return ExecCommand
119
     */
120 1
    private static function parseExecLine(string $line): ExecCommand
121
    {
122 1
        $pattern = "/^{[ ](?<command>.*)[ ]}$/";
123 1
        preg_match($pattern, $line, $matches);
124
125 1
        $execCommand = new ExecCommand;
126 1
        if (!array_key_exists('command', $matches)) {
127 1
            $execCommand->path = $line;
128 1
            return $execCommand;
129
        }
130
131
        $explode = array_map('trim', explode(';', $matches['command']));
132
        array_walk($explode, function (string $value, int $key, ExecCommand $execCommand) {
133
            $split = explode(' ', $value);
134
            $array = self::parseExecDetail($split);
135
            if (count($array)) {
136
                $execCommand->{$array[0]} = $array[1];
137
            }
138
        }, $execCommand);
139
140
        return $execCommand;
141
    }
142
143
    /**
144
     * @param array $values
145
     * @return array
146
     */
147
    private static function parseExecDetail(array $values): array
148
    {
149
        $index = $values[0];
150
151
        if (in_array($index, ['path', 'pid', 'code', 'status'])) {
152
            return [$index, self::parseValueByContent($values)];
153
        }
154
155
        if ($index === 'argv[]') {
156
            array_shift($values);
157
            array_shift($values);
158
159
            return ['argv', implode(' ', $values),];
160
        }
161
162
        if ($index === 'start_time') {
163
            return ['startTime', $values[1]];
164
        }
165
166
        if ($index === 'stop_time') {
167
            return ['stopTime', $values[1]];
168
        }
169
170
        if ($index === 'ignore_errors') {
171
            return ['ignoreErrors', self::parseValueByContent($values)];
172
        }
173
174
        return [];
175
    }
176
177
    /**
178
     * @param array $values
179
     * @return array
180
     */
181 1
    private static function parseEnvironmentLine(array $values): array
182
    {
183 1
        array_shift($values);
184 1
        $environments = [];
185
186 1
        foreach (explode(' ', implode('=', $values)) as $environment) {
187 1
            $explode = explode('=', $environment);
188 1
            $environments[$explode[0]] = self::parseValueByContent($explode);
189
        }
190
191 1
        return $environments;
192
    }
193
194
    /**
195
     * Used by PHPUnit
196
     *
197
     * @return array
198
     * @codeCoverageIgnore
199
     */
200
    public static function getArrayTypes(): array
201
    {
202
        return self::$arrayTypes;
203
    }
204
205
    /**
206
     * Used by PHPUnit
207
     *
208
     * @return array
209
     * @codeCoverageIgnore
210
     */
211
    public static function getExecTypes(): array
212
    {
213
        return self::$execTypes;
214
    }
215
}
216