GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 4bdee8...e73272 )
by Miles
06:43
created

VariableParser   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 300
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 100%

Importance

Changes 3
Bugs 0 Features 1
Metric Value
wmc 35
c 3
b 0
f 1
lcom 1
cbo 5
dl 0
loc 300
ccs 94
cts 94
cp 1
rs 9

12 Methods

Rating   Name   Duplication   Size   Complexity  
A parse() 0 14 3
A fetchVariableMatches() 0 10 4
A fetchVariable() 0 15 4
A hasParameterExpansion() 0 10 3
A checkVariableExists() 0 18 3
A fetchParameterExpansion() 0 15 2
A fetchParameterExpansionType() 0 8 2
A fetchParameterExpansionSymbol() 0 13 2
A splitVariableDefault() 0 16 3
A parseVariableParameter() 0 9 3
A assignVariableParameterDefault() 0 10 3
A doReplacements() 0 15 3
1
<?php
2
3
/**
4
 * This file is part of the m1\env library
5
 *
6
 * (c) m1 <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 *
11
 * @package     m1/env
12
 * @version     1.1.0
13
 * @author      Miles Croxford <[email protected]>
14
 * @copyright   Copyright (c) Miles Croxford <[email protected]>
15
 * @license     http://github.com/m1/env/blob/master/LICENSE.md
16
 * @link        http://github.com/m1/env/blob/master/README.md Documentation
17
 */
18
19
namespace M1\Env\Parser;
20
21
use M1\Env\Exception\ParseException;
22
use M1\Env\Traits\ValueCheckTrait;
23
24
/**
25
 * The value parser for Env
26
 *
27
 * @since 1.1.0
28
 */
29
class VariableParser extends AbstractParser
30
{
31
    /**
32
     * The trait for checking types
33
     */
34
    use ValueCheckTrait;
35
36
    /**
37
     * The regex to get variables '$(VARIABLE)' in .env
38
     * Unescaped: ${(.*?)}
39
     *
40
     * @var string REGEX_ENV_VARIABLE
41
     */
42
    const REGEX_ENV_VARIABLE = '\\${(.*?)}';
43
44
    /**
45
     * The symbol for the assign default value parameter expansion
46
     *
47
     * @var string SYMBOL_ASSIGN_DEFAULT_VALUE
48
     */
49
    const SYMBOL_ASSIGN_DEFAULT_VALUE = '=';
50
51
    /**
52
     * The symbol for the default value parameter expansion
53
     *
54
     * @var string SYMBOL_DEFAULT_VALUE
55
     */
56
    const SYMBOL_DEFAULT_VALUE = '-';
57
58
    /**
59
     * Parses a .env variable
60
     *
61
     * @param string $value         The value to parse
62
     * @param bool   $quoted_string Is the value in a quoted string
63
     *
64
     * @return string The parsed value
65
     */
66 33
    public function parse($value, $quoted_string = false)
67
    {
68 33
        $matches = $this->fetchVariableMatches($value);
69
70 33
        if (is_array($matches)) {
71 18
            if ($this->isVariableClone($value, $matches, $quoted_string)) {
72 18
                return $this->fetchVariable($value, $matches[1][0], $matches, $quoted_string);
73
            }
74
75 9
            $value = $this->doReplacements($value, $matches, $quoted_string);
76 9
        }
77
78 27
        return $value;
79
    }
80
81
    /**
82
     * Get variable matches inside a string
83
     *
84
     * @param string $value The value to parse
85
     *
86
     * @return array The variable matches
87
     */
88 33
    private function fetchVariableMatches($value)
89
    {
90 33
        preg_match_all('/' . self::REGEX_ENV_VARIABLE . '/', $value, $matches);
91
92 33
        if (!is_array($matches) || !isset($matches[0]) || empty($matches[0])) {
93 24
            return false;
94
        }
95
96 18
        return $matches;
97
    }
98
99
    /**
100
     * Parses a .env variable
101
     *
102
     * @param string $value         The value to parse
103
     * @param string $variable_name The variable name to get
104
     * @param array  $matches       The matches of the variables
105
     * @param bool   $quoted_string Is the value in a quoted string
106
     *
107
     * @return string The parsed value
108
     */
109 18
    private function fetchVariable($value, $variable_name, $matches, $quoted_string)
110
    {
111 18
        if ($this->hasParameterExpansion($variable_name)) {
112 9
            $replacement = $this->fetchParameterExpansion($variable_name);
113 6
        } else {
114 12
            $this->checkVariableExists($value, $variable_name);
115 9
            $replacement = $this->parser->lines[$variable_name];
116
        }
117
118 12
        if ($this->isBoolInString($replacement, $quoted_string, count($matches[0]))) {
119 6
            $replacement = ($replacement) ? 'true' : 'false';
120 6
        }
121
122 12
        return $replacement;
123
    }
124
125
    /**
126
     * Checks to see if the variable has a parameter expansion
127
     *
128
     * @param string $variable The variable to check
129
     *
130
     * @return bool Does the variable have a parameter expansion
131
     */
132 18
    private function hasParameterExpansion($variable)
133
    {
134 18
        if ((strpos($variable, self::SYMBOL_DEFAULT_VALUE) !== false) ||
135 18
            (strpos($variable, self::SYMBOL_ASSIGN_DEFAULT_VALUE) !== false)
136 18
        ) {
137 9
            return true;
138
        }
139
140 12
        return false;
141
    }
142
143
    /**
144
     * Fetches and sets the parameter expansion
145
     *
146
     * @param string $variable_name The parameter expansion inside this to fetch
147
     *
148
     * @return string The parsed value
149
     */
150 9
    private function fetchParameterExpansion($variable_name)
151
    {
152 9
        $parameter_type = $this->fetchParameterExpansionType($variable_name);
153
154 9
        list($parameter_symbol, $empty_flag) = $this->fetchParameterExpansionSymbol($variable_name, $parameter_type);
155 9
        list($variable, $default) = $this->splitVariableDefault($variable_name, $parameter_symbol);
156
157 6
        return $this->parseVariableParameter(
158 6
            $variable,
159 6
            $default,
160 6
            $this->checkVariableExists($variable, $variable, true),
161 6
            $empty_flag && empty($this->parser->lines[$variable]),
162
            $parameter_type
163 6
        );
164
    }
165
166
    /**
167
     * Fetches the parameter expansion type
168
     *
169
     * @param string $variable_name The parameter expansion type to get from this
170
     *
171
     * @return string The parameter expansion type
172
     */
173 9
    private function fetchParameterExpansionType($variable_name)
174
    {
175 9
        if (strpos($variable_name, self::SYMBOL_ASSIGN_DEFAULT_VALUE) !== false) {
176 9
            return 'assign_default_value';
177
        }
178
179 6
        return 'default_value'; // self::DEFAULT_VALUE_SYMBOL
180
    }
181
182
    /**
183
     * Fetches the parameter type symbol
184
     *
185
     * @param string $variable_name The variable
186
     * @param string $type          The type of parameter expansion
187
     *
188
     * @return array The symbol and if there is a empty check
189
     */
190 9
    private function fetchParameterExpansionSymbol($variable_name, $type)
191
    {
192 9
        $symbol = (new \ReflectionClass($this))->getConstant('SYMBOL_'.strtoupper($type));
193 9
        $pos = strpos($variable_name, $symbol);
194
195 9
        $check_empty = substr($variable_name, ($pos - 1), 1) === ":";
196
197 9
        if ($check_empty) {
198 9
            $symbol = sprintf(":%s", $symbol);
199 9
        }
200
201 9
        return array($symbol, $check_empty);
202
    }
203
204
    /**
205
     * Splits the parameter expansion into variable and default
206
     *
207
     * @param string $variable_name    The variable name to split
208
     * @param string $parameter_symbol The parameter expansion symbol
209
     *
210
     * @throws \M1\Env\Exception\ParseException If the parameter expansion if not valid syntax
211
     *
212
     * @return array The split variable and default value
213
     */
214 9
    private function splitVariableDefault($variable_name, $parameter_symbol)
215
    {
216 9
        $variable_default = explode($parameter_symbol, $variable_name, 2);
217
218 9
        if (count($variable_default) !== 2 || empty($variable_default[1])) {
219 3
            throw new ParseException(
220 3
                'You must have valid parameter expansion syntax, eg. ${parameter:=word}',
221 3
                $this->parser->origin_exception,
222 3
                $this->parser->file,
223 3
                $variable_name,
224 3
                $this->parser->line_num
225 3
            );
226
        }
227
228 6
        return array(trim($variable_default[0]), trim($variable_default[1]));
229
    }
230
231
232
    /**
233
     * Parses and sets the variable and default if needed
234
     *
235
     * @param string $variable The variable to parse
236
     * @param string $default  The default value
237
     * @param bool   $exists   Does the variable exist
238
     * @param bool   $empty    Is there the variable empty if exists and the empty flag is set
239
     * @param string $type     The type of parameter expansion
240
     *
241
     * @return string The parsed value
242
     */
243 6
    private function parseVariableParameter($variable, $default, $exists, $empty, $type)
244
    {
245 6
        if ($exists && !$empty) {
246 6
            return $this->parser->lines[$variable];
247
        }
248
249 6
        return $this->assignVariableParameterDefault($variable, $default, $empty, $type);
250
251
    }
252
253
    /**
254
     * Parses and sets the variable parameter to default
255
     *
256
     * @param string $variable The variable to parse
257
     * @param string $default  The default value
258
     * @param bool   $empty    Is there the variable empty if exists and the empty flag is set
259
     * @param string $type     The type of parameter expansion
260
     *
261
     * @return string The parsed default value
262
     */
263 6
    private function assignVariableParameterDefault($variable, $default, $empty, $type)
264
    {
265 6
        $default = $this->parser->value_parser->parse($default);
266
267 6
        if ($type === "assign_default_value" && $empty) {
268 6
            $this->parser->lines[$variable] = $default;
269 6
        }
270
271 6
        return $default;
272
    }
273
274
    /**
275
     * Checks to see if a variable exists
276
     *
277
     * @param string $value          The value to throw an error with if doesn't exist
278
     * @param string $variable       The variable name to get
279
     * @param bool   $variable_check Are you checking to only see if a variable exists and not to throw an exception
280
     *
281
     * @throws \M1\Env\Exception\ParseException If the variable can not be found and `$variable_check` is false
282
     *
283
     * @return bool Does the variable exist
284
     */
285 15
    private function checkVariableExists($value, $variable, $variable_check = false)
286
    {
287 15
        if (!array_key_exists($variable, $this->parser->lines)) {
288 9
            if ($variable_check) {
289 6
                return false;
290
            }
291
292 3
            throw new ParseException(
293 3
                sprintf('Variable has not been defined: %s', $variable),
294 3
                $this->parser->origin_exception,
295 3
                $this->parser->file,
296 3
                $value,
297 3
                $this->parser->line_num
298 3
            );
299
        }
300
301 12
        return true;
302
    }
303
304
    /**
305
     * Do the variable replacements
306
     *
307
     * @param string $value         The value to throw an error with if doesn't exist
308
     * @param array  $matches       The matches of the variables
309
     * @param bool   $quoted_string Is the value in a quoted string
310
     *
311
     * @return string The parsed value
312
     */
313 9
    public function doReplacements($value, $matches, $quoted_string)
314
    {
315 9
        $replacements = array();
316
317 9
        for ($i = 0; $i <= (count($matches[0]) - 1); $i++) {
318 9
            $replacement = $this->fetchVariable($value, $matches[1][$i], $matches, $quoted_string);
319 9
            $replacements[$matches[0][$i]] = $replacement;
320 9
        }
321
322 9
        if (!empty($replacements)) {
323 9
            $value = strtr($value, $replacements);
324 9
        }
325
326 9
        return $value;
327
    }
328
}
329