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 extends Nette\Collections\Hashtable
24: {
25:
26: const READONLY = 1;
27: const EXPAND = 2;
28:
29:
30:
31: private static $extensions = array(
32: 'ini' => 'Nette\Config\ConfigAdapterIni',
33: );
34:
35:
36:
37: 38: 39: 40: 41: 42:
43: public static function registerExtension($extension, $class)
44: {
45: if (!class_exists($class)) {
46: throw new \InvalidArgumentException("Class '$class' was not found.");
47: }
48:
49: if (!Nette\Reflection\ClassReflection::from($class)->implementsInterface('Nette\Config\IConfigAdapter')) {
50: throw new \InvalidArgumentException("Configuration adapter '$class' is not Nette\\Config\\IConfigAdapter implementor.");
51: }
52:
53: self::$extensions[strtolower($extension)] = $class;
54: }
55:
56:
57:
58: 59: 60: 61: 62: 63: 64:
65: public static function fromFile($file, $section = NULL, $flags = self::READONLY)
66: {
67: $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
68: if (isset(self::$extensions[$extension])) {
69: $arr = call_user_func(array(self::$extensions[$extension], 'load'), $file, $section);
70: return new static($arr, $flags);
71:
72: } else {
73: throw new \InvalidArgumentException("Unknown file extension '$file'.");
74: }
75: }
76:
77:
78:
79: 80: 81: 82:
83: public function __construct($arr = NULL, $flags = self::READONLY)
84: {
85: parent::__construct($arr);
86:
87: if ($arr !== NULL) {
88: if ($flags & self::EXPAND) {
89: $this->expand();
90: }
91:
92: if ($flags & self::READONLY) {
93: $this->freeze();
94: }
95: }
96: }
97:
98:
99:
100: 101: 102: 103: 104: 105:
106: public function save($file, $section = NULL)
107: {
108: $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
109: if (isset(self::$extensions[$extension])) {
110: return call_user_func(array(self::$extensions[$extension], 'save'), $this, $file, $section);
111:
112: } else {
113: throw new \InvalidArgumentException("Unknown file extension '$file'.");
114: }
115: }
116:
117:
118:
119:
120:
121:
122:
123: 124: 125: 126:
127: public function expand()
128: {
129: $this->updating();
130:
131: $data = $this->getArrayCopy();
132: foreach ($data as $key => $val) {
133: if (is_string($val)) {
134: $data[$key] = Nette\Environment::expand($val);
135: } elseif ($val instanceof self) {
136: $val->expand();
137: }
138: }
139: $this->setArray($data);
140: }
141:
142:
143:
144: 145: 146: 147: 148: 149:
150: public function import($arr)
151: {
152: $this->updating();
153:
154: foreach ($arr as $key => $val) {
155: if (is_array($val)) {
156: $arr[$key] = $obj = clone $this;
157: $obj->import($val);
158: }
159: }
160: $this->setArray($arr);
161: }
162:
163:
164:
165: 166: 167: 168:
169: public function toArray()
170: {
171: $res = $this->getArrayCopy();
172: foreach ($res as $key => $val) {
173: if ($val instanceof self) {
174: $res[$key] = $val->toArray();
175: }
176: }
177: return $res;
178: }
179:
180:
181:
182: 183: 184: 185:
186: public function freeze()
187: {
188: parent::freeze();
189: foreach ($this->getArrayCopy() as $val) {
190: if ($val instanceof self) {
191: $val->freeze();
192: }
193: }
194: }
195:
196:
197:
198: 199: 200: 201:
202: public function __clone()
203: {
204: parent::__clone();
205: $data = $this->getArrayCopy();
206: foreach ($data as $key => $val) {
207: if ($val instanceof self) {
208: $data[$key] = clone $val;
209: }
210: }
211: $this->setArray($data);
212: }
213:
214:
215:
216:
217:
218:
219:
220: 221: 222: 223: 224:
225: public function &__get($key)
226: {
227: $val = $this->offsetGet($key);
228: return $val;
229: }
230:
231:
232:
233: 234: 235: 236: 237: 238:
239: public function __set($key, $item)
240: {
241: $this->offsetSet($key, $item);
242: }
243:
244:
245:
246: 247: 248: 249: 250:
251: public function __isset($key)
252: {
253: return $this->offsetExists($key);
254: }
255:
256:
257:
258: 259: 260: 261: 262:
263: public function __unset($key)
264: {
265: $this->offsetUnset($key);
266: }
267:
268: }
269: