1: <?php
2:
3: 4: 5: 6: 7:
8:
9:
10:
11: 12: 13: 14: 15: 16:
17: class ConfigNeonAdapter extends Object implements IConfigAdapter
18: {
19:
20: const INHERITING_SEPARATOR = '<',
21: PREVENT_MERGING = '!';
22:
23: 24: 25: 26: 27:
28: public function load($file)
29: {
30: return $this->process((array) Neon::decode(file_get_contents($file)));
31: }
32:
33:
34: private function process(array $arr)
35: {
36: $res = array();
37: foreach ($arr as $key => $val) {
38: if (substr($key, -1) === self::PREVENT_MERGING) {
39: if (!is_array($val) && $val !== NULL) {
40: throw new InvalidStateException("Replacing operator is available only for arrays, item '$key' is not array.");
41: }
42: $key = substr($key, 0, -1);
43: $val[ConfigHelpers::EXTENDS_KEY] = ConfigHelpers::OVERWRITE;
44:
45: } elseif (preg_match('#^(\S+)\s+' . self::INHERITING_SEPARATOR . '\s+(\S+)\z#', $key, $matches)) {
46: if (!is_array($val) && $val !== NULL) {
47: throw new InvalidStateException("Inheritance operator is available only for arrays, item '$key' is not array.");
48: }
49: list(, $key, $val[ConfigHelpers::EXTENDS_KEY]) = $matches;
50: if (isset($res[$key])) {
51: throw new InvalidStateException("Duplicated key '$key'.");
52: }
53: }
54:
55: if (is_array($val)) {
56: $val = $this->process($val);
57: } elseif ($val instanceof NeonEntity) {
58: $val = (object) array('value' => $val->value, 'attributes' => $this->process($val->attributes));
59: }
60: $res[$key] = $val;
61: }
62: return $res;
63: }
64:
65:
66: 67: 68: 69:
70: public function dump(array $data)
71: {
72: $tmp = array();
73: foreach ($data as $name => $secData) {
74: if ($parent = ConfigHelpers::takeParent($secData)) {
75: $name .= ' ' . self::INHERITING_SEPARATOR . ' ' . $parent;
76: }
77: $tmp[$name] = $secData;
78: }
79: return "# generated by Nette\n\n" . Neon::encode($tmp, Neon::BLOCK);
80: }
81:
82: }
83: