xref: /dokuwiki/lib/plugins/config/admin.php (revision 5675a07c0fd72003cd7cbd0a02af629f8175300f)
110449332Schris<?php
210449332Schris/**
310449332Schris * Configuration Manager admin plugin
410449332Schris *
510449332Schris * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
610449332Schris * @author     Christopher Smith <chris@jalakai.co.uk>
7685bdd2eSBen Coburn * @author     Ben Coburn <btcoburn@silicodon.net>
810449332Schris */
910449332Schris
10c6639e6aSAndreas Gohruse dokuwiki\plugin\config\core\Configuration;
11077c27b2SAndreas Gohruse dokuwiki\plugin\config\core\Setting;
12077c27b2SAndreas Gohruse dokuwiki\plugin\config\core\SettingFieldset;
13077c27b2SAndreas Gohruse dokuwiki\plugin\config\core\SettingHidden;
1410449332Schris
1510449332Schris/**
1610449332Schris * All DokuWiki plugins to extend the admin function
1710449332Schris * need to inherit from this class
1810449332Schris */
1910449332Schrisclass admin_plugin_config extends DokuWiki_Admin_Plugin {
2010449332Schris
21c6639e6aSAndreas Gohr    const METADATA = __DIR__ . 'settings/config.metadata.php';
22c6639e6aSAndreas Gohr    const IMGDIR = DOKU_BASE . 'lib/plugins/config/images/';
23c6639e6aSAndreas Gohr
2461e35c35SAndreas Gohr    protected $_localised_prompts = false;
2510449332Schris
26077c27b2SAndreas Gohr    /** @var Configuration */
27077c27b2SAndreas Gohr    protected $configuration;
28077c27b2SAndreas Gohr
29253d4b48SGerrit Uitslag    /**
30077c27b2SAndreas Gohr     * admin_plugin_config constructor.
31253d4b48SGerrit Uitslag     */
32077c27b2SAndreas Gohr    public function __construct() {
33077c27b2SAndreas Gohr        $this->configuration = new Configuration();
34077c27b2SAndreas Gohr    }
3510449332Schris
3610449332Schris    /**
3710449332Schris     * handle user request
3810449332Schris     */
3961e35c35SAndreas Gohr    public function handle() {
40392c9b52SHakan Sandell        global $ID, $INPUT;
4110449332Schris
42077c27b2SAndreas Gohr        if(!$INPUT->bool('save') || !checkSecurityToken()) {
43253d4b48SGerrit Uitslag            return;
44253d4b48SGerrit Uitslag        }
4510449332Schris
4610449332Schris        // don't go any further if the configuration is locked
47077c27b2SAndreas Gohr        if($this->configuration->isLocked()) return;
48077c27b2SAndreas Gohr
49077c27b2SAndreas Gohr        // update settings and redirect of successful
50077c27b2SAndreas Gohr        $ok = $this->configuration->updateSettings($INPUT->arr('config'));
51077c27b2SAndreas Gohr        if($ok) { // no errors
52077c27b2SAndreas Gohr            try {
53077c27b2SAndreas Gohr                if($this->configuration->hasChanged()) {
54077c27b2SAndreas Gohr                    $this->configuration->save();
55077c27b2SAndreas Gohr                } else {
56077c27b2SAndreas Gohr                    $this->configuration->touch();
57253d4b48SGerrit Uitslag                }
58077c27b2SAndreas Gohr                msg($this->getLang('updated'), -1);
59077c27b2SAndreas Gohr            } catch(Exception $e) {
60077c27b2SAndreas Gohr                msg($this->getLang('error'), -1);
6110449332Schris            }
623295f40aSAndreas Gohr            send_redirect(wl($ID, array('do' => 'admin', 'page' => 'config'), true, '&'));
6310449332Schris        }
6410449332Schris    }
6510449332Schris
6610449332Schris    /**
6710449332Schris     * output appropriate html
6810449332Schris     */
6961e35c35SAndreas Gohr    public function html() {
70685bdd2eSBen Coburn        $allow_debug = $GLOBALS['conf']['allowdebug']; // avoid global $conf; here.
7110449332Schris        global $lang;
72400497e1Schris        global $ID;
7310449332Schris
7489d74a2fSchris        $this->setupLocale(true);
7510449332Schris
7610449332Schris        print $this->locale_xhtml('intro');
7710449332Schris
7824a33b42SAndreas Gohr        ptln('<div id="config__manager">');
7910449332Schris
80077c27b2SAndreas Gohr        if($this->configuration->isLocked()) {
81e4a98f5cSAnika Henke            ptln('<div class="info">' . $this->getLang('locked') . '</div>');
82077c27b2SAndreas Gohr        }
8310449332Schris
845d85efc6SAdrian Lang        // POST to script() instead of wl($ID) so config manager still works if
855d85efc6SAdrian Lang        // rewrite config is broken. Add $ID as hidden field to remember
865d85efc6SAdrian Lang        // current ID in most cases.
87f338aa80SAndreas Gohr        ptln('<form action="' . script() . '" method="post">');
88f24af591SAnika Henke        ptln('<div class="no"><input type="hidden" name="id" value="' . $ID . '" /></div>');
89634d7150SAndreas Gohr        formSecurityToken();
904fa2dffcSBen Coburn        $this->_print_h1('dokuwiki_settings', $this->getLang('_header_dokuwiki'));
9110449332Schris
924fa2dffcSBen Coburn        $in_fieldset = false;
934fa2dffcSBen Coburn        $first_plugin_fieldset = true;
944fa2dffcSBen Coburn        $first_template_fieldset = true;
95077c27b2SAndreas Gohr        foreach($this->configuration->getSettings() as $setting) {
96077c27b2SAndreas Gohr            if(is_a($setting, SettingHidden::class)) {
97685bdd2eSBen Coburn                continue;
98077c27b2SAndreas Gohr            } else if(is_a($setting, settingFieldset::class)) {
994fa2dffcSBen Coburn                // config setting group
1004fa2dffcSBen Coburn                if($in_fieldset) {
1014fa2dffcSBen Coburn                    ptln('  </table>');
102e260f93bSAnika Henke                    ptln('  </div>');
1034fa2dffcSBen Coburn                    ptln('  </fieldset>');
1044fa2dffcSBen Coburn                } else {
1054fa2dffcSBen Coburn                    $in_fieldset = true;
1064fa2dffcSBen Coburn                }
107077c27b2SAndreas Gohr                // fixme this should probably be a function in setting:
108077c27b2SAndreas Gohr                if($first_plugin_fieldset && substr($setting->getKey(), 0, 10) == 'plugin' . Configuration::KEYMARKER) {
1094fa2dffcSBen Coburn                    $this->_print_h1('plugin_settings', $this->getLang('_header_plugin'));
1104fa2dffcSBen Coburn                    $first_plugin_fieldset = false;
111077c27b2SAndreas Gohr                } else if($first_template_fieldset && substr($setting->getKey(), 0, 7) == 'tpl' . Configuration::KEYMARKER) {
1124fa2dffcSBen Coburn                    $this->_print_h1('template_settings', $this->getLang('_header_template'));
1134fa2dffcSBen Coburn                    $first_template_fieldset = false;
1144fa2dffcSBen Coburn                }
115077c27b2SAndreas Gohr                ptln('  <fieldset id="' . $setting->getKey() . '">');
1164fa2dffcSBen Coburn                ptln('  <legend>' . $setting->prompt($this) . '</legend>');
117c7b28ffdSAnika Henke                ptln('  <div class="table">');
1184fa2dffcSBen Coburn                ptln('  <table class="inline">');
1194fa2dffcSBen Coburn            } else {
1204fa2dffcSBen Coburn                // config settings
12110449332Schris                list($label, $input) = $setting->html($this, $this->_error);
12210449332Schris
12364159a61SAndreas Gohr                $class = $setting->is_default()
12464159a61SAndreas Gohr                    ? ' class="default"'
12564159a61SAndreas Gohr                    : ($setting->is_protected() ? ' class="protected"' : '');
12664159a61SAndreas Gohr                $error = $setting->error()
12764159a61SAndreas Gohr                    ? ' class="value error"'
12864159a61SAndreas Gohr                    : ' class="value"';
12964159a61SAndreas Gohr                $icon = $setting->caution()
130c6639e6aSAndreas Gohr                    ? '<img src="' . self::IMGDIR . $setting->caution() . '.png" ' .
13164159a61SAndreas Gohr                    'alt="' . $setting->caution() . '" title="' . $this->getLang($setting->caution()) . '" />'
13264159a61SAndreas Gohr                    : '';
13310449332Schris
13410449332Schris                ptln('    <tr' . $class . '>');
135dde31035SAndreas Gohr                ptln('      <td class="label">');
1367ed33b2aSAnika Henke                ptln('        <span class="outkey">' . $setting->_out_key(true, true) . '</span>');
137bccdba06SAndreas Gohr                ptln('        ' . $icon . $label);
138dde31035SAndreas Gohr                ptln('      </td>');
13910449332Schris                ptln('      <td' . $error . '>' . $input . '</td>');
14010449332Schris                ptln('    </tr>');
14110449332Schris            }
1424fa2dffcSBen Coburn        }
14310449332Schris
14410449332Schris        ptln('  </table>');
145c7b28ffdSAnika Henke        ptln('  </div>');
1464fa2dffcSBen Coburn        if($in_fieldset) {
1474fa2dffcSBen Coburn            ptln('  </fieldset>');
1484fa2dffcSBen Coburn        }
14910449332Schris
150685bdd2eSBen Coburn        // show undefined settings list
151077c27b2SAndreas Gohr        $undefined_settings = $this->configuration->getUndefined();
152685bdd2eSBen Coburn        if($allow_debug && !empty($undefined_settings)) {
153253d4b48SGerrit Uitslag            /**
154253d4b48SGerrit Uitslag             * Callback for sorting settings
155253d4b48SGerrit Uitslag             *
156077c27b2SAndreas Gohr             * @param Setting $a
157077c27b2SAndreas Gohr             * @param Setting $b
158253d4b48SGerrit Uitslag             * @return int if $a is lower/equal/higher than $b
159253d4b48SGerrit Uitslag             */
160253d4b48SGerrit Uitslag            function _setting_natural_comparison($a, $b) {
161077c27b2SAndreas Gohr                return strnatcmp($a->getKey(), $b->getKey());
162253d4b48SGerrit Uitslag            }
163253d4b48SGerrit Uitslag
164685bdd2eSBen Coburn            usort($undefined_settings, '_setting_natural_comparison');
165685bdd2eSBen Coburn            $this->_print_h1('undefined_settings', $this->getLang('_header_undefined'));
166685bdd2eSBen Coburn            ptln('<fieldset>');
167c7b28ffdSAnika Henke            ptln('<div class="table">');
168685bdd2eSBen Coburn            ptln('<table class="inline">');
169685bdd2eSBen Coburn            $undefined_setting_match = array();
170685bdd2eSBen Coburn            foreach($undefined_settings as $setting) {
17164159a61SAndreas Gohr                if(
17264159a61SAndreas Gohr                preg_match(
173c6639e6aSAndreas Gohr                    '/^(?:plugin|tpl)' . Configuration::KEYMARKER . '.*?' . Configuration::KEYMARKER . '(.*)$/',
174077c27b2SAndreas Gohr                    $setting->getKey(),
17564159a61SAndreas Gohr                    $undefined_setting_match
17664159a61SAndreas Gohr                )
17764159a61SAndreas Gohr                ) {
178685bdd2eSBen Coburn                    $undefined_setting_key = $undefined_setting_match[1];
179685bdd2eSBen Coburn                } else {
180077c27b2SAndreas Gohr                    $undefined_setting_key = $setting->getKey();
181685bdd2eSBen Coburn                }
182685bdd2eSBen Coburn                ptln('  <tr>');
183077c27b2SAndreas Gohr                ptln(
184077c27b2SAndreas Gohr                    '    <td class="label"><span title="$meta[\'' . $undefined_setting_key . '\']">$' .
185077c27b2SAndreas Gohr                    'conf' . '[\'' . $setting->_out_key() . '\']</span></td>'
186077c27b2SAndreas Gohr                );
187685bdd2eSBen Coburn                ptln('    <td>' . $this->getLang('_msg_' . get_class($setting)) . '</td>');
188685bdd2eSBen Coburn                ptln('  </tr>');
189685bdd2eSBen Coburn            }
190685bdd2eSBen Coburn            ptln('</table>');
191c7b28ffdSAnika Henke            ptln('</div>');
192685bdd2eSBen Coburn            ptln('</fieldset>');
193685bdd2eSBen Coburn        }
194685bdd2eSBen Coburn
195685bdd2eSBen Coburn        // finish up form
19610449332Schris        ptln('<p>');
19710449332Schris        ptln('  <input type="hidden" name="do"     value="admin" />');
19810449332Schris        ptln('  <input type="hidden" name="page"   value="config" />');
19910449332Schris
200077c27b2SAndreas Gohr        if(!$this->configuration->isLocked()) {
20110449332Schris            ptln('  <input type="hidden" name="save"   value="1" />');
202ae614416SAnika Henke            ptln('  <button type="submit" name="submit" accesskey="s">' . $lang['btn_save'] . '</button>');
203ae614416SAnika Henke            ptln('  <button type="reset">' . $lang['btn_reset'] . '</button>');
20410449332Schris        }
20510449332Schris
20610449332Schris        ptln('</p>');
20710449332Schris
20810449332Schris        ptln('</form>');
20910449332Schris        ptln('</div>');
21010449332Schris    }
21110449332Schris
21210449332Schris    /**
213253d4b48SGerrit Uitslag     * @param bool $prompts
214253d4b48SGerrit Uitslag     */
21561e35c35SAndreas Gohr    public function setupLocale($prompts = false) {
21689d74a2fSchris        parent::setupLocale();
21789d74a2fSchris        if(!$prompts || $this->_localised_prompts) return;
218*5675a07cSAndreas Gohr        $this->configuration->getLangs();
21989d74a2fSchris        $this->_localised_prompts = true;
22089d74a2fSchris    }
22189d74a2fSchris
2224fa2dffcSBen Coburn    /**
2234fa2dffcSBen Coburn     * Generates a two-level table of contents for the config plugin.
2244fa2dffcSBen Coburn     *
2254fa2dffcSBen Coburn     * @author Ben Coburn <btcoburn@silicodon.net>
226253d4b48SGerrit Uitslag     *
227253d4b48SGerrit Uitslag     * @return array
2284fa2dffcSBen Coburn     */
22961e35c35SAndreas Gohr    public function getTOC() {
230b8595a66SAndreas Gohr        $this->setupLocale(true);
231b8595a66SAndreas Gohr
232685bdd2eSBen Coburn        $allow_debug = $GLOBALS['conf']['allowdebug']; // avoid global $conf; here.
233685bdd2eSBen Coburn
2344fa2dffcSBen Coburn        // gather toc data
2354fa2dffcSBen Coburn        $toc = array('conf' => array(), 'plugin' => array(), 'template' => null);
236077c27b2SAndreas Gohr        foreach($this->configuration->getSettings() as $setting) {
2374fa2dffcSBen Coburn            if(is_a($setting, 'setting_fieldset')) {
238077c27b2SAndreas Gohr                // FIXME as above this should go into Setting class
239077c27b2SAndreas Gohr                if(substr($setting->getKey(), 0, 10) == 'plugin' . Configuration::KEYMARKER) {
2404fa2dffcSBen Coburn                    $toc['plugin'][] = $setting;
241077c27b2SAndreas Gohr                } else if(substr($setting->getKey(), 0, 7) == 'tpl' . Configuration::KEYMARKER) {
2424fa2dffcSBen Coburn                    $toc['template'] = $setting;
2434fa2dffcSBen Coburn                } else {
2444fa2dffcSBen Coburn                    $toc['conf'][] = $setting;
2454fa2dffcSBen Coburn                }
2464fa2dffcSBen Coburn            }
2474fa2dffcSBen Coburn        }
2484fa2dffcSBen Coburn
249e1b31a95SBen Coburn        // build toc
250b8595a66SAndreas Gohr        $t = array();
251b8595a66SAndreas Gohr
252cbfba956SMichael Hamann        $check = false;
253cbfba956SMichael Hamann        $title = $this->getLang('_configuration_manager');
254cbfba956SMichael Hamann        $t[] = html_mktocitem(sectionID($title, $check), $title, 1);
255b8595a66SAndreas Gohr        $t[] = html_mktocitem('dokuwiki_settings', $this->getLang('_header_dokuwiki'), 1);
256253d4b48SGerrit Uitslag        /** @var setting $setting */
257e1b31a95SBen Coburn        foreach($toc['conf'] as $setting) {
258e1b31a95SBen Coburn            $name = $setting->prompt($this);
259077c27b2SAndreas Gohr            $t[] = html_mktocitem($setting->getKey(), $name, 2);
260e1b31a95SBen Coburn        }
261e1b31a95SBen Coburn        if(!empty($toc['plugin'])) {
262b8595a66SAndreas Gohr            $t[] = html_mktocitem('plugin_settings', $this->getLang('_header_plugin'), 1);
263e1b31a95SBen Coburn        }
264e1b31a95SBen Coburn        foreach($toc['plugin'] as $setting) {
265e1b31a95SBen Coburn            $name = $setting->prompt($this);
266077c27b2SAndreas Gohr            $t[] = html_mktocitem($setting->getKey(), $name, 2);
267e1b31a95SBen Coburn        }
268e1b31a95SBen Coburn        if(isset($toc['template'])) {
269b8595a66SAndreas Gohr            $t[] = html_mktocitem('template_settings', $this->getLang('_header_template'), 1);
270e1b31a95SBen Coburn            $setting = $toc['template'];
271e1b31a95SBen Coburn            $name = $setting->prompt($this);
272077c27b2SAndreas Gohr            $t[] = html_mktocitem($setting->getKey(), $name, 2);
273e1b31a95SBen Coburn        }
274077c27b2SAndreas Gohr        if(count($this->configuration->getUndefined()) && $allow_debug) {
275b8595a66SAndreas Gohr            $t[] = html_mktocitem('undefined_settings', $this->getLang('_header_undefined'), 1);
276e1b31a95SBen Coburn        }
277e1b31a95SBen Coburn
278b8595a66SAndreas Gohr        return $t;
2794fa2dffcSBen Coburn    }
2804fa2dffcSBen Coburn
281253d4b48SGerrit Uitslag    /**
282253d4b48SGerrit Uitslag     * @param string $id
283253d4b48SGerrit Uitslag     * @param string $text
284253d4b48SGerrit Uitslag     */
28561e35c35SAndreas Gohr    protected function _print_h1($id, $text) {
28663e967bdSAnika Henke        ptln('<h1 id="' . $id . '">' . $text . '</h1>');
2874fa2dffcSBen Coburn    }
2884fa2dffcSBen Coburn
28961e35c35SAndreas Gohr    /**
29061e35c35SAndreas Gohr     * Adds a translation to this plugin's language array
29161e35c35SAndreas Gohr     *
29261e35c35SAndreas Gohr     * @param string $key
29361e35c35SAndreas Gohr     * @param string $value
29461e35c35SAndreas Gohr     */
29561e35c35SAndreas Gohr    public function addLang($key, $value) {
29661e35c35SAndreas Gohr        if(!$this->localised) $this->setupLocale();
29761e35c35SAndreas Gohr        $this->lang[$key] = $value;
29861e35c35SAndreas Gohr    }
29910449332Schris}
300