Verzeichnisstruktur phpBB-3.2.0
- Veröffentlicht
- 06.01.2017
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
path_helper.php
001 <?php
002 /**
003 *
004 * This file is part of the phpBB Forum Software package.
005 *
006 * @copyright (c) phpBB Limited <https://www.phpbb.com>
007 * @license GNU General Public License, version 2 (GPL-2.0)
008 *
009 * For full copyright and license information, please see
010 * the docs/CREDITS.txt file.
011 *
012 */
013
014 namespace phpbb;
015
016 /**
017 * A class with various functions that are related to paths, files and the filesystem
018 */
019 class path_helper
020 {
021 /** @var \phpbb\symfony_request */
022 protected $symfony_request;
023
024 /** @var \phpbb\filesystem\filesystem_interface */
025 protected $filesystem;
026
027 /** @var \phpbb\request\request_interface */
028 protected $request;
029
030 /** @var string */
031 protected $phpbb_root_path;
032
033 /** @var string */
034 protected $adm_relative_path;
035
036 /** @var string */
037 protected $php_ext;
038
039 /** @var string */
040 protected $web_root_path;
041
042 /**
043 * Constructor
044 *
045 * @param \phpbb\symfony_request $symfony_request
046 * @param \phpbb\filesystem\filesystem_interface $filesystem
047 * @param \phpbb\request\request_interface $request
048 * @param string $phpbb_root_path Relative path to phpBB root
049 * @param string $php_ext PHP file extension
050 * @param mixed $adm_relative_path Relative path admin path to adm/ root
051 */
052 public function __construct(\phpbb\symfony_request $symfony_request, \phpbb\filesystem\filesystem_interface $filesystem, \phpbb\request\request_interface $request, $phpbb_root_path, $php_ext, $adm_relative_path = null)
053 {
054 $this->symfony_request = $symfony_request;
055 $this->filesystem = $filesystem;
056 $this->request = $request;
057 $this->phpbb_root_path = $phpbb_root_path;
058 $this->php_ext = $php_ext;
059 $this->adm_relative_path = $adm_relative_path;
060 }
061
062 /**
063 * Get the phpBB root path
064 *
065 * @return string
066 */
067 public function get_phpbb_root_path()
068 {
069 return $this->phpbb_root_path;
070 }
071
072 /**
073 * Get the adm root path
074 *
075 * @return string
076 */
077 public function get_adm_relative_path()
078 {
079 return $this->adm_relative_path;
080 }
081
082 /**
083 * Get the php extension
084 *
085 * @return string
086 */
087 public function get_php_ext()
088 {
089 return $this->php_ext;
090 }
091
092 /**
093 * Update a web path to the correct relative root path
094 *
095 * This replaces $phpbb_root_path . some_url with
096 * get_web_root_path() . some_url
097 *
098 * @param string $path The path to be updated
099 * @return string
100 */
101 public function update_web_root_path($path)
102 {
103 $web_root_path = $this->get_web_root_path();
104
105 // Removes the web root path if it is already present
106 if (strpos($path, $web_root_path) === 0)
107 {
108 $path = $this->phpbb_root_path . substr($path, strlen($web_root_path));
109 }
110
111 if (strpos($path, $this->phpbb_root_path) === 0)
112 {
113 $path = substr($path, strlen($this->phpbb_root_path));
114
115 if (substr($web_root_path, -8) === 'app.php/' && substr($path, 0, 7) === 'app.php')
116 {
117 $path = substr($path, 8);
118 }
119
120 return $this->filesystem->clean_path($web_root_path . $path);
121 }
122
123 return $path;
124 }
125
126 /**
127 * Strips away the web root path and prepends the normal root path
128 *
129 * This replaces get_web_root_path() . some_url with
130 * $phpbb_root_path . some_url
131 *
132 * @param string $path The path to be updated
133 * @return string
134 */
135 public function remove_web_root_path($path)
136 {
137 if (strpos($path, $this->get_web_root_path()) === 0)
138 {
139 $path = substr($path, strlen($this->get_web_root_path()));
140
141 return $this->phpbb_root_path . $path;
142 }
143
144 return $path;
145 }
146
147 /**
148 * Get a relative root path from the current URL
149 *
150 * @return string
151 */
152 public function get_web_root_path()
153 {
154 if ($this->symfony_request === null)
155 {
156 return $this->phpbb_root_path;
157 }
158
159 if (null !== $this->web_root_path)
160 {
161 return $this->web_root_path;
162 }
163
164 // We do not need to escape $path_info, $request_uri and $script_name because we can not find their content in the result.
165 // Path info (e.g. /foo/bar)
166 $path_info = $this->filesystem->clean_path($this->symfony_request->getPathInfo());
167
168 // Full request URI (e.g. phpBB/app.php/foo/bar)
169 $request_uri = $this->symfony_request->getRequestUri();
170
171 // Script name URI (e.g. phpBB/app.php)
172 $script_name = $this->symfony_request->getScriptName();
173
174 /*
175 * If the path info is empty but we're using app.php, then we
176 * might be using an empty route like app.php/ which is
177 * supported by symfony's routing
178 */
179 if ($path_info === '/' && preg_match('/app\.' . $this->php_ext . '\/$/', $request_uri))
180 {
181 return $this->web_root_path = $this->filesystem->clean_path('./../' . $this->phpbb_root_path);
182 }
183
184 /*
185 * If the path info is empty (single /), then we're not using
186 * a route like app.php/foo/bar
187 */
188 if ($path_info === '/')
189 {
190 return $this->web_root_path = $this->phpbb_root_path;
191 }
192
193 /*
194 * Check AJAX request:
195 * If the current request is a AJAX we need to fix the paths.
196 * We need to get the root path based on the Referer, so we can use
197 * the generated URLs in the template of the Referer. If we do not
198 * generate the relative path based on the Referer, but based on the
199 * currently requested URL, the generated URLs will not point to the
200 * intended locations:
201 * Referer desired URL desired relative root path
202 * memberlist.php faq.php ./
203 * memberlist.php app.php/foo/bar ./
204 * app.php/foo memberlist.php ../
205 * app.php/foo app.php/fox ../
206 * app.php/foo/bar memberlist.php ../../
207 * ../page.php memberlist.php ./phpBB/
208 * ../sub/page.php memberlist.php ./../phpBB/
209 *
210 * The referer must be specified as a parameter in the query.
211 */
212 if ($this->request->is_ajax() && $this->symfony_request->get('_referer'))
213 {
214 // We need to escape $absolute_board_url because it can be partially concatenated to the result.
215 $absolute_board_url = $this->request->escape($this->symfony_request->getSchemeAndHttpHost() . $this->symfony_request->getBasePath(), true);
216
217 $referer_web_root_path = $this->get_web_root_path_from_ajax_referer(
218 $this->symfony_request->get('_referer'),
219 $absolute_board_url
220 );
221 return $this->web_root_path = $this->phpbb_root_path . $referer_web_root_path;
222 }
223
224 // How many corrections might we need?
225 $corrections = substr_count($path_info, '/');
226
227 /*
228 * If the script name (e.g. phpBB/app.php) does not exists in the
229 * requestUri (e.g. phpBB/app.php/foo/template), then we are rewriting
230 * the URL. So we must reduce the slash count by 1.
231 */
232 if (strpos($request_uri, $script_name) !== 0)
233 {
234 $corrections--;
235 }
236
237 // Prepend ../ to the phpbb_root_path as many times as / exists in path_info
238 $this->web_root_path = $this->filesystem->clean_path(
239 './' . str_repeat('../', $corrections) . $this->phpbb_root_path
240 );
241 return $this->web_root_path;
242 }
243
244 /**
245 * Get the web root path of the referer form an ajax request
246 *
247 * @param string $absolute_referer_url
248 * @param string $absolute_board_url
249 * @return string
250 */
251 public function get_web_root_path_from_ajax_referer($absolute_referer_url, $absolute_board_url)
252 {
253 // If the board URL is in the beginning of the referer, this means
254 // we the referer is in the board URL or a subdirectory of it.
255 // So we just need to count the / (slashes) in the left over part of
256 // the referer and prepend ../ the the current root_path, to get the
257 // web root path of the referer.
258 if (strpos($absolute_referer_url, $absolute_board_url) === 0)
259 {
260 $relative_referer_path = substr($absolute_referer_url, strlen($absolute_board_url));
261 $has_params = strpos($relative_referer_path, '?');
262 if ($has_params !== false)
263 {
264 $relative_referer_path = substr($relative_referer_path, 0, $has_params);
265 }
266 $corrections = substr_count($relative_referer_path, '/');
267 return $this->phpbb_root_path . str_repeat('../', $corrections - 1);
268 }
269
270 // If not, it's a bit more complicated. We go to the parent directory
271 // of the referer until we find the remaining referer in the board URL.
272 // Foreach directory we need to add a ../ to the fixed root_path.
273 // When we finally found it, we need to remove the remaining referer
274 // from the board URL, to get the boards root path.
275 // If the then append these two strings, we get our fixed web root path.
276 $fixed_root_path = '';
277 $referer_dir = $absolute_referer_url;
278 $has_params = strpos($referer_dir, '?');
279 if ($has_params !== false)
280 {
281 $referer_dir = substr($referer_dir, 0, $has_params);
282 }
283
284 // If we do not find a slash at the end of the referer, we come
285 // from a file. So the first dirname() does not need a traversal
286 // path correction.
287 if (substr($referer_dir, -1) !== '/')
288 {
289 $referer_dir = dirname($referer_dir);
290 }
291
292 while (($dir_position = strpos($absolute_board_url, $referer_dir)) !== 0)
293 {
294 $fixed_root_path .= '../';
295 $referer_dir = dirname($referer_dir);
296
297 // Just return phpbb_root_path if we reach the top directory
298 if ($referer_dir === '.')
299 {
300 return $this->phpbb_root_path;
301 }
302 }
303
304 $fixed_root_path .= substr($absolute_board_url, strlen($referer_dir) + 1);
305 // Add trailing slash
306 return $this->phpbb_root_path . $fixed_root_path . '/';
307 }
308
309 /**
310 * Eliminates useless . and .. components from specified URL
311 *
312 * @param string $url URL to clean
313 *
314 * @return string Cleaned URL
315 */
316 public function clean_url($url)
317 {
318 $delimiter_position = strpos($url, '://');
319 // URL should contain :// but it shouldn't start with it.
320 // Do not clean URLs that do not fit these constraints.
321 if (empty($delimiter_position))
322 {
323 return $url;
324 }
325 $scheme = substr($url, 0, $delimiter_position) . '://';
326 // Add length of URL delimiter to position
327 $path = substr($url, $delimiter_position + 3);
328
329 return $scheme . $this->filesystem->clean_path($path);
330 }
331
332 /**
333 * Glue URL parameters together
334 *
335 * @param array $params URL parameters in the form of array(name => value)
336 * @return string Returns the glued string, e.g. name1=value1&name2&name3=value3
337 */
338 public function glue_url_params($params)
339 {
340 $_params = array();
341
342 foreach ($params as $key => $value)
343 {
344 // some parameters do not have value
345 if ($value !== null)
346 {
347 $_params[] = $key . '=' . $value;
348 }
349 else
350 {
351 $_params[] = $key;
352 }
353 }
354 return implode('&', $_params);
355 }
356
357 /**
358 * Get the base and parameters of a URL
359 *
360 * @param string $url URL to break apart
361 * @param bool $is_amp Is the parameter separator &. Defaults to true.
362 * @return array Returns the base and parameters in the form of array('base' => string, 'params' => array(name => value))
363 */
364 public function get_url_parts($url, $is_amp = true)
365 {
366 $separator = ($is_amp) ? '&' : '&';
367 $params = array();
368
369 if (strpos($url, '?') !== false)
370 {
371 $base = substr($url, 0, strpos($url, '?'));
372 $args = substr($url, strlen($base) + 1);
373 $args = ($args) ? explode($separator, $args) : array();
374
375 foreach ($args as $argument)
376 {
377 if (empty($argument))
378 {
379 continue;
380 }
381
382 // some parameters don't have value
383 if (strpos($argument, '=') !== false)
384 {
385 list($key, $value) = explode('=', $argument, 2);
386 }
387 else
388 {
389 $key = $argument;
390 $value = null;
391 }
392
393 if ($key === '')
394 {
395 continue;
396 }
397
398 $params[$key] = $value;
399 }
400 }
401 else
402 {
403 $base = $url;
404 }
405
406 return array(
407 'base' => $base,
408 'params' => $params,
409 );
410 }
411
412 /**
413 * Strip parameters from an already built URL.
414 *
415 * @param string $url URL to strip parameters from
416 * @param array|string $strip Parameters to strip.
417 * @param bool $is_amp Is the parameter separator &. Defaults to true.
418 * @return string Returns the new URL.
419 */
420 public function strip_url_params($url, $strip, $is_amp = true)
421 {
422 $url_parts = $this->get_url_parts($url, $is_amp);
423 $params = $url_parts['params'];
424
425 if (!is_array($strip))
426 {
427 $strip = array($strip);
428 }
429
430 if (!empty($params))
431 {
432 // Strip the parameters off
433 foreach ($strip as $param)
434 {
435 unset($params[$param]);
436 }
437 }
438
439 return $url_parts['base'] . (($params) ? '?' . $this->glue_url_params($params) : '');
440 }
441
442 /**
443 * Append parameters to an already built URL.
444 *
445 * @param string $url URL to append parameters to
446 * @param array $new_params Parameters to add in the form of array(name => value)
447 * @param bool $is_amp Is the parameter separator &. Defaults to true.
448 * @return string Returns the new URL.
449 */
450 public function append_url_params($url, $new_params, $is_amp = true)
451 {
452 $url_parts = $this->get_url_parts($url, $is_amp);
453 $params = array_merge($url_parts['params'], $new_params);
454
455 // Move the sid to the end if it's set
456 if (isset($params['sid']))
457 {
458 $sid = $params['sid'];
459 unset($params['sid']);
460 $params['sid'] = $sid;
461 }
462
463 return $url_parts['base'] . (($params) ? '?' . $this->glue_url_params($params) : '');
464 }
465
466 /**
467 * Get a valid page
468 *
469 * @param string $page The page to verify
470 * @param bool $mod_rewrite Whether mod_rewrite is enabled, default: false
471 *
472 * @return string A valid page based on given page and mod_rewrite
473 */
474 public function get_valid_page($page, $mod_rewrite = false)
475 {
476 // We need to be cautious here.
477 // On some situations, the redirect path is an absolute URL, sometimes a relative path
478 // For a relative path, let's prefix it with $phpbb_root_path to point to the correct location,
479 // else we use the URL directly.
480 $url_parts = parse_url($page);
481
482 // URL
483 if ($url_parts === false || empty($url_parts['scheme']) || empty($url_parts['host']))
484 {
485 // Remove 'app.php/' from the page, when rewrite is enabled.
486 // Treat app.php as a reserved file name and remove on mod rewrite
487 // even if it might not be in the phpBB root.
488 if ($mod_rewrite && ($app_position = strpos($page, 'app.' . $this->php_ext . '/')) !== false)
489 {
490 $page = substr($page, 0, $app_position) . substr($page, $app_position + strlen('app.' . $this->php_ext . '/'));
491 }
492
493 // Remove preceding slashes from page name and prepend root path
494 $page = $this->get_phpbb_root_path() . ltrim($page, '/\\');
495 }
496
497 return $page;
498 }
499 }
500