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