Passed
Push — master ( e297c9...6645eb )
by Dawid
02:47
created

Config::get()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 2
dl 0
loc 4
ccs 0
cts 3
cp 0
crap 6
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Igni\Application;
4
5
/**
6
 * Application's config container.
7
 * Treats dots as an operator for accessing nested values.
8
 * If constant name is put in curly braces as a value, it wil be replaced
9
 * to the constant value.
10
 *
11
 * @example:
12
 * // Example usage.
13
 * $config = new Config();
14
 * $config->set('some.key', true);
15
 * $some = $config->get('some'); // returns ['key' => true]
16
 *
17
 * @package Igni\Application
18
 */
19
class Config
20
{
21
    /**
22
     * @var array
23
     */
24
    private $config;
25
26
    /**
27
     * Config constructor.
28
     *
29
     * @param array $config
30
     */
31 15
    public function __construct(array $config = [])
32
    {
33 15
        $this->config = $config;
34 15
    }
35
36
    /**
37
     * Checks if config key exists.
38
     *
39
     * @param string $key
40
     * @return bool
41
     */
42
    public function has(string $key): bool
43
    {
44
        return $this->lookup($key) !== null;
45
    }
46
47
    private function lookup(string $key)
48
    {
49
        $result = $this->config;
50
        $key = explode('.', $key);
51
        foreach($key as $part) {
52
            if (!is_array($result) || !isset($result[$part])) {
53
                return null;
54
            }
55
            $result = $result[$part];
56
        }
57
58
        return $result;
59
    }
60
61
    /**
62
     * Gets value behind the key, or returns $default value if path does not exists.
63
     *
64
     * @param string $key
65
     * @param null $default
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $default is correct as it would always require null to be passed?
Loading history...
66
     * @return null|string|string[]
67
     */
68
    public function get(string $key, $default = null)
69
    {
70
        $result = $this->lookup($key);
71
        return $result === null ? $default : $this->fetchConstants($result);
72
    }
73
74
    /**
75
     * Merges one instance of Config class into current one and
76
     * returns current instance.
77
     *
78
     * @param Config $config
79
     * @return Config
80
     */
81
    public function merge(Config $config): Config
82
    {
83
        $this->config = array_merge_recursive($this->config, $config);
0 ignored issues
show
Bug introduced by
$config of type Igni\Application\Config is incompatible with the type array expected by parameter $_ of array_merge_recursive(). ( Ignorable by Annotation )

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

83
        $this->config = array_merge_recursive($this->config, /** @scrutinizer ignore-type */ $config);
Loading history...
84
85
        return $this;
86
    }
87
88
    /**
89
     * Sets new value.
90
     *
91
     * @param string $key
92
     * @param $value
93
     */
94
    public function set(string $key, $value): void
95
    {
96
        $key = explode('.', $key);
97
        $last = array_pop($key);
98
        $result = &$this->config;
99
100
        foreach ($key as $part) {
101
            if (!isset($result[$part]) || !is_array($result[$part])) {
102
                $result[$part] = [];
103
            }
104
            $result = &$result[$part];
105
        }
106
        $result[$last] = $value;
107
    }
108
109
    /**
110
     * Returns array representation of the config.
111
     *
112
     * @return array
113
     */
114
    public function toArray(): array
115
    {
116
        return $this->config;
117
    }
118
119
    private function fetchConstants($value)
120
    {
121
        if (!is_string($value)) {
122
            return $value;
123
        }
124
        return preg_replace_callback(
125
            '#\$\{([^{}]*)\}#',
126
            function($matches) {
127
                if (defined($matches[1])) {
128
                    return constant($matches[1]);
129
                }
130
                return $matches[0];
131
            },
132
            $value
133
        );
134
    }
135
}
136