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