1<?php 2/** 3 * Utilities for handling pagenames 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Andreas Gohr <andi@splitbrain.org> 7 * @todo Combine similar functions like {wiki,media,meta}FN() 8 */ 9 10/** 11 * Fetch the an ID from request 12 * 13 * Uses either standard $_REQUEST variable or extracts it from 14 * the full request URI when userewrite is set to 2 15 * 16 * For $param='id' $conf['start'] is returned if no id was found. 17 * If the second parameter is true (default) the ID is cleaned. 18 * 19 * @author Andreas Gohr <andi@splitbrain.org> 20 */ 21function getID($param='id',$clean=true){ 22 global $conf; 23 24 $id = $_REQUEST[$param]; 25 26 //construct page id from request URI 27 if(empty($id) && $conf['userewrite'] == 2){ 28 //get the script URL 29 if($conf['basedir']){ 30 $relpath = ''; 31 if($param != 'id') { 32 $relpath = 'lib/exe/'; 33 } 34 $script = $conf['basedir'].$relpath.basename($_SERVER['SCRIPT_FILENAME']); 35 }elseif($_SERVER['DOCUMENT_ROOT'] && $_SERVER['SCRIPT_FILENAME']){ 36 $script = preg_replace ('/^'.preg_quote($_SERVER['DOCUMENT_ROOT'],'/').'/','', 37 $_SERVER['SCRIPT_FILENAME']); 38 $script = '/'.$script; 39 }else{ 40 $script = $_SERVER['SCRIPT_NAME']; 41 } 42 43 //clean script and request (fixes a windows problem) 44 $script = preg_replace('/\/\/+/','/',$script); 45 $request = preg_replace('/\/\/+/','/',$_SERVER['REQUEST_URI']); 46 47 //remove script URL and Querystring to gain the id 48 if(preg_match('/^'.preg_quote($script,'/').'(.*)/',$request, $match)){ 49 $id = preg_replace ('/\?.*/','',$match[1]); 50 } 51 $id = urldecode($id); 52 //strip leading slashes 53 $id = preg_replace('!^/+!','',$id); 54 } 55 if($clean) $id = cleanID($id); 56 if(empty($id) && $param=='id') $id = $conf['start']; 57 58 return $id; 59} 60 61/** 62 * Remove unwanted chars from ID 63 * 64 * Cleans a given ID to only use allowed characters. Accented characters are 65 * converted to unaccented ones 66 * 67 * @author Andreas Gohr <andi@splitbrain.org> 68 */ 69function cleanID($id){ 70 global $conf; 71 global $lang; 72 static $sepcharpat = null; 73 74 $sepchar = $conf['sepchar']; 75 if($sepcharpat == null) // build string only once to save clock cycles 76 $sepcharpat = '#\\'.$sepchar.'+#'; 77 78 $id = trim($id); 79 $id = utf8_strtolower($id); 80 81 //alternative namespace seperator 82 $id = strtr($id,';',':'); 83 if($conf['useslash']){ 84 $id = strtr($id,'/',':'); 85 }else{ 86 $id = strtr($id,'/',$sepchar); 87 } 88 89 if($conf['deaccent']) $id = utf8_deaccent($id,-1); 90 91 //remove specials 92 $id = utf8_stripspecials($id,$sepchar,'\*'); 93 94 //clean up 95 $id = preg_replace($sepcharpat,$sepchar,$id); 96 $id = preg_replace('#:+#',':',$id); 97 $id = trim($id,':._-'); 98 $id = preg_replace('#:[:\._\-]+#',':',$id); 99 100 return($id); 101} 102 103/** 104 * Return namespacepart of a wiki ID 105 * 106 * @author Andreas Gohr <andi@splitbrain.org> 107 */ 108function getNS($id){ 109 if(strpos($id,':')!==false){ 110 return substr($id,0,strrpos($id,':')); 111 } 112 return false; 113} 114 115/** 116 * Returns the ID without the namespace 117 * 118 * @author Andreas Gohr <andi@splitbrain.org> 119 */ 120function noNS($id){ 121 return preg_replace('/.*:/','',$id); 122} 123 124/** 125 * returns the full path to the datafile specified by ID and 126 * optional revision 127 * 128 * The filename is URL encoded to protect Unicode chars 129 * 130 * @author Andreas Gohr <andi@splitbrain.org> 131 */ 132function wikiFN($id,$rev=''){ 133 global $conf; 134 $id = cleanID($id); 135 $id = str_replace(':','/',$id); 136 if(empty($rev)){ 137 $fn = $conf['datadir'].'/'.utf8_encodeFN($id).'.txt'; 138 }else{ 139 $fn = $conf['olddir'].'/'.utf8_encodeFN($id).'.'.$rev.'.txt'; 140 if($conf['usegzip'] && !@file_exists($fn)){ 141 //return gzip if enabled and plaintext doesn't exist 142 $fn .= '.gz'; 143 } 144 } 145 return $fn; 146} 147 148/** 149 * returns the full path to the meta file specified by ID and extension 150 * 151 * The filename is URL encoded to protect Unicode chars 152 * 153 * @author Steven Danz <steven-danz@kc.rr.com> 154 */ 155function metaFN($id,$ext){ 156 global $conf; 157 $id = cleanID($id); 158 $id = str_replace(':','/',$id); 159 $fn = $conf['metadir'].'/'.utf8_encodeFN($id).$ext; 160 return $fn; 161} 162 163/** 164 * returns an array of full paths to all metafiles of a given ID 165 * 166 * @author Esther Brunner <esther@kaffeehaus.ch> 167 */ 168function metaFiles($id){ 169 $name = noNS($id); 170 $dir = metaFN(getNS($id),''); 171 $files = array(); 172 173 $dh = @opendir($dir); 174 if(!$dh) return $files; 175 while(($file = readdir($dh)) !== false){ 176 if(strpos($file,$name.'.') === 0 && !is_dir($dir.$file)) 177 $files[] = $dir.$file; 178 } 179 closedir($dh); 180 181 return $files; 182} 183 184/** 185 * returns the full path to the mediafile specified by ID 186 * 187 * The filename is URL encoded to protect Unicode chars 188 * 189 * @author Andreas Gohr <andi@splitbrain.org> 190 */ 191function mediaFN($id){ 192 global $conf; 193 $id = cleanID($id); 194 $id = str_replace(':','/',$id); 195 $fn = $conf['mediadir'].'/'.utf8_encodeFN($id); 196 return $fn; 197} 198 199/** 200 * Returns the full filepath to a localized textfile if local 201 * version isn't found the english one is returned 202 * 203 * @author Andreas Gohr <andi@splitbrain.org> 204 */ 205function localeFN($id){ 206 global $conf; 207 $file = DOKU_INC.'inc/lang/'.$conf['lang'].'/'.$id.'.txt'; 208 if(!@file_exists($file)){ 209 //fall back to english 210 $file = DOKU_INC.'inc/lang/en/'.$id.'.txt'; 211 } 212 return $file; 213} 214 215/** 216 * Returns a full media id 217 * 218 * @author Andreas Gohr <andi@splitbrain.org> 219 */ 220function resolve_mediaid($ns,&$page,&$exists){ 221 global $conf; 222 223 //if links starts with . add current namespace 224 if($page{0} == '.'){ 225 $page = $ns.':'.substr($page,1); 226 } 227 228 //if link contains no namespace. add current namespace (if any) 229 if($ns !== false && strpos($page,':') === false){ 230 $page = $ns.':'.$page; 231 } 232 233 $page = cleanID($page); 234 $file = mediaFN($page); 235 $exists = @file_exists($file); 236} 237 238/** 239 * Returns a full page id 240 * 241 * @author Andreas Gohr <andi@splitbrain.org> 242 */ 243function resolve_pageid($ns,&$page,&$exists){ 244 global $conf; 245 $exists = false; 246 247 //if links starts with . add current namespace 248 if($page{0} == '.'){ 249 $page = $ns.':'.substr($page,1); 250 } 251 252 //if link contains no namespace. add current namespace (if any) 253 if($ns !== false && strpos($page,':') === false){ 254 $page = $ns.':'.$page; 255 } 256 257 //keep hashlink if exists then clean both parts 258 list($page,$hash) = split('#',$page,2); 259 $page = cleanID($page); 260 $hash = cleanID($hash); 261 262 $file = wikiFN($page); 263 264 //check alternative plural/nonplural form 265 if(!@file_exists($file)){ 266 if( $conf['autoplural'] ){ 267 if(substr($page,-1) == 's'){ 268 $try = substr($page,0,-1); 269 }else{ 270 $try = $page.'s'; 271 } 272 if(@file_exists(wikiFN($try))){ 273 $page = $try; 274 $exists = true; 275 } 276 } 277 }else{ 278 $exists = true; 279 } 280 281 //add hash if any 282 if(!empty($hash)) $page .= '#'.$hash; 283} 284 285/** 286 * Returns the name of a cachefile from given data 287 * 288 * The needed directory is created by this function! 289 * 290 * @author Andreas Gohr <andi@splitbrain.org> 291 * 292 * @param string $data This data is used to create a unique md5 name 293 * @param string $ext This is appended to the filename if given 294 * @return string The filename of the cachefile 295 */ 296function getCacheName($data,$ext=''){ 297 global $conf; 298 $md5 = md5($data); 299 $file = $conf['cachedir'].'/'.$md5{0}.'/'.$md5.$ext; 300 io_makeFileDir($file); 301 return $file; 302} 303 304/** 305 * Checks a pageid against $conf['hidepages'] 306 * 307 * @author Andreas Gohr <gohr@cosmocode.de> 308 */ 309function isHiddenPage($id){ 310 global $conf; 311 if(empty($conf['hidepages'])) return false; 312 313 if(preg_match('/'.$conf['hidepages'].'/ui',':'.$id)){ 314 return true; 315 } 316 return false; 317} 318 319/** 320 * Reverse of isHiddenPage 321 * 322 * @author Andreas Gohr <gohr@cosmocode.de> 323 */ 324function isVisiblePage($id){ 325 return !isHiddenPage($id); 326} 327 328//Setup VIM: ex: et ts=2 enc=utf-8 : 329