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