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