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
Pull Request — master (#6)
by Bogdan
14:31
created

VariableParser::hasVariable()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 0
cts 0
cp 0
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 1
crap 12
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     2.0.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
23
/**
24
 * The value parser for Env
25
 *
26
 * @since 1.1.0
27
 */
28
class VariableParser extends AbstractParser
29
{
30
    /**
31
     * The regex to get variables '$(VARIABLE)' in .env
32
     * Unescaped: ${(.*?)}
33
     *
34
     * @var string REGEX_ENV_VARIABLE
35
     */
36
    const REGEX_ENV_VARIABLE = '\\${(.*?)}';
37
38
    /**
39
     * The symbol for the assign default value parameter expansion
40
     *
41
     * @var string SYMBOL_ASSIGN_DEFAULT_VALUE
42
     */
43
    const SYMBOL_ASSIGN_DEFAULT_VALUE = '=';
44
45
    /**
46
     * The symbol for the default value parameter expansion
47
     *
48
     * @var string SYMBOL_DEFAULT_VALUE
49
     */
50
    const SYMBOL_DEFAULT_VALUE = '-';
51
52
    /**
53
     * Variables context
54
     *
55
     * @var array
56
     */
57
    private $context;
58
59
    /**
60 36
     * {@inheritdoc}
61
     *
62 36
     * @param \M1\Env\Parser $parser The parent parser
63
     * @param array $context Variables context
64 36
     */
65 18
    public function __construct($parser, array $context = array())
66 18
    {
67
        parent::__construct($parser);
68
69 9
        $this->context = $context;
70 9
    }
71
72 30
    /**
73
     * Parses a .env variable
74
     *
75
     * @param string $value         The value to parse
76
     * @param bool   $quoted_string Is the value in a quoted string
77
     *
78
     * @return string The parsed value
79
     */
80
    public function parse($value, $quoted_string = false)
81
    {
82 36
        $matches = $this->fetchVariableMatches($value);
83
84 36
        if (is_array($matches)) {
85
            if ($this->parser->string_helper->isVariableClone($value, $matches, $quoted_string)) {
86 36
                return $this->fetchVariable($value, $matches[1][0], $matches, $quoted_string);
87 27
            }
88
89
            $value = $this->doReplacements($value, $matches, $quoted_string);
90 18
        }
91
92
        return $value;
93
    }
94
95
    /**
96
     * Get variable matches inside a string
97
     *
98
     * @param string $value The value to parse
99
     *
100
     * @return array The variable matches
101
     */
102
    private function fetchVariableMatches($value)
103 18
    {
104
        preg_match_all('/' . self::REGEX_ENV_VARIABLE . '/', $value, $matches);
105 18
106 9
        if (!is_array($matches) || !isset($matches[0]) || empty($matches[0])) {
107 6
            return false;
108 12
        }
109 9
110
        return $matches;
111
    }
112 12
113 6
    /**
114 6
     * Parses a .env variable
115
     *
116 12
     * @param string $value The value to parse
117
     * @param string $variable_name The variable name to get
118
     * @param array $matches The matches of the variables
119
     * @param bool $quoted_string Is the value in a quoted string
120
     *
121
     * @return string The parsed value
122
     * @throws \M1\Env\Exception\ParseException If the variable can not be found
123
     */
124
    private function fetchVariable($value, $variable_name, $matches, $quoted_string)
125
    {
126 18
        if ($this->hasParameterExpansion($variable_name)) {
127
            $replacement = $this->fetchParameterExpansion($variable_name);
128 18
        } elseif ($this->hasVariable($variable_name)) {
129 18
            $replacement = $this->getVariable($variable_name);
130 18
        } else {
131 9
            throw new ParseException(
132
                sprintf('Variable has not been defined: %s', $variable_name),
133
                $value,
134 12
                $this->parser->line_num
135
            );
136
        }
137
138
        if ($this->parser->string_helper->isBoolInString($replacement, $quoted_string, count($matches[0]))) {
139
            $replacement = ($replacement) ? 'true' : 'false';
140
        }
141
142
        return $replacement;
143
    }
144 9
145
    /**
146 9
     * Checks to see if the variable has a parameter expansion
147
     *
148 9
     * @param string $variable The variable to check
149 9
     *
150
     * @return bool Does the variable have a parameter expansion
151 6
     */
152 6
    private function hasParameterExpansion($variable)
153 6
    {
154 6
        if ((strpos($variable, self::SYMBOL_DEFAULT_VALUE) !== false) ||
155 6
            (strpos($variable, self::SYMBOL_ASSIGN_DEFAULT_VALUE) !== false)
156
        ) {
157 6
            return true;
158
        }
159
160
        return false;
161
    }
162
163
    /**
164
     * Fetches and sets the parameter expansion
165
     *
166
     * @param string $variable_name The parameter expansion inside this to fetch
167 9
     *
168
     * @return string The parsed value
169 9
     */
170 9
    private function fetchParameterExpansion($variable_name)
171
    {
172
        $parameter_type = $this->fetchParameterExpansionType($variable_name);
173 6
174
        list($parameter_symbol, $empty_flag) = $this->fetchParameterExpansionSymbol($variable_name, $parameter_type);
175
        list($variable, $default) = $this->splitVariableDefault($variable_name, $parameter_symbol);
176
177
        return $this->parseVariableParameter(
178
            $variable,
179
            $default,
180
            $this->checkVariableExists($variable, $variable, true),
181
            $empty_flag && !$this->hasVariable($variable),
182
            $parameter_type
183
        );
184 9
    }
185
186 9
    /**
187 9
     * Fetches the parameter expansion type
188 9
     *
189
     * @param string $variable_name The parameter expansion type to get from this
190 9
     *
191
     * @return string The parameter expansion type
192 9
     */
193 9
    private function fetchParameterExpansionType($variable_name)
194 9
    {
195
        if (strpos($variable_name, self::SYMBOL_ASSIGN_DEFAULT_VALUE) !== false) {
196 9
            return 'assign_default_value';
197
        }
198
199
        return 'default_value'; // self::DEFAULT_VALUE_SYMBOL
200
    }
201
202
    /**
203
     * Fetches the parameter type symbol
204
     *
205
     * @param string $variable_name The variable
206
     * @param string $type          The type of parameter expansion
207
     *
208
     * @return array The symbol and if there is a empty check
209 9
     */
210
    private function fetchParameterExpansionSymbol($variable_name, $type)
211 9
    {
212
        $class = new \ReflectionClass($this);
213 9
        $symbol = $class->getConstant('SYMBOL_'.strtoupper($type));
214 3
        $pos = strpos($variable_name, $symbol);
215 3
216 3
        $check_empty = substr($variable_name, ($pos - 1), 1) === ":";
217 3
218 3
        if ($check_empty) {
219
            $symbol = sprintf(":%s", $symbol);
220
        }
221 6
222
        return array($symbol, $check_empty);
223
    }
224
225
    /**
226
     * Splits the parameter expansion into variable and default
227
     *
228
     * @param string $variable_name    The variable name to split
229
     * @param string $parameter_symbol The parameter expansion symbol
230
     *
231
     * @throws \M1\Env\Exception\ParseException If the parameter expansion if not valid syntax
232
     *
233
     * @return array The split variable and default value
234
     */
235
    private function splitVariableDefault($variable_name, $parameter_symbol)
236 6
    {
237
        $variable_default = explode($parameter_symbol, $variable_name, 2);
238 6
239 6
        if (count($variable_default) !== 2 || empty($variable_default[1])) {
240
            throw new ParseException(
241
                'You must have valid parameter expansion syntax, eg. ${parameter:=word}',
242 6
                $variable_name,
243
                $this->parser->line_num
244
            );
245
        }
246
247
        return array(trim($variable_default[0]), trim($variable_default[1]));
248
    }
249
250
251
    /**
252
     * Parses and sets the variable and default if needed
253
     *
254
     * @param string $variable The variable to parse
255 6
     * @param string $default  The default value
256
     * @param bool   $exists   Does the variable exist
257 6
     * @param bool   $empty    Is there the variable empty if exists and the empty flag is set
258
     * @param string $type     The type of parameter expansion
259 6
     *
260 6
     * @return string The parsed value
261 6
     */
262
    private function parseVariableParameter($variable, $default, $exists, $empty, $type)
263 6
    {
264
        if ($exists && !$empty) {
265
            return $this->getVariable($variable);
266
        }
267
268
        return $this->assignVariableParameterDefault($variable, $default, $empty, $type);
269
    }
270
271
    /**
272
     * Parses and sets the variable parameter to default
273
     *
274
     * @param string $variable The variable to parse
275
     * @param string $default  The default value
276
     * @param bool   $empty    Is there the variable empty if exists and the empty flag is set
277 15
     * @param string $type     The type of parameter expansion
278
     *
279 15
     * @return string The parsed default value
280 9
     */
281 6
    private function assignVariableParameterDefault($variable, $default, $empty, $type)
282
    {
283
        $default = $this->parser->value_parser->parse($default);
284 3
285 3
        if ($type === "assign_default_value" && $empty) {
286 3
            $this->parser->lines[$variable] = $default;
287 3
        }
288 3
289
        return $default;
290
    }
291 12
292
    /**
293
     * Checks to see if a variable exists or throw
294
     *
295
     * @param string $value          The value to throw an error with if doesn't exist
296
     * @param string $variable       The variable name to get
297
     * @param bool   $variable_check Are you checking to only see if a variable exists and not to throw an exception
298
     *
299
     * @throws \M1\Env\Exception\ParseException If the variable can not be found and `$variable_check` is false
300
     *
301
     * @return bool Does the variable exist
302
     */
303 9
    private function checkVariableExists($value, $variable, $variable_check = false)
0 ignored issues
show
Unused Code introduced by
The parameter $value is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
304
    {
305 9
        if (!$this->hasVariable($variable)) {
306
            if ($variable_check) {
307 9
                return false;
308 9
            }
309 9
        }
310 9
311
        return true;
312 9
    }
313 9
314 9
    /**
315
     * Checks to see if a variable exists
316 9
     *
317
     * @param string $variable The variable name to get
318
     *
319
     * @return bool
320
     */
321
    private function hasVariable($variable)
322
    {
323
        if (array_key_exists($variable, $this->parser->lines)) {
324
            return true;
325
        }
326
327
        if (array_key_exists($variable, $this->context)) {
328
            return true;
329
        }
330
331
        return false;
332
    }
333
334
    /**
335
     * Get variable value
336
     *
337
     * @param string $variable
338
     *
339
     * @return mixed
340
     */
341
    private function getVariable($variable)
342
    {
343
        if (array_key_exists($variable, $this->parser->lines)) {
344
            return $this->parser->lines[$variable];
345
        }
346
347
        if (array_key_exists($variable, $this->context)) {
348
            return $this->context[$variable];
349
        }
350
351
        return null;
352
    }
353
354
    /**
355
     * Do the variable replacements
356
     *
357
     * @param string $value         The value to throw an error with if doesn't exist
358
     * @param array  $matches       The matches of the variables
359
     * @param bool   $quoted_string Is the value in a quoted string
360
     *
361
     * @return string The parsed value
362
     */
363
    public function doReplacements($value, $matches, $quoted_string)
364
    {
365
        $replacements = array();
366
367
        for ($i = 0; $i <= (count($matches[0]) - 1); $i++) {
368
            $replacement = $this->fetchVariable($value, $matches[1][$i], $matches, $quoted_string);
369
            $replacements[$matches[0][$i]] = $replacement;
370
        }
371
372
        if (!empty($replacements)) {
373
            $value = strtr($value, $replacements);
374
        }
375
376
        return $value;
377
    }
378
}
379