1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19: 20: 21: 22:
23: class NConfigLoader extends NObject
24: {
25:
26: const INCLUDES_KEY = 'includes';
27:
28: private $adapters = array(
29: 'php' => 'NConfigPhpAdapter',
30: 'ini' => 'NConfigIniAdapter',
31: 'neon' => 'NConfigNeonAdapter',
32: );
33:
34: private $dependencies = array();
35:
36:
37:
38: 39: 40: 41: 42: 43:
44: public function load($file, $section = NULL)
45: {
46: if (!is_file($file) || !is_readable($file)) {
47: throw new FileNotFoundException("File '$file' is missing or is not readable.");
48: }
49: $this->dependencies[] = $file = realpath($file);
50: $data = $this->getAdapter($file)->load($file);
51:
52: if ($section) {
53: if (isset($data[self::INCLUDES_KEY])) {
54: throw new InvalidStateException("Section 'includes' must be placed under some top section in file '$file'.");
55: }
56: $data = $this->getSection($data, $section, $file);
57: }
58:
59:
60: $merged = array();
61: if (isset($data[self::INCLUDES_KEY])) {
62: NValidators::assert($data[self::INCLUDES_KEY], 'list', "section 'includes' in file '$file'");
63: foreach ($data[self::INCLUDES_KEY] as $include) {
64: $merged = NConfigHelpers::merge($this->load(dirname($file) . '/' . $include), $merged);
65: }
66: }
67: unset($data[self::INCLUDES_KEY]);
68:
69: return NConfigHelpers::merge($data, $merged);
70: }
71:
72:
73:
74: 75: 76: 77: 78: 79:
80: public function save($data, $file)
81: {
82: if (file_put_contents($file, $this->getAdapter($file)->dump($data)) === FALSE) {
83: throw new IOException("Cannot write file '$file'.");
84: }
85: }
86:
87:
88:
89: 90: 91: 92:
93: public function getDependencies()
94: {
95: return array_unique($this->dependencies);
96: }
97:
98:
99:
100: 101: 102: 103: 104: 105:
106: public function addAdapter($extension, $adapter)
107: {
108: $this->adapters[strtolower($extension)] = $adapter;
109: return $this;
110: }
111:
112:
113:
114:
115: private function getAdapter($file)
116: {
117: $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
118: if (!isset($this->adapters[$extension])) {
119: throw new InvalidArgumentException("Unknown file extension '$file'.");
120: }
121: return is_object($this->adapters[$extension]) ? $this->adapters[$extension] : new $this->adapters[$extension];
122: }
123:
124:
125:
126: private function getSection(array $data, $key, $file)
127: {
128: NValidators::assertField($data, $key, 'array|null', "section '%' in file '$file'");
129: $item = $data[$key];
130: if ($parent = NConfigHelpers::takeParent($item)) {
131: $item = NConfigHelpers::merge($item, $this->getSection($data, $parent, $file));
132: }
133: return $item;
134: }
135:
136: }
137: