Getting things back on track in browse.php
[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. This is essentially a controller
32 * of all current information.
33 *
34 * @package ViewSVN
35 * @version $Id$
36 */
37 class Paths
38 {
39 /**
40 * Path manager type
41 * @var integer
42 */
43 var $type;
44
45 /**
46 * The universal path that is currently being browsed
47 * @var string
48 */
49 var $path;
50
51 /**
52 * Current repository that we're in
53 * @var string
54 */
55 var $repos;
56
57 /**
58 * Current internal path inside the repository
59 * @var string
60 */
61 var $relpath;
62
63 /**
64 * The current revision number
65 * @var integer
66 */
67 var $revnum;
68
69 /**
70 * The current revision as a string argument
71 * @var string
72 */
73 var $revstr;
74
75 /**
76 * Constructor: determine the type of linking to use
77 *
78 * @param integer Path management type
79 */
80 function Paths($type)
81 {
82 global $viewsvn;
83
84 if ($type < 1 OR $type > 2)
85 {
86 $viewsvn->trigger->error($viewsvn->lang->string('Invalid path management type specified in [includes/config.php]'));
87 }
88
89 $this->type = (int)$type;
90
91 $this->path = $this->parse();
92 $this->revnum = $this->revnum;
93 $this->revstr = $this->revstr;
94 }
95
96 /**
97 * Constructs a repository browser link
98 *
99 * @access public
100 *
101 * @param string Base path
102 * @param string Browser path, separated using '/'
103 *
104 * @return string Link path
105 */
106 function out($base, $addpath)
107 {
108 global $viewsvn;
109
110 $url = $this->fetch_arguments($base);
111 $addpath = $this->sanitize($addpath);
112
113 // standard URL type
114 if ($this->type == 1)
115 {
116 return $url[0] . '?path=' . $addpath . ($url[1] ? '&amp;' . $url[1] : '');
117 }
118 // advanced path system
119 else if ($this->type == 2)
120 {
121 return $url[0] . ($addpath{0} != '/' ? '/' : '') . $addpath . ($url[1] ? '?' . $url[1] : '');
122 }
123 }
124
125 /**
126 * Parses an incoming path with the various methods
127 * and returns a universal form
128 *
129 * @access public
130 *
131 * @return string Universal path, separated using '/'
132 */
133 function parse()
134 {
135 global $viewsvn;
136
137 if (defined('PATH_OVERRIDE') AND PATH_OVERRIDE == 1)
138 {
139 return;
140 }
141
142 // standard URL type
143 if ($this->type == 1)
144 {
145 $path = $viewsvn->in['path'];
146 }
147 // advanced path system
148 else if ($this->type == 2)
149 {
150 if (@$_SERVER['PATH_INFO'])
151 {
152 $path = $viewsvn->sanitize($_SERVER['PATH_INFO']);
153 }
154 else
155 {
156 $viewsvn->trigger->error($viewsvn->lang->string('Your server does not support type-2 path management'));
157 }
158 }
159
160 if (!$path)
161 {
162 $viewsvn->trigger->error($viewsvn->lang->string('Invalid path sent'));
163 }
164
165 if (!$viewsvn->repos->verify($this->repos = $this->fetch_repos($path), $this->relpath = $this->fetch_path($path)))
166 {
167 $viewsvn->trigger->error($viewsvn->lang->string('The path specified could not be verified'));
168 }
169
170 return $path;
171 }
172
173 /**
174 * Create path breadcrumb
175 *
176 * @access public
177 *
178 * @param string Universal path
179 * @param bool Add trailing slash
180 *
181 * @return string Breadcrumb HTML
182 */
183 function construct_breadcrumb($path, $doslash = true)
184 {
185 global $viewsvn, $cachev;
186
187 $html = '/ ';
188 $itembit = '/';
189
190 $temp = preg_split('#/#', $path, -1, PREG_SPLIT_NO_EMPTY);
191 $count = count($temp) - 1;
192
193 foreach ($temp AS $val => $item)
194 {
195 $itembit .= $item;
196 $itembit .= (($count != $val OR $cachev->isdir($itembit)) ? '/' : '');
197 $html .= '<a href="' . $viewsvn->path . '/' . $this->out('browse.php' . $this->revstr, $itembit) . '">' . $item . '</a>'. ($count != $val ? ' / ' : '');
198 }
199
200 return $html;
201 }
202
203 /**
204 * Returns the name of the repository from a upath
205 *
206 * @access public
207 *
208 * @param string Universal path
209 *
210 * @return string Repository name
211 */
212 function fetch_repos($path)
213 {
214 $temp = preg_split('#/#', $path, -1, PREG_SPLIT_NO_EMPTY);
215 return $temp[0];
216 }
217
218 /**
219 * Returns the path without the repository from a upath
220 *
221 * @access public
222 *
223 * @param string Universal path
224 * @param bool Preceding slash
225 *
226 * @return string Relative path
227 */
228 function fetch_path($path, $doslash = false)
229 {
230 $temp = preg_split('#/#', $path, -1, PREG_SPLIT_NO_EMPTY);
231 unset($temp[0]);
232 return ($doslash ? '/' : '') . implode('/', $temp);
233 }
234
235 /**
236 * Fetches any URL parameters a link has
237 *
238 * @access public
239 *
240 * @param string Original URL
241 *
242 * @return array Two-element array: base path (no trailing '?'), arguments
243 */
244 function fetch_arguments($url)
245 {
246 $return = array();
247
248 $bits = parse_url($url);
249
250 if (isset($bits['query']))
251 {
252 $return[0] = $bits['path'];
253 $return[1] = $bits['query'];
254 }
255 else
256 {
257 $return[0] = $bits['path'];
258 $return[1] = '';
259 }
260
261 return $return;
262 }
263
264 /**
265 * Determines if the root path has been reached
266 *
267 * @access public
268 *
269 * @param string Universal path
270 *
271 * @return bool Root of path?
272 */
273 function is_root_path($path)
274 {
275 $path = $this->fetch_path($path);
276 $temp = preg_split('#/#', $path, -1, PREG_SPLIT_NO_EMPTY);
277 if (count($temp) > 0)
278 {
279 return false;
280 }
281 else
282 {
283 return true;
284 }
285 }
286
287 /**
288 * Returns the current sanitized revision
289 *
290 * @access public
291 *
292 * @param bool High-low or not
293 * @param mixed High revision (or regular)
294 * @param mixed Low revision
295 *
296 * @return mixed Revision number or HEAD
297 */
298 function fetch_rev_num($highlow = false, $high = null, $low = null)
299 {
300 global $viewsvn;
301
302 if ($highlow)
303 {
304 if (isset($viewsvn->in['high']) AND is_null($high))
305 {
306 $high = $viewsvn->svn->rev($viewsvn->in['high']);
307 }
308 else if (is_null($high))
309 {
310 $high = 'HEAD';
311 }
312
313 if (isset($viewsvn->in['low']) AND is_null($low))
314 {
315 $low = $viewsvn->svn->rev($viewsvn->in['low']);
316 }
317 else if (is_null($low))
318 {
319 $low = 0;
320 }
321
322 if ($low == 'HEAD')
323 {
324 $low = 0;
325 }
326
327 if (is_int($high) AND is_int($low) AND $low > $high)
328 {
329 $temp = $high;
330 $high = $low;
331 $low = $temp;
332 }
333
334 return array('high' => $high, 'low' => $low);
335 }
336 else
337 {
338 if (isset($viewsvn->in['rev']) AND is_null($high))
339 {
340 $rev = $viewsvn->svn->rev($viewsvn->in['rev']);
341 }
342 else if (is_null($high))
343 {
344 $rev = 'HEAD';
345 }
346 else
347 {
348 $rev = $high;
349 }
350
351 return $rev;
352 }
353 }
354
355 /**
356 * Returns a GET string with sanitized revision data
357 *
358 * @access public
359 *
360 * @param bool High-low or not
361 * @param mixed High revision (or regular)
362 * @param mixed Low revision
363 *
364 * @return string Revision GET data
365 */
366 function fetch_rev_str($highlow = false, $high = null, $low = null)
367 {
368 $rev = $this->fetch_rev_num($highlow, $high, $low);
369
370 if ($highlow)
371 {
372 return '?low=' . $rev['low'] . '&amp;high=' . $rev['high'];
373 }
374 else
375 {
376 return '?rev=' . $rev;
377 }
378 }
379
380 /**
381 * Sanitizes a path for passing
382 *
383 * @access private
384 *
385 * @param string Path
386 *
387 * @return string Cleaned string
388 */
389 function sanitize($path)
390 {
391 return preg_replace('#[^a-z0-9\./\-_]*#i', '', $path);
392 }
393 }
394
395 /*=====================================================================*\
396 || ###################################################################
397 || # $HeadURL$
398 || # $Id$
399 || ###################################################################
400 \*=====================================================================*/
401 ?>