1 <?php
2 
3 namespace dokuwiki\plugin\config\core;
4 
5 use dokuwiki\Extension\Event;
6 
7 /**
8  * Configuration loader
9  *
10  * Loads configuration meta data and settings from the various files. Honors the
11  * configuration cascade and installed plugins.
12  */
13 class Loader
14 {
15     /** @var ConfigParser */
16     protected $parser;
17 
18     /** @var string[] list of enabled plugins */
19     protected $plugins;
20     /** @var string current template */
21     protected $template;
22 
23     /**
24      * Loader constructor.
25      * @param ConfigParser $parser
26      * @triggers PLUGIN_CONFIG_PLUGINLIST
27      */
28     public function __construct(ConfigParser $parser)
29     {
30         global $conf;
31         $this->parser = $parser;
32         $this->plugins = plugin_list();
33         $this->template = $conf['template'];
34         // allow plugins to remove configurable plugins
35         Event::createAndTrigger('PLUGIN_CONFIG_PLUGINLIST', $this->plugins);
36     }
37 
38     /**
39      * Read the settings meta data
40      *
41      * Reads the main file, plugins and template settings meta data
42      *
43      * @return array
44      */
45     public function loadMeta()
46     {
47         // load main file
48         $meta = [];
49         include DOKU_PLUGIN . 'config/settings/config.metadata.php';
50 
51         // plugins
52         foreach ($this->plugins as $plugin) {
53             $meta = array_merge(
54                 $meta,
55                 $this->loadExtensionMeta(
56                     DOKU_PLUGIN . $plugin . '/conf/metadata.php',
57                     'plugin',
58                     $plugin
59                 )
60             );
61         }
62 
63         // current template
64         $meta = array_merge(
65             $meta,
66             $this->loadExtensionMeta(
67                 tpl_incdir() . '/conf/metadata.php',
68                 'tpl',
69                 $this->template
70             )
71         );
72 
73         return $meta;
74     }
75 
76     /**
77      * Read the default values
78      *
79      * Reads the main file, plugins and template defaults
80      *
81      * @return array
82      */
83     public function loadDefaults()
84     {
85 
86         // initialize array
87         $conf = [];
88 
89         // plugins
90         foreach ($this->plugins as $plugin) {
91             $conf = array_merge(
92                 $conf,
93                 $this->loadExtensionConf(
94                     DOKU_PLUGIN . $plugin . '/conf/default.php',
95                     'plugin',
96                     $plugin
97                 )
98             );
99         }
100 
101         // current template
102         $conf = array_merge(
103             $conf,
104             $this->loadExtensionConf(
105                 tpl_incdir() . '/conf/default.php',
106                 'tpl',
107                 $this->template
108             )
109         );
110 
111         // load main files
112         global $config_cascade;
113         return array_merge(
114             $conf,
115             $this->loadConfigs($config_cascade['main']['default'])
116         );
117     }
118 
119     /**
120      * Reads the language strings
121      *
122      * Only reads extensions, main one is loaded the usual way
123      *
124      * @return array
125      */
126     public function loadLangs()
127     {
128         $lang = [];
129 
130         // plugins
131         foreach ($this->plugins as $plugin) {
132             $lang = array_merge(
133                 $lang,
134                 $this->loadExtensionLang(
135                     DOKU_PLUGIN . $plugin . '/',
136                     'plugin',
137                     $plugin
138                 )
139             );
140         }
141 
142         // current template
143         $lang = array_merge(
144             $lang,
145             $this->loadExtensionLang(
146                 tpl_incdir() . '/',
147                 'tpl',
148                 $this->template
149             )
150         );
151 
152         return $lang;
153     }
154 
155     /**
156      * Read the local settings
157      *
158      * @return array
159      */
160     public function loadLocal()
161     {
162         global $config_cascade;
163         return $this->loadConfigs($config_cascade['main']['local']);
164     }
165 
166     /**
167      * Read the protected settings
168      *
169      * @return array
170      */
171     public function loadProtected()
172     {
173         global $config_cascade;
174         return $this->loadConfigs($config_cascade['main']['protected']);
175     }
176 
177     /**
178      * Read the config values from the given files
179      *
180      * @param string[] $files paths to config php's
181      * @return array
182      */
183     protected function loadConfigs($files)
184     {
185         $conf = [];
186         foreach ($files as $file) {
187             $conf = array_merge($conf, $this->parser->parse($file));
188         }
189         return $conf;
190     }
191 
192     /**
193      * Read settings file from an extension
194      *
195      * This is used to read the settings.php files of plugins and templates
196      *
197      * @param string $file php file to read
198      * @param string $type should be 'plugin' or 'tpl'
199      * @param string $extname name of the extension
200      * @return array
201      */
202     protected function loadExtensionMeta($file, $type, $extname)
203     {
204         if (!file_exists($file)) return [];
205         $prefix = $type . Configuration::KEYMARKER . $extname . Configuration::KEYMARKER;
206 
207         // include file
208         $meta = [];
209         include $file;
210         if ($meta === []) return [];
211 
212         // read data
213         $data = [];
214         $data[$prefix . $type . '_settings_name'] = ['fieldset'];
215         foreach ($meta as $key => $value) {
216             if (isset($value[0]) && $value[0] == 'fieldset') continue; //plugins only get one fieldset
217             $data[$prefix . $key] = $value;
218         }
219 
220         return $data;
221     }
222 
223     /**
224      * Read a default file from an extension
225      *
226      * This is used to read the default.php files of plugins and templates
227      *
228      * @param string $file php file to read
229      * @param string $type should be 'plugin' or 'tpl'
230      * @param string $extname name of the extension
231      * @return array
232      */
233     protected function loadExtensionConf($file, $type, $extname)
234     {
235         if (!file_exists($file)) return [];
236         $prefix = $type . Configuration::KEYMARKER . $extname . Configuration::KEYMARKER;
237 
238         // parse file
239         $conf = $this->parser->parse($file);
240         if (empty($conf)) return [];
241 
242         // read data
243         $data = [];
244         foreach ($conf as $key => $value) {
245             $data[$prefix . $key] = $value;
246         }
247 
248         return $data;
249     }
250 
251     /**
252      * Read the language file of an extension
253      *
254      * @param string $dir directory of the extension
255      * @param string $type should be 'plugin' or 'tpl'
256      * @param string $extname name of the extension
257      * @return array
258      */
259     protected function loadExtensionLang($dir, $type, $extname)
260     {
261         global $conf;
262         $ll = $conf['lang'];
263         $prefix = $type . Configuration::KEYMARKER . $extname . Configuration::KEYMARKER;
264 
265         // include files
266         $lang = [];
267         if (file_exists($dir . 'lang/en/settings.php')) {
268             include $dir . 'lang/en/settings.php';
269         }
270         if ($ll != 'en' && file_exists($dir . 'lang/' . $ll . '/settings.php')) {
271             include $dir . 'lang/' . $ll . '/settings.php';
272         }
273 
274         // set up correct keys
275         $strings = [];
276         foreach ($lang as $key => $val) {
277             $strings[$prefix . $key] = $val;
278         }
279 
280         // add fieldset key
281         $strings[$prefix . $type . '_settings_name'] = ucwords(str_replace('_', ' ', $extname));
282 
283         return $strings;
284     }
285 }
286