Test Failed
Push — develop ( 8a31ce...8fcf9d )
by nguereza
02:43
created

DbConfig::load()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 46
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 10
nc 3
nop 1
dl 0
loc 46
rs 9.9332
c 0
b 0
f 0
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 DbConfig.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 DbConfig
57
 * @package Platine\Framework\Config
58
 * @template T
59
 * @implements ArrayAccess<string, mixed>
60
 */
61
class DbConfig 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
        echo '<pre>';
117
        print_r($this->items);
118
        echo '</pre>';
119
120
        return Arr::get($this->items, $key, $default);
121
    }
122
123
    /**
124
     * Set the configuration value for the given key
125
     * @param  string $key     the name of the configuration item
126
     * @param  mixed $value the configuration value
127
     * @return void
128
     */
129
    public function set(string $key, $value): void
130
    {
131
        $results = $this->parseKey($key);
132
        $groups = $results['groups'];
133
        $name = array_pop($groups);
134
        $lastModule = array_pop($groups);
135
136
        $parentId = null;
137
        foreach ($groups as $module) {
138
            $config = $this->loader->loadConfig([
139
                'module' => $module,
140
                'env' => $this->env
141
            ]);
142
143
            if ($config) {
144
                $parentId = $config->id;
145
            } else {
146
                $parentId = $this->loader->insertConfig([
147
                    'parent_id' => $parentId,
148
                    'env' => $this->env,
149
                    'module' => $module,
150
                    'status' => 1,
151
                    'created_at' => date('Y-m-d H:i:s'),
152
                ]);
153
            }
154
        }
155
156
        $config = $this->loader->loadConfig([
157
            'parent_id' => $parentId,
158
            'module' => $lastModule,
159
            'env' => $this->env,
160
            'name' => $name,
161
        ]);
162
163
        if ($config) {
164
            $config->value = $this->getFormattedConfigValue($value);
165
            $config->type = gettype($value);
166
            $config->updated_at = date('Y-m-d H:i:s');
167
168
            $this->loader->updateConfig($config);
169
        } else {
170
            $this->loader->insertConfig([
171
                'parent_id' => $parentId,
172
                'env' => $this->env,
173
                'module' => $lastModule,
174
                'status' => 1,
175
                'name' => $name,
176
                'value' => $this->getFormattedConfigValue($value),
177
                'type' => gettype($value),
178
                'created_at' => date('Y-m-d H:i:s'),
179
            ]);
180
        }
181
    }
182
183
    /**
184
     * Return all the current loaded configuration items
185
     * @return array<string, mixed>
186
     */
187
    public function getItems(): array
188
    {
189
        return $this->items;
190
    }
191
192
    /**
193
     * Return the configuration current environment
194
     * @return string
195
     */
196
    public function getEnvironment(): string
197
    {
198
        return $this->env;
199
    }
200
201
    /**
202
     * Set the configuration environment
203
     *
204
     * @param string $env
205
     * @return $this
206
     */
207
    public function setEnvironment(string $env): self
208
    {
209
        $this->env = $env;
210
211
        return $this;
212
    }
213
214
    /**
215
     * Return the configuration current loader
216
     * @return DatabaseConfigLoaderInterface
217
     */
218
    public function getLoader(): DatabaseConfigLoaderInterface
219
    {
220
        return $this->loader;
221
    }
222
223
    /**
224
     * Set the configuration loader
225
     *
226
     * @param DatabaseConfigLoaderInterface $loader
227
     * @return $this
228
     */
229
    public function setLoader(DatabaseConfigLoaderInterface $loader): self
230
    {
231
        $this->loader = $loader;
232
233
        return $this;
234
    }
235
236
    /**
237
     * Return all the configuration
238
     * @return Entity[]
239
     */
240
    public function all(): array
241
    {
242
        return $this->loader->all();
243
    }
244
245
    /**
246
     * {@inheritdoc}
247
     */
248
    public function offsetExists($key)
249
    {
250
        return $this->has($key);
251
    }
252
253
    /**
254
     * {@inheritdoc}
255
     */
256
    public function offsetGet($key)
257
    {
258
        return $this->get($key);
259
    }
260
261
    /**
262
     *
263
     * @param string $key
264
     * @param mixed $value
265
     * @return void
266
     */
267
    public function offsetSet($key, $value)
268
    {
269
        $this->set($key, $value);
270
    }
271
272
    /**
273
     * {@inheritdoc}
274
     */
275
    public function offsetUnset($key)
276
    {
277
        $this->set($key, null);
278
    }
279
280
    /**
281
     * Load the configuration
282
     * @param string $group
283
     * @return void
284
     */
285
    protected function load(string $group): void
286
    {
287
        $groups = explode('.', $group);
288
        $root = array_shift($groups);
289
290
        // If we've already loaded this collection, we will just bail out since we do
291
        // not want to load it again. Once items are loaded a first time they will
292
        // stay kept in memory within this class and not loaded from disk again.
293
        if (isset($this->items[$root])) {
294
            return;
295
        }
296
297
        //$this->items[$root] = $this->loader->load($this->env, $root);
298
        $lastModule = $root;
299
        //tnh
300
        //
301
        //foo. last = 'root'
302
        //bar. last = 'foo'
303
        //one. last = 'bar'
304
        //two. last = 'one'
305
        //three. last = 'two'
306
        //four  last = 'three'
307
        //last['tnh'] = []
308
        //
309
        //last['tnh']['foo'] = []
310
        //last['tnh']['foo']['bar'] = []
311
        //last['tnh']['foo']['bar']['one'] = []
312
        //last['tnh']['foo']['bar']['one']['two'] = []
313
        //last['tnh']['foo']['bar']['one']['two']['three'] = []
314
        //last['tnh']['foo']['bar']['one']['two']['three']['four'] = []
315
        //name
316
        $last[$root] = $this->loader->load($this->env, $root);
0 ignored issues
show
Comprehensibility Best Practice introduced by
$last was never initialized. Although not strictly required by PHP, it is generally a good practice to add $last = array(); before regardless.
Loading history...
317
        foreach ($groups as $module) {
318
            // if ($lastModule) {
319
                $last[$lastModule][$module] = $this->loader->load($this->env, $module);
320
            //} else {
321
              //  $last[$root][$module] = $this->loader->load($this->env, $module);
322
            //}
323
            //$last = array_merge_recursive($last, $last[$lastModule][$module]);
324
325
            $lastModule = $module;
326
        }
327
328
        //var_dump($last);
329
330
        $this->items[$root] = $last[$root];
331
    }
332
333
    /**
334
     *
335
     * @param string $key
336
     * @return array<string, string>
337
     * @throws InvalidArgumentException
338
     */
339
    protected function parseKey(string $key): array
340
    {
341
        if (strpos($key, '.') === false) {
342
            throw new InvalidArgumentException(sprintf(
343
                'Invalid configuration key [%s] must have format module.name',
344
                $key
345
            ));
346
        }
347
348
        $groups = explode('.', $key);
349
        //remove the key from list
350
        //$name = array_pop($groups);
351
        //get the module root
352
353
        return [
0 ignored issues
show
Bug Best Practice introduced by
The expression return array('groups' =>... implode('.', $groups)) returns an array which contains values of type string[] which are incompatible with the documented value type string.
Loading history...
354
            'groups' => $groups,
355
            'key' => array_pop($groups),
356
            'group' => implode('.', $groups)
357
        ];
358
    }
359
360
    /**
361
     * Return the formatted configuration value
362
     * @param mixed $value
363
     * @return mixed
364
     */
365
    protected function getFormattedConfigValue($value)
366
    {
367
        if (is_array($value) || is_object($value)) {
368
            return serialize($value);
369
        }
370
371
        return $value;
372
    }
373
}
374