1<?php 2/* 3 * TxtConfiguration Class and generic setting classes 4 * 5 * @author Stephane Chamberland <stephane.chamberland@ec.gc.ca> 6 * 7 * Extends Configuration Class and generic setting classes by Chris Smith <chris@jalakai.co.uk> 8 * Deals with TXT (None PHP) config files 9 */ 10 11if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 12if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 13 14if(!defined('PLUGIN_TXTCONF')) define('PLUGIN_TXTCONF',dirname(__FILE__).'/'); 15 16require_once(PLUGIN_TXTCONF.'config0.class.php'); 17 18 19if (!class_exists('txtconfiguration') && class_exists('configuration0')) { 20 21 class txtconfiguration extends configuration0 { 22 23 var $_intro = ''; 24 var $_format = 'txt'; 25 var $_defkeymeta = array('text'); // holds metametadata describing the settings key/name 26 var $_defvalmeta = array('text'); // holds metametadata describing the settings valueblog 27 28 /** 29 * constructor 30 */ 31 function txtconfiguration($datafile) { 32 global $conf; 33 34 if (!@file_exists($datafile)) { 35 //TODO: localize msg 36 msg('No configuration metadata found at - '.htmlspecialchars($datafile),-1); 37 return; 38 } 39 include($datafile); 40 41 //?TODO:? fill $meta with appropriate values 42 43 if (isset($config['intro'])) $this->_intro = $config['intro']; 44 45 if (isset($config['varname'])) $this->_name = $config['varname']; 46 if (isset($config['format'])) $this->_format = $config['format']; 47 if (isset($config['heading'])) $this->_heading = $config['heading']; 48 49 if (isset($file['default'])) $this->_default_file = $file['default']; 50 if (isset($file['local'])) $this->_local_file = $file['local']; 51 if (isset($file['protected'])) $this->_protected_file = $file['protected']; 52 53 if (isset($metameta['key'])) $this->_defkeymeta = $metameta['key']; 54 if (isset($metameta['value'])) $this->_defvalmeta = $metameta['value']; 55 56 $this->locked = $this->_is_locked(); 57 58 //$this->_metadata = array_merge($meta, $this->get_plugintpl_metadata($conf['template'])); 59 60 $this->retrieve_settings(); 61 } 62 63 function retrieve_settings() { 64 global $conf; 65 66 if (!$this->_loaded) { 67 //$default = array_merge($this->_read_config($this->_default_file), $this->get_plugintpl_default($conf['template'])); 68 $default = $this->_read_config($this->_default_file); 69 $local = $this->_read_config($this->_local_file); 70 $protected = $this->_read_config($this->_protected_file); 71 72 $keys = array_merge(array_keys($this->_metadata),array_keys($default), array_keys($local), array_keys($protected)); 73 $keys = array_unique($keys); 74 75 $class = NULL; 76 $defparam = NULL; 77 if (isset($this->_defvalmeta[0])) { 78 $class = $this->_defvalmeta[0]; 79 $defparam = $this->_defvalmeta; 80 array_shift($defparam); 81 } 82 $defclass = ($class && class_exists('setting_'.$class)) ? 'setting_'.$class : 'setting0'; 83 84 foreach ($keys as $key) { 85 if (isset($this->_metadata[$key])) { 86 $class = $this->_metadata[$key][0]; 87 //$class = ($class && class_exists('setting_'.$class)) ? 'setting_'.$class : 'setting'; 88 //$param = $this->_metadata[$key]; 89 //array_shift($param); 90 //$class = $defclass; 91 $param = $defparam; 92 if ($class && class_exists('setting_'.$class)) { 93 $class = 'setting_'.$class; 94 $param = $this->_metadata[$key]; 95 array_shift($param); 96 } 97 } else { 98 //$class = 'setting'; 99 //$param = NULL; 100 $class = $defclass; 101 $param = $defparam; 102 } 103 104 $this->setting[$key] = new $class($key,$param); 105 $this->setting[$key]->initialize($default[$key],$local[$key],$protected[$key]); 106 } 107 108 $this->_loaded = true; 109 } 110 111 } 112 113 function add_local_setting($key,$value) { 114 global $conf; 115 116 $defclass = NULL; 117 $defparam = NULL; 118 $class = NULL; 119 if (isset($this->_defvalmeta[0])) { 120 $class = $this->_defvalmeta[0]; 121 $defparam = $this->_defvalmeta; 122 array_shift($defparam); 123 } 124 $defclass = ($class && class_exists('setting_'.$class)) ? 'setting_'.$class : 'setting0'; 125 126 $class = $defclass; 127 $param = $defparam; 128 129 if (isset($this->_metadata[$key])) { 130 $class = $this->_metadata[$key][0]; 131 $param = $defparam; 132 if ($class && class_exists('setting_'.$class)) { 133 $class = 'setting_'.$class; 134 $param = $this->_metadata[$key]; 135 array_shift($param); 136 } 137 } 138 139 $this->setting[$key] = new $class($key,$param); 140 $this->setting[$key]->initialize(null,$value,null); 141 142 //TODO: if key already exist, return False 143 return True; 144 } 145 146 /** 147 * return an array of config settings 148 */ 149 function _read_config($file) { 150 151 if (!$file) return array(); 152 153 $config = array(); 154 $file = eval('return '.$file.';'); 155 156 if ($this->_format == 'php') { 157 158 $contents = @php_strip_whitespace($file); 159 $pattern = '/\$'.$this->_name.'\[[\'"]([^=]+)[\'"]\] ?= ?(.*?);/'; 160 $matches=array(); 161 preg_match_all($pattern,$contents,$matches,PREG_SET_ORDER); 162 163 for ($i=0; $i<count($matches); $i++) { 164 165 // correct issues with the incoming data 166 // FIXME ... for now merge multi-dimensional array indices using ____ 167 $key = preg_replace('/.\]\[./',CM_KEYMARKER,$matches[$i][1]); 168 169 // remove quotes from quoted strings & unescape escaped data 170 $value = preg_replace('/^(\'|")(.*)(?<!\\\\)\1$/','$2',$matches[$i][2]); 171 $value = strtr($value, array('\\\\'=>'\\','\\\''=>'\'','\\"'=>'"')); 172 173 $config[$key] = $value; 174 } 175 } else if ($this->_format == 'txt') { 176 //TODO: if confToHash not found, include(confutils.php) 177 //if(!defined('DOKU_CONF')) define('DOKU_CONF',DOKU_INC.'conf/'); 178 //require_once(DOKU_INC.'inc/confutils.php'); 179 //include(); 180 $config = confToHash($file); 181 } 182 183 return $config; 184 } 185 186 function _out_header($id, $header) { 187 $out = ''; 188 if ($this->_format == 'php') { 189 $out .= '<'.'?php'."\n". 190 "/*\n". 191 " * ".$header." \n". 192 " * Auto-generated by ".$id." plugin \n". 193 " * Run for user: ".$_SERVER['REMOTE_USER']."\n". 194 " * Date: ".date('r')."\n". 195 " */\n\n"; 196 } else if ($this->_format == 'txt') { 197 $out .= 198 "#\n". 199 "# ".$header." \n". 200 "# Auto-generated by ".$id." plugin \n". 201 "# Run for user: ".$_SERVER['REMOTE_USER']."\n". 202 "# Date: ".date('r')."\n". 203 "#\n\n"; 204 } 205 206 return $out; 207 } 208 209 function _out_footer() { 210 $out = ''; 211 if ($this->_format == 'php') { 212 if ($this->_protected_file) { 213 $out .= "\n@include(".$this->_protected_file.");\n"; 214 } 215 $out .= "\n// end auto-generated content\n"; 216 } else if ($this->_format == 'txt') { 217 $out .= "\n# end auto-generated content\n"; 218 } 219 220 return $out; 221 } 222 223 function html() { 224 } 225 226 } 227} 228 229if (!class_exists('setting_text') && class_exists('setting0')) { 230 class setting_text extends setting0 { 231 232 /** 233 * update setting with user provided value $input 234 * if value fails error check, save it 235 * 236 * @return true if changed, false otherwise (incl. on error) 237 */ 238 function update($input) { 239 if (is_null($input)) return false; 240 if ($this->is_protected()) return false; 241 242 $value = is_null($this->_local) ? $this->_default : $this->_local; 243 if ($value == $input) return false; 244 245 if ($this->_pattern && !preg_match($this->_pattern,$input)) { 246 $this->_error = true; 247 $this->_input = $input; 248 return false; 249 } 250 251 $this->_local = $input; 252 return true; 253 } 254 255 /** 256 * @return array(string $label_html, string $input_html) 257 */ 258 function html(&$plugin, $echo=false) { 259 $value = ''; 260 $defaultstyle = ''; 261 $disable = ''; 262 263 if ($this->is_protected()) { 264 $value = $this->_protected; 265 $disable = 'disabled="disabled"'; 266 } else { 267 if ($echo && $this->_error) { 268 $value = $this->_input; 269 } else { 270 $value = is_null($this->_local) ? $this->_default : $this->_local; 271 } 272 } 273 274 if (is_null($this->_local)) $defaultstyle = 'style="font-weight:bold;"'; 275 276 $key = htmlspecialchars($this->_key); 277 $value = htmlspecialchars($value); 278 279 //$label = '<input type="checkbox" name="configbox__'.$key.'" value="1"'.$noerase.'/> <label for="config__'.$key.'">'.$key.'</label> '; 280 $label = '<label '.$defaultstyle.' for="config__'.$key.'">'.$key.'</label> '; 281 //$input = '<textarea rows="3" cols="80" id="config__'.$key.'" name="config['.$key.']" class="edit" '.$disable.'>'.$value.'</textarea>'; 282 $input = '<input id="config__'.$key.'" name="config['.$key.']" type="text" class="edit" size="80" value="'.$value.'" '.$disable.'/>'; 283 return array($label,$input); 284 } 285 286 /** 287 * generate string to save setting value to file according to $fmt 288 */ 289 function out($var='config', $fmt='txt') { 290 291 if ($this->is_protected()) return ''; 292 if (is_null($this->_local) || ($this->_default == $this->_local)) return ''; 293 294 if ($fmt=='php') { 295 // translation string needs to be improved FIXME 296 $tr = array("\n"=>'\n', "\r"=>'\r', "\t"=>'\t', "\\" => '\\\\', "'" => '\\\''); 297 $tr = array("\\" => '\\\\', "'" => '\\\''); 298 299 $out = '$'.$var."['".$this->_out_key()."'] = '".strtr($this->_local, $tr)."';\n"; 300 } else if ($fmt=='txt') { 301 //$value = is_null($this->_local) ? $this->_default : $this->_local; 302 //$out = $this->_key."\t".$value."\n"; 303 $out = $this->_key."\t".$this->_local."\n"; 304 } 305 306 return $out; 307 } 308 309 } 310} 311