Completed
Push — master ( b209b1...84fcc2 )
by Peter
05:42
created

YamlServiceAliasingDataFactory   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 141
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 22
eloc 63
c 1
b 0
f 0
dl 0
loc 141
ccs 62
cts 62
cp 1
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A existsServicesInHighestParent() 0 7 1
B isAliasStandalone() 0 35 8
A isLineOppositeAliasByType() 0 7 2
B getCorrectYamlLines() 0 31 6
A belongLineToServices() 0 20 5
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace YamlStandards\Model\YamlServiceAliasing;
6
7
use YamlStandards\Model\Component\YamlService;
8
use YamlStandards\Model\Config\StandardParametersData;
9
use YamlStandards\Model\Config\YamlStandardConfigDefinition;
10
11
class YamlServiceAliasingDataFactory
12
{
13
    private const SERVICES_KEY = 'services:';
14
    private const SHORT_TYPE_REGEX = '/^\s+\S+:\s*\'@\S+\'$/';
15
    private const LONG_TYPE_REGEX = '/^\s+alias:\s*\S+$/';
16
17
    /**
18
     * @param string[] $yamlLines
19
     * @return bool
20
     */
21 9
    public static function existsServicesInHighestParent(array $yamlLines): bool
22
    {
23
        $trimmedYamlLines = array_map(static function ($yamlLine) {
24 9
            return rtrim($yamlLine);
25 9
        }, $yamlLines);
26
27 9
        return in_array(self::SERVICES_KEY, $trimmedYamlLines, true);
28
    }
29
30
    /**
31
     * @param string[] $yamlLines
32
     * @param string[][] $yamlParsedData
33
     * @param \YamlStandards\Model\Config\StandardParametersData $standardParametersData
34
     * @return string[]
35
     */
36 8
    public static function getCorrectYamlLines(array $yamlLines, array $yamlParsedData, StandardParametersData $standardParametersData): array
37
    {
38 8
        foreach ($yamlLines as $key => $yamlLine) {
39 8
            $type = $standardParametersData->getServiceAliasingType();
40 8
            if (self::isLineOppositeAliasByType($yamlLine, $type) &&
0 ignored issues
show
Bug introduced by
It seems like $type can also be of type null; however, parameter $type of YamlStandards\Model\Yaml...neOppositeAliasByType() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

40
            if (self::isLineOppositeAliasByType($yamlLine, /** @scrutinizer ignore-type */ $type) &&
Loading history...
41 8
                self::belongLineToServices($yamlLines, $key) &&
42 8
                self::isAliasStandalone($yamlLines, $yamlParsedData, $key, $type)
0 ignored issues
show
Bug introduced by
It seems like $type can also be of type null; however, parameter $type of YamlStandards\Model\Yaml...ry::isAliasStandalone() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

42
                self::isAliasStandalone($yamlLines, $yamlParsedData, $key, /** @scrutinizer ignore-type */ $type)
Loading history...
43
            ) {
44 5
                $explodedLine = explode(':', $yamlLine);
45 5
                [$lineKey, $lineValue] = $explodedLine;
46 5
                $trimmedLineValue = trim($lineValue);
47
48 5
                if ($type === YamlStandardConfigDefinition::CONFIG_PARAMETERS_SERVICE_ALIASING_TYPE_VALUE_SHORT) {
49 3
                    $key--;
50 3
                    $prevYamlLine = $yamlLines[$key];
51 3
                    $yamlLines[$key] = $prevYamlLine . ' \'@' . $trimmedLineValue . '\'';
52 3
                    unset($yamlLines[$key + 1]); // remove `alias:` line
53
                } else {
54 2
                    $countOfRowIndents = YamlService::rowIndentsOf($yamlLine);
55 2
                    $nextIndents = $standardParametersData->getIndents() ?? 4;  // `alias:` is child so I need add extra indents
56 2
                    $indents = YamlService::createCorrectIndentsByCountOfIndents($countOfRowIndents + $nextIndents);
57 2
                    $replacedLineValue = str_replace(['@', '\''], '', $trimmedLineValue);
58 2
                    $yamlLines[$key] = $lineKey . ':';
59 8
                    $yamlLines[$key . 'alias'] = $indents . 'alias: ' . $replacedLineValue;
60
                }
61
            }
62
        }
63
64 8
        ksort($yamlLines, SORT_NATURAL); // add `key . alias` to right position
65
66 8
        return $yamlLines;
67
    }
68
69
    /**
70
     * @param string[] $yamlLines
71
     * @param int $key
72
     * @return bool
73
     */
74 10
    private static function belongLineToServices(array $yamlLines, int $key): bool
75
    {
76 10
        while ($key > 0) {
77 10
            $key--;
78
79
            // some lines could removed so I need to check that line exists
80 10
            if (array_key_exists($key, $yamlLines) === false) {
81 2
                continue;
82
            }
83
84 10
            $yamlLine = $yamlLines[$key];
85 10
            $trimmedYamlLine = rtrim($yamlLine);
86 10
            $countOfRowIndents = YamlService::rowIndentsOf($trimmedYamlLine);
87
88 10
            if ($countOfRowIndents === 0 && $trimmedYamlLine === self::SERVICES_KEY) {
89 9
                return true;
90
            }
91
        }
92
93 1
        return false;
94
    }
95
96
    /**
97
     * @param string $yamlLine
98
     * @param string $type
99
     * @return bool
100
     */
101 10
    private static function isLineOppositeAliasByType(string $yamlLine, string $type): bool
102
    {
103 10
        if ($type === YamlStandardConfigDefinition::CONFIG_PARAMETERS_SERVICE_ALIASING_TYPE_VALUE_SHORT) {
104 6
            return preg_match(self::LONG_TYPE_REGEX, $yamlLine) === 1; // long because we want find opposite aliases
105
        }
106
107 4
        return preg_match(self::SHORT_TYPE_REGEX, $yamlLine) === 1; // short because we want find opposite aliases
108
    }
109
110
    /**
111
     * @param string[] $yamlLines
112
     * @param string[][] $yamlParsedData
113
     * @param int $key
114
     * @param string $type
115
     * @return bool
116
     */
117 12
    private static function isAliasStandalone(array $yamlLines, array $yamlParsedData, int $key, string $type): bool
118
    {
119 12
        $currentYamlLine = $yamlLines[$key];
120
121
        // is located alias as direct child (not argument or something like that)
122 12
        if ($type === YamlStandardConfigDefinition::CONFIG_PARAMETERS_SERVICE_ALIASING_TYPE_VALUE_LONG) {
123 5
            $explodedLine = explode(':', $currentYamlLine);
124 5
            $lineKey = trim(reset($explodedLine));
125
126 5
            return array_key_exists($lineKey, $yamlParsedData['services']);
127
        }
128
129 7
        $countOfCurrentRowIndents = YamlService::rowIndentsOf($currentYamlLine);
130 7
        $prevYamlLine = $yamlLines[$key - 1];
131 7
        $countOfPrevRowIndents = YamlService::rowIndentsOf($prevYamlLine);
132 7
        $hasNextRowLessCountOfIndentsAsCurrent = true;
133
134
        // alias can be last element in file
135 7
        if (array_key_exists($key + 1, $yamlLines)) {
136 6
            $nextYamlLine = $yamlLines[$key + 1];
137 6
            $countOfNextRowIndents = YamlService::rowIndentsOf($nextYamlLine);
138
139 6
            $hasNextRowLessCountOfIndentsAsCurrent = $countOfNextRowIndents < $countOfCurrentRowIndents;
140
        }
141
142 7
        if ($countOfPrevRowIndents < $countOfCurrentRowIndents &&
143 7
            $hasNextRowLessCountOfIndentsAsCurrent &&
144 7
            YamlService::hasLineColon($prevYamlLine) &&
145 7
            YamlService::hasLineValue($prevYamlLine) === false &&
146 7
            strpos($prevYamlLine, 'arguments:') === false
147
        ) {
148 4
            return true;
149
        }
150
151 6
        return false;
152
    }
153
}
154