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: set_error_handler(create_function('$severity, $message', ' // parse_ini_file returns FALSE on failure since PHP 5.2.7
39: restore_error_handler();
40: throw new InvalidStateException("parse_ini_file(): $message");
41: '));
42: $ini = parse_ini_file($file, TRUE);
43: restore_error_handler();
44:
45: $data = array();
46: foreach ($ini as $secName => $secData) {
47: if (is_array($secData)) {
48: if (substr($secName, -1) === self::RAW_SECTION) {
49: $secName = substr($secName, 0, -1);
50: } else {
51: $tmp = array();
52: foreach ($secData as $key => $val) {
53: $cursor = & $tmp;
54: $key = str_replace(self::ESCAPED_KEY_SEPARATOR, "\xFF", $key);
55: foreach (explode(self::KEY_SEPARATOR, $key) as $part) {
56: $part = str_replace("\xFF", self::KEY_SEPARATOR, $part);
57: if (!isset($cursor[$part]) || is_array($cursor[$part])) {
58: $cursor = & $cursor[$part];
59: } else {
60: throw new InvalidStateException("Invalid key '$key' in section [$secName] in file '$file'.");
61: }
62: }
63: $cursor = $val;
64: }
65: $secData = $tmp;
66: }
67:
68: $parts = explode(self::INHERITING_SEPARATOR, $secName);
69: if (count($parts) > 1) {
70: $secName = trim($parts[0]);
71: $secData[ConfigHelpers::EXTENDS_KEY] = trim($parts[1]);
72: }
73: }
74:
75: $cursor = & $data;
76: foreach (explode(self::KEY_SEPARATOR, $secName) as $part) {
77: if (!isset($cursor[$part]) || is_array($cursor[$part])) {
78: $cursor = & $cursor[$part];
79: } else {
80: throw new InvalidStateException("Invalid section [$secName] in file '$file'.");
81: }
82: }
83:
84: if (is_array($secData) && is_array($cursor)) {
85: $secData = ConfigHelpers::merge($secData, $cursor);
86: }
87:
88: $cursor = $secData;
89: }
90:
91: return $data;
92: }
93:
94:
95:
96: 97: 98: 99: 100:
101: public function dump(array $data)
102: {
103: $output = array();
104: foreach ($data as $name => $secData) {
105: if (!is_array($secData)) {
106: $output = array();
107: self::build($data, $output, '');
108: break;
109: }
110: if ($parent = ConfigHelpers::takeParent($secData)) {
111: $output[] = "[$name " . self::INHERITING_SEPARATOR . " $parent]";
112: } else {
113: $output[] = "[$name]";
114: }
115: self::build($secData, $output, '');
116: $output[] = '';
117: }
118: return "; generated by Nette\n\n" . implode(PHP_EOL, $output);
119: }
120:
121:
122:
123: 124: 125: 126:
127: private static function build($input, & $output, $prefix)
128: {
129: foreach ($input as $key => $val) {
130: $key = str_replace(self::KEY_SEPARATOR, self::ESCAPED_KEY_SEPARATOR, $key);
131: if (is_array($val)) {
132: self::build($val, $output, $prefix . $key . self::KEY_SEPARATOR);
133:
134: } elseif (is_bool($val)) {
135: $output[] = "$prefix$key = " . ($val ? 'true' : 'false');
136:
137: } elseif (is_numeric($val)) {
138: $output[] = "$prefix$key = $val";
139:
140: } elseif (is_string($val)) {
141: $output[] = "$prefix$key = \"$val\"";
142:
143: } else {
144: throw new InvalidArgumentException("The '$prefix$key' item must be scalar or array, " . gettype($val) ." given.");
145: }
146: }
147: }
148:
149: }
150: