We have to use viewsvn::paths::isdir() but we'll silence it
[viewsvn.git] / includes / paths.php
1 <?php
2 /*=====================================================================*\
3 || ###################################################################
4 || # ViewSVN [#]version[#]
5 || # Copyright ©2002-[#]year[#] Iris Studios, Inc.
6 || #
7 || # This program is free software; you can redistribute it and/or modify
8 || # it under the terms of the GNU General Public License as published by
9 || # the Free Software Foundation; version [#]gpl[#] of the License.
10 || #
11 || # This program is distributed in the hope that it will be useful, but
12 || # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 || # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 || # more details.
15 || #
16 || # You should have received a copy of the GNU General Public License along
17 || # with this program; if not, write to the Free Software Foundation, Inc.,
18 || # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 || ###################################################################
20 \*=====================================================================*/
21
22 /**
23 * Handles the various methods that are used to navigate
24 * browser paths
25 *
26 * @package ViewSVN
27 */
28
29 /**
30 * Path managing class that constructs and parses input
31 * and output for paths
32 *
33 * @package ViewSVN
34 * @version $Id$
35 */
36 class Paths
37 {
38 /**
39 * Path manager type
40 * @var integer
41 */
42 var $type;
43
44 /**
45 * Constructor: determine the type of linking to use
46 *
47 * @param integer Path management type
48 */
49 function Paths($type)
50 {
51 global $viewsvn;
52
53 if ($type < 1 OR $type > 2)
54 {
55 $viewsvn->trigger->error('invalid path management type');
56 }
57
58 $this->type = (int)$type;
59 }
60
61 /**
62 * Constructs a repository browser link
63 *
64 * @access public
65 *
66 * @param string Base path
67 * @param string Browser path, separated using '/'
68 *
69 * @return string Link path
70 */
71 function out($base, $addpath)
72 {
73 global $viewsvn;
74
75 $url = $this->fetch_arguments($base);
76 $addpath = $this->sanitize($addpath);
77
78 // standard URL type
79 if ($this->type == 1)
80 {
81 return $url[0] . '?path=' . $addpath . ($url[1] ? '&amp;' . $url[1] : '');
82 }
83 // advanced path system
84 else if ($this->type == 2)
85 {
86 return $url[0] . ($addpath{0} != '/' ? '/' : '') . $addpath . ($url[1] ? '?' . $url[1] : '');
87 }
88 }
89
90 /**
91 * Parses an incoming path with the various methods
92 * and returns a universal form
93 *
94 * @access public
95 *
96 * @return string Universal path, separated using '/'
97 */
98 function parse()
99 {
100 global $viewsvn;
101
102 // standard URL type
103 if ($this->type == 1)
104 {
105 $path = $viewsvn->in['path'];
106 }
107 // advanced path system
108 else if ($this->type == 2)
109 {
110 if (@$_SERVER['PATH_INFO'])
111 {
112 $path = $viewsvn->sanitize($_SERVER['PATH_INFO']);
113 }
114 else
115 {
116 $viewsvn->trigger->error('server does not support type 2 management');
117 }
118 }
119
120 if (!$path)
121 {
122 $viewsvn->trigger->error('invalid path sent');
123 }
124
125 if (!$viewsvn->repos->verify($this->fetch_repos($path), $this->fetch_path($path)))
126 {
127 $viewsvn->trigger->error('invalid path');
128 }
129
130 return $path;
131 }
132
133 /**
134 * Create path breadcrumb
135 *
136 * @access public
137 *
138 * @param string Universal path
139 * @param bool Add trailing slash
140 *
141 * @return string Breadcrumb HTML
142 */
143 function construct_breadcrumb($path, $doslash = true)
144 {
145 global $viewsvn;
146
147 $html = '/ ';
148 $itembit = '/';
149
150 $temp = preg_split('#/#', $path, -1, PREG_SPLIT_NO_EMPTY);
151 $count = count($temp) - 1;
152
153 foreach ($temp AS $val => $item)
154 {
155 $itembit .= $item;
156 $itembit .= (($count != $val OR @$viewsvn->svn->common->isdir($itembit)) ? '/' : '');
157 $html .= '<a href="' . $viewsvn->path . '/' . $this->out('browse.php' . $this->fetch_rev_str(), $itembit) . '">' . $item . '</a>'. ($count != $val ? ' / ' : '');
158 }
159
160 return $html;
161 }
162
163 /**
164 * Returns the name of the repository from a upath
165 *
166 * @access public
167 *
168 * @param string Universal path
169 *
170 * @return string Repository name
171 */
172 function fetch_repos($path)
173 {
174 $temp = preg_split('#/#', $path, -1, PREG_SPLIT_NO_EMPTY);
175 return $temp[0];
176 }
177
178 /**
179 * Returns the path without the repository from a upath
180 *
181 * @access public
182 *
183 * @param string Universal path
184 * @param bool Preceding slash
185 *
186 * @return string Relative path
187 */
188 function fetch_path($path, $doslash = false)
189 {
190 $temp = preg_split('#/#', $path, -1, PREG_SPLIT_NO_EMPTY);
191 unset($temp[0]);
192 return ($doslash ? '/' : '') . implode('/', $temp);
193 }
194
195 /**
196 * Fetches any URL parameters a link has
197 *
198 * @access public
199 *
200 * @param string Original URL
201 *
202 * @return array Two-element array: base path (no trailing '?'), arguments
203 */
204 function fetch_arguments($url)
205 {
206 $return = array();
207
208 $bits = parse_url($url);
209
210 if (isset($bits['query']))
211 {
212 $return[0] = $bits['path'];
213 $return[1] = $bits['query'];
214 }
215 else
216 {
217 $return[0] = $bits['path'];
218 $return[1] = '';
219 }
220
221 return $return;
222 }
223
224 /**
225 * Determines if the root path has been reached
226 *
227 * @access public
228 *
229 * @param string Universal path
230 *
231 * @return bool Root of path?
232 */
233 function is_root_path($path)
234 {
235 $path = $this->fetch_path($path);
236 $temp = preg_split('#/#', $path, -1, PREG_SPLIT_NO_EMPTY);
237 if (count($temp) > 0)
238 {
239 return false;
240 }
241 else
242 {
243 return true;
244 }
245 }
246
247 /**
248 * Returns the current sanitized revision
249 *
250 * @access public
251 *
252 * @param bool High-low or not
253 * @param mixed High revision (or regular)
254 * @param mixed Low revision
255 *
256 * @return mixed Revision number or HEAD
257 */
258 function fetch_rev_num($highlow = false, $high = null, $low = null)
259 {
260 global $viewsvn;
261
262 if ($highlow)
263 {
264 if (isset($viewsvn->in['high']) AND is_null($high))
265 {
266 $high = $viewsvn->svn->rev($viewsvn->in['high']);
267 }
268 else if (is_null($high))
269 {
270 $high = 'HEAD';
271 }
272
273 if (isset($viewsvn->in['low']))
274 {
275 $low = $viewsvn->svn->rev($viewsvn->in['low']);
276 }
277 else if (is_null($low))
278 {
279 $low = 0;
280 }
281
282 if ($low == 'HEAD')
283 {
284 $low = 0;
285 }
286
287 if (is_int($high) AND is_int($low) AND $low > $high)
288 {
289 $temp = $high;
290 $high = $low;
291 $low = $temp;
292 }
293
294 return array('high' => $high, 'low' => $low);
295 }
296 else
297 {
298 if (isset($viewsvn->in['rev']) AND is_null($high))
299 {
300 $rev = $viewsvn->svn->rev($viewsvn->in['rev']);
301 }
302 else if (is_null($high))
303 {
304 $rev = 'HEAD';
305 }
306 else
307 {
308 $rev = $high;
309 }
310
311 return $rev;
312 }
313 }
314
315 /**
316 * Returns a GET string with sanitized revision data
317 *
318 * @access public
319 *
320 * @param bool High-low or not
321 * @param mixed High revision (or regular)
322 * @param mixed Low revision
323 *
324 * @return string Revision GET data
325 */
326 function fetch_rev_str($highlow = false, $high = null, $low = null)
327 {
328 $rev = $this->fetch_rev_num($highlow, $high, $low);
329
330 if ($highlow)
331 {
332 return '?low=' . $rev['low'] . '&amp;high=' . $rev['high'];
333 }
334 else
335 {
336 return '?rev=' . $rev;
337 }
338 }
339
340 /**
341 * Sanitizes a path for passing
342 *
343 * @access private
344 *
345 * @param string Path
346 *
347 * @return string Cleaned string
348 */
349 function sanitize($path)
350 {
351 return preg_replace('#[^a-z0-9\./\-_]*#i', '', $path);
352 }
353 }
354
355 /*=====================================================================*\
356 || ###################################################################
357 || # $HeadURL$
358 || # $Id$
359 || ###################################################################
360 \*=====================================================================*/
361 ?>