Completed
Push — master ( 125bc9...b4601a )
by Xeriab
03:31
created

AbstractKonfig   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 304
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
wmc 35
c 2
b 1
f 0
lcom 1
cbo 1
dl 0
loc 304
ccs 53
cts 53
cp 1
rs 9

16 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
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
     * Constructor method and sets default options, if any.
59
     *
60
     * @param array $input Input
61
     */
62
    public function __construct($input)
63
    {
64
        $this->data = Arr::mergeAssoc($this->getDefaults(), $input);
65
        //$this->data = array_merge($this->getDefaults(), $input);
66
    }
67
68
    /**
69
     * Override this method in your own subclass to provide an array of default
70
     * options and values.
71 3
     *
72
     * @return array
73 3
     *
74
     * @since 0.1.0
75 3
     */
76
    protected function getDefaults()
77
    {
78
        return [];
79
    }
80
81
    // KONFIGINTERFACE METHODS
82
83
    /**
84
     * {@inheritdoc}
85
     *
86
     * @return array Gets configuration items array
87
     */
88
    public function all()
89
    {
90
        return $this->data;
91
    }
92
93
    /**
94
     * {@inheritdoc}
95
     *
96
     * @param string $key Configuration item key name item
97
     *
98 3
     * @return bool Returns true if the configuration item key exists
99
     *
100 3
     * @since              0.1.0
101
     * @codeCoverageIgnore
102
     */
103
    public function has($key)
104
    {
105
        // Check if already cached
106
        if (Arr::get($this->cache, $key) || isset($this->cache[$key])) {
107
            return true;
108
        }
109
110
        $chunks = explode('.', $key);
111
        $root = $this->data;
112
113
        // Nested case
114
        foreach ($chunks as $chunk) {
115
            if (array_key_exists($chunk, $root)) {
116
                $root = $root[$chunk];
117
                continue;
118
            } else {
119
                return false;
120
            }
121
        }
122
123
        // Set cache for the given key
124
        $this->cache[$key] = $root;
125
126
        return true;
127
    }
128
129
    /**
130
     * {@inheritdoc}
131
     *
132
     * @param string            $key     Configuration item key name item
133
     * @param string|array|null $default Default configuration
134
     *
135
     * @return string|array|null Default configuration
136
     */
137
    public function get($key, $default = null)
138
    {
139
        if ($this->has($key)) {
140
            // return $this->cache[$key];
141
            return Arr::get($this->data, $key);
142
        }
143
144
        return $default;
145
    }
146
147 24
    /**
148
     * {@inheritdoc}
149 24
     *
150
     * @param string $key   Configuration item key name
151 12
     * @param mixed  $value Configuration item value
152
     *
153
     * @return void Void
154 12
     */
155
    public function set($key, $value)
156
    {
157
        $chunks = explode('.', $key);
158
        $root = &$this->data;
159
        $cacheKey = '';
160
161
        // Look for the key, creating nested keys if needed
162
        while ($part = array_shift($chunks)) {
163
            if ($cacheKey != '') {
164
                $cacheKey .= '.';
165 18
            }
166
167 18
            $cacheKey .= $part;
168 18
169 18
            if (!isset($root[$part]) && count($chunks)) {
170
                $root[$part] = [];
171
            }
172 18
173 18
            $root = &$root[$part];
174 12
175 4
            // Unset all old nested cache
176
            if (isset($this->cache[$cacheKey])) {
177 18
                unset($this->cache[$cacheKey]);
178
            }
179 18
180 3
            // Unset all old nested cache in case of array
181 1
            if (count($chunks) == 0) {
182
                foreach ($this->cache as $cacheLocalKey => $cacheValue) {
183 18
                    if (substr($cacheLocalKey, 0, strlen($cacheKey)) === $cacheKey) {
184
                        unset($this->cache[$cacheLocalKey]);
185
                    }
186 18
                }
187 9
            }
188 3
        }
189
190
        // Assign value at target node
191 18
        $this->cache[$key] = $root = $value;
192 18
    }
193 6
194 5
    /**
195 1
     * {@inheritdoc}
196 6
     *
197 6
     * @param string $key Configuration item key name
198 6
     *
199
     * @return             bool
200
     * @codeCoverageIgnore
201 18
     */
202 18
    public function delete($key)
203
    {
204
        if (isset($this->cache[$key])) {
205
            // unset($this->cache[$key]);
206
            Arr::delete($this->cache, $key);
207
        }
208
209
        return Arr::delete($this->data, $key);
210
    }
211
212
    // ARRAYACCESS METHODS
213
214
    /**
215
     * Gets a value using the offset as a key.
216
     *
217
     * @param string $offset Configuration item key name
218
     *
219
     * @return mixed Configuration item
220
     *
221
     * @since 0.1.0
222
     */
223
    public function offsetGet($offset)
224
    {
225
        return $this->get($offset);
226
    }
227
228
    /**
229
     * Checks if a key exists.
230
     *
231
     * @param string $offset Configuration item key name
232
     *
233 6
     * @return bool
234
     *
235 6
     * @since 0.1.0
236
     */
237
    public function offsetExists($offset)
238
    {
239
        return $this->has($offset);
240
    }
241
242
    /**
243
     * Sets a value using the offset as a key.
244
     *
245
     * @param string $offset Configuration item key name
246
     * @param mixed  $value  Configuration item value
247 6
     *
248
     * @return void Void
249 6
     * @since  0.1.0
250
     */
251
    public function offsetSet($offset, $value)
252
    {
253
        $this->set($offset, $value);
254
    }
255
256
    /**
257
     * Deletes a key and its value.
258
     *
259
     * @param string $offset Configuration item key name
260
     *
261 3
     * @return void Void
262
     * @since  0.1.0
263 3
     */
264 3
    public function offsetUnset($offset)
265
    {
266
        $this->set($offset, null);
267
    }
268
269
    // ITERATOR METHODS
270
271
    /**
272
     * Tests whether the iterator's current index is valid.
273
     *
274 3
     * @return bool True if the current index is valid; false otherwise
275
     *
276 3
     * @since 0.1.0
277 3
     */
278
    public function valid()
279
    {
280
        return is_array($this->data) ? key($this->data) !== null : false;
281
    }
282
283
    /**
284
     * Returns the data array index referenced by its internal cursor.
285
     *
286
     * @return mixed The index referenced by the data array's internal cursor.
287
     * If the array is empty or undefined or there is no element at the cursor,
288 3
     * the function returns null.
289
     *
290 3
     * @since 0.1.0
291
     */
292
    public function key()
293
    {
294
        return is_array($this->data) ? key($this->data) : null;
295
    }
296
297
    /**
298
     * Returns the data array element referenced by its internal cursor.
299
     *
300
     * @return mixed The element referenced by the data array's internal cursor.
301
     * If the array is empty or there is no element at the cursor,
302 3
     * the function returns false. If the array is undefined, the function
303
     * returns null
304 3
     *
305
     * @since 0.1.0
306
     */
307
    public function current()
308
    {
309
        return is_array($this->data) ? current($this->data) : null;
310
    }
311
312
    /**
313
     * Moves the data array's internal cursor forward one element.
314
     *
315
     * @return mixed The element referenced by the data array's internal cursor
316
     * after the move is completed. If there are no more elements in the
317 3
     * array after the move, the function returns false. If the data array
318
     * is undefined, the function returns null.
319 3
     *
320
     * @since 0.1.0
321
     */
322
    public function next()
323
    {
324
        return is_array($this->data) ? next($this->data) : null;
325
    }
326
327
    /**
328
     * Moves the data array's internal cursor to the first element.
329
     *
330
     * @return mixed The element referenced by the data array's internal cursor
331
     * after the move is completed. If the data array is empty, the function
332 3
     * returns false. If the data array is undefined, the function returns null.
333
     *
334 3
     * @since 0.1.0
335
     */
336
    public function rewind()
337
    {
338
        return is_array($this->data) ? reset($this->data) : null;
339
    }
340
}
341
342
// END OF ./src/AbstractKonfig.php FILE
343