[ Index ] |
PHP Cross Reference of phpBB-3.2.11-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 /** 43 * Constructor 44 * 45 * @param \phpbb\symfony_request $symfony_request 46 * @param \phpbb\filesystem\filesystem_interface $filesystem 47 * @param \phpbb\request\request_interface $request 48 * @param string $phpbb_root_path Relative path to phpBB root 49 * @param string $php_ext PHP file extension 50 * @param mixed $adm_relative_path Relative path admin path to adm/ root 51 */ 52 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) 53 { 54 $this->symfony_request = $symfony_request; 55 $this->filesystem = $filesystem; 56 $this->request = $request; 57 $this->phpbb_root_path = $phpbb_root_path; 58 $this->php_ext = $php_ext; 59 $this->adm_relative_path = $adm_relative_path; 60 } 61 62 /** 63 * Get the phpBB root path 64 * 65 * @return string 66 */ 67 public function get_phpbb_root_path() 68 { 69 return $this->phpbb_root_path; 70 } 71 72 /** 73 * Get the adm root path 74 * 75 * @return string 76 */ 77 public function get_adm_relative_path() 78 { 79 return $this->adm_relative_path; 80 } 81 82 /** 83 * Get the php extension 84 * 85 * @return string 86 */ 87 public function get_php_ext() 88 { 89 return $this->php_ext; 90 } 91 92 /** 93 * Update a web path to the correct relative root path 94 * 95 * This replaces $phpbb_root_path . some_url with 96 * get_web_root_path() . some_url 97 * 98 * @param string $path The path to be updated 99 * @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 /** 501 * Tells if the router is currently in use (if the current page is a route or not) 502 * 503 * @return bool 504 */ 505 public function is_router_used() 506 { 507 // Script name URI (e.g. phpBB/app.php) 508 $script_name = $this->symfony_request->getScriptName(); 509 510 return basename($script_name) === 'app.' . $this->php_ext; 511 } 512 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |