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