Test Failed
Push — master ( f64e60...d27667 )
by Miroslaw
44s queued 11s
created

Env::_preg_quote_except()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 7
c 1
b 0
f 0
nc 8
nop 3
dl 0
loc 12
rs 10
1
<?php
2
3
namespace msztorc\LaravelEnv;
4
5
class Env
6
{
7
    private $_envContent = null;
8
    private $_envVars = null;
9
    private $_envPath = null;
10
    private $_saved = false;
11
    private $_changed = false;
12
13
    public function __construct()
14
    {
15
        /** @scrutinizer ignore-call */ $this->_envPath = app()->environmentFilePath();
16
        $this->_envContent = file_get_contents($this->_envPath);
17
18
        $this->_parse();
19
    }
20
21
    /**
22
     *  Parse env content into array
23
     */
24
    private function _parse(): void
25
    {
26
        $env_lines = preg_split('/\r\n|\r|\n/', $this->_envContent);
27
28
        foreach ($env_lines as $line) {
29
            if (strlen(trim($line)) && !(strpos(trim($line), '#') === 0)) {
30
                [$key, $val] = explode('=', (string)$line);
31
                $this->_envVars[$key] = $this->_stripValue($val);
32
            }
33
        }
34
    }
35
36
37
    /**
38
     * Check if the variable exists
39
     * @param string $key Environment variable key
40
     * @return bool
41
     */
42
    public function exists(string $key): bool
43
    {
44
        if (is_null($this->_envVars)) {
45
            $this->_parse();
46
        }
47
48
        return isset($this->_envVars[$key]);
49
    }
50
51
    /**
52
     * Get the current env variable value
53
     *
54
     * @param string $key Environment variable key
55
     * @return string
56
     */
57
    public function getValue(string $key): string
58
    {
59
        if (is_null($this->_envVars)) {
60
            $this->_parse();
61
        }
62
63
        return $this->_envVars[$key] ?? '';
64
    }
65
66
67
    /**
68
     * Get env key-value
69
     *
70
     * @param string $key Environment variable key
71
     * @return array
72
     */
73
    public function getKeyValue(string $key): array
74
    {
75
        if (is_null($this->_envVars)) {
76
            $this->_parse();
77
        }
78
79
        return [$key => $this->_envVars[$key]] ?? [];
80
    }
81
82
83
    /**
84
     * Set env variable value
85
     * @param string $key Environment variable key
86
     * @param string $value Variable value
87
     * @param bool $write Write changes to .env file
88
     * @return string
89
     */
90
    public function setValue(string $key, string $value, $write = true): string
91
    {
92
        $value = $this->_prepareValue($value);
93
94
        if ($this->exists($key)) {
95
            $this->_envContent = preg_replace("/^{$key}=.*$/m", "{$key}={$value}", $this->_envContent);
96
        } else {
97
            $this->_envContent .= PHP_EOL . "{$key}={$value}" . PHP_EOL;
98
        }
99
100
        $this->_changed = true;
101
        $this->_saved = false;
102
103
        $this->_parse();
104
        if ($write) {
105
            $this->write();
106
        }
107
108
        return $this->getValue($key);
109
    }
110
111
112
    /**
113
     * Delete environment variable
114
     * @param string $key Environment variable key
115
     * @param bool $write Write changes to .env file
116
     * @return bool
117
     */
118
    public function deleteVariable(string $key, bool $write = true): bool
119
    {
120
        if ($this->exists($key)) {
121
            $this->_envContent = preg_replace("/^{$key}=.*\s{0,1}/m", '', $this->_envContent);
122
123
            $this->_changed = true;
124
            $this->_saved = false;
125
126
            if ($write) {
127
                $this->write();
128
            }
129
        }
130
131
        return true;
132
    }
133
134
    private function _preg_quote_except(string $str, string $exclude, ?string $delimiter = null): string
135
    {
136
        $str = preg_quote($str, $delimiter);
137
        $from = [];
138
        $to = [];
139
140
        for ($i = 0; $i < strlen($exclude); $i++) {
141
            $from[] = '\\' . $exclude[$i];
142
            $to[] = $exclude[$i];
143
        }
144
145
        return (count($from) && count($to)) ? str_replace($from, $to, $str) : $str;
146
    }
147
148
    /**
149
     * Check and prepare value to be safe
150
     * @param string $value
151
     * @return string
152
     */
153
    private function _prepareValue(string $value): string
154
    {
155
        if (false !== strpos($value, ' ') || in_array($value[0], ['=', '$'])) {
156
            $value = '"' . $value . '"';
157
        }
158
159
        return $this->_preg_quote_except($value, ':.');
160
    }
161
162
    private function _stripQuotes(string $value): string
163
    {
164
        return preg_replace('/^(\'(.*)\'|"(.*)")$/', '$2$3', $value);
165
    }
166
167
    /**
168
     * Strip output value from quotes and inline comments
169
     * @param string $value
170
     * @return string
171
     */
172
    private function _stripValue(string $value): string
173
    {
174
        $val = trim(explode('#', trim($value))[0]);
175
176
        return stripslashes($this->_stripQuotes($val));
177
    }
178
179
    /**
180
     * Get all env variables
181
     * @return array
182
     */
183
    public function getVariables(): array
184
    {
185
        return $this->_envVars;
186
    }
187
188
    /**
189
     * Get current env entire content from memory
190
     * @return string
191
     */
192
    public function getEnvContent(): string
193
    {
194
        return $this->_envContent;
195
    }
196
197
    /**
198
     * Write env config to file
199
     * @return bool
200
     */
201
    public function write(): bool
202
    {
203
        $this->_saved = (false !== file_put_contents($this->_envPath, $this->_envContent) ?? true);
204
205
        return $this->_saved;
206
    }
207
208
    /**
209
     * Check if the changes has been saved
210
     * @return bool
211
     */
212
    public function isSaved(): bool
213
    {
214
        return $this->_saved;
215
    }
216
217
    /**
218
     * Check if there were any env content changes
219
     * @return bool
220
     */
221
    public function wasChanged(): bool
222
    {
223
        return $this->_changed;
224
    }
225
}
226