[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * This file is part of the phpBB Forum Software package. 5 * 6 * @copyright (c) phpBB Limited <https://www.phpbb.com> 7 * @license GNU General Public License, version 2 (GPL-2.0) 8 * 9 * For full copyright and license information, please see 10 * the docs/CREDITS.txt file. 11 * 12 */ 13 14 namespace phpbb; 15 16 /** 17 * A class with various functions that are related to paths, files and the filesystem 18 */ 19 class path_helper 20 { 21 /** @var \phpbb\symfony_request */ 22 protected $symfony_request; 23 24 /** @var \phpbb\filesystem\filesystem_interface */ 25 protected $filesystem; 26 27 /** @var \phpbb\request\request_interface */ 28 protected $request; 29 30 /** @var string */ 31 protected $phpbb_root_path; 32 33 /** @var string */ 34 protected $adm_relative_path; 35 36 /** @var string */ 37 protected $php_ext; 38 39 /** @var string */ 40 protected $web_root_path; 41 42 /** @var bool Flag whether we're in adm path */ 43 protected $in_adm_path = false; 44 45 /** 46 * Constructor 47 * 48 * @param \phpbb\symfony_request $symfony_request 49 * @param \phpbb\filesystem\filesystem_interface $filesystem 50 * @param \phpbb\request\request_interface $request 51 * @param string $phpbb_root_path Relative path to phpBB root 52 * @param string $php_ext PHP file extension 53 * @param mixed $adm_relative_path Relative path admin path to adm/ root 54 */ 55 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) 56 { 57 $this->symfony_request = $symfony_request; 58 $this->filesystem = $filesystem; 59 $this->request = $request; 60 $this->phpbb_root_path = $phpbb_root_path; 61 $this->php_ext = $php_ext; 62 $this->adm_relative_path = $adm_relative_path; 63 } 64 65 /** 66 * Get the phpBB root path 67 * 68 * @return string 69 */ 70 public function get_phpbb_root_path() 71 { 72 return $this->phpbb_root_path; 73 } 74 75 /** 76 * Get the adm root path 77 * 78 * @return string 79 */ 80 public function get_adm_relative_path() 81 { 82 return $this->adm_relative_path; 83 } 84 85 /** 86 * Get the php extension 87 * 88 * @return string 89 */ 90 public function get_php_ext() 91 { 92 return $this->php_ext; 93 } 94 95 /** 96 * Update a web path to the correct relative root path 97 * 98 * This replaces $phpbb_root_path . some_url with 99 * get_web_root_path() . some_url 100 * 101 * @param string $path The path to be updated 102 * @return string 103 */ 104 public function update_web_root_path($path) 105 { 106 $web_root_path = $this->get_web_root_path(); 107 108 // Removes the web root path if it is already present 109 if (strpos($path, $web_root_path) === 0) 110 { 111 $path = $this->phpbb_root_path . substr($path, strlen($web_root_path)); 112 } 113 114 if (strpos($path, $this->phpbb_root_path) === 0) 115 { 116 $path = substr($path, strlen($this->phpbb_root_path)); 117 118 if (substr($web_root_path, -8) === 'app.php/' && substr($path, 0, 7) === 'app.php') 119 { 120 $path = substr($path, 8); 121 } 122 123 $path = $this->filesystem->clean_path($web_root_path . $path); 124 125 // Further clean path if we're in adm 126 if ($this->in_adm_path && strpos($path, $this->phpbb_root_path . $this->adm_relative_path) === 0) 127 { 128 $path = substr($path, strlen($this->phpbb_root_path . $this->adm_relative_path)); 129 } 130 } 131 132 return $path; 133 } 134 135 /** 136 * Strips away the web root path and prepends the normal root path 137 * 138 * This replaces get_web_root_path() . some_url with 139 * $phpbb_root_path . some_url 140 * 141 * @param string $path The path to be updated 142 * @return string 143 */ 144 public function remove_web_root_path($path) 145 { 146 if (strpos($path, $this->get_web_root_path()) === 0) 147 { 148 $path = substr($path, strlen($this->get_web_root_path())); 149 150 return $this->phpbb_root_path . $path; 151 } 152 153 return $path; 154 } 155 156 /** 157 * Get a relative root path from the current URL 158 * 159 * @return string 160 */ 161 public function get_web_root_path() 162 { 163 if (null !== $this->web_root_path) 164 { 165 return $this->web_root_path; 166 } 167 168 if (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) 169 { 170 return $this->web_root_path = generate_board_url() . '/'; 171 } 172 173 // We do not need to escape $path_info, $request_uri and $script_name because we can not find their content in the result. 174 // Path info (e.g. /foo/bar) 175 $path_info = $this->filesystem->clean_path($this->symfony_request->getPathInfo()); 176 177 // Full request URI (e.g. phpBB/app.php/foo/bar) 178 $request_uri = $this->symfony_request->getRequestUri(); 179 180 // Script name URI (e.g. phpBB/app.php) 181 $script_name = $this->symfony_request->getScriptName(); 182 183 /* 184 * If the path info is empty but we're using app.php, then we 185 * might be using an empty route like app.php/ which is 186 * supported by symfony's routing 187 */ 188 if ($path_info === '/' && preg_match('/app\.' . $this->php_ext . '\/$/', $request_uri)) 189 { 190 return $this->web_root_path = $this->filesystem->clean_path('./../' . $this->phpbb_root_path); 191 } 192 193 if ($path_info === '/' && defined('ADMIN_START') && preg_match('/\/' . preg_quote($this->adm_relative_path, '/') . 'index\.' . $this->php_ext . '$/', $script_name)) 194 { 195 $this->in_adm_path = true; 196 } 197 198 /* 199 * If the path info is empty (single /), then we're not using 200 * a route like app.php/foo/bar 201 */ 202 if ($path_info === '/') 203 { 204 return $this->web_root_path = $this->phpbb_root_path; 205 } 206 207 /* 208 * Check AJAX request: 209 * If the current request is a AJAX we need to fix the paths. 210 * We need to get the root path based on the Referer, so we can use 211 * the generated URLs in the template of the Referer. If we do not 212 * generate the relative path based on the Referer, but based on the 213 * currently requested URL, the generated URLs will not point to the 214 * intended locations: 215 * Referer desired URL desired relative root path 216 * memberlist.php faq.php ./ 217 * memberlist.php app.php/foo/bar ./ 218 * app.php/foo memberlist.php ../ 219 * app.php/foo app.php/fox ../ 220 * app.php/foo/bar memberlist.php ../../ 221 * ../page.php memberlist.php ./phpBB/ 222 * ../sub/page.php memberlist.php ./../phpBB/ 223 * 224 * The referer must be specified as a parameter in the query. 225 */ 226 if ($this->request->is_ajax() && $this->request->header('Referer')) 227 { 228 // We need to escape $absolute_board_url because it can be partially concatenated to the result. 229 $absolute_board_url = $this->request->escape($this->symfony_request->getSchemeAndHttpHost() . $this->symfony_request->getBasePath(), true); 230 231 $referer_web_root_path = $this->get_web_root_path_from_ajax_referer( 232 $this->request->header('Referer'), 233 $absolute_board_url 234 ); 235 return $this->web_root_path = $referer_web_root_path; 236 } 237 238 // How many corrections might we need? 239 $corrections = substr_count($path_info, '/'); 240 241 /* 242 * If the script name (e.g. phpBB/app.php) does not exists in the 243 * requestUri (e.g. phpBB/app.php/foo/template), then we are rewriting 244 * the URL. So we must reduce the slash count by 1. 245 */ 246 if (strpos($request_uri, $script_name) !== 0) 247 { 248 $corrections--; 249 } 250 251 // Prepend ../ to the phpbb_root_path as many times as / exists in path_info 252 $this->web_root_path = $this->filesystem->clean_path( 253 './' . str_repeat('../', max(0, $corrections)) . $this->phpbb_root_path 254 ); 255 return $this->web_root_path; 256 } 257 258 /** 259 * Get the web root path of the referer form an ajax request 260 * 261 * @param string $absolute_referer_url 262 * @param string $absolute_board_url 263 * @return string 264 */ 265 public function get_web_root_path_from_ajax_referer($absolute_referer_url, $absolute_board_url) 266 { 267 // If the board URL is in the beginning of the referer, this means 268 // we the referer is in the board URL or a subdirectory of it. 269 // So we just need to count the / (slashes) in the left over part of 270 // the referer and prepend ../ the the current root_path, to get the 271 // web root path of the referer. 272 if (strpos($absolute_referer_url, $absolute_board_url) === 0) 273 { 274 $relative_referer_path = substr($absolute_referer_url, strlen($absolute_board_url)); 275 $has_params = strpos($relative_referer_path, '?'); 276 if ($has_params !== false) 277 { 278 $relative_referer_path = substr($relative_referer_path, 0, $has_params); 279 } 280 $corrections = substr_count($relative_referer_path, '/'); 281 return $this->phpbb_root_path . str_repeat('../', max(0, $corrections - 1)); 282 } 283 284 // If not, it's a bit more complicated. We go to the parent directory 285 // of the referer until we find the remaining referer in the board URL. 286 // Foreach directory we need to add a ../ to the fixed root_path. 287 // When we finally found it, we need to remove the remaining referer 288 // from the board URL, to get the boards root path. 289 // If the then append these two strings, we get our fixed web root path. 290 $fixed_root_path = ''; 291 $referer_dir = $absolute_referer_url; 292 $has_params = strpos($referer_dir, '?'); 293 if ($has_params !== false) 294 { 295 $referer_dir = substr($referer_dir, 0, $has_params); 296 } 297 298 // If we do not find a slash at the end of the referer, we come 299 // from a file. So the first dirname() does not need a traversal 300 // path correction. 301 if (substr($referer_dir, -1) !== '/') 302 { 303 $referer_dir = dirname($referer_dir); 304 } 305 306 while (($dir_position = strpos($absolute_board_url, $referer_dir)) !== 0) 307 { 308 $fixed_root_path .= '../'; 309 $referer_dir = dirname($referer_dir); 310 311 // Just return phpbb_root_path if we reach the top directory 312 if ($referer_dir === '.') 313 { 314 return $this->phpbb_root_path; 315 } 316 } 317 318 $fixed_root_path .= substr($absolute_board_url, strlen($referer_dir) + 1); 319 // Add trailing slash 320 return $this->phpbb_root_path . $fixed_root_path . '/'; 321 } 322 323 /** 324 * Eliminates useless . and .. components from specified URL 325 * 326 * @param string $url URL to clean 327 * 328 * @return string Cleaned URL 329 */ 330 public function clean_url($url) 331 { 332 $delimiter_position = strpos($url, '://'); 333 // URL should contain :// but it shouldn't start with it. 334 // Do not clean URLs that do not fit these constraints. 335 if (empty($delimiter_position)) 336 { 337 return $url; 338 } 339 $scheme = substr($url, 0, $delimiter_position) . '://'; 340 // Add length of URL delimiter to position 341 $path = substr($url, $delimiter_position + 3); 342 343 return $scheme . $this->filesystem->clean_path($path); 344 } 345 346 /** 347 * Glue URL parameters together 348 * 349 * @param array $params URL parameters in the form of array(name => value) 350 * @return string Returns the glued string, e.g. name1=value1&name2&name3=value3 351 */ 352 public function glue_url_params($params) 353 { 354 $_params = array(); 355 356 foreach ($params as $key => $value) 357 { 358 // some parameters do not have value 359 if ($value !== null) 360 { 361 $_params[] = $key . '=' . $value; 362 } 363 else 364 { 365 $_params[] = $key; 366 } 367 } 368 return implode('&', $_params); 369 } 370 371 /** 372 * Get the base and parameters of a URL 373 * 374 * @param string $url URL to break apart 375 * @param bool $is_amp Is the parameter separator &. Defaults to true. 376 * @return array Returns the base and parameters in the form of array('base' => string, 'params' => array(name => value)) 377 */ 378 public function get_url_parts($url, $is_amp = true) 379 { 380 $separator = ($is_amp) ? '&' : '&'; 381 $params = array(); 382 383 if (strpos($url, '?') !== false) 384 { 385 $base = substr($url, 0, strpos($url, '?')); 386 $args = substr($url, strlen($base) + 1); 387 $args = ($args) ? explode($separator, $args) : array(); 388 389 foreach ($args as $argument) 390 { 391 if (empty($argument)) 392 { 393 continue; 394 } 395 396 // some parameters don't have value 397 if (strpos($argument, '=') !== false) 398 { 399 list($key, $value) = explode('=', $argument, 2); 400 } 401 else 402 { 403 $key = $argument; 404 $value = null; 405 } 406 407 if ($key === '') 408 { 409 continue; 410 } 411 412 $params[$key] = $value; 413 } 414 } 415 else 416 { 417 $base = $url; 418 } 419 420 return array( 421 'base' => $base, 422 'params' => $params, 423 ); 424 } 425 426 /** 427 * Strip parameters from an already built URL. 428 * 429 * @param string $url URL to strip parameters from 430 * @param array|string $strip Parameters to strip. 431 * @param bool $is_amp Is the parameter separator &. Defaults to true. 432 * @return string Returns the new URL. 433 */ 434 public function strip_url_params($url, $strip, $is_amp = true) 435 { 436 $url_parts = $this->get_url_parts($url, $is_amp); 437 $params = $url_parts['params']; 438 439 if (!is_array($strip)) 440 { 441 $strip = array($strip); 442 } 443 444 if (!empty($params)) 445 { 446 // Strip the parameters off 447 foreach ($strip as $param) 448 { 449 unset($params[$param]); 450 } 451 } 452 453 return $url_parts['base'] . (($params) ? '?' . $this->glue_url_params($params) : ''); 454 } 455 456 /** 457 * Append parameters to an already built URL. 458 * 459 * @param string $url URL to append parameters to 460 * @param array $new_params Parameters to add in the form of array(name => value) 461 * @param bool $is_amp Is the parameter separator &. Defaults to true. 462 * @return string Returns the new URL. 463 */ 464 public function append_url_params($url, $new_params, $is_amp = true) 465 { 466 $url_parts = $this->get_url_parts($url, $is_amp); 467 $params = array_merge($url_parts['params'], $new_params); 468 469 // Move the sid to the end if it's set 470 if (isset($params['sid'])) 471 { 472 $sid = $params['sid']; 473 unset($params['sid']); 474 $params['sid'] = $sid; 475 } 476 477 return $url_parts['base'] . (($params) ? '?' . $this->glue_url_params($params) : ''); 478 } 479 480 /** 481 * Get a valid page 482 * 483 * @param string $page The page to verify 484 * @param bool $mod_rewrite Whether mod_rewrite is enabled, default: false 485 * 486 * @return string A valid page based on given page and mod_rewrite 487 */ 488 public function get_valid_page($page, $mod_rewrite = false) 489 { 490 // We need to be cautious here. 491 // On some situations, the redirect path is an absolute URL, sometimes a relative path 492 // For a relative path, let's prefix it with $phpbb_root_path to point to the correct location, 493 // else we use the URL directly. 494 $url_parts = parse_url($page); 495 496 // URL 497 if ($url_parts === false || empty($url_parts['scheme']) || empty($url_parts['host'])) 498 { 499 // Remove 'app.php/' from the page, when rewrite is enabled. 500 // Treat app.php as a reserved file name and remove on mod rewrite 501 // even if it might not be in the phpBB root. 502 if ($mod_rewrite && ($app_position = strpos($page, 'app.' . $this->php_ext . '/')) !== false) 503 { 504 $page = substr($page, 0, $app_position) . substr($page, $app_position + strlen('app.' . $this->php_ext . '/')); 505 } 506 507 // Remove preceding slashes from page name and prepend root path 508 $page = $this->get_phpbb_root_path() . ltrim($page, '/\\'); 509 } 510 511 return $page; 512 } 513 514 /** 515 * Tells if the router is currently in use (if the current page is a route or not) 516 * 517 * @return bool 518 */ 519 public function is_router_used() 520 { 521 // Script name URI (e.g. phpBB/app.php) 522 $script_name = $this->symfony_request->getScriptName(); 523 524 return basename($script_name) === 'app.' . $this->php_ext; 525 } 526 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |