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 ( 8b864d...9c6238 )
by Miles
08:16
created

VariableParser::checkVariableExists()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 18
ccs 12
cts 12
cp 1
rs 9.4286
cc 3
eloc 11
nc 3
nop 3
crap 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->parseVariableDefault($variable, $default, $empty_flag, $parameter_type);
158
    }
159
160
    /**
161
     * Fetches the parameter expansion type
162
     *
163
     * @param string $variable_name The parameter expansion type to get from this
164
     *
165
     * @return string The parameter expansion type
166
     */
167 9
    private function fetchParameterExpansionType($variable_name)
168
    {
169 9
        if (strpos($variable_name, self::SYMBOL_ASSIGN_DEFAULT_VALUE) !== false) {
170 9
            return 'assign_default_value';
171
        }
172
173 6
        return 'default_value'; // self::DEFAULT_VALUE_SYMBOL
174
    }
175
176
    /**
177
     * Fetches the parameter type symbol
178
     *
179
     * @param string $variable_name The variable
180
     * @param string $type          The type of parameter expansion
181
     *
182
     * @return array The symbol and if there is a empty check
183
     */
184 9
    private function fetchParameterExpansionSymbol($variable_name, $type)
185
    {
186 9
        $symbol = (new \ReflectionClass($this))->getConstant('SYMBOL_'.strtoupper($type));
187 9
        $pos = strpos($variable_name, $symbol);
188
189 9
        $check_empty = substr($variable_name, ($pos - 1), 1) === ":";
190
191 9
        if ($check_empty) {
192 9
            $symbol = sprintf(":%s", $symbol);
193 9
        }
194
195 9
        return array($symbol, $check_empty);
196
    }
197
198
    /**
199
     * Splits the parameter expansion into variable and default
200
     *
201
     * @param string $variable_name    The variable name to split
202
     * @param string $parameter_symbol The parameter expansion symbol
203
     *
204
     * @throws \M1\Env\Exception\ParseException If the parameter expansion if not valid syntax
205
     *
206
     * @return array The split variable and default value
207
     */
208 9
    private function splitVariableDefault($variable_name, $parameter_symbol)
209
    {
210 9
        $variable_default = explode($parameter_symbol, $variable_name, 2);
211 9
        if (count($variable_default) !== 2 || empty($variable_default[1])) {
212 3
            throw new ParseException(
213 3
                'You must have valid parameter expansion syntax, eg. ${parameter:=word}',
214 3
                $this->parser->origin_exception,
215 3
                $this->parser->file,
216 3
                $variable_name,
217 3
                $this->parser->line_num
218 3
            );
219
        }
220
221 6
        return array(trim($variable_default[0]), trim($variable_default[1]));
222
    }
223
224
    /**
225
     * Parses and sets the variable and default if needed
226
     *
227
     * @param string $variable_name  The variable name to parse and set
228
     * @param string $default        The default value
229
     * @param bool   $check_empty    Is there a check empty flag `:`
230
     * @param string $parameter_type The type of parameter expansion
231
     *
232
     * @return string The parsed value
233
     */
234 6
    private function parseVariableDefault($variable_name, $default, $check_empty, $parameter_type)
235
    {
236 6
        $variable_exists = $this->checkVariableExists($variable_name, $variable_name, true);
237 6
        $variable_empty = $this->checkVariableEmpty($variable_name, $check_empty);
238
239 6
        if ($variable_exists && !$variable_empty) {
240 6
            $value = $this->parser->lines[$variable_name];
241 6
        } else {
242 6
            $default = $this->parser->value_parser->parse($default);
243 6
            $value = $default;
244
245 6
            if ($parameter_type === "assign_default_value" && $variable_empty) {
246 6
                $this->parser->lines[$variable_name] = $default;
247 6
            }
248
        }
249
250 6
        return $value;
251
    }
252
253
    /**
254
     * Checks to see if a variable exists
255
     *
256
     * @param string $value          The value to throw an error with if doesn't exist
257
     * @param string $variable       The variable name to get
258
     * @param bool   $variable_check Are you checking to only see if a variable exists and not to throw an exception
259
     *
260
     * @throws \M1\Env\Exception\ParseException If the variable can not be found and `$variable_check` is false
261
     *
262
     * @return bool Does the variable exist
263
     */
264 15
    private function checkVariableExists($value, $variable, $variable_check = false)
265
    {
266 15
        if (!array_key_exists($variable, $this->parser->lines)) {
267 9
            if ($variable_check) {
268 6
                return false;
269
            }
270
271 3
            throw new ParseException(
272 3
                sprintf('Variable has not been defined: %s', $variable),
273 3
                $this->parser->origin_exception,
274 3
                $this->parser->file,
275 3
                $value,
276 3
                $this->parser->line_num
277 3
            );
278
        }
279
280 12
        return true;
281
    }
282
283
    /**
284
     * Checks to see if a variable exists
285
     *
286
     * @param string $variable       The variable name to get
287
     * @param bool   $check_empty    Is there a check empty flag `:`
288
     *
289
     * @return bool Is the variable empty if the check empty flag is set
290
     */
291 6
    private function checkVariableEmpty($variable, $check_empty)
292
    {
293 6
        return $check_empty && empty($this->parser->lines[$variable]);
294
    }
295
296
    /**
297
     * Do the variable replacements
298
     *
299
     * @param string $value         The value to throw an error with if doesn't exist
300
     * @param array  $matches       The matches of the variables
301
     * @param bool   $quoted_string Is the value in a quoted string
302
     *
303
     * @return string The parsed value
304
     */
305 9
    public function doReplacements($value, $matches, $quoted_string)
306
    {
307 9
        $replacements = array();
308
309 9
        for ($i = 0; $i <= (count($matches[0]) - 1); $i++) {
310 9
            $replacement = $this->fetchVariable($value, $matches[1][$i], $matches, $quoted_string);
311 9
            $replacements[$matches[0][$i]] = $replacement;
312 9
        }
313
314 9
        if (!empty($replacements)) {
315 9
            $value = strtr($value, $replacements);
316 9
        }
317
318 9
        return $value;
319
    }
320
}
321