by Chris Smith
This plugin allows wiki administrators to easily alter its configuration settings online from the comfort of their favourite webbrowser.
Settings are shown with different backgrounds to highlight their source. A blue background is used to show default values (conf/dokuwiki.php). A white background to show local changes (conf/local.php) and a light red background to show protected settings (conf/local.protected.php).
On saving changed settings this plugin will copy the current local settings file (conf/local.php) to conf/local.php.bak and save the updated settings to conf/local.php. It will never make any changes to the default settings stored in conf/dokuwiki.php. However, any settings found in conf/local.php will override the default settings as explained in the manual.
The plugin adds the following lines to the top of conf/local.php when it updates it …
/* * Dokuwiki's Main Configuration File - Local Settings * Auto-generated by config plugin * Run for user: <username> * Date: <current date/time, rfc 2822 format (day, dd MMM YYYY hh:mm:ss TZ)> */
You can protect certain settings by placing them in conf/local.protected.php. This plugin adds the following line to the bottom of conf/local.php —
@include(DOKU_CONF.'local.protected.php');
— thereby ensuring the protected settings are included and will override any previously set values from conf/dokuwiki.php and conf/local.php. Any settings found in this file will be displayed by the plugin surrounded in light-red to indicated their protected status. Editing of protected values is disabled.
Plugin sources: zip format (15k), tar.gz format (12k), darcs repository
The first two links may be used with the plugin manager and the third with the darcs plugin.
To install the plugin manually, download the package from either of the first two links to your plugin folder, lib/plugins and extract its contents. That will create a new plugin folder, lib/plugins/config, and install the plugin.
The folder will contain:
admin.php the main plugin script style.css styles to assist in display of settings data settings/ folder containing scripts & data to manipulate dokuwiki settings settings/config.class.php contains configuration class and generic setting classes settings/extra.class.php contains additional setting classes specific to some dokuwiki settings settings/config.metadata.php metadata describing dokuwiki's configuration settings lang/ localisation root folder lang/xx/ folder for language xx, at least en (english) will be present lang/xx/intro.txt lang/xx/lang.php localised language strings
The plugin is now installed.
The plugin has been structured to work to separate knowledge of Dokuwiki settings from the scripts which handle the settings.
Of the remaining files,
<?php
/**
* Configuration Manager admin plugin
*
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
* @author Christopher Smith <chris@jalakai.co.uk>
*/
if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'admin.php');
define('CM_KEYMARKER','____'); // used for settings with multiple dimensions of array indices
define('PLUGIN_SELF',dirname(__FILE__).'/');
define('PLUGIN_METADATA',PLUGIN_SELF.'settings/config.metadata.php');
require_once(PLUGIN_SELF.'settings/config.class.php'); // main configuration class and generic settings classes
require_once(PLUGIN_SELF.'settings/extra.class.php'); // settings classes specific to these settings
/**
* All DokuWiki plugins to extend the admin function
* need to inherit from this class
*/
class admin_plugin_config extends DokuWiki_Admin_Plugin {
var $_file = PLUGIN_METADATA;
var $_config = null;
var $_input = null;
var $_changed = false; // set to true if configuration has altered
var $_error = false;
var $_session_started = false;
/**
* return some info
*/
function getInfo(){
return array(
'author' => 'Christopher Smith',
'email' => 'chris@jalakai.co.uk',
'date' => '2005-11-11',
'name' => 'Configuration Manager',
'desc' => "Manage Dokuwiki's Configuration Settings",
'url' => 'http://wiki.splitbrain.org/plugin:config',
);
}
function getMenuSort() { return 100; }
/**
* handle user request
*/
function handle() {
if (!$this->_restore_session()) return $this->_close_session();
if (!isset($_REQUEST['save']) || ($_REQUEST['save'] != 1)) return $this->_close_session();
if (is_null($this->_config)) { $this->_config = new configuration($this->_file); }
// don't go any further if the configuration is locked
if ($this->_config->_locked) return $this->_close_session();
$this->_input = $_REQUEST['config'];
while (list($key) = each($this->_config->setting)) {
$input = isset($this->_input[$key]) ? $this->_input[$key] : NULL;
if ($this->_config->setting[$key]->update($input)) {
$this->_changed = true;
}
if ($this->_config->setting[$key]->error()) $this->_error = true;
}
if ($this->_changed && !$this->_error) {
$this->_config->save_settings($this->getPluginName());
// save state & force a page reload to get the new settings to take effect
$_SESSION['PLUGIN_CONFIG'] = array('state' => 'updated', 'time' => time());
$this->_close_session();
header("Location: ".wl($ID)."?do=admin&page=config");
exit();
}
$this->_close_session();
}
/**
* output appropriate html
*/
function html() {
global $lang;
if (is_null($this->_config)) { $this->_config = new configuration($this->_file); }
print $this->locale_xhtml('intro');
ptln('<div id="configmanager">');
if ($this->_config->locked)
ptln('<p class="info">'.$this->getLang('locked').'</p>');
elseif ($this->_error)
ptln('<p class="error">'.$this->getLang('error').'</p>');
elseif ($this->_changed)
ptln('<p class="ok">'.$this->getLang('updated').'</p>');
ptln('<form action="'.wl($id).'" method="post">');
ptln(' <table class="inline">');
foreach($this->_config->setting as $setting) {
list($label,$input) = $setting->html($this, $this->_error);
$class = $setting->is_default() ? ' class="default"' : ($setting->is_protected() ? ' class="protected"' : '');
$error = $setting->error() ? ' class="error"' : '';
ptln(' <tr'.$class.'>');
ptln(' <td>'.$label.'</td>');
ptln(' <td'.$error.'>'.$input.'</td>');
ptln(' </tr>');
}
ptln(' </table>');
ptln('<p>');
ptln(' <input type="hidden" name="do" value="admin" />');
ptln(' <input type="hidden" name="page" value="config" />');
if (!$this->_config->locked) {
ptln(' <input type="hidden" name="save" value="1" />');
ptln(' <input type="submit" name="submit" value="'.$lang['btn_save'].'" />');
ptln(' <input type="reset" value="'.$lang['btn_reset'].'" />');
}
ptln('</p>');
ptln('</form>');
ptln('</div>');
}
/**
* @return boolean true - proceed with handle, false - don't proceed
*/
function _restore_session() {
// dokuwiki closes the session before act_dispatch. $_SESSION variables are all set,
// however they can't be changed without starting the session again
if (!headers_sent()) {
session_start();
$this->_session_started = true;
}
if (!isset($_SESSION['PLUGIN_CONFIG'])) return true;
$session = $_SESSION['PLUGIN_CONFIG'];
unset($_SESSION['PLUGIN_CONFIG']);
// still valid?
if (time() - $session['time'] > 120) return true;
switch ($session['state']) {
case 'updated' :
$this->_changed = true;
return false;
}
return true;
}
function _close_session() {
if ($this->_session_started) session_write_close();
}
}
<?php
/*
* Configuration Class and generic setting classes
*
* @author Chris Smith <chris@jalakai.co.uk>
*/
if (!class_exists('configuration')) {
class configuration {
var $_name = 'conf'; // name of the config variable found in the files (overridden by $config['varname'])
var $_format = 'php'; // format of the config file, supported formats - php (overridden by $config['format'])
var $_heading = ''; // heading string written at top of config file - don't include comment indicators
var $_loaded = false; // set to true after configuration files are loaded
var $_metadata = array(); // holds metadata describing the settings
var $setting = array(); // array of setting objects
var $locked = false; // configuration is considered locked if it can't be updated
// filenames, these will be eval()'d prior to use so maintain any constants in output
var $_default_file = '';
var $_local_file = '';
var $_protected_file = '';
/**
* constructor
*/
function configuration($datafile) {
if (!@file_exists($datafile)) {
msg('No configuration metadata found at - '.htmlspecialchars($datafile),-1);
return;
}
include($datafile);
if (isset($config['varname'])) $this->_name = $config['varname'];
if (isset($config['format'])) $this->_format = $config['format'];
if (isset($config['heading'])) $this->_heading = $config['heading'];
if (isset($file['default'])) $this->_default_file = $file['default'];
if (isset($file['local'])) $this->_local_file = $file['local'];
if (isset($file['protected'])) $this->_protected_file = $file['protected'];
$this->locked = $this->_is_locked();
$this->_metadata = $meta;
$this->retrieve_settings();
}
function retrieve_settings() {
if (!$this->_loaded) {
$default = $this->_read_config($this->_default_file);
$local = $this->_read_config($this->_local_file);
$protected = $this->_read_config($this->_protected_file);
$keys = array_merge(array_keys($this->_metadata),array_keys($default), array_keys($local), array_keys($protected));
$keys = array_unique($keys);
foreach ($keys as $key) {
if (isset($this->_metadata[$key])) {
$class = $this->_metadata[$key][0];
$class = ($class && class_exists('setting_'.$class)) ? 'setting_'.$class : 'setting';
$param = $this->_metadata[$key];
array_shift($param);
} else {
$class = 'setting';
$param = NULL;
}
$this->setting[$key] = new $class($key,$param);
$this->setting[$key]->initialize($default[$key],$local[$key],$protected[$key]);
}
$this->_loaded = true;
}
}
function save_settings($id, $header='', $backup=true) {
if ($this->locked) return false;
$file = eval('return '.$this->_local_file.';');
// backup current file (remove any existing backup)
if (@file_exists($file) && $backup) {
if (@file_exists($file.'.bak')) @unlink($file.'.bak');
if (!@rename($file, $file.'.bak')) return false;
}
if (!$fh = @fopen($file, 'wb')) {
@rename($file.'.bak', $file); // problem opening, restore the backup
return false;
}
if (empty($header)) $header = $this->_heading;
$out = '<'.'?php'."\n".
"/*\n".
" * ".$header." \n".
" * Auto-generated by ".$id." plugin \n".
" * Run for user: ".$_SERVER['REMOTE_USER']."\n".
" * Date: ".date('r')."\n".
" */\n\n";
foreach ($this->setting as $setting) {
$out .= $setting->out($this->_name, $this->_format);
}
if ($this->_protected_file) {
$out .= "\n@include(".$this->_protected_file.");\n";
}
$out .= "\n// end auto-generated content\n";
@fwrite($fh, $out);
fclose($fh);
return true;
}
/**
* return an array of config settings
*/
function _read_config($file) {
if (!$file) return array();
$config = array();
$file = eval('return '.$file.';');
if ($this->_format == 'php') {
$contents = php_strip_whitespace($file);
$pattern = '/\$'.$this->_name.'\[[\'"]([^=]+)[\'"]\]=(.*?);/';
preg_match_all($pattern,$contents,$matches=array(),PREG_SET_ORDER);
for ($i=0; $i<count($matches); $i++) {
// correct issues with the incoming data
// FIXME ... for now merge multi-dimensional array indices using _
$key = preg_replace('/.\]\[./',CM_KEYMARKER,$matches[$i][1]);
// remove quotes from quoted strings & unescape escaped data (FIXME)
$value = preg_replace('/^(\'|")(.*)(?<!\\\\)\1$/','$2',$matches[$i][2]);
$value = strtr($value, array('\\\\'=>'\\','\\\''=>'\'','\\"'=>'"'));
$config[$key] = $value;
}
}
return $config;
}
// configuration is considered locked if there is no local settings filename
// or the directory its in is not writable or the file exists and is not writable
function _is_locked() {
if (!$this->_local_file) return true;
$local = eval('return '.$this->_local_file.';');
if (!is_writable(dirname($local))) return true;
if (file_exists($local) && !is_writable($local)) return true;
return false;
}
/**
* not used ... conf's contents are an array!
* reduce any multidimensional settings to one dimension using CM_KEYMARKER
*/
function _flatten($conf,$prefix='') {
$out = array();
foreach($conf as $key => $value) {
if (!is_array($value)) {
$out[$prefix.$key] = $value;
continue;
}
$tmp = $this->_flatten($value,$prefix.$key.CM_KEYMARKER);
$out = array_merge($out,$tmp);
}
return $out;
}
}
}
if (!class_exists('setting')) {
class setting {
var $_key = '';
var $_default = NULL;
var $_local = NULL;
var $_protected = NULL;
var $_pattern = '';
var $_error = false; // only used by those classes which error check
var $_input = NULL; // only used by those classes which error check
function setting($key, $params=NULL) {
$this->_key = $key;
if (is_array($params)) {
foreach($params as $property => $value) {
$this->$property = $value;
}
}
}
/**
* recieves current values for the setting $key
*/
function initialize($default, $local, $protected) {
if (isset($default)) $this->_default = $default;
if (isset($local)) $this->_local = $local;
if (isset($protected)) $this->_protected = $protected;
}
/*
* update setting with user provided value $input
* if value fails error check, save it
*
* FIXME value must be cleaned and validated
*/
function update($input) {
if (is_null($input)) return false;
if ($this->is_protected()) return false;
$value = is_null($this->_local) ? $this->_default : $this->_local;
if ($value == $input) return false;
if ($this->_pattern && !preg_match($this->_pattern,$input)) {
$this->_error = true;
$this->_input = $input;
return false;
}
$this->_local = $input;
return true;
}
/**
* @return array(string $label_html, string $input_html)
*/
function html(&$plugin, $echo=false) {
$value = '';
$disable = '';
if ($this->is_protected()) {
$value = $this->_protected;
$disable = 'disabled="disabled"';
} else {
if ($echo && $this->_error) {
$value = $this->_input;
} else {
$value = is_null($this->_local) ? $this->_default : $this->_local;
}
}
$key = htmlspecialchars($this->_key);
$value = htmlspecialchars($value);
$label = '<label for="config_'.$key.'">'.$this->prompt($plugin).'</label>';
$input = '<input id="config_'.$key.'" name="config['.$key.']" type="text" class="text" value="'.$value.'" '.$disable.'/>';
return array($label,$input);
}
/**
* generate string to save setting value to file according to $fmt
*/
function out($var, $fmt='php') {
if ($this->is_protected()) return '';
if (is_null($this->_local) || ($this->_default == $this->_local)) return '';
if ($fmt=='php') {
// translation string needs to be improved FIXME
$tr = array("\n"=>'\n', "\r"=>'\r', "\t"=>'\t', "\\" => '\\\\', "'" => '\\\'');
$out = '$'.$var."['".$this->_out_key()."'] = '".strtr($this->_local, $tr)."';\n";
return $out;
}
}
function prompt(&$plugin) {
$prompt = $plugin->getLang($this->_key);
if (!$prompt) $prompt = str_replace(array('____','_'),' ',$this->_key);
return htmlspecialchars($prompt);
}
function is_protected() { return !is_null($this->_protected); }
function is_default() { return !$this->is_protected() && is_null($this->_local); }
function error() { return $this->_error; }
function _out_key() { return str_replace(CM_KEYMARKER,"']['",$this->_key); }
}
}
if (!class_exists('setting_password')) {
class setting_password extends setting {
function update($input) {
if ($this->is_protected()) return false;
if (!$input) return false;
if ($this->_pattern && !preg_match($this->_pattern,$input)) {
$this->_error = true;
$this->_input = $input;
return false;
}
$this->_local = $input;
return true;
}
function html(&$plugin, $echo=false) {
$value = '';
$disable = $this->is_protected() ? 'disabled="disabled"' : '';
$key = htmlspecialchars($this->_key);
$label = '<label for="config_'.$key.'">'.$this->prompt($plugin).'</label>';
$input = '<input id="config_'.$key.'" name="config['.$key.']" type="password" class="text" value="" '.$disable.'/>';
return array($label,$input);
}
}
}
if (!class_exists('setting_email')) {
class setting_email extends setting {
var $_pattern = '#([a-z0-9\-_.]+?)@([\w\-]+\.([\w\-\.]+\.)*[\w]+)#i';
}
}
if (!class_exists('setting_numeric')) {
class setting_numeric extends setting {
var $_pattern = '/^[-+\/*0-9 ]*$/';
function out($var, $fmt='php') {
if ($this->is_protected()) return '';
if (is_null($this->_local) || ($this->_default == $this->_local)) return '';
if ($fmt=='php') {
$out .= '$'.$var."['".$this->_out_key()."'] = ".$this->_local.";\n";
return $out;
}
}
}
}
if (!class_exists('setting_onoff')) {
class setting_onoff extends setting_numeric {
function html(&$plugin) {
$value = '';
$disable = '';
if ($this->is_protected()) {
$value = $this->_protected;
$disable = ' disabled="disabled"';
} else {
$value = is_null($this->_local) ? $this->_default : $this->_local;
}
$key = htmlspecialchars($this->_key);
$checked = ($value) ? ' checked="checked"' : '';
$label = '<label for="config_'.$key.'">'.$this->prompt($plugin).'</label>';
$input = '<div class="input"><input id="config_'.$key.'" name="config['.$key.']" type="checkbox" class="checkbox" value="1"'.$checked.$disable.'/></div>';
return array($label,$input);
}
function update($input) {
if ($this->is_protected()) return false;
$input = ($input) ? 1 : 0;
$value = is_null($this->_local) ? $this->_default : $this->_local;
if ($value == $input) return false;
$this->_local = $input;
return true;
}
}
}
if (!class_exists('setting_mulitchoice')) {
class setting_multichoice extends setting {
var $_choices = array();
function html(&$plugin) {
$value = '';
$disable = '';
$nochoice = '';
if ($this->is_protected()) {
$value = $this->_protected;
$disable = ' disabled="disabled"';
} else {
$value = is_null($this->_local) ? $this->_default : $this->_local;
}
// ensure current value is included
if (!in_array($value, $this->_choices)) {
$this->_choices[] = $value;
}
// disable if no other choices
if (!$this->is_protected() && count($this->_choices) <= 1) {
$disable = ' disabled="disabled"';
$nochoice = $plugin->getLang('nochoice');
}
$key = htmlspecialchars($this->_key);
$label = '<label for="config_'.$key.'">'.$this->prompt($plugin).'</label>';
$input = "<div class=\"input\">\n";
$input .= '<select id="config_'.$key.'" name="config['.$key.']"'.$disable.'>'."\n";
foreach ($this->_choices as $choice) {
$selected = ($value == $choice) ? ' selected="selected"' : '';
$option = $plugin->getLang($this->_key.'_o_'.$choice);
if (!$option) $option = $choice;
$choice = htmlspecialchars($choice);
$option = htmlspecialchars($option);
$input .= ' <option value="'.$choice.'"'.$selected.' >'.$option.'</option>'."\n";
}
$input .= "</select> $nochoice \n";
$input .= "</div>\n";
return array($label,$input);
}
function update($input) {
if (is_null($input)) return false;
if ($this->is_protected()) return false;
$value = is_null($this->_local) ? $this->_default : $this->_local;
if ($value == $input) return false;
if (!in_array($input, $this->_choices)) return false;
$this->_local = $input;
return true;
}
}
}
if (!class_exists('setting_dirchoice')) {
class setting_dirchoice extends setting_multichoice {
var $_dir = '';
function initialize($default,$local,$protected) {
// populate $this->_choices with a list of available templates
$list = array();
if ($dh = @opendir($this->_dir)) {
while (false !== ($entry = readdir($dh))) {
if ($entry == '.' || $entry == '..') continue;
$file = (is_link($this->_dir.$entry)) ? readlink($this->_dir.$entry) : $entry;
if (is_dir($this->_dir.$file)) $list[] = $entry;
}
closedir($dh);
}
sort($list);
$this->_choices = $list;
parent::initialize($default,$local,$protected);
}
}
}
/**
* Provide php_strip_whitespace (php5 function) functionality
*
* Currently uses token_get_all(), this requires php 4.2+
*
* @author Chris Smith <chris@jalakai.co.uk>
*/
if (!function_exists('php_strip_whitespace')) {
if (function_exists('token_get_all')) {
if (!defined('T_ML_COMMENT')) {
define('T_ML_COMMENT', T_COMMENT);
} else {
define('T_DOC_COMMENT', T_ML_COMMENT);
}
/**
* modified from original
* source Google Groups, php.general, by David Otton
*/
function php_strip_whitespace($file) {
if (!@is_readable($file)) return '';
$in = join('',@file($file));
$out = '';
$tokens = token_get_all($in);
foreach ($tokens as $token) {
if (is_string ($token)) {
$out .= $token;
} else {
list ($id, $text) = $token;
switch ($id) {
case T_COMMENT : // fall thru
case T_ML_COMMENT : // fall thru
case T_DOC_COMMENT : // fall thru
case T_WHITESPACE :
break;
default : $out .= $text; break;
}
}
}
return ($out);
}
} else {
function is_whitespace($c) { return (strpos("\t\n\r ",$c) !== false); }
function is_quote($c) { return (strpos("\"'",$c) !== false); }
function is_escaped($s,$i) {
$idx = $i-1;
while(($idx>=0) && ($s{$idx} == '\\')) $idx--;
return (($i - $idx + 1) % 2);
}
function is_commentopen($str, $i) {
if ($str{$i} == '#') return "\n";
if ($str{$i} == '/') {
if ($str{$i+1} == '/') return "\n";
if ($str{$i+1} == '*') return "*/";
}
return false;
}
function php_strip_whitespace($file) {
if (!@is_readable($file)) return '';
$contents = join('',@file($file));
$out = '';
$state = 0;
for ($i=0; $i<strlen($contents); $i++) {
if (!$state && is_whitespace($contents{$i})) continue;
if (!$state && ($c_close = is_commentopen($contents, $i))) {
$c_open_len = ($contents{$i} == '/') ? 2 : 1;
$i = strpos($contents, $c_close, $i+$c_open_len)+strlen($c_close)-1;
continue;
}
$out .= $contents{$i};
if (is_quote($contents{$i})) {
if (($state == $contents{$i}) && !is_escaped($contents, $i)) { $state = 0; continue; }
if (!$state) {$state = $contents{$i}; continue; }
}
}
return $out;
}
}
}
<?php
/**
* additional setting classes specific to these settings
*
* @author Chris Smith <chris@jalakai.co.uk>
*/
if (!class_exists('setting_sepchar')) {
class setting_sepchar extends setting_multichoice {
function setting_sepchar($key,$param=NULL) {
$str = '_-.0123456789abcdefghijklnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
for ($i=0;$i<strlen($str);$i++) $this->_choices[] = $str{$i};
// call foundation class constructor
$this->setting($key,$param);
}
}
}
if (!class_exists('setting_savedir')) {
class setting_savedir extends setting {
function update($input) {
if ($this->is_protected()) return false;
$value = is_null($this->_local) ? $this->_default : $this->_local;
if ($value == $input) return false;
if (!init_path($input)) {
$this->_error = true;
$this->_input = $input;
return false;
}
$this->_local = $input;
return true;
}
}
}
if (!class_exists('setting_authtype')) {
class setting_authtype extends setting {
var $_pattern = '#^[a-zA-Z0-9_]*$#';
function update($input) {
if ($this->is_protected()) return false;
$input = trim($input);
$value = is_null($this->_local) ? $this->_default : $this->_local;
if ($value == $input) return false;
if (preg_match($this->_pattern, $input)) {
if (@file_exists(DOKU_INC.'inc/auth/'.$input.'.class.php') ||
@file_exists(DOKU_INC.'inc/auth/'.$input.'.php')) {
$this->_local = $input;
return true;
}
}
$this->_error = true;
$this->_input = $input;
return false;
}
}
}
if (!class_exists('setting_im_convert')) {
class setting_im_convert extends setting {
function update($input) {
if ($this->is_protected()) return false;
$input = trim($input);
$value = is_null($this->_local) ? $this->_default : $this->_local;
if ($value == $input) return false;
if ($input && !@file_exists($input)) {
$this->_error = true;
$this->_input = $input;
return false;
}
$this->_local = $input;
return true;
}
}
}
<?php
/**
* Metadata for configuration manager plugin
*
* Note: This file should be included within a function to ensure it
* doesn't class with the settings it is describing.
*
* Format:
* $meta[<setting name>] = array(<handler class id>,<param name> => <param value>);
*
* <handler class id> is the handler class name without the "setting_" prefix
*
* Defined classes:
* Generic
* -------------
* '' - default class ('setting'), text input, minimal input validation, setting output in quotes
* 'numeric' - text input, accepts numbers and arithmetic operators, setting output without quotes
* 'onoff' - checkbox input, setting output 0|1
* 'multichoice' - select input (single choice), setting output with quotes, required _choices parameter
* 'email' - text input, input must conform to email address format, setting output in quotes
* 'password' - password input, minimal input validation, setting output plain text in quotes
* 'dirchoice' - as multichoice, selection choices based on folders found at location specified in _dir
* parameter (required)
*
* Single Setting
* --------------
* 'savedir' - as 'setting', input tested against initpath() (inc/init.php)
* 'sepchar' - as multichoice, selection constructed from string of valid values
* 'authtype' - as 'setting', input validated against a valid php file at expected location for auth files
* 'im_convert' - as 'setting', input must exist and be an im_convert module
*
* Any setting commented or missing will use 'setting' class - text input, minimal validation, quoted output
*
* Defined parameters:
* '_pattern' - string, a preg pattern. input is tested against this pattern before being accepted
* optional all classes, except onoff, multichoice & dirchoice which ignore it
* '_choices' - array of choices. used to populate a selection box. choice will be replaced by a localised
* language string, indexed by <setting name>_o_<choice>, if one exists
* required by 'multichoice' class, ignored by other classes
* '_dir' - location of directory to be used to populate choice list
* required by 'dirchoice' class, ignored by other classes
*
* @author Chris Smith <chris@jalakai.co.uk>
*/
// ---------------[ settings for settings ]------------------------------
$config['format'] = 'php'; // format of setting files, supported formats: php
$config['varname'] = 'conf'; // name of the config variable, sans $
// this string is written at the top of the rewritten settings file,
// !! do not include any comment indicators !!
// this value can be overriden when calling save_settings() method
$config['heading'] = 'Dokuwiki\'s Main Configuration File - Local Settings';
// ---------------[ setting files ]--------------------------------------
// these values can be string expressions, they will be eval'd before use
$file['local'] = "DOKU_CONF.'local.php'"; // mandatory (file doesn't have to exist)
$file['default'] = "DOKU_CONF.'dokuwiki.php'"; // optional
$file['protected'] = "DOKU_CONF.'local.protected.php'"; // optional
// --------------[ setting metadata ]------------------------------------
// - for description of format and fields see top of file
// - order the settings in the order you wish them to appear
// - any settings not mentioned will come after the last setting listed and
// will use the default class with no parameters
$meta['title'] = array('');
$meta['start'] = array('');
$meta['savedir'] = array('savedir');
$meta['lang'] = array('dirchoice','_dir' => DOKU_INC.'inc/lang/');
$meta['template'] = array('dirchoice','_dir' => DOKU_INC.'lib/tpl/');
$meta['umask'] = array('numeric','_pattern' => '/0[0-7]{3}/'); // only accept octal representation
$meta['dmask'] = array('numeric','_pattern' => '/0[0-7]{3}/'); // only accept octal representation
$meta['basedir'] = array('');
$meta['baseurl'] = array('');
$meta['fullpath'] = array('onoff');
$meta['recent'] = array('numeric');
$meta['breadcrumbs'] = array('numeric');
$meta['typography'] = array('onoff');
$meta['htmlok'] = array('onoff');
$meta['phpok'] = array('onoff');
$meta['dformat'] = array('');
$meta['signature'] = array('');
$meta['toptoclevel'] = array('multichoice','_choices' => array(1,2,3,4,5)); // 5 toc levels
$meta['maxtoclevel'] = array('multichoice','_choices' => array(1,2,3,4,5));
$meta['maxseclevel'] = array('multichoice','_choices' => array(1,2,3,4,5));
$meta['camelcase'] = array('onoff');
$meta['deaccent'] = array('onoff');
$meta['useheading'] = array('onoff');
$meta['refcheck'] = array('onoff');
$meta['refshow'] = array('numeric');
$meta['usewordblock']= array('onoff');
$meta['indexdelay'] = array('numeric');
$meta['relnofollow'] = array('onoff');
$meta['mailguard'] = array('multichoice','_choices' => array('visible','hex','none'));
$meta['useacl'] = array('onoff');
$meta['openregister']= array('onoff');
$meta['autopasswd'] = array('onoff');
$meta['authtype'] = array('authtype');
$meta['passcrypt'] = array('multichoice','_choices' => array('smd5','md5','sha1','ssha','crypt','mysql','my411'));
$meta['defaultgroup']= array('');
$meta['superuser'] = array('');
$meta['profileconfirm'] = array('onoff');
$meta['userewrite'] = array('multichoice','_choices' => array(0,1,2));
$meta['useslash'] = array('onoff');
$meta['sepchar'] = array('sepchar');
$meta['canonical'] = array('onoff');
$meta['autoplural'] = array('onoff');
$meta['usegzip'] = array('onoff');
$meta['cachetime'] = array('numeric');
$meta['purgeonadd'] = array('onoff');
$meta['locktime'] = array('numeric');
$meta['notify'] = array('email');
$meta['mailfrom'] = array('email');
$meta['gdlib'] = array('multichoice','_choices' => array(0,1,2));
$meta['im_convert'] = array('im_convert');
$meta['spellchecker']= array('onoff');
$meta['subscribers'] = array('onoff');
$meta['pluginmanager'] = array('onoff');
$meta['rss_type'] = array('multichoice','_choices' => array('rss','rss1','rss2','atom'));
$meta['rss_linkto'] = array('multichoice','_choices' => array('diff','page','rev','current'));
$meta['target____wiki'] = array('');
$meta['target____interwiki'] = array('');
$meta['target____extern'] = array('');
$meta['target____media'] = array('');
$meta['target____windows'] = array('');
$meta['proxy____host'] = array('','_pattern' => '#^[a-z0-9\-\.+]+?#i');
$meta['proxy____port'] = array('numeric');
$meta['proxy____user'] = array('');
$meta['proxy____pass'] = array('password');
$meta['proxy____ssl'] = array('onoff');
$meta['safemodehack'] = array('onoff');
$meta['ftp____host'] = array('','_pattern' => '#^[a-z0-9\-\.+]+?#i');
$meta['ftp____port'] = array('numeric');
$meta['ftp____user'] = array('');
$meta['ftp____pass'] = array('password');
$meta['ftp____root'] = array('');
/* plugin:configmanager */
#configmanager {margin: 1em;}
#configmanager p.error {border: 1px solid red; background-color: #c66; color: white; padding: 0.5em; text-align:center}
#configmanager p.ok {border: 1px solid green; background-color: #6c6; color: black; padding: 0.5em; text-align:center}
#configmanager p.info {border: 1px solid #8cacbb; background-color: #dee7ec; color: black; padding: 0.5em; text-align:center}
#configmanager form { }
#configmanager table {margin: 1em 0;}
#configmanager td input.text {width: 30em; border: 1px solid #dee7ec;}
#configmanager td select {border: 1px solid #dee7ec;}
#configmanager tr.default .input,
#configmanager tr.default input,
#configmanager tr.default select {
background-color: #dee7ec;
}
#configmanager tr.protected .input,
#configmanager tr.protected input,
#configmanager tr.protected select {
background-color: #ffcccc;
}
#configmanager td.error {background-color: red;}
/* end plugin:configmanager */
<file | lang/en/intro.txt>
Use this page to control the settings of your Dokuwiki installation. For help on individual settings refer to wiki:config. For more details about this plugin see plugin:config.
Settings shown with a light red background are protected and can not be altered with this plugin. Settings shown with a blue background are the default values and settings shown with a white background have been set locally for this particular installation. Both blue and white settings can be altered.
Remember to press the SAVE button before leaving this page otherwise your changes will be lost. </file>
<?php
/**
* english language file
*
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
* @author Christopher Smith <chris@jalakai.co.uk>
*/
// settings must be present and set appropriately for the language
$lang['encoding'] = 'utf-8';
$lang['direction'] = 'ltr';
// for admin plugins, the menu prompt to be displayed in the admin menu
// if set here, the plugin doesn't need to override the getMenuText() method
$lang['menu'] = 'Configuration Settings ...';
$lang['error'] = 'Settings not updated due to an invalid value, please review your changes and resubmit.
<br />The incorrect value(s) will be shown surrounded by a red border.';
$lang['updated'] = 'Settings updated successfully.';
$lang['nochoice'] = '(no other choices available)';
$lang['locked'] = 'The settings file can not be updated, if this is unintentional, <br />
ensure the local settings file name and permissions are correct.';
// settings prompts
$lang['umask'] = 'new file permission mask'; //set the umask for new files
$lang['dmask'] = 'new folder permission mask'; //directory mask accordingly
$lang['lang'] = 'language'; //your language
$lang['basedir'] = 'base directory'; //absolute dir from serveroot - blank for autodetection
$lang['baseurl'] = 'base url'; //URL to server including protocol - blank for autodetect
$lang['savedir'] = 'save directory'; //where to store all the files
$lang['start'] = 'start page name'; //name of start page
$lang['title'] = 'wiki title'; //what to show in the title
$lang['template'] = 'template'; //see tpl directory
$lang['fullpath'] = 'use full path'; //show full path of the document or relative to datadir only? 0|1
$lang['recent'] = 'recent changes'; //how many entries to show in recent
$lang['breadcrumbs'] = 'breadcrumbs'; //how many recent visited pages to show
$lang['typography'] = 'typography'; //convert quotes, dashes and stuff to typographic equivalents? 0|1
$lang['htmlok'] = 'allow embedded html';//may raw HTML be embedded? This may break layout and XHTML validity 0|1
$lang['phpok'] = 'allow embedded php'; //may PHP code be embedded? Never do this on the internet! 0|1
$lang['dformat'] = 'date format'; //dateformat accepted by PHPs date() function
$lang['signature'] = 'signature'; //signature see wiki:langig for details
$lang['toptoclevel'] = 'top toc level'; //Level starting with and below to include in AutoTOC (max. 5)
$lang['maxtoclevel'] = 'max toc level'; //Up to which level include into AutoTOC (max. 5)
$lang['maxseclevel'] = 'max section edit level'; //Up to which level create editable sections (max. 5)
$lang['camelcase'] = 'use camelcase for links'; //Use CamelCase for linking? (I don't like it) 0|1
$lang['deaccent'] = 'deaccent in pagenames'; //convert accented chars to unaccented ones in pagenames?
$lang['useheading'] = 'use first heading'; //use the first heading in a page as its name
$lang['refcheck'] = 'media reference check'; //check for references before deleting media files
$lang['refshow'] = 'media references to show'; //how many references should be shown, 5 is a good value
$lang['usewordblock']= 'block spam based on words'; //block spam based on words? 0|1
$lang['indexdelay'] = 'time delay before indexing'; //allow indexing after this time (seconds) default is 5 days
$lang['relnofollow'] = 'use rel no follow'; //use rel="nofollow" for external links?
$lang['mailguard'] = 'obfuscate email addresses'; //obfuscate email addresses against spam harvesters?
/* Authentication Options - read http://www.splitbrain.org/dokuwiki/wiki:acl */
$lang['useacl'] = 'use ACL'; //Use Access Control Lists to restrict access?
$lang['openregister']= 'open register'; //Should users to be allowed to register?
$lang['autopasswd'] = 'autogenerate passwords'; //autogenerate passwords and email them to user
$lang['authtype'] = 'authentication backend'; //which authentication backend should be used
$lang['passcrypt'] = 'password encryption'; //Used crypt method (smd5,md5,sha1,ssha,crypt,mysql,my411)
$lang['defaultgroup']= 'default group'; //Default groups new Users are added to
$lang['superuser'] = 'superuser'; //The admin can be user or @group
$lang['profileconfirm'] = 'profile confirm'; //Require current password to langirm changes to user profile
/* Advanced Options */
$lang['userewrite'] = 'use nice URLs'; //this makes nice URLs: 0: off 1: .htaccess 2: internal
$lang['useslash'] = 'use slash'; //use slash instead of colon? only when rewrite is on
$lang['sepchar'] = 'page name word separator'; //word separator character in page names; may be a
$lang['canonical'] = 'use fully canonical URLs'; //Should all URLs use full canonical http://... style?
$lang['autoplural'] = 'auto-plural'; //try (non)plural form of nonexisting files?
$lang['usegzip'] = 'use gzip (for attic)'; //gzip old revisions?
$lang['cachetime'] = 'max. age for cache (sec)'; //maximum age for cachefile in seconds (defaults to a day)
$lang['purgeonadd'] = 'purge cache on add'; //purge cache when a new file is added (needed for up to date links)
$lang['locktime'] = 'max. age for lock files (sec)'; //maximum age for lockfiles (defaults to 15 minutes)
$lang['notify'] = 'notify email address'; //send change info to this email (leave blank for nobody)
$lang['mailfrom'] = 'wiki mail from'; //use this email when sending mails
$lang['gdlib'] = 'GD Lib version'; //the GDlib version (0, 1 or 2) 2 tries to autodetect
$lang['im_convert'] = 'imagemagick path'; //path to ImageMagicks convert (will be used instead of GD)
$lang['spellchecker']= 'enable spellchecker'; //enable Spellchecker (needs PHP >= 4.3.0 and aspell installed)
$lang['subscribers'] = 'enable subscription support'; //enable change notice subscription support
$lang['pluginmanager'] = 'enable plugin manager'; //enable automated plugin management (requires plugin)
$lang['rss_type'] = 'rss feed type'; //type of RSS feed to provide, by default:
$lang['rss_linkto'] = 'rss links to'; //what page RSS entries link to:
//Set target to use when creating links - leave empty for same window
$lang['target____wiki'] = 'target for internal links';
$lang['target____interwiki'] = 'target for interwiki links';
$lang['target____extern'] = 'target for external links';
$lang['target____media'] = 'target for media links';
$lang['target____windows'] = 'target for windows links';
//Proxy setup - if your Server needs a proxy to access the web set these
$lang['proxy____host'] = 'proxy - host';
$lang['proxy____port'] = 'proxy - port';
$lang['proxy____user'] = 'proxy - user name';
$lang['proxy____pass'] = 'proxy - password';
$lang['proxy____ssl'] = 'proxy - ssl';
/* Safemode Hack */
$lang['safemodehack'] = 'enable safemode hack'; //read http://wiki.splitbrain.org/wiki:safemodehack !
$lang['ftp____host'] = 'ftp - host';
$lang['ftp____port'] = 'ftp - port';
$lang['ftp____user'] = 'ftp - user name';
$lang['ftp____pass'] = 'ftp - password';
$lang['ftp____root'] = 'ftp - root directory';
/* userewrite options */
$lang['userewrite_o_0'] = 'none';
$lang['userewrite_o_1'] = 'htaccess';
$lang['userewrite_o_2'] = 'dokuwiki';
/* gdlib options */
$lang['gdlib_o_0'] = 'version 0.x';
$lang['gdlib_o_1'] = 'version 1.x';
$lang['gdlib_o_2'] = 'autodetect';
/* rss_type options */
$lang['rss_type_o_rss'] = 'RSS 0.91';
$lang['rss_type_o_rss1'] = 'RSS 1.0';
$lang['rss_type_o_rss2'] = 'RSS 2.0';
$lang['rss_type_o_atom'] = 'Atom 0.3';
/* rss_linkto options */
$lang['rss_linkto_o_diff'] = 'list of differences';
$lang['rss_linkto_o_page'] = 'the revised page';
$lang['rss_linkto_o_rev'] = 'list of revisions';
$lang['rss_linkto_o_current'] = 'the current page';






