1 | <?php |
||
9 | class VariableParser extends AbstractSectionParser |
||
10 | { |
||
11 | use Configuration\FilterInputVariable; |
||
12 | |||
13 | private const |
||
14 | ASSIGNMENT = '=', |
||
15 | ENV_SEPARATOR = ','; |
||
16 | |||
17 | private ?string |
||
|
|||
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 | { |
||
160 |