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