Passed
Push — nln-php7 ( 12eaac )
by Nicolas
05:28
created

VariableParser::changeCurrentVariable()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 24
ccs 16
cts 16
cp 1
rs 9.536
c 0
b 0
f 0
cc 2
nc 2
nop 2
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 \Karma\Configuration\FilterInputVariable;
12
13
    const
14
        ASSIGNMENT = '=',
15
        ENV_SEPARATOR = ',',
16
        DEFAULT_ENV = 'default';
17
18
    private
19
        $currentVariable,
0 ignored issues
show
Coding Style introduced by
It is generally advisable to only define one property per statement.

Only declaring a single property per statement allows you to later on add doc comments more easily.

It is also recommended by PSR2, so it is a common style that many people expect.

Loading history...
20
        $variables,
21
        $valueFound;
22
23 279
    public function __construct()
24
    {
25 279
        $this->currentVariable = null;
26 279
        $this->variables = array();
27 279
        $this->valueFound = false;
28 279
    }
29
30 252
    protected function parseLine($line)
31
    {
32 252
        if($this->isACommentLine($line))
33
        {
34 208
            return true;
35
        }
36
37 252
        list($variableName, $isSystem) = $this->extractVariableName($line);
38
39 251
        if($variableName !== null)
40
        {
41 247
            return $this->changeCurrentVariable($variableName, $isSystem);
42
        }
43
44 251
        $this->parseEnvironmentValue($line);
45 246
    }
46
47 252
    private function extractVariableName($line)
48
    {
49 252
        $variableName = null;
50 252
        $isSystem = false;
51 252
        $flag = Configuration::SYSTEM_VARIABLE_FLAG;
52
53 252
        if(preg_match("~^\s*(?P<systemVariableFlag>$flag)?(?P<variableName>[^:=]+):$~", $line, $matches))
54
        {
55 248
            $variableName = trim($matches['variableName']);
56 248
            $isSystem = $matches['systemVariableFlag'] === $flag;
57
58 248
            if(preg_match('~\s~', $variableName))
59
            {
60 1
                throw new \RuntimeException(sprintf(
61 1
                    'Blank characters are not allowed in variable name : "%s" (in file %s line %d)',
62 1
                    $variableName,
63 1
                    $this->currentFilePath,
64 1
                    $this->currentLineNumber
65
                ));
66
            }
67
        }
68
69 251
        return array($variableName, $isSystem);
70
    }
71
72 256
    private function checkCurrentVariableState()
73
    {
74 256
        if($this->currentVariable !== null && $this->valueFound === false)
75
        {
76 2
            $this->triggerError(sprintf(
77 2
                'Variable %s has no value (declared in file %s line %d)',
78 2
                $this->currentVariable,
79 2
                $this->variables[$this->currentVariable]['file'],
80 2
                $this->variables[$this->currentVariable]['line']
81
            ));
82
        }
83 256
    }
84
85 247
    private function changeCurrentVariable($variableName, $isSystem)
86
    {
87 247
        $this->checkCurrentVariableState();
88 247
        $this->currentVariable = $variableName;
89
90 247
        if(isset($this->variables[$this->currentVariable]))
91
        {
92 6
            $this->triggerError(sprintf(
93 6
                'Variable %s is already declared (in %s line %d)',
94 6
                $this->currentVariable,
95 6
                $this->variables[$this->currentVariable]['file'],
96 6
                $this->variables[$this->currentVariable]['line']
97
            ));
98
        }
99
100 247
        $this->variables[$this->currentVariable] = array(
101 247
            'env' => array(),
102 247
            'file' => $this->currentFilePath,
103 247
            'line' => $this->currentLineNumber,
104 247
            'system' => $isSystem,
105
        );
106
107 247
        $this->valueFound = false;
108 247
    }
109
110 251
    private function parseEnvironmentValue($line)
111
    {
112 251
        if($this->currentVariable === null)
113
        {
114 4
            $this->triggerError('Missing variable name');
115
        }
116
117 247
        if(substr_count($line, self::ASSIGNMENT) < 1)
118
        {
119 1
            $this->triggerError("line must contains = ($line)");
120
        }
121
122 246
        list($envList, $value) = explode(self::ASSIGNMENT, $line, 2);
123 246
        $environments = array_map('trim', explode(self::ENV_SEPARATOR, $envList));
124
125 246
        $value = $this->parseList($value);
126 246
        $value = $this->filterValue($value);
127
128 246
        foreach($environments as $environment)
129
        {
130 246
            if(array_key_exists($environment, $this->variables[$this->currentVariable]['env']))
131
            {
132 1
                $this->triggerError("Duplicated value for environment $environment and variable $this->currentVariable");
133
            }
134
135 246
            $this->variables[$this->currentVariable]['env'][$environment] = $value;
136
        }
137
138 246
        $this->valueFound = true;
139 246
    }
140
141 246
    public function getVariables(): array
142
    {
143 246
        return $this->variables;
144
    }
145
146 279
    public function setCurrentFile($filePath)
147
    {
148 279
        parent::setCurrentFile($filePath);
149
150 279
        $this->currentVariable = null;
151 279
    }
152
153 249
    public function endOfFileCheck()
154
    {
155 249
        $this->checkCurrentVariableState();
156 248
    }
157
}
158