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

VariableParser::parseLine()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 7
cts 7
cp 1
rs 9.8333
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Karma\Configuration\Parser;
6
7
use Karma\Configuration;
8
9
class VariableParser extends AbstractSectionParser
10
{
11
    use Configuration\FilterInputVariable;
12
13
    private const
14
        ASSIGNMENT = '=',
15
        ENV_SEPARATOR = ',';
16
17
    private ?string
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 '?', expecting T_FUNCTION or T_CONST
Loading history...
18
        $currentVariable;
19
20
    private array
21
        $variables;
22
23
    private bool
24
        $valueFound;
25
26 280
    public function __construct()
27
    {
28 280
        parent::__construct();
29
30 280
        $this->currentVariable = null;
31 280
        $this->variables = [];
32 280
        $this->valueFound = false;
33 280
    }
34
35 253
    protected function parseLine(string $line): void
36
    {
37 253
        [$variableName, $isSystem] = $this->extractVariableName($line);
38
39 252
        if($variableName !== null)
40
        {
41 248
            $this->changeCurrentVariable($variableName, $isSystem);
42
43 248
            return;
44
        }
45
46 252
        $this->parseEnvironmentValue($line);
47 247
    }
48
49 253
    private function extractVariableName(string $line): array
50
    {
51 253
        $variableName = null;
52 253
        $isSystem = false;
53 253
        $flag = Configuration::SYSTEM_VARIABLE_FLAG;
54
55 253
        if(preg_match("~^\s*(?P<systemVariableFlag>$flag)?(?P<variableName>[^:=]+):$~", $line, $matches))
56
        {
57 249
            $variableName = trim($matches['variableName']);
58 249
            $isSystem = $matches['systemVariableFlag'] === $flag;
59
60 249
            if(preg_match('~\s~', $variableName))
61
            {
62 1
                throw new \RuntimeException(sprintf(
63 1
                    'Blank characters are not allowed in variable name : "%s" (in file %s line %d)',
64
                    $variableName,
65 1
                    $this->currentFilePath,
66 1
                    $this->currentLineNumber
67
                ));
68
            }
69
        }
70
71 252
        return [$variableName, $isSystem];
72
    }
73
74 257
    private function checkCurrentVariableState(): void
75
    {
76 257
        if($this->currentVariable !== null && $this->valueFound === false)
77
        {
78 2
            $this->triggerError(sprintf(
79 2
                'Variable %s has no value (declared in file %s line %d)',
80 2
                $this->currentVariable,
81 2
                $this->variables[$this->currentVariable]['file'],
82 2
                $this->variables[$this->currentVariable]['line']
83
            ));
84
        }
85 257
    }
86
87 248
    private function changeCurrentVariable(string $variableName, bool $isSystem): void
88
    {
89 248
        $this->checkCurrentVariableState();
90 248
        $this->currentVariable = $variableName;
91
92 248
        if(isset($this->variables[$this->currentVariable]))
93
        {
94 6
            $this->triggerError(sprintf(
95 6
                'Variable %s is already declared (in %s line %d)',
96 6
                $this->currentVariable,
97 6
                $this->variables[$this->currentVariable]['file'],
98 6
                $this->variables[$this->currentVariable]['line']
99
            ));
100
        }
101
102 248
        $this->variables[$this->currentVariable] = [
103 248
            'env' => [],
104 248
            'file' => $this->currentFilePath,
105 248
            'line' => $this->currentLineNumber,
106 248
            'system' => $isSystem,
107
        ];
108
109 248
        $this->valueFound = false;
110 248
    }
111
112 252
    private function parseEnvironmentValue(string $line): void
113
    {
114 252
        if($this->currentVariable === null)
115
        {
116 4
            $this->triggerError('Missing variable name');
117
        }
118
119 248
        if(substr_count($line, self::ASSIGNMENT) < 1)
120
        {
121 1
            $this->triggerError("line must contains = ($line)");
122
        }
123
124 247
        list($envList, $value) = explode(self::ASSIGNMENT, $line, 2);
125 247
        $environments = array_map('trim', explode(self::ENV_SEPARATOR, $envList));
126
127 247
        $value = $this->parseList($value);
128 247
        $value = $this->filterValue($value);
129
130 247
        foreach($environments as $environment)
131
        {
132 247
            if(array_key_exists($environment, $this->variables[$this->currentVariable]['env']))
133
            {
134 1
                $this->triggerError("Duplicated value for environment $environment and variable $this->currentVariable");
135
            }
136
137 247
            $this->variables[$this->currentVariable]['env'][$environment] = $value;
138
        }
139
140 247
        $this->valueFound = true;
141 247
    }
142
143 247
    public function getVariables(): array
144
    {
145 247
        return $this->variables;
146
    }
147
148 280
    public function setCurrentFile(string $filePath): void
149
    {
150 280
        parent::setCurrentFile($filePath);
151
152 280
        $this->currentVariable = null;
153 280
    }
154
155 250
    public function endOfFileCheck(): void
156
    {
157 250
        $this->checkCurrentVariableState();
158 249
    }
159
}
160