Passed
Push — master ( 9b41ee...0d3ad3 )
by Enjoys
03:58
created

Dotenv::getEnvArray()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
6
namespace Enjoys\Dotenv;
7
8
9
use Webmozart\Assert\Assert;
10
11
class Dotenv
12
{
13
    private string $baseDirectory;
14
    /**
15
     * @var string[]
16
     */
17
    private array $envArray = [];
18
    private string $distEnvFilename;
19
    private string $envFilename;
20
21 15
    public function __construct(
22
        string $baseDirectory,
23
        string $envFilename = '.env',
24
        string $distEnvFilename = '.env.dist'
25
    ) {
26 15
        $this->baseDirectory = rtrim($baseDirectory, "/") . DIRECTORY_SEPARATOR;
27 15
        $this->distEnvFilename = $distEnvFilename;
28 15
        $this->envFilename = $envFilename;
29 15
    }
30
31 14
    public function loadEnv(bool $usePutEnv = false): void
32
    {
33 14
        $this->doMerge($this->getGeneralPaths());
34 13
        $this->doMerge($this->getExtraPaths());
35 13
        $this->doLoad($usePutEnv);
36 8
    }
37
38
    /**
39
     * @return string[]
40
     */
41 13
    private function getExtraPaths(): array
42
    {
43 13
        $env = $this->envArray['APP_ENV'] ?? '';
44
45 13
        if ($env === '') {
46 10
            return [];
47
        }
48 3
        $path = realpath($this->baseDirectory . $this->envFilename . '.' . $env);
49
50 3
        if ($path === false) {
51 1
            return [];
52
        }
53
54 2
        return [$path];
55
    }
56
57
    /**
58
     * @return string[]
59
     */
60 14
    private function getGeneralPaths(): array
61
    {
62
        $paths = [
63 14
            realpath($this->baseDirectory . $this->distEnvFilename),
64 14
            realpath($this->baseDirectory . $this->envFilename)
65
        ];
66
67 14
        return array_filter($paths, function ($item) {
68 14
            return is_string($item);
69 14
        });
70
    }
71
72
    /**
73
     * @param string[] $array
74
     */
75 14
    private function doMerge(array $array): void
76
    {
77 14
        foreach ($array as $path) {
78 14
            $this->envArray = array_merge($this->envArray, $this->getArrayData($path));
79
        }
80 13
    }
81
82
    /**
83
     * @return string[]
84
     */
85 14
    private function getArrayData(string $path): array
86
    {
87 14
        $result = [];
88
89 14
        $data = file_get_contents($path);
90
91
        /**
92
         * @var string $key
93
         * @var string $value
94
         */
95 14
        foreach ($this->parseToArray($data) as $key => $value) {
96 13
            $result[$key] = $value;
97
        }
98 13
        return $result;
99
    }
100
101
102 14
    private function parseToArray(string $input): \Generator
103
    {
104 14
        foreach (preg_split("/\R/", $input) as $line) {
105 14
            $line = trim($line);
106 14
            if ($this->isComment($line)) {
107 2
                continue;
108
            }
109 14
            $fields = array_map('trim', explode('=', $line, 2));
110
111 14
            if (count($fields) == 2) {
112 14
                list($key, $value) = $fields;
113 14
                Assert::regex(
114 14
                    $key,
115 14
                    '/^([A-Z_0-9]+)$/i',
116 14
                    'The key %s have invalid chars. The key must have only letters (A-Z) digits (0-9) and _'
117
                );
118
119 13
                yield $key => $value;
120
            }
121
        }
122 13
    }
123
124
125 13
    private function doLoad(bool $usePutEnv): void
126
    {
127
        /** @var string $key */
128 13
        foreach ($this->envArray as $key => $value) {
129 13
            $value = ValuesHandler::quotes($value);
130 13
            $value = ValuesHandler::handleVariables($key, $value, $this);
131
132 13
            if (getenv($key)) {
133 3
                $value = getenv($key);
134
            }
135
136
            /** @var string $value */
137 13
            $_ENV[$key] = ValuesHandler::cast($value);
138
139 8
            if (!getenv($key) && $usePutEnv === true) {
140 1
                putenv("$key=$value");
141
            }
142
        }
143 8
    }
144
145 14
    private function isComment(string $line): bool
146
    {
147 14
        return (bool)preg_match('/^#/', $line);
148
    }
149
150
    /**
151
     * @return string[]
152
     */
153 2
    public function getEnvArray(): array
154
    {
155 2
        return $this->envArray;
156
    }
157
158
159 13
    public function setEnvArrayOne(string $key, string  $value): void
160
    {
161 13
        $this->envArray[$key] = $value;
162 13
    }
163
164
165
}