xref: /dokuwiki/inc/pageutils.php (revision 7367b36877bca568d785e01be802652b6a719884)
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 the full path to the mediafile specified by ID
156 *
157 * The filename is URL encoded to protect Unicode chars
158 *
159 * @author Andreas Gohr <andi@splitbrain.org>
160 */
161function mediaFN($id){
162  global $conf;
163  $id = cleanID($id);
164  $id = str_replace(':','/',$id);
165    $fn = $conf['mediadir'].'/'.utf8_encodeFN($id);
166  return $fn;
167}
168
169/**
170 * Returns the full filepath to a localized textfile if local
171 * version isn't found the english one is returned
172 *
173 * @author Andreas Gohr <andi@splitbrain.org>
174 */
175function localeFN($id){
176  global $conf;
177  $file = DOKU_INC.'inc/lang/'.$conf['lang'].'/'.$id.'.txt';
178  if(!@file_exists($file)){
179    //fall back to english
180    $file = DOKU_INC.'inc/lang/en/'.$id.'.txt';
181  }
182  return $file;
183}
184
185/**
186 * Returns a full media id
187 *
188 * @author Andreas Gohr <andi@splitbrain.org>
189 */
190function resolve_mediaid($ns,&$page,&$exists){
191  global $conf;
192
193  //if links starts with . add current namespace
194  if($page{0} == '.'){
195    $page = $ns.':'.substr($page,1);
196  }
197
198  //if link contains no namespace. add current namespace (if any)
199  if($ns !== false && strpos($page,':') === false){
200    $page = $ns.':'.$page;
201  }
202
203  $page   = cleanID($page);
204  $file   = mediaFN($page);
205  $exists = @file_exists($file);
206}
207
208/**
209 * Returns a full page id
210 *
211 * @author Andreas Gohr <andi@splitbrain.org>
212 */
213function resolve_pageid($ns,&$page,&$exists){
214  global $conf;
215  $exists = false;
216
217  //if links starts with . add current namespace
218  if($page{0} == '.'){
219    $page = $ns.':'.substr($page,1);
220  }
221
222  //if link contains no namespace. add current namespace (if any)
223  if($ns !== false && strpos($page,':') === false){
224    $page = $ns.':'.$page;
225  }
226
227  //keep hashlink if exists then clean both parts
228  list($page,$hash) = split('#',$page,2);
229  $page = cleanID($page);
230  $hash = cleanID($hash);
231
232  $file = wikiFN($page);
233
234  //check alternative plural/nonplural form
235  if(!@file_exists($file)){
236    if( $conf['autoplural'] ){
237      if(substr($page,-1) == 's'){
238        $try = substr($page,0,-1);
239      }else{
240        $try = $page.'s';
241      }
242      if(@file_exists(wikiFN($try))){
243        $page   = $try;
244        $exists = true;
245      }
246    }
247  }else{
248    $exists = true;
249  }
250
251  //add hash if any
252  if(!empty($hash)) $page .= '#'.$hash;
253}
254
255/**
256 * Returns the name of a cachefile from given data
257 *
258 * The needed directory is created by this function!
259 *
260 * @author Andreas Gohr <andi@splitbrain.org>
261 *
262 * @param string $data  This data is used to create a unique md5 name
263 * @param string $ext   This is appended to the filename if given
264 * @return string       The filename of the cachefile
265 */
266function getCacheName($data,$ext=''){
267  global $conf;
268  $md5  = md5($data);
269  $file = $conf['cachedir'].'/'.$md5{0}.'/'.$md5.$ext;
270  io_makeFileDir($file);
271  return $file;
272}
273
274//Setup VIM: ex: et ts=2 enc=utf-8 :
275