1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19: 20:
21: class ConfigIniAdapter extends Object implements IConfigAdapter
22: {
23:
24: const INHERITING_SEPARATOR = '<',
25: KEY_SEPARATOR = '.',
26: ESCAPED_KEY_SEPARATOR = '..',
27: RAW_SECTION = '!';
28:
29:
30: 31: 32: 33: 34: 35:
36: public function load($file)
37: {
38: Debugger::tryError();
39: $ini = parse_ini_file($file, TRUE);
40: if (Debugger::catchError($e)) {
41: throw new InvalidStateException('parse_ini_file(): ' . $e->getMessage(), 0, $e);
42: }
43:
44: $data = array();
45: foreach ($ini as $secName => $secData) {
46: if (is_array($secData)) {
47: if (substr($secName, -1) === self::RAW_SECTION) {
48: $secName = substr($secName, 0, -1);
49: } else {
50: $tmp = array();
51: foreach ($secData as $key => $val) {
52: $cursor = & $tmp;
53: $key = str_replace(self::ESCAPED_KEY_SEPARATOR, "\xFF", $key);
54: foreach (explode(self::KEY_SEPARATOR, $key) as $part) {
55: $part = str_replace("\xFF", self::KEY_SEPARATOR, $part);
56: if (!isset($cursor[$part]) || is_array($cursor[$part])) {
57: $cursor = & $cursor[$part];
58: } else {
59: throw new InvalidStateException("Invalid key '$key' in section [$secName] in file '$file'.");
60: }
61: }
62: $cursor = $val;
63: }
64: $secData = $tmp;
65: }
66:
67: $parts = explode(self::INHERITING_SEPARATOR, $secName);
68: if (count($parts) > 1) {
69: $secName = trim($parts[0]);
70: $secData[ConfigHelpers::EXTENDS_KEY] = trim($parts[1]);
71: }
72: }
73:
74: $cursor = & $data;
75: foreach (explode(self::KEY_SEPARATOR, $secName) as $part) {
76: if (!isset($cursor[$part]) || is_array($cursor[$part])) {
77: $cursor = & $cursor[$part];
78: } else {
79: throw new InvalidStateException("Invalid section [$secName] in file '$file'.");
80: }
81: }
82:
83: if (is_array($secData) && is_array($cursor)) {
84: $secData = ConfigHelpers::merge($secData, $cursor);
85: }
86:
87: $cursor = $secData;
88: }
89:
90: return $data;
91: }
92:
93:
94:
95: 96: 97: 98: 99:
100: public function dump(array $data)
101: {
102: $output = array();
103: foreach ($data as $name => $secData) {
104: if (!is_array($secData)) {
105: $output = array();
106: self::build($data, $output, '');
107: break;
108: }
109: if ($parent = ConfigHelpers::takeParent($secData)) {
110: $output[] = "[$name " . self::INHERITING_SEPARATOR . " $parent]";
111: } else {
112: $output[] = "[$name]";
113: }
114: self::build($secData, $output, '');
115: $output[] = '';
116: }
117: return "; generated by Nette\n\n" . implode(PHP_EOL, $output);
118: }
119:
120:
121:
122: 123: 124: 125:
126: private static function build($input, & $output, $prefix)
127: {
128: foreach ($input as $key => $val) {
129: $key = str_replace(self::KEY_SEPARATOR, self::ESCAPED_KEY_SEPARATOR, $key);
130: if (is_array($val)) {
131: self::build($val, $output, $prefix . $key . self::KEY_SEPARATOR);
132:
133: } elseif (is_bool($val)) {
134: $output[] = "$prefix$key = " . ($val ? 'true' : 'false');
135:
136: } elseif (is_numeric($val)) {
137: $output[] = "$prefix$key = $val";
138:
139: } elseif (is_string($val)) {
140: $output[] = "$prefix$key = \"$val\"";
141:
142: } else {
143: throw new InvalidArgumentException("The '$prefix$key' item must be scalar or array, " . gettype($val) ." given.");
144: }
145: }
146: }
147:
148: }
149: