Completed
Push — master ( 965662...ac7f34 )
by Xeriab
07:12
created

AbstractKonfig   B

Complexity

Total Complexity 36

Size/Duplication

Total Lines 325
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 91.78%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
wmc 36
c 2
b 1
f 0
lcom 1
cbo 1
dl 0
loc 325
ccs 67
cts 73
cp 0.9178
rs 8.8

17 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getDefaults() 0 4 1
A all() 0 4 1
B has() 0 25 5
A get() 0 9 2
D set() 0 38 9
A delete() 0 9 2
A offsetGet() 0 4 1
A offsetExists() 0 4 1
A offsetSet() 0 4 1
A offsetUnset() 0 4 1
A valid() 0 4 2
A key() 0 4 2
A current() 0 4 2
A next() 0 4 2
A rewind() 0 4 2
A __toString() 0 4 1
1
<?php
2
3
/**
4
 * Konfig.
5
 *
6
 * Yet another simple configuration loader library.
7
 *
8
 * PHP version 5
9
 *
10
 * @category Library
11
 * @package  Konfig
12
 * @author   Xeriab Nabil (aka KodeBurner) <[email protected]>
13
 * @license  https://raw.github.com/xeriab/konfig/master/LICENSE MIT
14
 * @link     https://xeriab.github.io/projects/konfig
15
 */
16
17
namespace Exen\Konfig;
18
19
use ArrayAccess;
20
use Iterator;
21
22
/**
23
 * AbstractKonfig.
24
 *
25
 * Main Konfig abstract class.
26
 *
27
 * @category Main
28
 * @package  Konfig
29
 * @author   Xeriab Nabil (aka KodeBurner) <[email protected]>
30
 * @license  https://raw.github.com/xeriab/konfig/master/LICENSE MIT
31
 * @link     https://xeriab.github.io/projects/konfig
32
 *
33
 * @implements ArrayAccess
34
 * @implements Iterator
35
 * @implements KonfigInterface
36
 */
37
abstract class AbstractKonfig implements ArrayAccess, Iterator, KonfigInterface
38
{
39
    /**
40
     * Stores the configuration items.
41
     *
42
     * @var array Data
43
     *
44
     * @since 0.1.0
45
     */
46
    protected $data = [];
47
48
    /**
49
     * Caches the configuration data.
50
     *
51
     * @var array Cache
52
     *
53
     * @since 0.1.0
54
     */
55
    protected $cache = [];
56
57
    /**
58
     * Random value used as a not-found check in get().
59
     *
60
     * @var string
61
     *
62
     * @since 0.1.0
63
     */
64
    protected static $defaultCheckValue;
65
66
    /**
67
     * Constructor method and sets default options, if any.
68
     *
69
     * @param array $input Input
70
     */
71 3
    public function __construct($input)
72
    {
73 3
        $this->data = Arr::mergeAssoc($this->getDefaults(), $input);
74
        //$this->data = array_merge($this->getDefaults(), $input);
75 3
    }
76
77
    /**
78
     * Override this method in your own subclass to provide an array of default
79
     * options and values.
80
     *
81
     * @return array
82
     *
83
     * @since              0.1.0
84
     * @codeCoverageIgnore
85
     */
86
    protected function getDefaults()
87
    {
88
        return [];
89
    }
90
91
    // KONFIGINTERFACE METHODS
92
93
    /**
94
     * {@inheritdoc}
95
     *
96
     * @return array Gets configuration items array
97
     */
98 3
    public function all()
99
    {
100 3
        return $this->data;
101
    }
102
103
    /**
104
     * {@inheritdoc}
105
     *
106
     * @param string $key Configuration item key name item
107
     *
108
     * @return bool Returns true if the configuration item key exists
109
     *
110
     * @since 0.1.0
111
     */
112 6
    public function has($key)
113
    {
114
        // Check if already cached
115 6
        if (Arr::get($this->cache, $key) || isset($this->cache[$key])) {
116
            return true;
117
        }
118
119 6
        $chunks = explode('.', $key);
120 6
        $root = $this->data;
121
122
        // Nested case
123 6
        foreach ($chunks as $chunk) {
124 6
            if (array_key_exists($chunk, $root)) {
125 6
                $root = $root[$chunk];
126 6
                continue;
127
            } else {
128 6
                return false;
129
            }
130 4
        }
131
132
        // Set cache for the given key
133 6
        $this->cache[$key] = $root;
134
135 6
        return true;
136
    }
137
138
    /**
139
     * {@inheritdoc}
140
     *
141
     * @param string            $key     Configuration item key name item
142
     * @param string|array|null $default Default configuration
143
     *
144
     * @return string|array|null Default configuration
145
     */
146 24
    public function get($key, $default = null)
147
    {
148 24
        if ($this->has($key)) {
149
            // return $this->cache[$key];
150 12
            return Arr::get($this->data, $key);
151
        }
152
153 12
        return $default;
154
    }
155
156
    /**
157
     * {@inheritdoc}
158
     *
159
     * @param string $key   Configuration item key name
160
     * @param mixed  $value Configuration item value
161
     *
162
     * @return void Void
163
     */
164 18
    public function set($key, $value)
165
    {
166 18
        $chunks = explode('.', $key);
167 18
        $root = &$this->data;
168 18
        $cacheKey = '';
169
170
        // Look for the key, creating nested keys if needed
171 18
        while ($part = array_shift($chunks)) {
172 18
            if ($cacheKey != '') {
173 12
                $cacheKey .= '.';
174 8
            }
175
176 18
            $cacheKey .= $part;
177
178 18
            if (!isset($root[$part]) && count($chunks)) {
179 3
                $root[$part] = [];
180 2
            }
181
182 18
            $root = &$root[$part];
183
184
            // Unset all old nested cache
185 18
            if (isset($this->cache[$cacheKey])) {
186 9
                unset($this->cache[$cacheKey]);
187 6
            }
188
189
            // Unset all old nested cache in case of array
190 18
            if (count($chunks) == 0) {
191 18
                foreach ($this->cache as $cacheLocalKey => $cacheValue) {
192 6
                    if (substr($cacheLocalKey, 0, strlen($cacheKey)) === $cacheKey) {
193 4
                        unset($this->cache[$cacheLocalKey]);
194 2
                    }
195 12
                }
196 12
            }
197 12
        }
198
199
        // Assign value at target node
200 18
        $this->cache[$key] = $root = $value;
201 18
    }
202
203
    /**
204
     * {@inheritdoc}
205
     *
206
     * @param string $key Configuration item key name
207
     *
208
     * @return bool
209
     */
210
    public function delete($key)
211
    {
212
        if (isset($this->cache[$key])) {
213
            // unset($this->cache[$key]);
214
            Arr::delete($this->cache, $key);
215
        }
216
217
        return Arr::delete($this->data, $key);
218
    }
219
220
    // ARRAYACCESS METHODS
221
222
    /**
223
     * Gets a value using the offset as a key.
224
     *
225
     * @param string $offset Configuration item key name
226
     *
227
     * @return mixed Configuration item
228
     *
229
     * @since 0.1.0
230
     */
231 6
    public function offsetGet($offset)
232
    {
233 6
        return $this->get($offset);
234
    }
235
236
    /**
237
     * Checks if a key exists.
238
     *
239
     * @param string $offset Configuration item key name
240
     *
241
     * @return bool
242
     *
243
     * @since 0.1.0
244
     */
245 6
    public function offsetExists($offset)
246
    {
247 6
        return $this->has($offset);
248
    }
249
250
    /**
251
     * Sets a value using the offset as a key.
252
     *
253
     * @param string $offset Configuration item key name
254
     * @param mixed  $value  Configuration item value
255
     *
256
     * @return void Void
257
     * @since  0.1.0
258
     */
259 3
    public function offsetSet($offset, $value)
260
    {
261 3
        $this->set($offset, $value);
262 3
    }
263
264
    /**
265
     * Deletes a key and its value.
266
     *
267
     * @param string $offset Configuration item key name
268
     *
269
     * @return void Void
270
     * @since  0.1.0
271
     */
272 3
    public function offsetUnset($offset)
273
    {
274 3
        $this->set($offset, null);
275 3
    }
276
277
    // ITERATOR METHODS
278
279
    /**
280
     * Tests whether the iterator's current index is valid.
281
     *
282
     * @return bool True if the current index is valid; false otherwise
283
     *
284
     * @since 0.1.0
285
     */
286 3
    public function valid()
287
    {
288 3
        return is_array($this->data) ? key($this->data) !== null : false;
289
    }
290
291
    /**
292
     * Returns the data array index referenced by its internal cursor.
293
     *
294
     * @return mixed The index referenced by the data array's internal cursor.
295
     * If the array is empty or undefined or there is no element at the cursor,
296
     * the function returns null.
297
     *
298
     * @since 0.1.0
299
     */
300 3
    public function key()
301
    {
302 3
        return is_array($this->data) ? key($this->data) : null;
303
    }
304
305
    /**
306
     * Returns the data array element referenced by its internal cursor.
307
     *
308
     * @return mixed The element referenced by the data array's internal cursor.
309
     * If the array is empty or there is no element at the cursor,
310
     * the function returns false. If the array is undefined, the function
311
     * returns null
312
     *
313
     * @since 0.1.0
314
     */
315 3
    public function current()
316
    {
317 3
        return is_array($this->data) ? current($this->data) : null;
318
    }
319
320
    /**
321
     * Moves the data array's internal cursor forward one element.
322
     *
323
     * @return mixed The element referenced by the data array's internal cursor
324
     * after the move is completed. If there are no more elements in the
325
     * array after the move, the function returns false. If the data array
326
     * is undefined, the function returns null.
327
     *
328
     * @since 0.1.0
329
     */
330 3
    public function next()
331
    {
332 3
        return is_array($this->data) ? next($this->data) : null;
333
    }
334
335
    /**
336
     * Moves the data array's internal cursor to the first element.
337
     *
338
     * @return mixed The element referenced by the data array's internal cursor
339
     * after the move is completed. If the data array is empty, the function
340
     * returns false. If the data array is undefined, the function returns null.
341
     *
342
     * @since 0.1.0
343
     */
344 3
    public function rewind()
345
    {
346 3
        return is_array($this->data) ? reset($this->data) : null;
347
    }
348
349
    /**
350
     * __toString.
351
     *
352
     * @return string
353
     *
354
     * @since              0.1.2
355
     * @codeCoverageIgnore
356
     */
357
    public function __toString()
358
    {
359
        return 'Exen\Konfig\AbstractKonfig'.PHP_EOL;
360
    }
361
}
362
363
// END OF ./src/AbstractKonfig.php FILE
364