YamlIndentDataFactory::belongLineToArray()   A
last analyzed

Complexity

Conditions 5
Paths 7

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 5

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 13
nc 7
nop 2
dl 0
loc 22
ccs 13
cts 13
cp 1
crap 5
rs 9.5222
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace YamlStandards\Model\YamlIndent;
6
7
use YamlStandards\Model\Component\Parser\YamlParser;
8
use YamlStandards\Model\Component\YamlService;
9
use YamlStandards\Model\Config\StandardParametersData;
10
use YamlStandards\Model\Config\YamlStandardConfigDefinition;
11
12
class YamlIndentDataFactory
13
{
14
    /**
15
     * @param string[] $fileLines
16
     * @param int $key
17
     * @param \YamlStandards\Model\Config\StandardParametersData $standardParametersData
18
     * @param string $fileLine current checked line in loop
19
     * @param bool $isCommentLine
20
     * @return string
21
     */
22 12
    public function getRightFileLines(array $fileLines, int $key, StandardParametersData $standardParametersData, string $fileLine, bool $isCommentLine = false): string
23
    {
24
        // return comment line with original indent
25 12
        if (YamlService::isLineComment($fileLine) && $standardParametersData->isIgnoreCommentsIndent()) {
26 1
            return $fileLine;
27
        }
28
29 12
        $countOfIndents = $standardParametersData->getIndents();
30 12
        $lastFileRow = end($fileLines);
31
32
        // add empty line at the end because file can ending with comment line
33 12
        if (YamlService::isLineNotBlank($lastFileRow)) {
34 8
            $fileLines[] = '';
35
        }
36
37 12
        if (YamlService::isLineComment($fileLines[$key])) {
38 11
            $key++;
39 11
            return $this->getRightFileLines($fileLines, $key, $standardParametersData, $fileLine, true);
40
        }
41
42 12
        $line = $fileLines[$key];
43 12
        $trimmedLine = trim($line);
44 12
        $countOfRowIndents = YamlService::rowIndentsOf($line);
45 12
        $explodedLine = explode(':', $line);
46 12
        $fileRows = array_keys($fileLines);
47 12
        $lastFileRowKey = end($fileRows);
48
49
        // return comment line with original indent
50 12
        if ($isCommentLine &&
51 12
            $lastFileRowKey === $key &&
52 12
            $standardParametersData->getIndentsCommentsWithoutParent() === YamlStandardConfigDefinition::CONFIG_PARAMETERS_INDENTS_COMMENTS_WITHOUT_PARENT_VALUE_PRESERVED
53
        ) {
54 2
            return $fileLine;
55
        }
56
57
        // empty line
58 12
        if (YamlService::isLineBlank($line)) {
59
            /* set comment line indents by next non-empty line, e.g
60
                (empty line)
61
                # comment line
62
                (empty line)
63
                foo: bar
64
            */
65 12
            if ($isCommentLine && $lastFileRowKey !== $key) {
66 3
                $key++;
67 3
                return $this->getRightFileLines($fileLines, $key, $standardParametersData, $fileLine, true);
68
            }
69
70 12
            $correctIndents = YamlService::createCorrectIndentsByCountOfIndents(0);
71 12
            $trimmedFileLine = trim($fileLine);
72
73 12
            return $correctIndents . $trimmedFileLine;
74
        }
75
76
        // the highest parent
77 12
        if ($countOfRowIndents === 0) {
78 12
            return $this->processHighestParentScenario($fileLines, $key, $fileLine, $isCommentLine, $trimmedLine, $countOfRowIndents, $line, $countOfIndents);
79
        }
80
81
        // line start of array, e.g. "- foo: bar" or "- foo" or "- { foo: bar }" or "- foo:"
82 12
        if (YamlService::isLineStartOfArrayWithKeyAndValue($trimmedLine)) {
83 12
            return $this->getCorrectLineForArrayWithKeyAndValue($line, $fileLines, $key, $countOfIndents, $fileLine, $isCommentLine);
84
        }
85
86
        // children of array, description over name of function
87 12
        if ($this->belongLineToArray($fileLines, $key)) {
88 8
            $countOfParents = YamlParser::getCountOfParentsForLine($fileLines, $key);
89 8
            $correctIndents = YamlService::createCorrectIndentsByCountOfIndents($countOfParents * $countOfIndents);
90 8
            $trimmedFileLine = trim($fileLine);
91
92 8
            return $correctIndents . $trimmedFileLine;
93
        }
94
95
        // line without ':', e.g. array or string
96 12
        if (array_key_exists(1, $explodedLine) === false) {
97
            // is multidimensional array?
98 11
            if ($trimmedLine === '-') {
99 6
                $countOfParents = YamlParser::getCountOfParentsForLine($fileLines, $key);
100
101 6
                $correctIndents = YamlService::createCorrectIndentsByCountOfIndents($countOfParents * $countOfIndents);
102 6
                $trimmedFileLine = trim($fileLine);
103
104 6
                return $correctIndents . $trimmedFileLine;
105
            }
106
107
            // is array or string?
108 8
            $countOfParents = YamlParser::getCountOfParentsForLine($fileLines, $key);
109 8
            $correctIndents = YamlService::createCorrectIndentsByCountOfIndents($countOfParents * $countOfIndents);
110 8
            $trimmedFileLine = trim($fileLine);
111
112 8
            return $correctIndents . $trimmedFileLine;
113
        }
114
115 12
        $lineValue = $explodedLine[1];
116 12
        $trimmedLineValue = trim($lineValue);
117
118
        // parent, not comment line
119 12
        if ($isCommentLine === false && (YamlService::isLineBlank($lineValue) || YamlService::isValueReuseVariable($trimmedLineValue))) {
120
            // fix situation when key is without value and is not parent, e.g.: "   foo:"
121 12
            $nextLine = array_key_exists($key + 1, $fileLines) ? $fileLines[$key + 1] : '';
122 12
            if (YamlService::rowIndentsOf($nextLine) > $countOfRowIndents) {
123 12
                $countOfParents = YamlParser::getCountOfParentsForLine($fileLines, $key);
124
125 12
                $correctIndents = YamlService::createCorrectIndentsByCountOfIndents($countOfParents * $countOfIndents);
126 12
                $trimmedFileLine = trim($fileLine);
127
128 12
                return $correctIndents . $trimmedFileLine;
129
            }
130
        }
131
132 12
        $countOfParents = YamlParser::getCountOfParentsForLine($fileLines, $key);
133 12
        $correctIndents = YamlService::createCorrectIndentsByCountOfIndents($countOfParents * $countOfIndents);
134 12
        $trimmedFileLine = trim($fileLine);
135
136 12
        return $correctIndents . $trimmedFileLine;
137
    }
138
139
    /**
140
     * @param array $fileLines
141
     * @param int $key
142
     * @param string $fileLine
143
     * @param bool $isCommentLine
144
     * @param string $trimmedLine
145
     * @param int $countOfRowIndents
146
     * @param string $line
147
     * @param int $countOfIndents
148
     * @return string
149
     */
150 12
    private function processHighestParentScenario(
151
        array $fileLines,
152
        int $key,
153
        string $fileLine,
154
        bool $isCommentLine,
155
        string $trimmedLine,
156
        int $countOfRowIndents,
157
        string $line,
158
        int $countOfIndents
159
    ): string {
160
        // line is directive
161 12
        if (YamlService::hasLineThreeDashesOnStartOfLine($trimmedLine)) {
162 8
            $correctIndents = YamlService::createCorrectIndentsByCountOfIndents($countOfRowIndents);
163 8
            $trimmedFileLine = trim($fileLine);
164
165 8
            return $correctIndents . $trimmedFileLine;
166
        }
167
168
        // parent start as array, e.g. "- foo: bar"
169
        // skip comment line because we want result after this condition
170 12
        if ($isCommentLine === false && YamlService::isLineStartOfArrayWithKeyAndValue($trimmedLine)) {
171 3
            return $this->getCorrectLineForArrayWithKeyAndValue($line, $fileLines, $key, $countOfIndents, $fileLine, $isCommentLine);
172
        }
173
174 12
        $correctIndents = YamlService::createCorrectIndentsByCountOfIndents($countOfRowIndents);
175 12
        $trimmedFileLine = trim($fileLine);
176
177 12
        return $correctIndents . $trimmedFileLine;
178
    }
179
180
    /**
181
     * Belong line to children of array, e.g.
182
     * - foo: bar
183
     *   baz: qux
184
     *   quux: quuz
185
     *   etc.: etc.
186
     *
187
     * @param string[] $fileLines
188
     * @param int $key
189
     * @return bool
190
     */
191 12
    private function belongLineToArray(array $fileLines, int $key): bool
192
    {
193 12
        while ($key >= 0) {
194 12
            $line = $fileLines[$key];
195 12
            $key--;
196 12
            $prevLine = $fileLines[$key];
197 12
            $trimmedPrevLine = trim($prevLine);
198
199 12
            if (YamlService::hasLineDashOnStartOfLine($trimmedPrevLine)) {
200 11
                $prevLine = preg_replace('/-/', ' ', $prevLine, 1); // replace '-' for space
201
            }
202
203 12
            if (YamlService::rowIndentsOf($prevLine) === YamlService::rowIndentsOf($line)) {
204 12
                if (YamlService::isLineStartOfArrayWithKeyAndValue($trimmedPrevLine)) {
205 12
                    return true;
206
                }
207
            } else {
208 12
                break;
209
            }
210
        }
211
212 12
        return false;
213
    }
214
215
    /**
216
     * line start of array, e.g. "- foo: bar" or "- foo" or "- { foo: bar }"
217
     *
218
     * @param string $line
219
     * @param string[] $fileLines
220
     * @param int $key
221
     * @param int $countOfIndents
222
     * @param string $fileLine current checked line in loop
223
     * @param bool $isCommentLine
224
     * @return string
225
     */
226 12
    private function getCorrectLineForArrayWithKeyAndValue(string $line, array $fileLines, int $key, int $countOfIndents, string $fileLine, bool $isCommentLine): string
227
    {
228 12
        $lineWithReplacedDashToSpace = preg_replace('/-/', ' ', $line, 1);
229 12
        $trimmedLineWithoutDash = trim($lineWithReplacedDashToSpace);
230
231 12
        $countOfParents = YamlParser::getCountOfParentsForLine($fileLines, $key);
232 12
        $correctIndentsOnStartOfLine = YamlService::createCorrectIndentsByCountOfIndents($countOfParents * $countOfIndents);
233
234 12
        $trimmedFileLine = trim($fileLine);
235 12
        if ($isCommentLine) {
236 6
            return $correctIndentsOnStartOfLine . $trimmedFileLine;
237
        }
238
239
        // solution "- { foo: bar }"
240 12
        if (YamlService::isCurlyBracketInStartOfString($trimmedLineWithoutDash)) {
241 7
            $correctIndentsBetweenDashAndBracket = YamlService::createCorrectIndentsByCountOfIndents(1);
242
243 7
            return $correctIndentsOnStartOfLine . '-' . $correctIndentsBetweenDashAndBracket . $trimmedLineWithoutDash;
244
        }
245
246
        // solution "- foo" (single value of an array)
247 9
        if (YamlService::isKeyInStartOfString($trimmedLineWithoutDash) === false) {
248 4
            $correctIndentsBetweenDashAndKey = YamlService::createCorrectIndentsByCountOfIndents(1);
249
250 4
            return $correctIndentsOnStartOfLine . '-' . $correctIndentsBetweenDashAndKey . $trimmedLineWithoutDash;
251
        }
252
253
        /**
254
         * solution for one or more values in array
255
         * "- foo: bar"
256
         * "  baz: qux"
257
         */
258 8
        $correctIndentsBetweenDashAndKey = YamlService::createCorrectIndentsByCountOfIndents($countOfIndents - 1); // 1 space is dash, dash is as indent
259
260 8
        return $correctIndentsOnStartOfLine . '-' . $correctIndentsBetweenDashAndKey . $trimmedLineWithoutDash;
261
    }
262
}
263