Completed
Push — nln-php7 ( 311875...6680df )
by Nicolas
11:20
created

GroupParser::checkGroupsAreNotPartsOfAnotherGroups()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 8
cts 8
cp 1
rs 9.7998
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 2
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Karma\Configuration\Parser;
6
7
class GroupParser extends AbstractSectionParser
8
{
9
    private array
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_ARRAY, expecting T_FUNCTION or T_CONST
Loading history...
10
        $groups,
11
        $defaultEnvironments;
12
13 270
    public function __construct()
14
    {
15 270
        parent::__construct();
16
17 270
        $this->groups = [];
18 270
        $this->defaultEnvironments = [];
19 270
    }
20
21 23
    protected function parseLine(string $line): void
22
    {
23 23
        $line = trim($line);
24
25 23
        if(preg_match('~(?P<groupName>[^=]+)\s*=\s*\[(?P<envList>[^\[\]]+)\]$~', $line, $matches))
26
        {
27 15
            $this->processGroupDefinition($matches['groupName'], $matches['envList']);
28
29 10
            return;
30
        }
31
32 8
        $this->triggerError($line);
33
    }
34
35 15
    private function processGroupDefinition(string $groupName, string $envList): void
36
    {
37 15
        $groupName = trim($groupName);
38
39 15
        $this->checkGroupStillNotExists($groupName);
40
41 15
        $environments = array_map('trim', explode(',', $envList));
42 15
        $environments = $this->checkForDefaultMarker($groupName, $environments);
43 14
        $this->checkEnvironmentAreUnique($groupName, $environments);
44
45 13
        $this->groups[$groupName] = [];
46
47 13
        foreach($environments as $env)
48
        {
49 13
            if(empty($env))
50
            {
51 3
                $this->triggerError("empty environment in declaration of group $groupName");
52
            }
53
54 12
            $this->groups[$groupName][] = $env;
55
        }
56 10
    }
57
58 15
    private function checkForDefaultMarker(string $groupName, array $environments): array
59
    {
60 15
        $environmentNames = [];
61 15
        $this->defaultEnvironments[$groupName] = null;
62
63 15
        foreach($environments as $envString)
64
        {
65 15
            $name = $envString;
66
67 15
            if(preg_match('~\*\s*(?P<envName>.*)~', $envString, $matches))
68
            {
69 3
                $name = $matches['envName'];
70
71 3
                if(isset($this->defaultEnvironments[$groupName]))
72
                {
73 1
                    throw new \RuntimeException(sprintf(
74 1
                        'Group %s must have only one default environment : %s and %s are declared as default',
75
                        $groupName,
76 1
                        $this->defaultEnvironments[$groupName],
77
                        $name
78
                    ));
79
                }
80
81 3
                $this->defaultEnvironments[$groupName] = $name;
82
            }
83
84 15
            $environmentNames[] = $name;
85
        }
86
87 14
        return $environmentNames;
88
    }
89
90 15
    private function checkGroupStillNotExists(string $groupName): void
91
    {
92 15
        if(isset($this->groups[$groupName]))
93
        {
94 1
            $this->triggerError("group $groupName has already been declared");
95
        }
96 15
    }
97
98 14
    private function checkEnvironmentAreUnique(string $groupName, array $environments): void
99
    {
100 14
        if($this->hasDuplicatedValues($environments))
101
        {
102 1
            $this->triggerError("duplicated environment in group $groupName");
103
        }
104 13
    }
105
106 240
    private function hasDuplicatedValues(array $values): bool
107
    {
108 240
        $duplicatedValues = array_filter(array_count_values($values), function ($counter) {
109 14
            return $counter !== 1;
110 240
        });
111
112 240
        return empty($duplicatedValues) === false;
113
    }
114
115 38
    public function getCollectedGroups(): array
116
    {
117 38
        return $this->groups;
118
    }
119
120 235
    public function postParse(): void
121
    {
122 235
        $this->checkEnvironmentsBelongToOnlyOneGroup();
123 234
        $this->checkGroupsAreNotPartsOfAnotherGroups();
124 233
    }
125
126 235
    private function checkEnvironmentsBelongToOnlyOneGroup(): void
127
    {
128 235
        $allEnvironments = $this->getAllEnvironmentsBelongingToGroups();
129
130 235
        if($this->hasDuplicatedValues($allEnvironments))
131
        {
132 1
            throw new \RuntimeException('Error : some environments are in various groups');
133
        }
134 234
    }
135
136 235
    private function getAllEnvironmentsBelongingToGroups(): array
137
    {
138 235
        $allEnvironments = [];
139
140 235
        foreach($this->groups as $group)
141
        {
142 9
            $allEnvironments = array_merge($allEnvironments, $group);
143
        }
144
145 235
        return $allEnvironments;
146
    }
147
148 234
    private function checkGroupsAreNotPartsOfAnotherGroups(): void
149
    {
150 234
        $allEnvironments = $this->getAllEnvironmentsBelongingToGroups();
151
152 234
        $errors = array_intersect($allEnvironments, array_keys($this->groups));
153
154 234
        if(! empty($errors))
155
        {
156 1
            throw new \RuntimeException(sprintf(
157 1
               'Error : a group can not be part of another group (%s)',
158 1
                implode(', ', $errors)
159
            ));
160
        }
161 233
    }
162
163 33
    public function getDefaultEnvironmentsForGroups(): array
164
    {
165 33
        return $this->defaultEnvironments;
166
    }
167
}
168