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