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