Passed
Push — master ( 7ccd83...3eb928 )
by Peter
02:28 queued 11s
created

YamlCountOfParents::isStartOfArray()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 1
c 1
b 0
f 0
nc 3
nop 4
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace YamlStandards\Model\Component;
6
7
class YamlCountOfParents
8
{
9
    /**
10
     * Go back until deepest parent and count them
11
     *
12
     * @param string[] $yamlLines
13
     * @param int $key
14
     * @return int
15
     */
16 10
    public static function getCountOfParentsForLine(array $yamlLines, int $key): int
17
    {
18 10
        $countOfParents = 0;
19 10
        $line = $yamlLines[$key];
20 10
        $originalLine = $line;
21 10
        $countOfRowIndents = YamlService::rowIndentsOf($line);
22 10
        $trimmedLine = trim($line);
23 10
        $isArrayLine = YamlService::hasLineDashOnStartOfLine($trimmedLine);
24
25 10
        while ($key > 0) {
26 10
            $currentLine = $yamlLines[$key];
27 10
            $countOfCurrentRowIndents = YamlService::rowIndentsOf($currentLine);
28 10
            $key--;
29 10
            $prevLine = $yamlLines[$key];
30 10
            $trimmedPrevLine = trim($prevLine);
31 10
            $isPrevLineArrayLine = YamlService::hasLineDashOnStartOfLine($trimmedPrevLine);
32 10
            $countOfPrevRowIndents = YamlService::rowIndentsOf($prevLine);
33
34
            // ignore comment line and empty line
35 10
            if (YamlService::isLineBlank($prevLine) || YamlService::isLineComment($prevLine)) {
36 6
                continue;
37
            }
38
39 10
            if (self::isPrevLineNextParent($isArrayLine, $countOfPrevRowIndents, $countOfRowIndents, $isPrevLineArrayLine)) {
40 10
                $line = $yamlLines[$key];
41 10
                $countOfRowIndents = YamlService::rowIndentsOf($line);
42 10
                $trimmedLine = trim($line);
43 10
                $isArrayLine = YamlService::hasLineDashOnStartOfLine($trimmedLine);
44
45
                /*
46
                 * array has array values at beginning and is not first element in array, e.g.
47
                 *  -  pathsToCheck:
48
                 *      - path/to/file
49
                 */
50 10
                if ($isArrayLine &&
51 10
                    YamlService::isLineOpeningAnArray($trimmedLine) &&
52 10
                    YamlService::rowIndentsOf($line) === 0 &&
53 10
                    $countOfParents > 0
54
                ) {
55 4
                    $countOfParents--;
56
                }
57
58 10
                $countOfParents++;
59
60
                /* nested hierarchy in array fix, eg.
61
                   - foo:
62
                       nested: value
63
                     bar: baz
64
                */
65 10
                if ($isArrayLine && YamlService::isLineOpeningAnArray($trimmedLine) && YamlService::keyIndentsOf($originalLine) > YamlService::keyIndentsOf($line)) {
66 4
                    $countOfParents++;
67
                }
68
            }
69
70
            // if line has zero counts of indents then it's highest parent and should be ended
71 10
            if ($countOfRowIndents === 0) {
72
                /**
73
                 * find parent if line belong to array, if it exists then add one parent to count of parents variable, e.g.
74
                 * foo:
75
                 * - bar
76
                 */
77 10
                if (YamlService::isLineStartOfArrayWithKeyAndValue($trimmedLine)) {
78 4
                    while ($key >= 0) {
79 4
                        $prevLine = $yamlLines[$key];
80 4
                        $countOfPrevRowIndents = YamlService::rowIndentsOf($prevLine);
81 4
                        if (YamlService::isLineBlank($prevLine) || YamlService::isLineComment($prevLine)) {
82 3
                            $key--;
83 3
                            continue;
84
                        }
85
86
                        /**
87
                         * 'qux' is highest parent, so skip this, e.g.
88
                         * - foo:
89
                         *      bar: baz
90
                         * - qux:
91
                         *      - quux: quuz
92
                         */
93 4
                        if ($countOfPrevRowIndents > $countOfCurrentRowIndents) {
94 4
                            break;
95
                        }
96
97 4
                        if ($countOfPrevRowIndents === 0 &&
98 4
                            $countOfPrevRowIndents === $countOfCurrentRowIndents &&
99 4
                            YamlService::hasLineColon($prevLine) &&
100 4
                            YamlService::hasLineValue($prevLine) === false
101
                        ) {
102 3
                            $countOfParents++;
103
104 3
                            break;
105
                        }
106
107 4
                        $currentLine = $yamlLines[$key];
108 4
                        $countOfCurrentRowIndents = YamlService::rowIndentsOf($currentLine);
109 4
                        $key--;
110
                    }
111
                }
112
113 10
                break;
114
            }
115
        }
116
117 10
        return $countOfParents;
118
    }
119
120
    /**
121
     * @param bool $isArrayLine
122
     * @param int $countOfPrevRowIndents
123
     * @param int $countOfRowIndents
124
     * @param bool $isPrevLineArrayLine
125
     * @return bool
126
     */
127 11
    private static function isPrevLineNextParent(bool $isArrayLine, int $countOfPrevRowIndents, int $countOfRowIndents, bool $isPrevLineArrayLine): bool
128
    {
129 11
        return self::isClassicHierarchy($isArrayLine, $countOfPrevRowIndents, $countOfRowIndents) ||
130 11
            self::isStartOfArray($isArrayLine, $countOfPrevRowIndents, $countOfRowIndents, $isPrevLineArrayLine) ||
131 11
            self::isStartOfArrayInArray($isArrayLine, $countOfPrevRowIndents, $countOfRowIndents, $isPrevLineArrayLine);
132
    }
133
134
    /**
135
     * @param bool $isArrayLine
136
     * @param int $countOfPrevRowIndents
137
     * @param int $countOfRowIndents
138
     * @return bool
139
     *
140
     * @example
141
     * foo:
142
     *     bar: baz
143
     */
144 12
    private static function isClassicHierarchy(bool $isArrayLine, int $countOfPrevRowIndents, int $countOfRowIndents): bool
145
    {
146 12
        return $isArrayLine === false && $countOfPrevRowIndents < $countOfRowIndents;
147
    }
148
149
    /**
150
     * @param bool $isArrayLine
151
     * @param int $countOfPrevRowIndents
152
     * @param int $countOfRowIndents
153
     * @param bool $isPrevLineArrayLine
154
     * @return bool
155
     *
156
     * @example
157
     * foo:
158
     *     - bar: baz
159
     */
160 12
    private static function isStartOfArray(bool $isArrayLine, int $countOfPrevRowIndents, int $countOfRowIndents, bool $isPrevLineArrayLine): bool
161
    {
162 12
        return $isArrayLine && $countOfPrevRowIndents <= $countOfRowIndents && $isPrevLineArrayLine === false;
163
    }
164
165
    /**
166
     * @param bool $isArrayLine
167
     * @param int $countOfPrevRowIndents
168
     * @param int $countOfRowIndents
169
     * @param bool $isPrevLineArrayLine
170
     * @return bool
171
     *
172
     * @example
173
     * foo:
174
     *     - bar:
175
     *         - 'any text'
176
     */
177 12
    private static function isStartOfArrayInArray(bool $isArrayLine, int $countOfPrevRowIndents, int $countOfRowIndents, bool $isPrevLineArrayLine): bool
178
    {
179 12
        return $isArrayLine && $countOfPrevRowIndents < $countOfRowIndents && $isPrevLineArrayLine;
180
    }
181
}
182