Passed
Push — master ( 1f28ab...20f7d8 )
by Alexander
01:54
created

Parser::parseExecLine()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 23
ccs 0
cts 14
cp 0
rs 9.552
c 0
b 0
f 0
cc 4
nc 4
nop 1
crap 20
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
    public static function parseValueByContent(array $values)
46
    {
47
        if (!array_key_exists(1, $values)) {
48
            return null;
49
        }
50
51
        $key = $values[0];
52
        $value = $values[1];
53
54
        if ($value === '0') {
55
            return 0;
56
        }
57
58
        if ($value === 'yes') {
59
            return true;
60
        }
61
62
        if ($value === 'no') {
63
            return false;
64
        }
65
66
        if ($key === 'Environment') {
67
            return self::parseEnvironmentLine($values);
68
        }
69
70
        if (in_array($key, self::$execTypes)) {
71
            array_shift($values);
72
            return self::parseExecLine(implode(' ', $values));
73
        }
74
75
        if (preg_match('/Timestamp$/', $key)) {
76
            return \date_create_immutable_from_format('* Y-m-d H:i:s e', $value);
77
        }
78
79
        if (in_array($key, self::$arrayTypes)) {
80
            return explode(' ', $value);
81
        }
82
83
        if (preg_match('/^[1-9][0-9]*$/', $value) && $value < PHP_INT_MAX) {
84
            return (int)$value;
85
        }
86
87
        return $value;
88
    }
89
90
    /**
91
     * @param string $line
92
     * @return ExecCommand
93
     */
94
    private static function parseExecLine(string $line): ExecCommand
95
    {
96
        $pattern = "/^{[ ](?<command>.*)[ ]}$/";
97
        preg_match($pattern, $line, $matches);
98
99
        $execCommand = new ExecCommand;
100
        if (!array_key_exists('command', $matches)) {
101
            $execCommand->path = $line;
102
            return $execCommand;
103
        }
104
105
        $explode = array_map('trim', explode(';', $matches['command']));
106
107
        foreach ($explode as $item) {
108
            $split = explode(' ', $item);
109
            $array = self::parseExecDetail($split);
110
            if (count($array)) {
111
                $execCommand->{$array[0]} = $array[1];
112
            }
113
        }
114
115
        return $execCommand;
116
    }
117
118
    /**
119
     * @param array $values
120
     * @return array
121
     */
122
    private static function parseExecDetail(array $values): array
123
    {
124
        if (in_array($values[0], ['path', 'pid', 'code', 'status'])) {
125
            return [
126
                $values[0],
127
                self::parseValueByContent($values)
128
            ];
129
        }
130
131
        if ($values[0] === 'argv[]') {
132
            array_shift($values);
133
            array_shift($values);
134
            return [
135
                'argv',
136
                implode(' ', $values),
137
            ];
138
        }
139
140
        if ($values[0] === 'start_time') {
141
            return [
142
                'startTime',
143
                $values[1]
144
            ];
145
        }
146
147
        if ($values[0] === 'stop_time') {
148
            return [
149
                'stopTime',
150
                $values[1]
151
            ];
152
        }
153
154
        if ($values[0] === 'ignore_errors') {
155
            return [
156
                'ignoreErrors',
157
                self::parseValueByContent($values)
158
            ];
159
        }
160
161
        return [];
162
    }
163
164
    /**
165
     * @param array $values
166
     * @return array
167
     */
168
    private static function parseEnvironmentLine(array $values): array
169
    {
170
        array_shift($values);
171
        $environments = [];
172
173
        foreach (explode(' ', implode('=', $values)) as $environment) {
174
            $explode = explode('=', $environment);
175
            $environments[$explode[0]] = self::parseValueByContent($explode);
176
        }
177
178
        return $environments;
179
    }
180
181
    /**
182
     * Used by PHPUnit
183
     *
184
     * @return array
185
     */
186
    public static function getArrayTypes(): array
187
    {
188
        return self::$arrayTypes;
189
    }
190
191
    /**
192
     * Used by PHPUnit
193
     *
194
     * @return array
195
     */
196
    public static function getExecTypes(): array
197
    {
198
        return self::$execTypes;
199
    }
200
}
201