1<?php 2/** 3 * Utilities for collecting data from config files 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Harry Fuecks <hfuecks@gmail.com> 7 */ 8 9/* 10 * line prefix used to negate single value config items 11 * (scheme.conf & stopwords.conf), e.g. 12 * !gopher 13 */ 14const DOKU_CONF_NEGATION = '!'; 15 16/** 17 * Returns the (known) extension and mimetype of a given filename 18 * 19 * If $knownonly is true (the default), then only known extensions 20 * are returned. 21 * 22 * @author Andreas Gohr <andi@splitbrain.org> 23 * 24 * @param string $file file name 25 * @param bool $knownonly 26 * @return array with extension, mimetype and if it should be downloaded 27 */ 28function mimetype($file, $knownonly=true){ 29 $mtypes = getMimeTypes(); // known mimetypes 30 $ext = strrpos($file, '.'); 31 if ($ext === false) { 32 return array(false, false, false); 33 } 34 $ext = strtolower(substr($file, $ext + 1)); 35 if (!isset($mtypes[$ext])){ 36 if ($knownonly) { 37 return array(false, false, false); 38 } else { 39 return array($ext, 'application/octet-stream', true); 40 } 41 } 42 if($mtypes[$ext][0] == '!'){ 43 return array($ext, substr($mtypes[$ext],1), true); 44 }else{ 45 return array($ext, $mtypes[$ext], false); 46 } 47} 48 49/** 50 * returns a hash of mimetypes 51 * 52 * @author Andreas Gohr <andi@splitbrain.org> 53 */ 54function getMimeTypes() { 55 static $mime = null; 56 if ( !$mime ) { 57 $mime = retrieveConfig('mime','confToHash'); 58 $mime = array_filter($mime); 59 } 60 return $mime; 61} 62 63/** 64 * returns a hash of acronyms 65 * 66 * @author Harry Fuecks <hfuecks@gmail.com> 67 */ 68function getAcronyms() { 69 static $acronyms = null; 70 if ( !$acronyms ) { 71 $acronyms = retrieveConfig('acronyms','confToHash'); 72 $acronyms = array_filter($acronyms, 'strlen'); 73 } 74 return $acronyms; 75} 76 77/** 78 * returns a hash of smileys 79 * 80 * @author Harry Fuecks <hfuecks@gmail.com> 81 */ 82function getSmileys() { 83 static $smileys = null; 84 if ( !$smileys ) { 85 $smileys = retrieveConfig('smileys','confToHash'); 86 $smileys = array_filter($smileys, 'strlen'); 87 } 88 return $smileys; 89} 90 91/** 92 * returns a hash of entities 93 * 94 * @author Harry Fuecks <hfuecks@gmail.com> 95 */ 96function getEntities() { 97 static $entities = null; 98 if ( !$entities ) { 99 $entities = retrieveConfig('entities','confToHash'); 100 $entities = array_filter($entities, 'strlen'); 101 } 102 return $entities; 103} 104 105/** 106 * returns a hash of interwikilinks 107 * 108 * @author Harry Fuecks <hfuecks@gmail.com> 109 */ 110function getInterwiki() { 111 static $wikis = null; 112 if ( !$wikis ) { 113 $wikis = retrieveConfig('interwiki','confToHash',array(true)); 114 $wikis = array_filter($wikis, 'strlen'); 115 116 //add sepecial case 'this' 117 $wikis['this'] = DOKU_URL.'{NAME}'; 118 } 119 return $wikis; 120} 121 122/** 123 * returns array of wordblock patterns 124 * 125 */ 126function getWordblocks() { 127 static $wordblocks = null; 128 if ( !$wordblocks ) { 129 $wordblocks = retrieveConfig('wordblock','file',null,'array_merge_with_removal'); 130 } 131 return $wordblocks; 132} 133 134/** 135 * Gets the list of configured schemes 136 * 137 * @return array the schemes 138 */ 139function getSchemes() { 140 static $schemes = null; 141 if ( !$schemes ) { 142 $schemes = retrieveConfig('scheme','file',null,'array_merge_with_removal'); 143 $schemes = array_map('trim', $schemes); 144 $schemes = preg_replace('/^#.*/', '', $schemes); 145 $schemes = array_filter($schemes); 146 } 147 return $schemes; 148} 149 150/** 151 * Builds a hash from an array of lines 152 * 153 * If $lower is set to true all hash keys are converted to 154 * lower case. 155 * 156 * @author Harry Fuecks <hfuecks@gmail.com> 157 * @author Andreas Gohr <andi@splitbrain.org> 158 * @author Gina Haeussge <gina@foosel.net> 159 */ 160function linesToHash($lines, $lower=false) { 161 $conf = array(); 162 // remove BOM 163 if (isset($lines[0]) && substr($lines[0],0,3) == pack('CCC',0xef,0xbb,0xbf)) 164 $lines[0] = substr($lines[0],3); 165 foreach ( $lines as $line ) { 166 //ignore comments (except escaped ones) 167 $line = preg_replace('/(?<![&\\\\])#.*$/','',$line); 168 $line = str_replace('\\#','#',$line); 169 $line = trim($line); 170 if(empty($line)) continue; 171 $line = preg_split('/\s+/',$line,2); 172 // Build the associative array 173 if($lower){ 174 $conf[strtolower($line[0])] = $line[1]; 175 }else{ 176 $conf[$line[0]] = $line[1]; 177 } 178 } 179 180 return $conf; 181} 182 183/** 184 * Builds a hash from a configfile 185 * 186 * If $lower is set to true all hash keys are converted to 187 * lower case. 188 * 189 * @author Harry Fuecks <hfuecks@gmail.com> 190 * @author Andreas Gohr <andi@splitbrain.org> 191 * @author Gina Haeussge <gina@foosel.net> 192 */ 193function confToHash($file,$lower=false) { 194 $conf = array(); 195 $lines = @file( $file ); 196 if ( !$lines ) return $conf; 197 198 return linesToHash($lines, $lower); 199} 200 201/** 202 * Retrieve the requested configuration information 203 * 204 * @author Chris Smith <chris@jalakai.co.uk> 205 * 206 * @param string $type the configuration settings to be read, must correspond to a key/array in $config_cascade 207 * @param callback $fn the function used to process the configuration file into an array 208 * @param array $params optional additional params to pass to the callback 209 * @return array configuration values 210 */ 211function retrieveConfig($type,$fn,$params=null,$combine='array_merge') { 212 global $config_cascade; 213 214 if(!is_array($params)) $params = array(); 215 216 $combined = array(); 217 if (!is_array($config_cascade[$type])) trigger_error('Missing config cascade for "'.$type.'"',E_USER_WARNING); 218 foreach (array('default','local','protected') as $config_group) { 219 if (empty($config_cascade[$type][$config_group])) continue; 220 foreach ($config_cascade[$type][$config_group] as $file) { 221 if (file_exists($file)) { 222 $config = call_user_func_array($fn,array_merge(array($file),$params)); 223 $combined = $combine($combined, $config); 224 } 225 } 226 } 227 228 return $combined; 229} 230 231/** 232 * Include the requested configuration information 233 * 234 * @author Chris Smith <chris@jalakai.co.uk> 235 * 236 * @param string $type the configuration settings to be read, must correspond to a key/array in $config_cascade 237 * @return array list of files, default before local before protected 238 */ 239function getConfigFiles($type) { 240 global $config_cascade; 241 $files = array(); 242 243 if (!is_array($config_cascade[$type])) trigger_error('Missing config cascade for "'.$type.'"',E_USER_WARNING); 244 foreach (array('default','local','protected') as $config_group) { 245 if (empty($config_cascade[$type][$config_group])) continue; 246 $files = array_merge($files, $config_cascade[$type][$config_group]); 247 } 248 249 return $files; 250} 251 252/** 253 * check if the given action was disabled in config 254 * 255 * @author Andreas Gohr <andi@splitbrain.org> 256 * @param string $action 257 * @returns boolean true if enabled, false if disabled 258 */ 259function actionOK($action){ 260 static $disabled = null; 261 if(is_null($disabled) || defined('SIMPLE_TEST')){ 262 global $conf; 263 /** @var DokuWiki_Auth_Plugin $auth */ 264 global $auth; 265 266 // prepare disabled actions array and handle legacy options 267 $disabled = explode(',',$conf['disableactions']); 268 $disabled = array_map('trim',$disabled); 269 if((isset($conf['openregister']) && !$conf['openregister']) || is_null($auth) || !$auth->canDo('addUser')) { 270 $disabled[] = 'register'; 271 } 272 if((isset($conf['resendpasswd']) && !$conf['resendpasswd']) || is_null($auth) || !$auth->canDo('modPass')) { 273 $disabled[] = 'resendpwd'; 274 } 275 if((isset($conf['subscribers']) && !$conf['subscribers']) || is_null($auth)) { 276 $disabled[] = 'subscribe'; 277 } 278 if (is_null($auth) || !$auth->canDo('Profile')) { 279 $disabled[] = 'profile'; 280 } 281 if (is_null($auth) || !$auth->canDo('delUser')) { 282 $disabled[] = 'profile_delete'; 283 } 284 if (is_null($auth)) { 285 $disabled[] = 'login'; 286 } 287 if (is_null($auth) || !$auth->canDo('logout')) { 288 $disabled[] = 'logout'; 289 } 290 $disabled = array_unique($disabled); 291 } 292 293 return !in_array($action,$disabled); 294} 295 296/** 297 * check if headings should be used as link text for the specified link type 298 * 299 * @author Chris Smith <chris@jalakai.co.uk> 300 * 301 * @param string $linktype 'content'|'navigation', content applies to links in wiki text 302 * navigation applies to all other links 303 * @return boolean true if headings should be used for $linktype, false otherwise 304 */ 305function useHeading($linktype) { 306 static $useHeading = null; 307 308 if (is_null($useHeading)) { 309 global $conf; 310 311 if (!empty($conf['useheading'])) { 312 switch ($conf['useheading']) { 313 case 'content': 314 $useHeading['content'] = true; 315 break; 316 317 case 'navigation': 318 $useHeading['navigation'] = true; 319 break; 320 default: 321 $useHeading['content'] = true; 322 $useHeading['navigation'] = true; 323 } 324 } else { 325 $useHeading = array(); 326 } 327 } 328 329 return (!empty($useHeading[$linktype])); 330} 331 332/** 333 * obscure config data so information isn't plain text 334 * 335 * @param string $str data to be encoded 336 * @param string $code encoding method, values: plain, base64, uuencode. 337 * @return string the encoded value 338 */ 339function conf_encodeString($str,$code) { 340 switch ($code) { 341 case 'base64' : return '<b>'.base64_encode($str); 342 case 'uuencode' : return '<u>'.convert_uuencode($str); 343 case 'plain': 344 default: 345 return $str; 346 } 347} 348/** 349 * return obscured data as plain text 350 * 351 * @param string $str encoded data 352 * @return string plain text 353 */ 354function conf_decodeString($str) { 355 switch (substr($str,0,3)) { 356 case '<b>' : return base64_decode(substr($str,3)); 357 case '<u>' : return convert_uudecode(substr($str,3)); 358 default: // not encode (or unknown) 359 return $str; 360 } 361} 362 363/** 364 * array combination function to remove negated values (prefixed by !) 365 * 366 * @param array $current 367 * @param array $new 368 * 369 * @return array the combined array, numeric keys reset 370 */ 371function array_merge_with_removal($current, $new) { 372 foreach ($new as $val) { 373 if (substr($val,0,1) == DOKU_CONF_NEGATION) { 374 $idx = array_search(trim(substr($val,1)),$current); 375 if ($idx !== false) { 376 unset($current[$idx]); 377 } 378 } else { 379 $current[] = trim($val); 380 } 381 } 382 383 return array_slice($current,0); 384} 385//Setup VIM: ex: et ts=4 : 386