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