Completed
Push — develop ( fc22ae...ff002b )
by Davide
03:04
created

AbstractConfig::offsetSet()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 2
crap 1
1
<?php
2
3
namespace Noodlehaus;
4
5
use ArrayAccess;
6
use Iterator;
7
8
/**
9
 * Abstract Config class
10
 *
11
 * @package    Config
12
 * @author     Jesus A. Domingo <[email protected]>
13
 * @author     Hassan Khan <[email protected]>
14
 * @link       https://github.com/noodlehaus/config
15
 * @license    MIT
16
 */
17
abstract class AbstractConfig implements ArrayAccess, ConfigInterface, Iterator
18
{
19
    /**
20
     * Stores the configuration data
21
     *
22
     * @var array|null
23
     */
24
    protected $data = null;
25
26
    /**
27
     * Caches the configuration data
28
     *
29
     * @var array
30
     */
31
    protected $cache = array();
32
33
    /**
34
     * Constructor method and sets default options, if any
35
     *
36
     * @param array $data
37 3
     */
38
    public function __construct(Array $data)
39 3
    {
40 3
        $this->data = array_merge($this->getDefaults(), $data);
41
    }
42
43
    /**
44
     * Override this method in your own subclass to provide an array of default
45
     * options and values
46
     *
47
     * @return array
48
     *
49
     * @codeCoverageIgnore
50
     */
51
    protected function getDefaults()
52
    {
53
        return array();
54
    }
55
56
    /**
57
     * ConfigInterface Methods
58
     */
59
60
    /**
61
     * {@inheritDoc}
62 24
     */
63
    public function get($key, $default = null)
64
    {
65 24
        // Check if already cached
66 3
        if (isset($this->cache[$key])) {
67
            return $this->cache[$key];
68
        }
69 24
70 24
        $segs = explode('.', $key);
71
        $root = $this->data;
72
73 24
        // nested case
74 24
        foreach ($segs as $part) {
75 15
            if (isset($root[$part])) {
76 15
                $root = $root[$part];
77
                continue;
78 12
            } else {
79 12
                $root = $default;
80
                break;
81 24
            }
82
        }
83
84 24
        // whatever we have is what we needed
85
        return ($this->cache[$key] = $root);
86
    }
87
88
    /**
89
     * {@inheritDoc}
90 15
     */
91
    public function set($key, $value)
92 15
    {
93 15
        $segs = explode('.', $key);
94 15
        $root = &$this->data;
95
        $cacheKey = '';
96
97 15
        // Look for the key, creating nested keys if needed
98 15
        while ($part = array_shift($segs)) {
99 9
            if($cacheKey != ''){
100 9
                $cacheKey .= '.';
101 15
            }
102 15
            $cacheKey .= $part;
103 3
            if (!isset($root[$part]) && count($segs)) {
104 3
                $root[$part] = array();
105 15
            }
106
            $root = &$root[$part];
107
108 15
            //Unset all old nested cache
109 6
            if(isset($this->cache[$cacheKey])){
110 6
                unset($this->cache[$cacheKey]);
111 15
            }
112
        }
113
114 15
        // Assign value at target node
115 15
        $this->cache[$key] = $root = $value;
116
    }
117
118
    /**
119
     * {@inheritDoc}
120 6
     */
121
    public function has($key)
122 6
    {
123
        return !is_null($this->get($key));
124
    }
125
126
    /**
127
     * {@inheritDoc}
128 3
     */
129
    public function all()
130 3
    {
131
        return $this->data;
132
    }
133
134
135
136
    /**
137
     * ArrayAccess Methods
138
     */
139
140
    /**
141
     * Gets a value using the offset as a key
142
     *
143
     * @param  string $offset
144
     *
145
     * @return mixed
146 6
     */
147
    public function offsetGet($offset)
148 6
    {
149
        return $this->get($offset);
150
    }
151
152
    /**
153
     * Checks if a key exists
154
     *
155
     * @param  string $offset
156
     *
157
     * @return bool
158 6
     */
159
    public function offsetExists($offset)
160 6
    {
161
        return $this->has($offset);
162
    }
163
164
    /**
165
     * Sets a value using the offset as a key
166
     *
167
     * @param  string $offset
168
     * @param  mixed  $value
169
     *
170
     * @return void
171 3
     */
172
    public function offsetSet($offset, $value)
173 3
    {
174 3
        $this->set($offset, $value);
175
    }
176
177
    /**
178
     * Deletes a key and its value
179
     *
180
     * @param  string $offset
181
     *
182
     * @return void
183 3
     */
184
    public function offsetUnset($offset)
185 3
    {
186 3
        $this->set($offset, null);
187
    }
188
189
    /**
190
     * Iterator Methods
191
     */
192
193
    /**
194
     * Returns the data array element referenced by its internal cursor
195
     *
196
     * @return mixed The element referenced by the data array's internal cursor.
197
     *     If the array is empty or there is no element at the cursor, the
198
     *     function returns false. If the array is undefined, the function
199
     *     returns null
200
     */
201
    public function current()
202
    {
203
        return (is_array($this->data) ? current($this->data) : null);
204
    }
205
206
    /**
207
     * Returns the data array index referenced by its internal cursor
208
     *
209
     * @return mixed The index referenced by the data array's internal cursor.
210
     *     If the array is empty or undefined or there is no element at the
211
     *     cursor, the function returns null
212
     */
213
    public function key()
214
    {
215
        return (is_array($this->data) ? key($this->data) : null);
216
    }
217
218
    /**
219
     * Moves the data array's internal cursor forward one element
220
     *
221
     * @return mixed The element referenced by the data array's internal cursor
222
     *     after the move is completed. If there are no more elements in the
223
     *     array after the move, the function returns false. If the data array
224
     *     is undefined, the function returns null
225
     */
226
    public function next()
227
    {
228
        return (is_array($this->data) ? next($this->data) : null);
229
    }
230
231
    /**
232
     * Moves the data array's internal cursor to the first element
233
     *
234
     * @return mixed The element referenced by the data array's internal cursor
235
     *     after the move is completed. If the data array is empty, the function
236
     *     returns false. If the data array is undefined, the function returns
237
     *     null
238
     */
239
    public function rewind()
240
    {
241
        return (is_array($this->data) ? reset($this->data) : null);
242
    }
243
244
    /**
245
     * Tests whether the iterator's current index is valid
246
     *
247
     * @return bool True if the current index is valid; false otherwise
248
     */
249
    public function valid()
250
    {
251
        return (is_array($this->data) ? key($this->data) !== null : false);
252
    }
253
}
254