|
1
|
|
|
<?php |
|
2
|
|
|
namespace Darya\Foundation; |
|
3
|
|
|
|
|
4
|
|
|
use ArrayAccess; |
|
5
|
|
|
|
|
6
|
|
|
/** |
|
7
|
|
|
* Darya's abstract application configuration implementation (what a mouthful). |
|
8
|
|
|
* |
|
9
|
|
|
* TODO: The static methods belong somewhere else. |
|
10
|
|
|
* |
|
11
|
|
|
* @author Chris Andrew <[email protected]> |
|
12
|
|
|
*/ |
|
13
|
|
|
abstract class AbstractConfiguration implements ArrayAccess, Configuration |
|
14
|
|
|
{ |
|
15
|
|
|
/** |
|
16
|
|
|
* The configuration data. |
|
17
|
|
|
* |
|
18
|
|
|
* @var array |
|
19
|
|
|
*/ |
|
20
|
|
|
protected $data = array(); |
|
21
|
|
|
|
|
22
|
|
|
/** |
|
23
|
|
|
* Determine whether an array has a value at the given dot-notated key. |
|
24
|
|
|
* |
|
25
|
|
|
* @param array $array |
|
26
|
|
|
* @param string $key |
|
27
|
|
|
* @return bool |
|
28
|
|
|
*/ |
|
29
|
|
|
protected static function arrayHas(array $array, $key) |
|
30
|
|
|
{ |
|
31
|
|
|
if (empty($array) || $key === null) { |
|
32
|
|
|
return false; |
|
33
|
|
|
} |
|
34
|
|
|
|
|
35
|
|
|
if (array_key_exists($key, $array)) { |
|
36
|
|
|
return true; |
|
37
|
|
|
} |
|
38
|
|
|
|
|
39
|
|
|
$parts = explode('.', $key); |
|
40
|
|
|
|
|
41
|
|
View Code Duplication |
foreach ($parts as $part) { |
|
|
|
|
|
|
42
|
|
|
if (is_array($array) && array_key_exists($part, $array)) { |
|
43
|
|
|
$array = $array[$part]; |
|
44
|
|
|
} else { |
|
45
|
|
|
return false; |
|
46
|
|
|
} |
|
47
|
|
|
} |
|
48
|
|
|
|
|
49
|
|
|
return true; |
|
50
|
|
|
} |
|
51
|
|
|
|
|
52
|
|
|
/** |
|
53
|
|
|
* Retrieve a value from the given array using dot notation. |
|
54
|
|
|
* |
|
55
|
|
|
* @param array $array |
|
56
|
|
|
* @param string $key |
|
57
|
|
|
* @param mixed $default [optional] |
|
58
|
|
|
* @return mixed |
|
59
|
|
|
*/ |
|
60
|
|
|
protected static function arrayGet(array $array, $key, $default = null) |
|
61
|
|
|
{ |
|
62
|
|
|
if (empty($array) || $key === null) { |
|
63
|
|
|
return $default; |
|
64
|
|
|
} |
|
65
|
|
|
|
|
66
|
|
|
if (array_key_exists($key, $array)) { |
|
67
|
|
|
return $array[$key]; |
|
68
|
|
|
} |
|
69
|
|
|
|
|
70
|
|
|
$parts = explode('.', $key); |
|
71
|
|
|
|
|
72
|
|
View Code Duplication |
foreach ($parts as $part) { |
|
|
|
|
|
|
73
|
|
|
if (is_array($array) && array_key_exists($part, $array)) { |
|
74
|
|
|
$array = $array[$part]; |
|
75
|
|
|
} else { |
|
76
|
|
|
return $default; |
|
77
|
|
|
} |
|
78
|
|
|
} |
|
79
|
|
|
|
|
80
|
|
|
return $array; |
|
81
|
|
|
} |
|
82
|
|
|
|
|
83
|
|
|
/** |
|
84
|
|
|
* Set a value on the given array using dot notation. |
|
85
|
|
|
* |
|
86
|
|
|
* @param array $array |
|
87
|
|
|
* @param string $key |
|
88
|
|
|
* @param mixed $value |
|
89
|
|
|
*/ |
|
90
|
|
|
protected static function arraySet(array &$array, $key, $value) |
|
91
|
|
|
{ |
|
92
|
|
|
if ($key === null) { |
|
93
|
|
|
return; |
|
94
|
|
|
} |
|
95
|
|
|
|
|
96
|
|
|
$parts = explode('.', $key); |
|
97
|
|
|
|
|
98
|
|
|
while (count($parts) > 1) { |
|
99
|
|
|
$part = array_shift($parts); |
|
100
|
|
|
|
|
101
|
|
|
if (!isset($array[$part]) || !is_array($array[$part])) { |
|
102
|
|
|
$array[$part] = array(); |
|
103
|
|
|
} |
|
104
|
|
|
|
|
105
|
|
|
$array = &$array[$part]; |
|
106
|
|
|
} |
|
107
|
|
|
|
|
108
|
|
|
$array[array_shift($parts)] = $value; |
|
109
|
|
|
} |
|
110
|
|
|
|
|
111
|
|
|
/** |
|
112
|
|
|
* Determine whether a configuration value exists for the given key. |
|
113
|
|
|
* |
|
114
|
|
|
* @param string $key |
|
115
|
|
|
* @return bool |
|
116
|
|
|
*/ |
|
117
|
|
|
public function has($key) |
|
118
|
|
|
{ |
|
119
|
|
|
return static::arrayHas($this->data, $key); |
|
120
|
|
|
} |
|
121
|
|
|
|
|
122
|
|
|
/** |
|
123
|
|
|
* Retrieve a configuration value. |
|
124
|
|
|
* |
|
125
|
|
|
* @param string $key |
|
126
|
|
|
* @param mixed $default [optional] |
|
127
|
|
|
* @return mixed |
|
128
|
|
|
*/ |
|
129
|
|
|
public function get($key, $default = null) |
|
130
|
|
|
{ |
|
131
|
|
|
return static::arrayGet($this->data, $key, $default); |
|
132
|
|
|
} |
|
133
|
|
|
|
|
134
|
|
|
/** |
|
135
|
|
|
* Set a configuration value. |
|
136
|
|
|
* |
|
137
|
|
|
* @param string $key |
|
138
|
|
|
* @param mixed $value |
|
139
|
|
|
*/ |
|
140
|
|
|
public function set($key, $value) |
|
141
|
|
|
{ |
|
142
|
|
|
static::arraySet($this->data, $key, $value); |
|
143
|
|
|
} |
|
144
|
|
|
|
|
145
|
|
|
/** |
|
146
|
|
|
* Retrieve all of the configuration values. |
|
147
|
|
|
* |
|
148
|
|
|
* @return array |
|
149
|
|
|
*/ |
|
150
|
|
|
public function all() |
|
151
|
|
|
{ |
|
152
|
|
|
return $this->data; |
|
153
|
|
|
} |
|
154
|
|
|
|
|
155
|
|
|
/** |
|
156
|
|
|
* Determine whether a configuration value exists for the given offset. |
|
157
|
|
|
* |
|
158
|
|
|
* @param mixed $offset |
|
159
|
|
|
* @return bool |
|
160
|
|
|
*/ |
|
161
|
|
|
public function offsetExists($offset) |
|
162
|
|
|
{ |
|
163
|
|
|
return $this->has($offset); |
|
164
|
|
|
} |
|
165
|
|
|
|
|
166
|
|
|
/** |
|
167
|
|
|
* Retrieve the configuration value at the given offset. |
|
168
|
|
|
* |
|
169
|
|
|
* @param mixed $offset |
|
170
|
|
|
* @return mixed |
|
171
|
|
|
*/ |
|
172
|
|
|
public function offsetGet($offset) |
|
173
|
|
|
{ |
|
174
|
|
|
return $this->get($offset); |
|
175
|
|
|
} |
|
176
|
|
|
|
|
177
|
|
|
/** |
|
178
|
|
|
* Set a configuration value to the given offset. |
|
179
|
|
|
* |
|
180
|
|
|
* @param mixed $offset |
|
181
|
|
|
* @param mixed $value |
|
182
|
|
|
*/ |
|
183
|
|
|
public function offsetSet($offset, $value) |
|
184
|
|
|
{ |
|
185
|
|
|
$this->set($offset, $value); |
|
186
|
|
|
} |
|
187
|
|
|
|
|
188
|
|
|
/** |
|
189
|
|
|
* Clear the given offset and its value. |
|
190
|
|
|
* |
|
191
|
|
|
* @param mixed $offset |
|
192
|
|
|
*/ |
|
193
|
|
|
public function offsetUnset($offset) |
|
194
|
|
|
{ |
|
195
|
|
|
$this->set($offset, null); |
|
196
|
|
|
} |
|
197
|
|
|
} |
|
198
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.