diff --git a/lib/plugins/admin.php b/lib/plugins/admin.php index a5a8bd940bd2a1b2efa810bd1a6a54dd6d986ee1..16e2ed72ed573b7200de2fae2754f10480ce892e 100644 --- a/lib/plugins/admin.php +++ b/lib/plugins/admin.php @@ -15,7 +15,7 @@ if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); class DokuWiki_Admin_Plugin { var $localised = false; // set to true by setupLocale() after loading language dependent strings - var $lang = array(); // array to hold language dependent strings, best accessed via ->getLang() + var $lang = array(); // array to hold language dependent strings, best accessed via ->getLang() /** * General Info @@ -114,11 +114,13 @@ class DokuWiki_Admin_Plugin { * this function is automatically called by getLang() */ function setupLocale() { - if ($this->localised) return; - + if ($this->localised) return; + global $conf; // definitely don't invoke "global $lang" $path = DOKU_PLUGIN.$this->getPluginName().'/lang/'; - + + $lang = array(); + // don't include once, in case several plugin components require the same language file @include($path.'en/lang.php'); if ($conf['lang'] != 'en') @include($path.$conf['lang'].'/lang.php'); diff --git a/lib/plugins/config/admin.php b/lib/plugins/config/admin.php index 41ec9cbbe31da2a15598755a6867a5799a6b53c0..39af573ae7c50b70166874cbb7648c023a5ec9f3 100644 --- a/lib/plugins/config/admin.php +++ b/lib/plugins/config/admin.php @@ -30,6 +30,7 @@ class admin_plugin_config extends DokuWiki_Admin_Plugin { var $_changed = false; // set to true if configuration has altered var $_error = false; var $_session_started = false; + var $_localised_prompts = false; /** * return some info @@ -91,6 +92,7 @@ class admin_plugin_config extends DokuWiki_Admin_Plugin { global $lang; if (is_null($this->_config)) { $this->_config = new configuration($this->_file); } + $this->setupLocale(true); print $this->locale_xhtml('intro'); @@ -165,9 +167,45 @@ class admin_plugin_config extends DokuWiki_Admin_Plugin { return true; } - + function _close_session() { if ($this->_session_started) session_write_close(); } + + function setupLocale($prompts=false) { + + parent::setupLocale(); + if (!$prompts || $this->_localised_prompts) return; + + $this->_setup_localised_plugin_prompts(); + $this->_localised_prompts = true; + + } + + function _setup_localised_plugin_prompts() { + global $conf; + + $langfile = '/lang/'.$conf[lang].'/settings.php'; + $enlangfile = '/lang/en/settings.php'; + + $lang = array(); + + if ($dh = opendir(DOKU_PLUGIN)) { + while (false !== ($plugin = readdir($dh))) { + if ($plugin == '.' || $plugin == '..' || $plugin == 'tmp' || $plugin == 'config') continue; + if (is_file(DOKU_PLUGIN.$plugin)) continue; + + if (@file_exists(DOKU_PLUGIN.$plugin.$enlangfile)){ + @include(DOKU_PLUGIN.$plugin.$enlangfile); + if ($conf['lang'] != 'en') @include(DOKU_PLUGIN.$plugin.$langfile); + } + } + closedir($dh); + + $this->lang = array_merge($lang, $this->lang); + } + + return true; + } } diff --git a/lib/plugins/config/settings/config.class.php b/lib/plugins/config/settings/config.class.php index b45429cc931b5e7e4e176e01a031255f177355ff..7166dc192e08c52fa1db462e8b35ba38ffec9612 100644 --- a/lib/plugins/config/settings/config.class.php +++ b/lib/plugins/config/settings/config.class.php @@ -6,6 +6,7 @@ */ if (!class_exists('configuration')) { + class configuration { var $_name = 'conf'; // name of the config variable found in the files (overridden by $config['varname']) @@ -20,57 +21,55 @@ if (!class_exists('configuration')) { var $_default_file = ''; var $_local_file = ''; var $_protected_file = ''; - - var $_pluginLocale = false; // locale strings for plugin settings loaded? /** * 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 = array_merge($meta, $this->get_plugin_metadata()); - + $this->retrieve_settings(); } - + function retrieve_settings() { - + if (!$this->_loaded) { $default = array_merge($this->_read_config($this->_default_file), $this->get_plugin_default()); $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]); } @@ -82,9 +81,9 @@ if (!class_exists('configuration')) { 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'); @@ -95,7 +94,7 @@ if (!class_exists('configuration')) { @rename($file.'.bak', $file); // problem opening, restore the backup return false; } - + if (empty($header)) $header = $this->_heading; $out = $this->_out_header($id,$header); @@ -115,84 +114,84 @@ if (!class_exists('configuration')) { * 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); + + $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 $value = preg_replace('/^(\'|")(.*)(?<!\\\\)\1$/','$2',$matches[$i][2]); $value = strtr($value, array('\\\\'=>'\\','\\\''=>'\'','\\"'=>'"')); - + $config[$key] = $value; } } return $config; } - - function _out_header($id, $header) { - $out = ''; - if ($this->_format == 'php') { - $out .= '<'.'?php'."\n". + + function _out_header($id, $header) { + $out = ''; + if ($this->_format == 'php') { + $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"; - } - - return $out; - } - - function _out_footer() { - $out = ''; - if ($this->_format == 'php') { - if ($this->_protected_file) { - $out .= "\n@include(".$this->_protected_file.");\n"; - } - $out .= "\n// end auto-generated content\n"; - } - - return $out; - } + } + return $out; + } + + function _out_footer() { + $out = ''; + if ($this->_format == 'php') { + if ($this->_protected_file) { + $out .= "\n@include(".$this->_protected_file.");\n"; + } + $out .= "\n// end auto-generated content\n"; + } + + return $out; + } + // 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; @@ -202,17 +201,17 @@ if (!class_exists('configuration')) { $tmp = $this->_flatten($value,$prefix.$key.CM_KEYMARKER); $out = array_merge($out,$tmp); } - + return $out; } - + /** * load metadata for plugin settings */ function get_plugin_metadata(){ $file = '/settings/config.metadata.php'; $meta = array(); - + if ($dh = opendir(DOKU_PLUGIN)) { while (false !== ($plugin = readdir($dh))) { if ($plugin == '.' || $plugin == '..' || $plugin == 'tmp' || $plugin == 'config') continue; @@ -226,14 +225,14 @@ if (!class_exists('configuration')) { } return $meta; } - + /** * load default settings for plugins */ function get_plugin_default(){ $file = '/settings/config.default.php'; $default = array(); - + if ($dh = opendir(DOKU_PLUGIN)) { while (false !== ($plugin = readdir($dh))) { if (@file_exists(DOKU_PLUGIN.$plugin.$file)){ @@ -255,21 +254,21 @@ if (!class_exists('setting')) { 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 */ @@ -282,22 +281,22 @@ if (!class_exists('setting')) { /** * update setting with user provided value $input * if value fails error check, save it - * - * @return true if changed, false otherwise (incl. on error) + * + * @return true if changed, false otherwise (incl. on error) */ 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; } @@ -309,7 +308,7 @@ if (!class_exists('setting')) { $value = ''; $disable = ''; - + if ($this->is_protected()) { $value = $this->_protected; $disable = 'disabled="disabled"'; @@ -319,8 +318,8 @@ if (!class_exists('setting')) { } else { $value = is_null($this->_local) ? $this->_default : $this->_local; } - } - + } + $key = htmlspecialchars($this->_key); $value = htmlspecialchars($value); @@ -328,32 +327,31 @@ if (!class_exists('setting')) { $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 ''; - - $out = ''; - + + $out = ''; + if ($fmt=='php') { - // translation string needs to be improved FIXME + // 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) { - if (!$this->pluginLocale) $this->setupPluginLocale($plugin); - $prompt = $plugin->getLang($this->_key); - if (!$prompt) $prompt = str_replace(array('____','_'),' ',$this->_key); - return htmlspecialchars($prompt); + 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); } @@ -361,34 +359,7 @@ if (!class_exists('setting')) { function error() { return $this->_error; } function _out_key() { return str_replace(CM_KEYMARKER,"']['",$this->_key); } - - /** - * load extra localized strings for the plugin setting prompts - */ - function setupPluginLocale(&$config){ - global $conf; - - $langfile = '/lang/'.$conf[lang].'/settings.php'; - $enlangfile = '/lang/en/settings.php'; - - if ($dh = opendir(DOKU_PLUGIN)) { - while (false !== ($plugin = readdir($dh))) { - if ($plugin == '.' || $plugin == '..' || $plugin == 'tmp' || $plugin == 'config') continue; - if (is_file(DOKU_PLUGIN.$plugin)) continue; - - if (@file_exists(DOKU_PLUGIN.$plugin.$enlangfile)){ - @include(DOKU_PLUGIN.$plugin.$enlangfile); - if ($conf['lang'] != 'en') @include(DOKU_PLUGIN.$plugin.$langfile); - } - } - closedir($dh); - - $config->lang = array_merge($lang, $config->lang); - } - $this->pluginLocale = true; - return true; - } - } + } } if (!class_exists('setting_password')) { @@ -397,22 +368,22 @@ if (!class_exists('setting_password')) { 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>'; @@ -436,14 +407,14 @@ if (!class_exists('setting_numeric')) { if ($this->is_protected()) return ''; if (is_null($this->_local) || ($this->_default == $this->_local)) return ''; - - $out = ''; - + + $out = ''; + if ($fmt=='php') { $out .= '$'.$var."['".$this->_out_key()."'] = ".$this->_local.";\n"; } - - return $out; + + return $out; } } } @@ -454,14 +425,14 @@ if (!class_exists('setting_onoff')) { 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"' : ''; @@ -469,14 +440,14 @@ if (!class_exists('setting_onoff')) { $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; } @@ -486,19 +457,19 @@ if (!class_exists('setting_onoff')) { 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; @@ -508,7 +479,7 @@ if (!class_exists('setting_mulitchoice')) { $disable = ' disabled="disabled"'; $nochoice = $plugin->getLang('nochoice'); } - + $key = htmlspecialchars($this->_key); $label = '<label for="config_'.$key.'">'.$this->prompt($plugin).'</label>'; @@ -519,7 +490,7 @@ if (!class_exists('setting_mulitchoice')) { $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"; @@ -529,14 +500,14 @@ if (!class_exists('setting_mulitchoice')) { 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; @@ -555,7 +526,7 @@ if (!class_exists('setting_dirchoice')) { // 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; @@ -588,19 +559,19 @@ if (!function_exists('php_strip_whitespace')) { } 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; @@ -618,9 +589,9 @@ if (!function_exists('php_strip_whitespace')) { } 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) { @@ -635,17 +606,17 @@ if (!function_exists('php_strip_whitespace')) { 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; @@ -654,16 +625,16 @@ if (!function_exists('php_strip_whitespace')) { $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; + + return $out; } } }