AbstractKonfig::next()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

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