xref: /dokuwiki/lib/plugins/config/core/Configuration.php (revision c6639e6a6a4b11d65ecbc19f1bbbf2d9b32d0c19)
1*c6639e6aSAndreas Gohr<?php
2*c6639e6aSAndreas Gohr/**
3*c6639e6aSAndreas Gohr * Configuration Class
4*c6639e6aSAndreas Gohr *
5*c6639e6aSAndreas Gohr * @author  Chris Smith <chris@jalakai.co.uk>
6*c6639e6aSAndreas Gohr * @author  Ben Coburn <btcoburn@silicodon.net>
7*c6639e6aSAndreas Gohr */
8*c6639e6aSAndreas Gohr
9*c6639e6aSAndreas Gohrnamespace dokuwiki\plugin\config\core;
10*c6639e6aSAndreas Gohr
11*c6639e6aSAndreas Gohr/**
12*c6639e6aSAndreas Gohr * Class configuration
13*c6639e6aSAndreas Gohr */
14*c6639e6aSAndreas Gohrclass Configuration {
15*c6639e6aSAndreas Gohr
16*c6639e6aSAndreas Gohr    const KEYMARKER = '____';
17*c6639e6aSAndreas Gohr
18*c6639e6aSAndreas Gohr    protected $_name = 'conf';     // name of the config variable found in the files (overridden by $config['varname'])
19*c6639e6aSAndreas Gohr    protected $_format = 'php';    // format of the config file, supported formats - php (overridden by $config['format'])
20*c6639e6aSAndreas Gohr    protected $_heading = '';      // heading string written at top of config file - don't include comment indicators
21*c6639e6aSAndreas Gohr    protected $_loaded = false;    // set to true after configuration files are loaded
22*c6639e6aSAndreas Gohr    protected $_metadata = array();// holds metadata describing the settings
23*c6639e6aSAndreas Gohr    /** @var Setting[] */
24*c6639e6aSAndreas Gohr    public $setting = array();  // array of setting objects
25*c6639e6aSAndreas Gohr    public $locked = false;     // configuration is considered locked if it can't be updated
26*c6639e6aSAndreas Gohr    public $show_disabled_plugins = false;
27*c6639e6aSAndreas Gohr
28*c6639e6aSAndreas Gohr    // configuration filenames
29*c6639e6aSAndreas Gohr    protected $_default_files = array();
30*c6639e6aSAndreas Gohr    protected $_local_files = array();      // updated configuration is written to the first file
31*c6639e6aSAndreas Gohr    protected $_protected_files = array();
32*c6639e6aSAndreas Gohr
33*c6639e6aSAndreas Gohr    protected $_plugin_list = null;
34*c6639e6aSAndreas Gohr
35*c6639e6aSAndreas Gohr    /**
36*c6639e6aSAndreas Gohr     * constructor
37*c6639e6aSAndreas Gohr     *
38*c6639e6aSAndreas Gohr     * @param string $datafile path to config metadata file
39*c6639e6aSAndreas Gohr     */
40*c6639e6aSAndreas Gohr    public function __construct($datafile) {
41*c6639e6aSAndreas Gohr        global $conf, $config_cascade;
42*c6639e6aSAndreas Gohr
43*c6639e6aSAndreas Gohr        if(!file_exists($datafile)) {
44*c6639e6aSAndreas Gohr            msg('No configuration metadata found at - ' . htmlspecialchars($datafile), -1);
45*c6639e6aSAndreas Gohr            return;
46*c6639e6aSAndreas Gohr        }
47*c6639e6aSAndreas Gohr        $meta = array();
48*c6639e6aSAndreas Gohr        /** @var array $config gets loaded via include here */
49*c6639e6aSAndreas Gohr        include($datafile);
50*c6639e6aSAndreas Gohr
51*c6639e6aSAndreas Gohr        if(isset($config['varname'])) $this->_name = $config['varname'];
52*c6639e6aSAndreas Gohr        if(isset($config['format'])) $this->_format = $config['format'];
53*c6639e6aSAndreas Gohr        if(isset($config['heading'])) $this->_heading = $config['heading'];
54*c6639e6aSAndreas Gohr
55*c6639e6aSAndreas Gohr        $this->_default_files = $config_cascade['main']['default'];
56*c6639e6aSAndreas Gohr        $this->_local_files = $config_cascade['main']['local'];
57*c6639e6aSAndreas Gohr        $this->_protected_files = $config_cascade['main']['protected'];
58*c6639e6aSAndreas Gohr
59*c6639e6aSAndreas Gohr        $this->locked = $this->_is_locked();
60*c6639e6aSAndreas Gohr        $this->_metadata = array_merge($meta, $this->get_plugintpl_metadata($conf['template']));
61*c6639e6aSAndreas Gohr        $this->retrieve_settings();
62*c6639e6aSAndreas Gohr    }
63*c6639e6aSAndreas Gohr
64*c6639e6aSAndreas Gohr    /**
65*c6639e6aSAndreas Gohr     * Retrieve and stores settings in setting[] attribute
66*c6639e6aSAndreas Gohr     */
67*c6639e6aSAndreas Gohr    public function retrieve_settings() {
68*c6639e6aSAndreas Gohr        global $conf;
69*c6639e6aSAndreas Gohr        $no_default_check = array('setting_fieldset', 'setting_undefined', 'setting_no_class');
70*c6639e6aSAndreas Gohr
71*c6639e6aSAndreas Gohr        if(!$this->_loaded) {
72*c6639e6aSAndreas Gohr            $default = array_merge(
73*c6639e6aSAndreas Gohr                $this->get_plugintpl_default($conf['template']),
74*c6639e6aSAndreas Gohr                $this->_read_config_group($this->_default_files)
75*c6639e6aSAndreas Gohr            );
76*c6639e6aSAndreas Gohr            $local = $this->_read_config_group($this->_local_files);
77*c6639e6aSAndreas Gohr            $protected = $this->_read_config_group($this->_protected_files);
78*c6639e6aSAndreas Gohr
79*c6639e6aSAndreas Gohr            $keys = array_merge(
80*c6639e6aSAndreas Gohr                array_keys($this->_metadata),
81*c6639e6aSAndreas Gohr                array_keys($default),
82*c6639e6aSAndreas Gohr                array_keys($local),
83*c6639e6aSAndreas Gohr                array_keys($protected)
84*c6639e6aSAndreas Gohr            );
85*c6639e6aSAndreas Gohr            $keys = array_unique($keys);
86*c6639e6aSAndreas Gohr
87*c6639e6aSAndreas Gohr            $param = null;
88*c6639e6aSAndreas Gohr            foreach($keys as $key) {
89*c6639e6aSAndreas Gohr                if(isset($this->_metadata[$key])) {
90*c6639e6aSAndreas Gohr                    $class = $this->_metadata[$key][0];
91*c6639e6aSAndreas Gohr
92*c6639e6aSAndreas Gohr                    if($class && class_exists('setting_' . $class)) {
93*c6639e6aSAndreas Gohr                        $class = 'setting_' . $class;
94*c6639e6aSAndreas Gohr                    } else {
95*c6639e6aSAndreas Gohr                        if($class != '') {
96*c6639e6aSAndreas Gohr                            $this->setting[] = new SettingNoClass($key, $param);
97*c6639e6aSAndreas Gohr                        }
98*c6639e6aSAndreas Gohr                        $class = 'setting';
99*c6639e6aSAndreas Gohr                    }
100*c6639e6aSAndreas Gohr
101*c6639e6aSAndreas Gohr                    $param = $this->_metadata[$key];
102*c6639e6aSAndreas Gohr                    array_shift($param);
103*c6639e6aSAndreas Gohr                } else {
104*c6639e6aSAndreas Gohr                    $class = 'setting_undefined';
105*c6639e6aSAndreas Gohr                    $param = null;
106*c6639e6aSAndreas Gohr                }
107*c6639e6aSAndreas Gohr
108*c6639e6aSAndreas Gohr                if(!in_array($class, $no_default_check) && !isset($default[$key])) {
109*c6639e6aSAndreas Gohr                    $this->setting[] = new SettingNoDefault($key, $param);
110*c6639e6aSAndreas Gohr                }
111*c6639e6aSAndreas Gohr
112*c6639e6aSAndreas Gohr                $this->setting[$key] = new $class($key, $param);
113*c6639e6aSAndreas Gohr
114*c6639e6aSAndreas Gohr                $d = array_key_exists($key, $default) ? $default[$key] : null;
115*c6639e6aSAndreas Gohr                $l = array_key_exists($key, $local) ? $local[$key] : null;
116*c6639e6aSAndreas Gohr                $p = array_key_exists($key, $protected) ? $protected[$key] : null;
117*c6639e6aSAndreas Gohr
118*c6639e6aSAndreas Gohr                $this->setting[$key]->initialize($d, $l, $p);
119*c6639e6aSAndreas Gohr            }
120*c6639e6aSAndreas Gohr
121*c6639e6aSAndreas Gohr            $this->_loaded = true;
122*c6639e6aSAndreas Gohr        }
123*c6639e6aSAndreas Gohr    }
124*c6639e6aSAndreas Gohr
125*c6639e6aSAndreas Gohr    /**
126*c6639e6aSAndreas Gohr     * Stores setting[] array to file
127*c6639e6aSAndreas Gohr     *
128*c6639e6aSAndreas Gohr     * @param string $id Name of plugin, which saves the settings
129*c6639e6aSAndreas Gohr     * @param string $header Text at the top of the rewritten settings file
130*c6639e6aSAndreas Gohr     * @param bool $backup backup current file? (remove any existing backup)
131*c6639e6aSAndreas Gohr     * @return bool succesful?
132*c6639e6aSAndreas Gohr     */
133*c6639e6aSAndreas Gohr    public function save_settings($id, $header = '', $backup = true) {
134*c6639e6aSAndreas Gohr        global $conf;
135*c6639e6aSAndreas Gohr
136*c6639e6aSAndreas Gohr        if($this->locked) return false;
137*c6639e6aSAndreas Gohr
138*c6639e6aSAndreas Gohr        // write back to the last file in the local config cascade
139*c6639e6aSAndreas Gohr        $file = end($this->_local_files);
140*c6639e6aSAndreas Gohr
141*c6639e6aSAndreas Gohr        // backup current file (remove any existing backup)
142*c6639e6aSAndreas Gohr        if(file_exists($file) && $backup) {
143*c6639e6aSAndreas Gohr            if(file_exists($file . '.bak')) @unlink($file . '.bak');
144*c6639e6aSAndreas Gohr            if(!io_rename($file, $file . '.bak')) return false;
145*c6639e6aSAndreas Gohr        }
146*c6639e6aSAndreas Gohr
147*c6639e6aSAndreas Gohr        if(!$fh = @fopen($file, 'wb')) {
148*c6639e6aSAndreas Gohr            io_rename($file . '.bak', $file);     // problem opening, restore the backup
149*c6639e6aSAndreas Gohr            return false;
150*c6639e6aSAndreas Gohr        }
151*c6639e6aSAndreas Gohr
152*c6639e6aSAndreas Gohr        if(empty($header)) $header = $this->_heading;
153*c6639e6aSAndreas Gohr
154*c6639e6aSAndreas Gohr        $out = $this->_out_header($id, $header);
155*c6639e6aSAndreas Gohr
156*c6639e6aSAndreas Gohr        foreach($this->setting as $setting) {
157*c6639e6aSAndreas Gohr            $out .= $setting->out($this->_name, $this->_format);
158*c6639e6aSAndreas Gohr        }
159*c6639e6aSAndreas Gohr
160*c6639e6aSAndreas Gohr        $out .= $this->_out_footer();
161*c6639e6aSAndreas Gohr
162*c6639e6aSAndreas Gohr        @fwrite($fh, $out);
163*c6639e6aSAndreas Gohr        fclose($fh);
164*c6639e6aSAndreas Gohr        if($conf['fperm']) chmod($file, $conf['fperm']);
165*c6639e6aSAndreas Gohr        return true;
166*c6639e6aSAndreas Gohr    }
167*c6639e6aSAndreas Gohr
168*c6639e6aSAndreas Gohr    /**
169*c6639e6aSAndreas Gohr     * Update last modified time stamp of the config file
170*c6639e6aSAndreas Gohr     *
171*c6639e6aSAndreas Gohr     * @return bool
172*c6639e6aSAndreas Gohr     */
173*c6639e6aSAndreas Gohr    public function touch_settings() {
174*c6639e6aSAndreas Gohr        if($this->locked) return false;
175*c6639e6aSAndreas Gohr        $file = end($this->_local_files);
176*c6639e6aSAndreas Gohr        return @touch($file);
177*c6639e6aSAndreas Gohr    }
178*c6639e6aSAndreas Gohr
179*c6639e6aSAndreas Gohr    /**
180*c6639e6aSAndreas Gohr     * Read and merge given config files
181*c6639e6aSAndreas Gohr     *
182*c6639e6aSAndreas Gohr     * @param array $files file paths
183*c6639e6aSAndreas Gohr     * @return array config settings
184*c6639e6aSAndreas Gohr     */
185*c6639e6aSAndreas Gohr    protected function _read_config_group($files) {
186*c6639e6aSAndreas Gohr        $config = array();
187*c6639e6aSAndreas Gohr        foreach($files as $file) {
188*c6639e6aSAndreas Gohr            $config = array_merge($config, $this->_read_config($file));
189*c6639e6aSAndreas Gohr        }
190*c6639e6aSAndreas Gohr
191*c6639e6aSAndreas Gohr        return $config;
192*c6639e6aSAndreas Gohr    }
193*c6639e6aSAndreas Gohr
194*c6639e6aSAndreas Gohr    /**
195*c6639e6aSAndreas Gohr     * Return an array of config settings
196*c6639e6aSAndreas Gohr     *
197*c6639e6aSAndreas Gohr     * @param string $file file path
198*c6639e6aSAndreas Gohr     * @return array config settings
199*c6639e6aSAndreas Gohr     */
200*c6639e6aSAndreas Gohr    protected function _read_config($file) {
201*c6639e6aSAndreas Gohr
202*c6639e6aSAndreas Gohr        if(!$file) return array();
203*c6639e6aSAndreas Gohr
204*c6639e6aSAndreas Gohr        $config = array();
205*c6639e6aSAndreas Gohr
206*c6639e6aSAndreas Gohr        if($this->_format == 'php') {
207*c6639e6aSAndreas Gohr
208*c6639e6aSAndreas Gohr            if(file_exists($file)) {
209*c6639e6aSAndreas Gohr                $contents = @php_strip_whitespace($file);
210*c6639e6aSAndreas Gohr            } else {
211*c6639e6aSAndreas Gohr                $contents = '';
212*c6639e6aSAndreas Gohr            }
213*c6639e6aSAndreas Gohr            $pattern = '/\$' . $this->_name . '\[[\'"]([^=]+)[\'"]\] ?= ?(.*?);(?=[^;]*(?:\$' . $this->_name . '|$))/s';
214*c6639e6aSAndreas Gohr            $matches = array();
215*c6639e6aSAndreas Gohr            preg_match_all($pattern, $contents, $matches, PREG_SET_ORDER);
216*c6639e6aSAndreas Gohr
217*c6639e6aSAndreas Gohr            for($i = 0; $i < count($matches); $i++) {
218*c6639e6aSAndreas Gohr                $value = $matches[$i][2];
219*c6639e6aSAndreas Gohr
220*c6639e6aSAndreas Gohr                // correct issues with the incoming data
221*c6639e6aSAndreas Gohr                // FIXME ... for now merge multi-dimensional array indices using ____
222*c6639e6aSAndreas Gohr                $key = preg_replace('/.\]\[./', Configuration::KEYMARKER, $matches[$i][1]);
223*c6639e6aSAndreas Gohr
224*c6639e6aSAndreas Gohr                // handle arrays
225*c6639e6aSAndreas Gohr                if(preg_match('/^array ?\((.*)\)/', $value, $match)) {
226*c6639e6aSAndreas Gohr                    $arr = explode(',', $match[1]);
227*c6639e6aSAndreas Gohr
228*c6639e6aSAndreas Gohr                    // remove quotes from quoted strings & unescape escaped data
229*c6639e6aSAndreas Gohr                    $len = count($arr);
230*c6639e6aSAndreas Gohr                    for($j = 0; $j < $len; $j++) {
231*c6639e6aSAndreas Gohr                        $arr[$j] = trim($arr[$j]);
232*c6639e6aSAndreas Gohr                        $arr[$j] = $this->_readValue($arr[$j]);
233*c6639e6aSAndreas Gohr                    }
234*c6639e6aSAndreas Gohr
235*c6639e6aSAndreas Gohr                    $value = $arr;
236*c6639e6aSAndreas Gohr                } else {
237*c6639e6aSAndreas Gohr                    $value = $this->_readValue($value);
238*c6639e6aSAndreas Gohr                }
239*c6639e6aSAndreas Gohr
240*c6639e6aSAndreas Gohr                $config[$key] = $value;
241*c6639e6aSAndreas Gohr            }
242*c6639e6aSAndreas Gohr        }
243*c6639e6aSAndreas Gohr
244*c6639e6aSAndreas Gohr        return $config;
245*c6639e6aSAndreas Gohr    }
246*c6639e6aSAndreas Gohr
247*c6639e6aSAndreas Gohr    /**
248*c6639e6aSAndreas Gohr     * Convert php string into value
249*c6639e6aSAndreas Gohr     *
250*c6639e6aSAndreas Gohr     * @param string $value
251*c6639e6aSAndreas Gohr     * @return bool|string
252*c6639e6aSAndreas Gohr     */
253*c6639e6aSAndreas Gohr    protected function _readValue($value) {
254*c6639e6aSAndreas Gohr        $removequotes_pattern = '/^(\'|")(.*)(?<!\\\\)\1$/s';
255*c6639e6aSAndreas Gohr        $unescape_pairs = array(
256*c6639e6aSAndreas Gohr            '\\\\' => '\\',
257*c6639e6aSAndreas Gohr            '\\\'' => '\'',
258*c6639e6aSAndreas Gohr            '\\"' => '"'
259*c6639e6aSAndreas Gohr        );
260*c6639e6aSAndreas Gohr
261*c6639e6aSAndreas Gohr        if($value == 'true') {
262*c6639e6aSAndreas Gohr            $value = true;
263*c6639e6aSAndreas Gohr        } elseif($value == 'false') {
264*c6639e6aSAndreas Gohr            $value = false;
265*c6639e6aSAndreas Gohr        } else {
266*c6639e6aSAndreas Gohr            // remove quotes from quoted strings & unescape escaped data
267*c6639e6aSAndreas Gohr            $value = preg_replace($removequotes_pattern, '$2', $value);
268*c6639e6aSAndreas Gohr            $value = strtr($value, $unescape_pairs);
269*c6639e6aSAndreas Gohr        }
270*c6639e6aSAndreas Gohr        return $value;
271*c6639e6aSAndreas Gohr    }
272*c6639e6aSAndreas Gohr
273*c6639e6aSAndreas Gohr    /**
274*c6639e6aSAndreas Gohr     * Returns header of rewritten settings file
275*c6639e6aSAndreas Gohr     *
276*c6639e6aSAndreas Gohr     * @param string $id plugin name of which generated this output
277*c6639e6aSAndreas Gohr     * @param string $header additional text for at top of the file
278*c6639e6aSAndreas Gohr     * @return string text of header
279*c6639e6aSAndreas Gohr     */
280*c6639e6aSAndreas Gohr    protected function _out_header($id, $header) {
281*c6639e6aSAndreas Gohr        $out = '';
282*c6639e6aSAndreas Gohr        if($this->_format == 'php') {
283*c6639e6aSAndreas Gohr            $out .= '<' . '?php' . "\n" .
284*c6639e6aSAndreas Gohr                "/*\n" .
285*c6639e6aSAndreas Gohr                " * " . $header . "\n" .
286*c6639e6aSAndreas Gohr                " * Auto-generated by " . $id . " plugin\n" .
287*c6639e6aSAndreas Gohr                " * Run for user: " . $_SERVER['REMOTE_USER'] . "\n" .
288*c6639e6aSAndreas Gohr                " * Date: " . date('r') . "\n" .
289*c6639e6aSAndreas Gohr                " */\n\n";
290*c6639e6aSAndreas Gohr        }
291*c6639e6aSAndreas Gohr
292*c6639e6aSAndreas Gohr        return $out;
293*c6639e6aSAndreas Gohr    }
294*c6639e6aSAndreas Gohr
295*c6639e6aSAndreas Gohr    /**
296*c6639e6aSAndreas Gohr     * Returns footer of rewritten settings file
297*c6639e6aSAndreas Gohr     *
298*c6639e6aSAndreas Gohr     * @return string text of footer
299*c6639e6aSAndreas Gohr     */
300*c6639e6aSAndreas Gohr    protected function _out_footer() {
301*c6639e6aSAndreas Gohr        $out = '';
302*c6639e6aSAndreas Gohr        if($this->_format == 'php') {
303*c6639e6aSAndreas Gohr            $out .= "\n// end auto-generated content\n";
304*c6639e6aSAndreas Gohr        }
305*c6639e6aSAndreas Gohr
306*c6639e6aSAndreas Gohr        return $out;
307*c6639e6aSAndreas Gohr    }
308*c6639e6aSAndreas Gohr
309*c6639e6aSAndreas Gohr    /**
310*c6639e6aSAndreas Gohr     * Configuration is considered locked if there is no local settings filename
311*c6639e6aSAndreas Gohr     * or the directory its in is not writable or the file exists and is not writable
312*c6639e6aSAndreas Gohr     *
313*c6639e6aSAndreas Gohr     * @return bool true: locked, false: writable
314*c6639e6aSAndreas Gohr     */
315*c6639e6aSAndreas Gohr    protected function _is_locked() {
316*c6639e6aSAndreas Gohr        if(!$this->_local_files) return true;
317*c6639e6aSAndreas Gohr
318*c6639e6aSAndreas Gohr        $local = $this->_local_files[0];
319*c6639e6aSAndreas Gohr
320*c6639e6aSAndreas Gohr        if(!is_writable(dirname($local))) return true;
321*c6639e6aSAndreas Gohr        if(file_exists($local) && !is_writable($local)) return true;
322*c6639e6aSAndreas Gohr
323*c6639e6aSAndreas Gohr        return false;
324*c6639e6aSAndreas Gohr    }
325*c6639e6aSAndreas Gohr
326*c6639e6aSAndreas Gohr    /**
327*c6639e6aSAndreas Gohr     * not used ... conf's contents are an array!
328*c6639e6aSAndreas Gohr     * reduce any multidimensional settings to one dimension using Configuration::KEYMARKER
329*c6639e6aSAndreas Gohr     *
330*c6639e6aSAndreas Gohr     * @param $conf
331*c6639e6aSAndreas Gohr     * @param string $prefix
332*c6639e6aSAndreas Gohr     * @return array
333*c6639e6aSAndreas Gohr     */
334*c6639e6aSAndreas Gohr    protected function _flatten($conf, $prefix = '') {
335*c6639e6aSAndreas Gohr
336*c6639e6aSAndreas Gohr        $out = array();
337*c6639e6aSAndreas Gohr
338*c6639e6aSAndreas Gohr        foreach($conf as $key => $value) {
339*c6639e6aSAndreas Gohr            if(!is_array($value)) {
340*c6639e6aSAndreas Gohr                $out[$prefix . $key] = $value;
341*c6639e6aSAndreas Gohr                continue;
342*c6639e6aSAndreas Gohr            }
343*c6639e6aSAndreas Gohr
344*c6639e6aSAndreas Gohr            $tmp = $this->_flatten($value, $prefix . $key . Configuration::KEYMARKER);
345*c6639e6aSAndreas Gohr            $out = array_merge($out, $tmp);
346*c6639e6aSAndreas Gohr        }
347*c6639e6aSAndreas Gohr
348*c6639e6aSAndreas Gohr        return $out;
349*c6639e6aSAndreas Gohr    }
350*c6639e6aSAndreas Gohr
351*c6639e6aSAndreas Gohr    /**
352*c6639e6aSAndreas Gohr     * Returns array of plugin names
353*c6639e6aSAndreas Gohr     *
354*c6639e6aSAndreas Gohr     * @return array plugin names
355*c6639e6aSAndreas Gohr     * @triggers PLUGIN_CONFIG_PLUGINLIST event
356*c6639e6aSAndreas Gohr     */
357*c6639e6aSAndreas Gohr    protected function get_plugin_list() {
358*c6639e6aSAndreas Gohr        if(is_null($this->_plugin_list)) {
359*c6639e6aSAndreas Gohr            $list = plugin_list('', $this->show_disabled_plugins);
360*c6639e6aSAndreas Gohr
361*c6639e6aSAndreas Gohr            // remove this plugin from the list
362*c6639e6aSAndreas Gohr            $idx = array_search('config', $list);
363*c6639e6aSAndreas Gohr            unset($list[$idx]);
364*c6639e6aSAndreas Gohr
365*c6639e6aSAndreas Gohr            trigger_event('PLUGIN_CONFIG_PLUGINLIST', $list);
366*c6639e6aSAndreas Gohr            $this->_plugin_list = $list;
367*c6639e6aSAndreas Gohr        }
368*c6639e6aSAndreas Gohr
369*c6639e6aSAndreas Gohr        return $this->_plugin_list;
370*c6639e6aSAndreas Gohr    }
371*c6639e6aSAndreas Gohr
372*c6639e6aSAndreas Gohr    /**
373*c6639e6aSAndreas Gohr     * load metadata for plugin and template settings
374*c6639e6aSAndreas Gohr     *
375*c6639e6aSAndreas Gohr     * @param string $tpl name of active template
376*c6639e6aSAndreas Gohr     * @return array metadata of settings
377*c6639e6aSAndreas Gohr     */
378*c6639e6aSAndreas Gohr    protected function get_plugintpl_metadata($tpl) {
379*c6639e6aSAndreas Gohr        $file = '/conf/metadata.php';
380*c6639e6aSAndreas Gohr        $class = '/conf/settings.class.php';
381*c6639e6aSAndreas Gohr        $metadata = array();
382*c6639e6aSAndreas Gohr
383*c6639e6aSAndreas Gohr        foreach($this->get_plugin_list() as $plugin) {
384*c6639e6aSAndreas Gohr            $plugin_dir = plugin_directory($plugin);
385*c6639e6aSAndreas Gohr            if(file_exists(DOKU_PLUGIN . $plugin_dir . $file)) {
386*c6639e6aSAndreas Gohr                $meta = array();
387*c6639e6aSAndreas Gohr                @include(DOKU_PLUGIN . $plugin_dir . $file);
388*c6639e6aSAndreas Gohr                @include(DOKU_PLUGIN . $plugin_dir . $class);
389*c6639e6aSAndreas Gohr                if(!empty($meta)) {
390*c6639e6aSAndreas Gohr                    $metadata['plugin' . Configuration::KEYMARKER . $plugin . Configuration::KEYMARKER . 'plugin_settings_name'] = ['fieldset'];
391*c6639e6aSAndreas Gohr                }
392*c6639e6aSAndreas Gohr                foreach($meta as $key => $value) {
393*c6639e6aSAndreas Gohr                    if($value[0] == 'fieldset') {
394*c6639e6aSAndreas Gohr                        continue;
395*c6639e6aSAndreas Gohr                    } //plugins only get one fieldset
396*c6639e6aSAndreas Gohr                    $metadata['plugin' . Configuration::KEYMARKER . $plugin . Configuration::KEYMARKER . $key] = $value;
397*c6639e6aSAndreas Gohr                }
398*c6639e6aSAndreas Gohr            }
399*c6639e6aSAndreas Gohr        }
400*c6639e6aSAndreas Gohr
401*c6639e6aSAndreas Gohr        // the same for the active template
402*c6639e6aSAndreas Gohr        if(file_exists(tpl_incdir() . $file)) {
403*c6639e6aSAndreas Gohr            $meta = array();
404*c6639e6aSAndreas Gohr            @include(tpl_incdir() . $file);
405*c6639e6aSAndreas Gohr            @include(tpl_incdir() . $class);
406*c6639e6aSAndreas Gohr            if(!empty($meta)) {
407*c6639e6aSAndreas Gohr                $metadata['tpl' . Configuration::KEYMARKER . $tpl . Configuration::KEYMARKER . 'template_settings_name'] = array('fieldset');
408*c6639e6aSAndreas Gohr            }
409*c6639e6aSAndreas Gohr            foreach($meta as $key => $value) {
410*c6639e6aSAndreas Gohr                if($value[0] == 'fieldset') {
411*c6639e6aSAndreas Gohr                    continue;
412*c6639e6aSAndreas Gohr                } //template only gets one fieldset
413*c6639e6aSAndreas Gohr                $metadata['tpl' . Configuration::KEYMARKER . $tpl . Configuration::KEYMARKER . $key] = $value;
414*c6639e6aSAndreas Gohr            }
415*c6639e6aSAndreas Gohr        }
416*c6639e6aSAndreas Gohr
417*c6639e6aSAndreas Gohr        return $metadata;
418*c6639e6aSAndreas Gohr    }
419*c6639e6aSAndreas Gohr
420*c6639e6aSAndreas Gohr    /**
421*c6639e6aSAndreas Gohr     * Load default settings for plugins and templates
422*c6639e6aSAndreas Gohr     *
423*c6639e6aSAndreas Gohr     * @param string $tpl name of active template
424*c6639e6aSAndreas Gohr     * @return array default settings
425*c6639e6aSAndreas Gohr     */
426*c6639e6aSAndreas Gohr    protected function get_plugintpl_default($tpl) {
427*c6639e6aSAndreas Gohr        $file = '/conf/default.php';
428*c6639e6aSAndreas Gohr        $default = array();
429*c6639e6aSAndreas Gohr
430*c6639e6aSAndreas Gohr        foreach($this->get_plugin_list() as $plugin) {
431*c6639e6aSAndreas Gohr            $plugin_dir = plugin_directory($plugin);
432*c6639e6aSAndreas Gohr            if(file_exists(DOKU_PLUGIN . $plugin_dir . $file)) {
433*c6639e6aSAndreas Gohr                $conf = $this->_read_config(DOKU_PLUGIN . $plugin_dir . $file);
434*c6639e6aSAndreas Gohr                foreach($conf as $key => $value) {
435*c6639e6aSAndreas Gohr                    $default['plugin' . Configuration::KEYMARKER . $plugin . Configuration::KEYMARKER . $key] = $value;
436*c6639e6aSAndreas Gohr                }
437*c6639e6aSAndreas Gohr            }
438*c6639e6aSAndreas Gohr        }
439*c6639e6aSAndreas Gohr
440*c6639e6aSAndreas Gohr        // the same for the active template
441*c6639e6aSAndreas Gohr        if(file_exists(tpl_incdir() . $file)) {
442*c6639e6aSAndreas Gohr            $conf = $this->_read_config(tpl_incdir() . $file);
443*c6639e6aSAndreas Gohr            foreach($conf as $key => $value) {
444*c6639e6aSAndreas Gohr                $default['tpl' . Configuration::KEYMARKER . $tpl . Configuration::KEYMARKER . $key] = $value;
445*c6639e6aSAndreas Gohr            }
446*c6639e6aSAndreas Gohr        }
447*c6639e6aSAndreas Gohr
448*c6639e6aSAndreas Gohr        return $default;
449*c6639e6aSAndreas Gohr    }
450*c6639e6aSAndreas Gohr
451*c6639e6aSAndreas Gohr}
452*c6639e6aSAndreas Gohr
453