Test Failed
Pull Request — master (#27)
by Petr
02:24
created

ay()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 6
rs 10
1
<?php
2
3
namespace YamlStandards\Model\YamlIndent;
4
5
use Symfony\Component\Yaml\Yaml;
6
use YamlStandards\Model\Component\YamlService;
7
8
class YamlIndentDataFactory
9
{
10
    /**
11
     * @param string[] $fileLines
12
     * @param int $key
13
     * @param int $countOfIndents
14
     * @param string $fileLine current checked line in loop
15
     * @param bool $isCommentLine
16
     * @return string
17
     *
18
     * @SuppressWarnings("CyclomaticComplexity")
19
     * @SuppressWarnings("ExcessiveMethodLength")
20
     */
21
    public function getRightFileLines(array $fileLines, $key, $countOfIndents, $fileLine, $isCommentLine = false)
22
    {
23
        if (YamlService::isLineComment($fileLines[$key])) {
24
            $key++;
25
            return $this->getRightFileLines($fileLines, $key, $countOfIndents, $fileLine, true);
26
        }
27
28
        $line = $fileLines[$key];
29
        $trimmedLine = trim($line);
30
        $countOfRowIndents = strlen($line) - strlen(ltrim($line));
31
        $explodedLine = explode(':', $line);
32
33
        // empty line
34
        if ($trimmedLine === '') {
35
            $fileRows = array_keys($fileLines);
36
            $lastFileRow = end($fileRows);
37
            /* set comment line indents by next non-empty line, e.g
38
                (empty line)
39
                # comment line
40
                (empty line)
41
                foo: bar
42
            */
43
            if ($isCommentLine && $lastFileRow !== $key) {
44
                $key++;
45
                return $this->getRightFileLines($fileLines, $key, $countOfIndents, $fileLine, true);
46
            }
47
48
            $correctIndents = $this->getCorrectIndents(0);
49
            $trimmedFileLine = trim($fileLine);
50
51
            return $correctIndents . $trimmedFileLine;
52
        }
53
54
        // the highest parent
55
        if ($countOfRowIndents === 0) {
56
            // line is directive
57
            if (YamlService::hasLineThreeDashesOnStartOfLine($trimmedLine)) {
58
                $correctIndents = $this->getCorrectIndents($countOfRowIndents);
59
                $trimmedFileLine = trim($fileLine);
60
61
                return $correctIndents . $trimmedFileLine;
62
            }
63
64
            // parent start as array, e.g. "- foo: bar"
65
            // skip comment line because we want result after this condition
66
            if ($isCommentLine === false && YamlService::isLineStartOfArrayWithKeyAndValue($trimmedLine)) {
67
                return $this->getCorrectLineForArrayWithKeyAndValue($line, $fileLines, $key, $countOfIndents, $fileLine, $isCommentLine);
68
            }
69
70
            $correctIndents = $this->getCorrectIndents($countOfRowIndents);
71
            $trimmedFileLine = trim($fileLine);
72
73
            return $correctIndents . $trimmedFileLine;
74
        }
75
76
        // line start of array, e.g. "- foo: bar" or "- foo" or "- { foo: bar }"
77
        if (YamlService::isLineStartOfArrayWithKeyAndValue($trimmedLine)) {
78
            return $this->getCorrectLineForArrayWithKeyAndValue($line, $fileLines, $key, $countOfIndents, $fileLine, $isCommentLine);
79
        }
80
81
        // children of array, description over name of function
82
        if ($this->belongLineToArray($fileLines, $key)) {
83
            $countOfParents = $this->getCountOfParentsForLine($fileLines, $key);
84
            $correctIndents = $this->getCorrectIndents($countOfParents * $countOfIndents);
85
            $trimmedFileLine = trim($fileLine);
86
87
            return $correctIndents . $trimmedFileLine;
88
        }
89
90
        // line without ':', e.g. array or string
91
        if (array_key_exists(1, $explodedLine) === false) {
92
            // is multidimensional array?
93
            if ($trimmedLine === '-') {
94
                $countOfParents = $this->getCountOfParentsForLine($fileLines, $key);
95
96
                $correctIndents = $this->getCorrectIndents($countOfParents * $countOfIndents);
97
                $trimmedFileLine = trim($fileLine);
98
99
                return $correctIndents . $trimmedFileLine;
100
            }
101
102
            // is array or string?
103
            $countOfParents = $this->getCountOfParentsForLine($fileLines, $key);
104
            $correctIndents = $this->getCorrectIndents($countOfParents * $countOfIndents);
105
            $trimmedFileLine = trim($fileLine);
106
107
            return $correctIndents . $trimmedFileLine;
108
        }
109
110
        $lineValue = $explodedLine[1];
111
        $trimmedLineValue = trim($lineValue);
112
113
        // parent, not comment line
114
        if ($isCommentLine === false && ($trimmedLineValue === '' || YamlService::isValueReuseVariable($trimmedLineValue))) {
115
            $nextLine = $fileLines[$key + 1];
116
            $countOfNextRowIndents = strlen($nextLine) - strlen(ltrim($nextLine));
117
            if ($countOfNextRowIndents > $countOfRowIndents) {
118
                $countOfParents = $this->getCountOfParentsForLine($fileLines, $key);
119
120
                $correctIndents = $this->getCorrectIndents($countOfParents * $countOfIndents);
121
                $trimmedFileLine = trim($fileLine);
122
123
                return $correctIndents . $trimmedFileLine;
124
            }
125
        }
126
127
        $countOfParents = $this->getCountOfParentsForLine($fileLines, $key);
128
        $correctIndents = $this->getCorrectIndents($countOfParents * $countOfIndents);
129
        $trimmedFileLine = trim($fileLine);
130
131
        return $correctIndents . $trimmedFileLine;
132
    }
133
134
    /**
135
     * @param int $countOfIndents
136
     * @return string
137
     */
138
    private function getCorrectIndents($countOfIndents)
139
    {
140
        return str_repeat(' ', $countOfIndents);
141
    }
142
143
    /**
144
     * Belong line to children of array, e.g.
145
     * - foo: bar
146
     *   baz: qux
147
     *   quux: quuz
148
     *   etc.: etc.
149
     *
150
     * @param string[] $fileLines
151
     * @param int $key
152
     * @return bool
153
     */
154
    private function belongLineToArray(array $fileLines, $key)
155
    {
156
        while ($key >= 0) {
157
            $line = $fileLines[$key];
158
            $countOfRowIndents = strlen($line) - strlen(ltrim($line));
159
160
            $key--;
161
            $prevLine = $fileLines[$key];
162
            $trimmedPrevLine = trim($prevLine);
163
164
            if (YamlService::hasLineDashOnStartOfLine($trimmedPrevLine)) {
165
                $prevLine = preg_replace('/-/', ' ', $prevLine, 1); // replace '-' for space
166
            }
167
168
            $countOfPrevRowIndents = strlen($prevLine) - strlen(ltrim($prevLine));
169
170
            if ($countOfPrevRowIndents === $countOfRowIndents) {
171
                if (YamlService::isLineStartOfArrayWithKeyAndValue($trimmedPrevLine)) {
172
                    return true;
173
                }
174
            } else {
175
                break;
176
            }
177
        }
178
179
        return false;
180
    }
181
182
    /**
183
     * line start of array, e.g. "- foo: bar" or "- foo" or "- { foo: bar }"
184
     *
185
     * @param string $line
186
     * @param string[] $fileLines
187
     * @param int $key
188
     * @param int $countOfIndents
189
     * @param string $fileLine current checked line in loop
190
     * @param bool $isCommentLine
191
     * @return string
192
     */
193
    private function getCorrectLineForArrayWithKeyAndValue($line, array $fileLines, $key, $countOfIndents, $fileLine, $isCommentLine)
194
    {
195
        $lineWithReplacedDashToSpace = preg_replace('/-/', ' ', $line, 1);
196
        $trimmedLineWithoutDash = trim($lineWithReplacedDashToSpace);
197
198
        $countOfParents = $this->getCountOfParentsForLine($fileLines, $key);
199
        $correctIndentsOnStartOfLine = $this->getCorrectIndents($countOfParents * $countOfIndents);
200
201
        $trimmedFileLine = trim($fileLine);
202
        if ($isCommentLine) {
203
            return $correctIndentsOnStartOfLine . $trimmedFileLine;
204
        }
205
206
        // solution "- { foo: bar }"
207
        if (YamlService::isCurlyBracketInStartOfString($trimmedLineWithoutDash)) {
208
            $correctIndentsBetweenDashAndBracket = $this->getCorrectIndents(1);
209
210
            return $correctIndentsOnStartOfLine . '-' . $correctIndentsBetweenDashAndBracket . $trimmedLineWithoutDash;
211
        }
212
213
        // solution "- foo" (single value of an array)
214
        if (!YamlService::isKeyInStartOfString($trimmedLineWithoutDash)) {
215
            $correctIndentsBetweenDashAndKey = $this->getCorrectIndents(1);
216
217
            return $correctIndentsOnStartOfLine . '-' . $correctIndentsBetweenDashAndKey . $trimmedLineWithoutDash;
218
        }
219
220
        /**
221
         * solution for one or more values in array
222
         * "- foo: bar"
223
         * "  baz: qux"
224
         */
225
        $correctIndentsBetweenDashAndKey = $this->getCorrectIndents($countOfIndents - 1); // 1 space is dash, dash is as indent
226
227
        return $correctIndentsOnStartOfLine . '-' . $correctIndentsBetweenDashAndKey . $trimmedLineWithoutDash;
228
    }
229
230
    /**
231
     * Go back until deepest parent and count them
232
     *
233
     * @param string[] $fileLines
234
     * @param int $key
235
     * @return int
236
     *
237
     * @SuppressWarnings("CyclomaticComplexity")
238
     */
239
    private function getCountOfParentsForLine(array $fileLines, $key)
240
    {
241
242
        $countOfParents = 0;
243
        $line = $fileLines[$key];
244
        $originalLine = $line;
245
        $countOfRowIndents = strlen($line) - strlen(ltrim($line));
246
        $trimmedLine = trim($line);
247
        $isArrayLine = YamlService::hasLineDashOnStartOfLine($trimmedLine);
248
249
        while ($key > 0) {
250
            $key--;
251
            $prevLine = $fileLines[$key];
252
            $trimmedPrevLine = trim($prevLine);
253
            $isPrevLineArrayLine = YamlService::hasLineDashOnStartOfLine($trimmedPrevLine);
254
            $countOfPrevRowIndents = strlen($prevLine) - strlen(ltrim($prevLine));
255
256
            // ignore comment line and empty line
257
            if ($trimmedPrevLine === '' || YamlService::isLineComment($prevLine)) {
258
                continue;
259
            }
260
261
            if (/* is start of array in array, e.g.
262
                   foo:
263
                     - bar:
264
                       - 'any text'
265
                */
266
                ($isArrayLine && $countOfPrevRowIndents < $countOfRowIndents && $isPrevLineArrayLine) ||
267
                /* is start of array, e.g.
268
                   foo:
269
                     - bar: baz
270
                */
271
                ($isArrayLine && $countOfPrevRowIndents <= $countOfRowIndents && $isPrevLineArrayLine === false) ||
272
                /* is classic hierarchy, e.g.
273
                   foo:
274
                     bar: baz
275
                */
276
                ($isArrayLine === false && $countOfPrevRowIndents < $countOfRowIndents)
277
            ) {
278
                $line = $fileLines[$key];
279
                $countOfRowIndents = strlen($line) - strlen(ltrim($line));
280
                $trimmedLine = trim($line);
281
                $isArrayLine = YamlService::hasLineDashOnStartOfLine($trimmedLine);
282
283
                $countOfParents++;
284
            }
285
286
            // if line has zero counts of indents then it's highest parent and should be ended
287
            if ($countOfRowIndents === 0) {
288
                // find parent if line belong to array, if it exists then add one parent to count of parents variable
289
                if (YamlService::isLineStartOfArrayWithKeyAndValue($trimmedLine)) {
290
                    while ($key > 0) {
291
                        $key--;
292
                        $prevLine = $fileLines[$key];
293
                        $trimmedPrevLine = trim($prevLine);
294
                        if ($trimmedPrevLine === '' || YamlService::isLineComment($prevLine)) {
295
                            continue;
296
                        }
297
298
                        $countOfRowIndents = strlen($prevLine) - strlen(ltrim($prevLine));
299
                        $explodedPrevLine = explode(':', $prevLine);
300
                        if ($countOfRowIndents === 0 && array_key_exists(1, $explodedPrevLine) && trim($explodedPrevLine[1]) === '') {
301
                            $countOfParents++;
302
303
                            /* nested hierarchy in array fix, eg.
304
                               - foo:
305
                                   nested: value
306
                                 bar: baz
307
                            */
308
                            $originalLineKeyIndent = strlen($originalLine) - strlen(ltrim($originalLine, '- '));
309
                            $lineKeyIndent = strlen($line) - strlen(ltrim($line, '- '));
310
                            if (YamlService::isLineOpeningAnArray($trimmedLine) && $originalLineKeyIndent > $lineKeyIndent) {
311
                                $countOfParents++;
312
                            }
313
314
                            break;
315
                        }
316
                    }
317
                }
318
319
                break;
320
            }
321
        }
322
323
        return $countOfParents;
324
    }
325
}
326