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