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