Config::load()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 5
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 12
rs 10
1
<?php
2
3
/**
4
 * Platine Config
5
 *
6
 * Platine Config is the library used to manage the application
7
 * configuration using differents loaders
8
 *
9
 * This content is released under the MIT License (MIT)
10
 *
11
 * Copyright (c) 2020 Platine Config
12
 *
13
 * Permission is hereby granted, free of charge, to any person obtaining a copy
14
 * of this software and associated documentation files (the "Software"), to deal
15
 * in the Software without restriction, including without limitation the rights
16
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
 * copies of the Software, and to permit persons to whom the Software is
18
 * furnished to do so, subject to the following conditions:
19
 *
20
 * The above copyright notice and this permission notice shall be included in all
21
 * copies or substantial portions of the Software.
22
 *
23
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
 * SOFTWARE.
30
 */
31
32
/**
33
 *  @file Config.php
34
 *
35
 *  The Config class used to manage application configuration
36
 *
37
 *  @package    Platine\Config
38
 *  @author Platine Developers Team
39
 *  @copyright  Copyright (c) 2020
40
 *  @license    http://opensource.org/licenses/MIT  MIT License
41
 *  @link   https://www.platine-php.com
42
 *  @version 1.0.0
43
 *  @filesource
44
 */
45
46
declare(strict_types=1);
47
48
namespace Platine\Config;
49
50
use ArrayAccess;
51
use Platine\Stdlib\Helper\Arr;
52
53
/**
54
 * Class Config
55
 * @package Platine\Config
56
 * @template T
57
 * @implements ArrayAccess<string, mixed>
58
 */
59
class Config implements ArrayAccess
60
{
61
    /**
62
     * The configuration loader to use
63
     * @var LoaderInterface
64
     */
65
    protected LoaderInterface $loader;
66
67
    /**
68
     * The configuration environment to use
69
     * @var string
70
     */
71
    protected string $env;
72
73
    /**
74
     * The configuration items loaded
75
     * @var array<string, mixed>
76
     */
77
    protected array $items = [];
78
79
    /**
80
     * Create new configuration instance
81
     * @param LoaderInterface $loader the loader to use
82
     * @param string          $env    the name of the environment
83
     */
84
    public function __construct(LoaderInterface $loader, string $env = '')
85
    {
86
        $this->loader = $loader;
87
        $this->env = $env;
88
    }
89
90
    /**
91
     * Check whether the configuration for given key exists
92
     * @param  string  $key the name of the key
93
     * @return boolean
94
     */
95
    public function has(string $key): bool
96
    {
97
        return $this->get($key, $this) !== $this;
98
    }
99
100
    /**
101
     * Return the configuration value for the given key
102
     * @param  string $key the name of the configuration item
103
     * @param  mixed $default the default value if can not find the configuration item
104
     * @return mixed
105
     */
106
    public function get(string $key, mixed $default = null): mixed
107
    {
108
        list($group, ) = $this->parseKey($key);
109
        $this->load($group);
110
111
        return Arr::get($this->items, $key, $default);
112
    }
113
114
    /**
115
     * Set the configuration value for the given key
116
     * @param  string $key the name of the configuration item
117
     * @param  mixed $value the configuration value
118
     * @return void
119
     */
120
    public function set(string $key, mixed $value): void
121
    {
122
        list($group, $item) = $this->parseKey($key);
123
124
        // We'll need to go ahead and lazy load each configuration groups even when
125
        // we're just setting a configuration item so that the set item does not
126
        // get overwritten if a different item in the group is requested later.
127
        $this->load($group);
128
129
        if (is_null($item)) {
130
            $this->items[$group] = $value;
131
        } else {
132
            Arr::set($this->items[$group], $item, $value);
133
        }
134
    }
135
136
    /**
137
     * Return all the configuration items
138
     * @return array<string, mixed>
139
     */
140
    public function getItems(): array
141
    {
142
        return $this->items;
143
    }
144
145
    /**
146
     * Return the configuration current environment
147
     * @return string
148
     */
149
    public function getEnvironment(): string
150
    {
151
        return $this->env;
152
    }
153
154
    /**
155
     * Set the configuration environment
156
     *
157
     * @param string $env
158
     * @return $this
159
     */
160
    public function setEnvironment(string $env): self
161
    {
162
        $this->env = $env;
163
164
        return $this;
165
    }
166
167
    /**
168
     * Return the configuration current loader
169
     * @return LoaderInterface
170
     */
171
    public function getLoader(): LoaderInterface
172
    {
173
        return $this->loader;
174
    }
175
176
    /**
177
     * Set the configuration loader
178
     *
179
     * @param LoaderInterface $loader
180
     * @return $this
181
     */
182
    public function setLoader(LoaderInterface $loader): self
183
    {
184
        $this->loader = $loader;
185
186
        return $this;
187
    }
188
189
    /**
190
     * {@inheritdoc}
191
     */
192
    public function offsetExists(mixed $key): bool
193
    {
194
        return $this->has($key);
195
    }
196
197
    /**
198
     * {@inheritdoc}
199
     */
200
    public function offsetGet(mixed $key): mixed
201
    {
202
        return $this->get($key);
203
    }
204
205
    /**
206
     *
207
     * @param string $key
208
     * @param mixed $value
209
     * @return void
210
     */
211
    public function offsetSet(mixed $key, mixed $value): void
212
    {
213
        $this->set($key, $value);
214
    }
215
216
    /**
217
     * {@inheritdoc}
218
     */
219
    public function offsetUnset(mixed $key): void
220
    {
221
        $this->set($key, null);
222
    }
223
224
    /**
225
     * Load the configuration group for the key.
226
     * @param  string $group the name of group to load
227
     * @return void
228
     */
229
    protected function load(string $group): void
230
    {
231
        // If we've already loaded this collection, we will just bail out since we do
232
        // not want to load it again. Once items are loaded a first time they will
233
        // stay kept in memory within this class and not loaded from disk again.
234
        if (isset($this->items[$group])) {
235
            return;
236
        }
237
        $loaded = $this->loader->load($this->env, $group);
238
239
        if (!empty($loaded)) {
240
            $this->items[$group] = $loaded;
241
        }
242
    }
243
244
    /**
245
     * Parse the configuration key
246
     * @param  string $key the name of the key
247
     * @return array<int, mixed>
248
     */
249
    protected function parseKey(string $key): array
250
    {
251
        if (($pos = strpos($key, '.')) === false) {
252
            return [$key, null];
253
        }
254
        return [substr($key, 0, $pos), substr($key, $pos + 1)];
255
    }
256
}
257