Passed
Push — develop ( 683c19...dcbd9a )
by nguereza
03:20
created

AppDatabaseConfig   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 242
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 56
c 1
b 0
f 0
dl 0
loc 242
rs 10
wmc 22

17 Methods

Rating   Name   Duplication   Size   Complexity  
A offsetSet() 0 3 1
A offsetGet() 0 3 1
A offsetExists() 0 3 1
A setLoader() 0 5 1
A getItems() 0 3 1
A parseKey() 0 14 2
A offsetUnset() 0 3 1
A setEnvironment() 0 5 1
A getEnvironment() 0 3 1
A getFormattedConfigValue() 0 7 3
A __construct() 0 4 1
A has() 0 3 1
A load() 0 10 2
A set() 0 26 2
A getLoader() 0 3 1
A all() 0 3 1
A get() 0 8 1
1
<?php
2
3
/**
4
 * Platine Framework
5
 *
6
 * Platine Framework is a lightweight, high-performance, simple and elegant
7
 * PHP Web framework
8
 *
9
 * This content is released under the MIT License (MIT)
10
 *
11
 * Copyright (c) 2020 Platine Framework
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 AppDatabaseConfig.php
34
 *
35
 *  The database configuration class
36
 *
37
 *  @package    Platine\Framework\Config
38
 *  @author Platine Developers team
39
 *  @copyright  Copyright (c) 2020
40
 *  @license    http://opensource.org/licenses/MIT  MIT License
41
 *  @link   http://www.iacademy.cf
42
 *  @version 1.0.0
43
 *  @filesource
44
 */
45
46
declare(strict_types=1);
47
48
namespace Platine\Framework\Config;
49
50
use ArrayAccess;
51
use InvalidArgumentException;
52
use Platine\Orm\Entity;
53
use Platine\Stdlib\Helper\Arr;
54
55
/**
56
 * @class AppDatabaseConfig
57
 * @package Platine\Framework\Config
58
 * @template T
59
 * @implements ArrayAccess<string, mixed>
60
 */
61
class AppDatabaseConfig implements ArrayAccess
62
{
63
    /**
64
     * The configuration loader to use
65
     * @var DatabaseConfigLoaderInterface
66
     */
67
    protected DatabaseConfigLoaderInterface $loader;
68
69
    /**
70
     * The configuration environment to use
71
     * @var string
72
     */
73
    protected string $env;
74
75
    /**
76
     * The configuration items loaded
77
     * @var array<string, mixed>
78
     */
79
    protected array $items = [];
80
81
    /**
82
     * Create new configuration instance
83
     * @param DatabaseConfigLoaderInterface $loader the loader to use
84
     * @param string          $env    the name of the environment
85
     */
86
    public function __construct(DatabaseConfigLoaderInterface $loader, string $env = '')
87
    {
88
        $this->loader = $loader;
89
        $this->env = $env;
90
    }
91
92
    /**
93
     * Check whether the configuration for given key exists
94
     * @param  string  $key the name of the key
95
     * @return boolean
96
     */
97
    public function has(string $key): bool
98
    {
99
        return $this->get($key, $this) !== $this;
100
    }
101
102
    /**
103
     * Return the configuration value for the given key
104
     * @param  string $key the name of the configuration item
105
     * @param  mixed $default the default value if can
106
     * not find the configuration item
107
     * @return mixed
108
     */
109
    public function get(string $key, $default = null)
110
    {
111
        $results = $this->parseKey($key);
112
        $group = $results['group'];
113
114
        $this->load($group);
115
116
        return Arr::get($this->items, $key, $default);
117
    }
118
119
    /**
120
     * Set the configuration value for the given key
121
     * @param  string $key     the name of the configuration item
122
     * @param  mixed $value the configuration value
123
     * @return void
124
     */
125
    public function set(string $key, $value): void
126
    {
127
        $results = $this->parseKey($key);
128
        $module = $results['group'];
129
        $name = $results['key'];
130
131
        $config = $this->loader->loadConfig([
132
             'name' => $name,
133
             'module' => $module,
134
             'env' => $this->env
135
         ]);
136
137
        if ($config === null) {
138
            $this->loader->insertConfig([
139
                'env' => $this->env,
140
                'module' => $module,
141
                'status' => 'Y',
142
                'name' => $name,
143
                'value' => $this->getFormattedConfigValue($value),
144
                'type' => gettype($value)
145
            ]);
146
        } else {
147
            $config->value = $this->getFormattedConfigValue($value);
148
            $config->type = gettype($value);
149
150
            $this->loader->updateConfig($config);
151
        }
152
    }
153
154
    /**
155
     * Return all the current loaded configuration items
156
     * @return array<string, mixed>
157
     */
158
    public function getItems(): array
159
    {
160
        return $this->items;
161
    }
162
163
    /**
164
     * Return the configuration current environment
165
     * @return string
166
     */
167
    public function getEnvironment(): string
168
    {
169
        return $this->env;
170
    }
171
172
    /**
173
     * Set the configuration environment
174
     *
175
     * @param string $env
176
     * @return $this
177
     */
178
    public function setEnvironment(string $env): self
179
    {
180
        $this->env = $env;
181
182
        return $this;
183
    }
184
185
    /**
186
     * Return the configuration current loader
187
     * @return DatabaseConfigLoaderInterface
188
     */
189
    public function getLoader(): DatabaseConfigLoaderInterface
190
    {
191
        return $this->loader;
192
    }
193
194
    /**
195
     * Set the configuration loader
196
     *
197
     * @param DatabaseConfigLoaderInterface $loader
198
     * @return $this
199
     */
200
    public function setLoader(DatabaseConfigLoaderInterface $loader): self
201
    {
202
        $this->loader = $loader;
203
204
        return $this;
205
    }
206
207
    /**
208
     * Return all the configuration
209
     * @return Entity[]
210
     */
211
    public function all(): array
212
    {
213
        return $this->loader->all();
214
    }
215
216
    /**
217
     * {@inheritdoc}
218
     */
219
    public function offsetExists($key)
220
    {
221
        return $this->has($key);
222
    }
223
224
    /**
225
     * {@inheritdoc}
226
     */
227
    public function offsetGet($key)
228
    {
229
        return $this->get($key);
230
    }
231
232
    /**
233
     *
234
     * @param string $key
235
     * @param mixed $value
236
     * @return void
237
     */
238
    public function offsetSet($key, $value)
239
    {
240
        $this->set($key, $value);
241
    }
242
243
    /**
244
     * {@inheritdoc}
245
     */
246
    public function offsetUnset($key)
247
    {
248
        $this->set($key, null);
249
    }
250
251
    /**
252
     * Load the configuration
253
     * @param string $group
254
     * @return void
255
     */
256
    protected function load(string $group): void
257
    {
258
        // If we've already loaded this collection, we will just bail out since we do
259
        // not want to load it again. Once items are loaded a first time they will
260
        // stay kept in memory within this class and not loaded from disk again.
261
        if (isset($this->items[$group])) {
262
            return;
263
        }
264
265
        $this->items[$group] = $this->loader->load($this->env, $group);
266
    }
267
268
    /**
269
     *
270
     * @param string $key
271
     * @return array<string, string>
272
     * @throws InvalidArgumentException
273
     */
274
    protected function parseKey(string $key): array
275
    {
276
        if (strpos($key, '.') === false) {
277
            throw new InvalidArgumentException(sprintf(
278
                'Invalid configuration key [%s] must have format module.name',
279
                $key
280
            ));
281
        }
282
283
        $groups = explode('.', $key);
284
285
        return [
286
            'key' => $groups[1],
287
            'group' => $groups[0]
288
        ];
289
    }
290
291
    /**
292
     * Return the formatted configuration value
293
     * @param mixed $value
294
     * @return mixed
295
     */
296
    protected function getFormattedConfigValue($value)
297
    {
298
        if (is_array($value) || is_object($value)) {
299
            return serialize($value);
300
        }
301
302
        return $value;
303
    }
304
}
305