Passed
Push — master ( 9a9b0b...b778d8 )
by Peter
08:40
created

YamlService::mergeMultipleValueLinesTogether()   B

Complexity

Conditions 7
Paths 11

Size

Total Lines 32
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 7

Importance

Changes 0
Metric Value
eloc 19
c 0
b 0
f 0
dl 0
loc 32
ccs 20
cts 20
cp 1
rs 8.8333
cc 7
nc 11
nop 1
crap 7
1
<?php
2
3
declare(strict_types=1);
4
5
namespace YamlStandards\Model\Component;
6
7
use Symfony\Component\Yaml\Inline;
8
use Symfony\Component\Yaml\Yaml;
9
10
class YamlService
11
{
12
    /**
13
     * @param string $pathToYamlFile
14
     * @throws \Symfony\Component\Yaml\Exception\ParseException
15
     * @return string[]|string[][]
16
     */
17 14
    public static function getYamlData(string $pathToYamlFile): array
18
    {
19 14
        return (array)Yaml::parse(file_get_contents($pathToYamlFile), Yaml::PARSE_CUSTOM_TAGS);
20
    }
21
22
    /**
23
     * @param string $key
24
     * @return bool
25
     */
26 6
    public static function hasArrayKeyUnderscoreAsFirstCharacter(string $key): bool
27
    {
28 6
        return strpos(trim($key), '_') === 0;
29
    }
30
31
    /**
32
     * @param string $key
33
     * @return bool
34
     */
35 6
    public static function hasNotArrayKeyUnderscoreAsFirstCharacter(string $key): bool
36
    {
37 6
        return strpos(trim($key), '_') !== 0;
38
    }
39
40
    /**
41
     * @param string $yamlLine
42
     * @return bool
43
     */
44 37
    public static function isLineNotBlank(string $yamlLine): bool
45
    {
46 37
        return trim($yamlLine) !== '';
47
    }
48
49
    /**
50
     * @param string $yamlLine
51
     * @return bool
52
     */
53 23
    public static function isLineBlank(string $yamlLine): bool
54
    {
55 23
        return trim($yamlLine) === '';
56
    }
57
58
    /**
59
     * @param string $yamlLine
60
     * @return bool
61
     */
62 22
    public static function isLineComment(string $yamlLine): bool
63
    {
64 22
        return preg_match('/^\s*#/', $yamlLine) === 1;
65
    }
66
67
    /**
68
     * @param string $value
69
     * @return bool
70
     */
71 11
    public static function isValueReuseVariable(string $value): bool
72
    {
73 11
        return strpos($value, '&') === 0;
74
    }
75
76
    /**
77
     * @param string $value
78
     * @return bool
79
     */
80 6
    public static function isMultipleLinesValue(string $value): bool
81
    {
82 6
        $value = trim($value);
83
84 6
        return strpos($value, '|') === 0 || strpos($value, '>') === 0;
85
    }
86
87
    /**
88
     * @param string $value
89
     * @return bool
90
     */
91 16
    public static function hasLineDashOnStartOfLine(string $value): bool
92
    {
93 16
        return strpos($value, '-') === 0;
94
    }
95
96
    /**
97
     * @param string $trimmedLine
98
     * @return bool
99
     */
100 15
    public static function hasLineThreeDashesOnStartOfLine(string $trimmedLine): bool
101
    {
102 15
        return strpos($trimmedLine, '---') === 0;
103
    }
104
105
    /**
106
     * @param string $value
107
     * @return bool
108
     */
109 15
    public static function isCurlyBracketInStartOfString(string $value): bool
110
    {
111 15
        return strpos($value, '{') === 0;
112
    }
113
114
    /**
115
     * @param string $value
116
     * @return bool
117
     */
118 5
    public static function isCurlyBracketInEndOfString(string $value): bool
119
    {
120 5
        return substr($value, -1) === '}';
121
    }
122
123
    /**
124
     * line start of array, e.g. "- foo: bar" or "- foo" or "- { foo: bar }"
125
     *
126
     * @param string $trimmedLine
127
     * @return bool
128
     */
129 16
    public static function isLineStartOfArrayWithKeyAndValue(string $trimmedLine): bool
130
    {
131 16
        return $trimmedLine !== '-' && self::hasLineDashOnStartOfLine($trimmedLine);
132
    }
133
134
    /**
135
     * value starting with key, e.g. 'foo: bar' or '"foo bar": baz'
136
     *
137
     * @param string $value
138
     * @return bool
139
     */
140 9
    public static function isKeyInStartOfString(string $value): bool
141
    {
142 9
        return (bool)preg_match('~^(' . Inline::REGEX_QUOTED_STRING . '|[^ \'"{\[].*?) *:(\s|$)~u', $value);
143
    }
144
145
    /**
146
     * line possibly opening an array, e.g. 'foo:' or '- foo:'
147
     *
148
     * @param string $trimmedLine
149
     * @return bool
150
     */
151 12
    public static function isLineOpeningAnArray(string $trimmedLine): bool
152
    {
153 12
        return (bool)preg_match('~^(- +)*(' . Inline::REGEX_QUOTED_STRING . '|[^ \'"{\[].*?) *:$~u', $trimmedLine);
154
    }
155
156
    /**
157
     * @param string $line
158
     * @return int
159
     */
160 34
    public static function rowIndentsOf(string $line): int
161
    {
162 34
        return strlen($line) - strlen(ltrim($line));
163
    }
164
165
    /**
166
     * @param string $line
167
     * @return int
168
     */
169 4
    public static function keyIndentsOf(string $line): int
170
    {
171 4
        return strlen($line) - strlen(ltrim($line, '- '));
172
    }
173
174
    /**
175
     * @param int $countOfIndents
176
     * @return string
177
     */
178 16
    public static function createCorrectIndentsByCountOfIndents(int $countOfIndents): string
179
    {
180 16
        return str_repeat(' ', $countOfIndents);
181
    }
182
183
    /**
184
     * @param string $line
185
     * @return bool
186
     */
187 15
    public static function hasLineValue(string $line): bool
188
    {
189 15
        $explodedLine = explode(':', $line);
190
191 15
        return array_key_exists(1, $explodedLine) && self::isLineNotBlank($explodedLine[1]);
192
    }
193
194
    /**
195
     * @param string $line
196
     * @return bool
197
     */
198 13
    public static function hasLineColon(string $line): bool
199
    {
200 13
        return strpos($line, ':') !== false;
201
    }
202
203
    /**
204
     * @param string $line
205
     * @return bool
206
     */
207 6
    public static function hasLineOnlyOneDash(string $line): bool
208
    {
209 6
        return trim($line) === '-';
210
    }
211
212
    /**
213
     * @param string[] $yamlLines
214
     * @return string[]
215
     *
216
     * @example
217
     * foo: | or <
218
     *     this is really a
219
     *     single line of text
220
     *     despite appearances
221
     *
222
     * to
223
     *
224
     * foo: | or < \n this is really a \n single line of text \n despite appearances\n
225
     */
226 6
    public static function mergeMultipleValueLinesTogether(array $yamlLines): array
227
    {
228 6
        foreach ($yamlLines as $yamlLineNumber => $yamlLine) {
229 6
            $explodedCurrentLine = explode(':', $yamlLine);
230 6
            $value = array_key_exists(1, $explodedCurrentLine) ? $explodedCurrentLine[1] : '';
231 6
            if (self::isMultipleLinesValue($value)) {
232 3
                $countOfCurrentLineIndents = self::rowIndentsOf($yamlLine);
233 3
                $explodedLine = explode(':', $yamlLine);
234 3
                $value = $explodedLine[1];
235
236 3
                $value .= "\n";
237 3
                foreach ($yamlLines as $lineNumber => $fileLine) {
238 3
                    if ($lineNumber <= $yamlLineNumber) {
239 3
                        continue;
240
                    }
241 3
                    $countOfLineIndents = self::rowIndentsOf($fileLine);
242
243 3
                    if ($countOfLineIndents <= $countOfCurrentLineIndents) {
244 3
                        break;
245
                    }
246
247 3
                    $value .= $fileLine . "\n";
248 3
                    unset($yamlLines[$lineNumber]);
249
                }
250
251 6
                $yamlLines[$yamlLineNumber] = $explodedCurrentLine[0] . ':' . rtrim($value);
252
            }
253
        }
254
255 6
        $yamlLines = array_values($yamlLines); // reset array keys
256
257 6
        return $yamlLines;
258
    }
259
260
    /**
261
     * @param string[] $yamlLines
262
     * @param int $key
263
     * @return string|null
264
     */
265 6
    public static function getNextNonCommentAndNonBlankLine(array $yamlLines, int $key): ?string
266
    {
267 6
        $arrayKeys = array_keys($yamlLines);
268 6
        $lastKey = end($arrayKeys);
269 6
        while ($key < $lastKey) {
270 6
            $key++;
271 6
            $line = $yamlLines[$key];
272
273 6
            if (self::isLineBlank($line) || self::isLineComment($line)) {
274 6
                continue;
275
            }
276
277 6
            return $line;
278
        }
279
280 6
        return null;
281
    }
282
}
283