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