Completed
Push — master ( d0ff07...576091 )
by Xeriab
04:55
created

AbstractKonfig::__toString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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