Environment   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 84
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 14
eloc 37
dl 0
loc 84
c 0
b 0
f 0
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getKeyValue() 0 18 5
A getOldValue() 0 9 2
A isValidKey() 0 10 3
A writeFile() 0 6 1
A set() 0 19 3
1
<?php
2
3
namespace Presspack\Framework\Support;
4
5
use Illuminate\Support\Str;
6
7
class Environment
8
{
9
    public static function set(string $key, string $value = null, string $dir = './.env')
10
    {
11
        try {
12
            list($key, $value) = self::getKeyValue($key, $value);
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type null; however, parameter $value of Presspack\Framework\Supp...ironment::getKeyValue() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

12
            list($key, $value) = self::getKeyValue($key, /** @scrutinizer ignore-type */ $value);
Loading history...
13
        } catch (\InvalidArgumentException $e) {
14
            return $e->getMessage();
15
        }
16
        $envFilePath = "{$dir}";
17
        $contents = file_get_contents($envFilePath);
18
        if ($oldValue = self::getOldValue($contents, $key)) {
19
            $contents = str_replace("{$key}={$oldValue}", "{$key}={$value}", $contents);
20
            self::writeFile($envFilePath, $contents);
21
22
            return "Environment variable with key '{$key}' has been changed from '{$oldValue}' to '{$value}'";
23
        }
24
        $contents = $contents."\n{$key}={$value}\n";
25
        self::writeFile($envFilePath, $contents);
26
27
        return "A new environment variable with key '{$key}' has been set to '{$value}'";
28
    }
29
30
    /**
31
     * Overwrite the contents of a file.
32
     */
33
    protected static function writeFile(string $path, string $contents): bool
34
    {
35
        $file = fopen($path, 'w');
36
        fwrite($file, $contents);
0 ignored issues
show
Bug introduced by
It seems like $file can also be of type false; however, parameter $handle of fwrite() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

36
        fwrite(/** @scrutinizer ignore-type */ $file, $contents);
Loading history...
37
38
        return fclose($file);
0 ignored issues
show
Bug introduced by
It seems like $file can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

38
        return fclose(/** @scrutinizer ignore-type */ $file);
Loading history...
39
    }
40
41
    /**
42
     * Get the old value of a given key from an environment file.
43
     */
44
    protected static function getOldValue(string $envFile, string $key): string
45
    {
46
        // Match the given key at the beginning of a line
47
        preg_match("/^{$key}=[^\r\n]*/m", $envFile, $matches);
48
        if (\count($matches)) {
49
            return substr($matches[0], \strlen($key) + 1);
50
        }
51
52
        return '';
53
    }
54
55
    /**
56
     * Determine what the supplied key and value is from the current command.
57
     */
58
    protected static function getKeyValue(string $key, string $value): array
59
    {
60
        if (! $value) {
61
            $parts = explode('=', $key, 2);
62
            if (2 !== \count($parts)) {
63
                throw new InvalidArgumentException('No value was set');
0 ignored issues
show
Bug introduced by
The type Presspack\Framework\Supp...nvalidArgumentException was not found. Did you mean InvalidArgumentException? If so, make sure to prefix the type with \.
Loading history...
64
            }
65
            $key = $parts[0];
66
            $value = $parts[1];
67
        }
68
        if (! self::isValidKey($key)) {
69
            throw new InvalidArgumentException('Invalid argument key');
70
        }
71
        if (! \is_bool(strpos($value, ' '))) {
0 ignored issues
show
introduced by
The condition is_bool(strpos($value, ' ')) is always false.
Loading history...
72
            $value = '"'.$value.'"';
73
        }
74
75
        return [strtoupper($key), $value];
76
    }
77
78
    /**
79
     * Check if a given string is valid as an environment variable key.
80
     */
81
    protected static function isValidKey(string $key): bool
82
    {
83
        if (Str::contains($key, '=')) {
84
            throw new InvalidArgumentException("Environment key should not contain '='");
85
        }
86
        if (! preg_match('/^[a-zA-Z_]+$/', $key)) {
87
            throw new InvalidArgumentException('Invalid environment key. Only use letters and underscores');
88
        }
89
90
        return true;
91
    }
92
}
93