Completed
Push — master ( 7a803c...5b8a72 )
by Peter
11:20
created

YamlIndentDataFactory   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 244
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 10
Bugs 4 Features 0
Metric Value
eloc 94
c 10
b 4
f 0
dl 0
loc 244
ccs 96
cts 96
cp 1
rs 9.84
wmc 32

4 Methods

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