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