1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19:
20: class Config implements ArrayAccess, IteratorAggregate
21: {
22:
23: private static $extensions = array(
24: 'ini' => 'ConfigAdapterIni',
25: 'neon' => 'ConfigAdapterNeon',
26: );
27:
28:
29:
30: 31: 32: 33: 34: 35:
36: public static function registerExtension($extension, $class)
37: {
38: if (!class_exists($class)) {
39: throw new InvalidArgumentException("Class '$class' was not found.");
40: }
41:
42: if (!ClassReflection::from($class)->implementsInterface('IConfigAdapter')) {
43: throw new InvalidArgumentException("Configuration adapter '$class' is not IConfigAdapter implementor.");
44: }
45:
46: self::$extensions[strtolower($extension)] = $class;
47: }
48:
49:
50:
51: 52: 53: 54: 55: 56:
57: public static function fromFile($file, $section = NULL)
58: {
59: $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
60: if (!isset(self::$extensions[$extension])) {
61: throw new InvalidArgumentException("Unknown file extension '$file'.");
62: }
63:
64: $data = call_user_func(array(self::$extensions[$extension], 'load'), $file, $section);
65: if ($section) {
66: if (!isset($data[$section]) || !is_array($data[$section])) {
67: throw new InvalidStateException("There is not section [$section] in '$file'.");
68: }
69: $data = $data[$section];
70: }
71: return new self($data);
72: }
73:
74:
75:
76: 77: 78:
79: public function __construct($arr = NULL)
80: {
81: foreach ((array) $arr as $k => $v) {
82: $this->$k = is_array($v) ? new self($v) : $v;
83: }
84: }
85:
86:
87:
88: 89: 90: 91: 92:
93: public function save($file)
94: {
95: $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
96: if (!isset(self::$extensions[$extension])) {
97: throw new InvalidArgumentException("Unknown file extension '$file'.");
98: }
99: return call_user_func(array(self::$extensions[$extension], 'save'), $this, $file);
100: }
101:
102:
103:
104:
105:
106:
107:
108: public function __set($key, $value)
109: {
110: if (!is_scalar($key)) {
111: throw new InvalidArgumentException("Key must be either a string or an integer.");
112:
113: } elseif ($value === NULL) {
114: unset($this->$key);
115:
116: } else {
117: $this->$key = $value;
118: }
119: }
120:
121:
122:
123: public function &__get($key)
124: {
125: if (!is_scalar($key)) {
126: throw new InvalidArgumentException("Key must be either a string or an integer.");
127: }
128: return $this->$key;
129: }
130:
131:
132:
133: public function __isset($key)
134: {
135: return FALSE;
136: }
137:
138:
139:
140: public function __unset($key)
141: {
142: }
143:
144:
145:
146: 147: 148: 149: 150: 151:
152: public function offsetSet($key, $value)
153: {
154: $this->__set($key, $value);
155: }
156:
157:
158:
159: 160: 161: 162: 163:
164: public function offsetGet($key)
165: {
166: if (!is_scalar($key)) {
167: throw new InvalidArgumentException("Key must be either a string or an integer.");
168:
169: } elseif (!isset($this->$key)) {
170: return NULL;
171: }
172: return $this->$key;
173: }
174:
175:
176:
177: 178: 179: 180: 181:
182: public function offsetExists($key)
183: {
184: if (!is_scalar($key)) {
185: throw new InvalidArgumentException("Key must be either a string or an integer.");
186: }
187: return isset($this->$key);
188: }
189:
190:
191:
192: 193: 194: 195: 196:
197: public function offsetUnset($key)
198: {
199: if (!is_scalar($key)) {
200: throw new InvalidArgumentException("Key must be either a string or an integer.");
201: }
202: unset($this->$key);
203: }
204:
205:
206:
207: 208: 209: 210:
211: public function getIterator()
212: {
213: return new GenericRecursiveIterator(new ArrayIterator($this));
214: }
215:
216:
217:
218: 219: 220:
221: public function toArray()
222: {
223: $arr = array();
224: foreach ($this as $k => $v) {
225: $arr[$k] = $v instanceof self ? $v->toArray() : $v;
226: }
227: return $arr;
228: }
229:
230: }
231: