[ Index ] |
PHP Cross Reference of phpBB-3.1.12-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 */ 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 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, \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 if (strpos($path, $this->phpbb_root_path) === 0) 104 { 105 $path = substr($path, strlen($this->phpbb_root_path)); 106 107 $web_root_path = $this->get_web_root_path(); 108 if (substr($web_root_path, -8) === 'app.php/' && substr($path, 0, 7) === 'app.php') 109 { 110 $path = substr($path, 8); 111 } 112 113 return $this->filesystem->clean_path($web_root_path . $path); 114 } 115 116 return $path; 117 } 118 119 /** 120 * Strips away the web root path and prepends the normal root path 121 * 122 * This replaces get_web_root_path() . some_url with 123 * $phpbb_root_path . some_url 124 * 125 * @param string $path The path to be updated 126 * @return string 127 */ 128 public function remove_web_root_path($path) 129 { 130 if (strpos($path, $this->get_web_root_path()) === 0) 131 { 132 $path = substr($path, strlen($this->get_web_root_path())); 133 134 return $this->phpbb_root_path . $path; 135 } 136 137 return $path; 138 } 139 140 /** 141 * Get a relative root path from the current URL 142 * 143 * @return string 144 */ 145 public function get_web_root_path() 146 { 147 if ($this->symfony_request === null) 148 { 149 return $this->phpbb_root_path; 150 } 151 152 if (null !== $this->web_root_path) 153 { 154 return $this->web_root_path; 155 } 156 157 // We do not need to escape $path_info, $request_uri and $script_name because we can not find their content in the result. 158 // Path info (e.g. /foo/bar) 159 $path_info = $this->filesystem->clean_path($this->symfony_request->getPathInfo()); 160 161 // Full request URI (e.g. phpBB/app.php/foo/bar) 162 $request_uri = $this->symfony_request->getRequestUri(); 163 164 // Script name URI (e.g. phpBB/app.php) 165 $script_name = $this->symfony_request->getScriptName(); 166 167 /* 168 * If the path info is empty but we're using app.php, then we 169 * might be using an empty route like app.php/ which is 170 * supported by symfony's routing 171 */ 172 if ($path_info === '/' && preg_match('/app\.' . $this->php_ext . '\/$/', $request_uri)) 173 { 174 return $this->web_root_path = $this->filesystem->clean_path('./../' . $this->phpbb_root_path); 175 } 176 177 /* 178 * If the path info is empty (single /), then we're not using 179 * a route like app.php/foo/bar 180 */ 181 if ($path_info === '/') 182 { 183 return $this->web_root_path = $this->phpbb_root_path; 184 } 185 186 /* 187 * Check AJAX request: 188 * If the current request is a AJAX we need to fix the paths. 189 * We need to get the root path based on the Referer, so we can use 190 * the generated URLs in the template of the Referer. If we do not 191 * generate the relative path based on the Referer, but based on the 192 * currently requested URL, the generated URLs will not point to the 193 * intended locations: 194 * Referer desired URL desired relative root path 195 * memberlist.php faq.php ./ 196 * memberlist.php app.php/foo/bar ./ 197 * app.php/foo memberlist.php ../ 198 * app.php/foo app.php/fox ../ 199 * app.php/foo/bar memberlist.php ../../ 200 * ../page.php memberlist.php ./phpBB/ 201 * ../sub/page.php memberlist.php ./../phpBB/ 202 * 203 * The referer must be specified as a parameter in the query. 204 */ 205 if ($this->request->is_ajax() && $this->symfony_request->get('_referer')) 206 { 207 // We need to escape $absolute_board_url because it can be partially concatenated to the result. 208 $absolute_board_url = $this->request->escape($this->symfony_request->getSchemeAndHttpHost() . $this->symfony_request->getBasePath(), true); 209 210 $referer_web_root_path = $this->get_web_root_path_from_ajax_referer( 211 $this->symfony_request->get('_referer'), 212 $absolute_board_url 213 ); 214 return $this->web_root_path = $this->phpbb_root_path . $referer_web_root_path; 215 } 216 217 // How many corrections might we need? 218 $corrections = substr_count($path_info, '/'); 219 220 /* 221 * If the script name (e.g. phpBB/app.php) does not exists in the 222 * requestUri (e.g. phpBB/app.php/foo/template), then we are rewriting 223 * the URL. So we must reduce the slash count by 1. 224 */ 225 if (strpos($request_uri, $script_name) !== 0) 226 { 227 $corrections--; 228 } 229 230 // Prepend ../ to the phpbb_root_path as many times as / exists in path_info 231 $this->web_root_path = $this->filesystem->clean_path( 232 './' . str_repeat('../', $corrections) . $this->phpbb_root_path 233 ); 234 return $this->web_root_path; 235 } 236 237 /** 238 * Get the web root path of the referer form an ajax request 239 * 240 * @param string $absolute_referer_url 241 * @param string $absolute_board_url 242 * @return string 243 */ 244 public function get_web_root_path_from_ajax_referer($absolute_referer_url, $absolute_board_url) 245 { 246 // If the board URL is in the beginning of the referer, this means 247 // we the referer is in the board URL or a subdirectory of it. 248 // So we just need to count the / (slashes) in the left over part of 249 // the referer and prepend ../ the the current root_path, to get the 250 // web root path of the referer. 251 if (strpos($absolute_referer_url, $absolute_board_url) === 0) 252 { 253 $relative_referer_path = substr($absolute_referer_url, strlen($absolute_board_url)); 254 $has_params = strpos($relative_referer_path, '?'); 255 if ($has_params !== false) 256 { 257 $relative_referer_path = substr($relative_referer_path, 0, $has_params); 258 } 259 $corrections = substr_count($relative_referer_path, '/'); 260 return $this->phpbb_root_path . str_repeat('../', $corrections - 1); 261 } 262 263 // If not, it's a bit more complicated. We go to the parent directory 264 // of the referer until we find the remaining referer in the board URL. 265 // Foreach directory we need to add a ../ to the fixed root_path. 266 // When we finally found it, we need to remove the remaining referer 267 // from the board URL, to get the boards root path. 268 // If the then append these two strings, we get our fixed web root path. 269 $fixed_root_path = ''; 270 $referer_dir = $absolute_referer_url; 271 $has_params = strpos($referer_dir, '?'); 272 if ($has_params !== false) 273 { 274 $referer_dir = substr($referer_dir, 0, $has_params); 275 } 276 277 // If we do not find a slash at the end of the referer, we come 278 // from a file. So the first dirname() does not need a traversal 279 // path correction. 280 if (substr($referer_dir, -1) !== '/') 281 { 282 $referer_dir = dirname($referer_dir); 283 } 284 285 while (($dir_position = strpos($absolute_board_url, $referer_dir)) !== 0) 286 { 287 $fixed_root_path .= '../'; 288 $referer_dir = dirname($referer_dir); 289 290 // Just return phpbb_root_path if we reach the top directory 291 if ($referer_dir === '.') 292 { 293 return $this->phpbb_root_path; 294 } 295 } 296 297 $fixed_root_path .= substr($absolute_board_url, strlen($referer_dir) + 1); 298 // Add trailing slash 299 return $this->phpbb_root_path . $fixed_root_path . '/'; 300 } 301 302 /** 303 * Eliminates useless . and .. components from specified URL 304 * 305 * @param string $url URL to clean 306 * 307 * @return string Cleaned URL 308 */ 309 public function clean_url($url) 310 { 311 $delimiter_position = strpos($url, '://'); 312 // URL should contain :// but it shouldn't start with it. 313 // Do not clean URLs that do not fit these constraints. 314 if (empty($delimiter_position)) 315 { 316 return $url; 317 } 318 $scheme = substr($url, 0, $delimiter_position) . '://'; 319 // Add length of URL delimiter to position 320 $path = substr($url, $delimiter_position + 3); 321 322 return $scheme . $this->filesystem->clean_path($path); 323 } 324 325 /** 326 * Glue URL parameters together 327 * 328 * @param array $params URL parameters in the form of array(name => value) 329 * @return string Returns the glued string, e.g. name1=value1&name2&name3=value3 330 */ 331 public function glue_url_params($params) 332 { 333 $_params = array(); 334 335 foreach ($params as $key => $value) 336 { 337 // some parameters do not have value 338 if ($value !== null) 339 { 340 $_params[] = $key . '=' . $value; 341 } 342 else 343 { 344 $_params[] = $key; 345 } 346 } 347 return implode('&', $_params); 348 } 349 350 /** 351 * Get the base and parameters of a URL 352 * 353 * @param string $url URL to break apart 354 * @param bool $is_amp Is the parameter separator &. Defaults to true. 355 * @return array Returns the base and parameters in the form of array('base' => string, 'params' => array(name => value)) 356 */ 357 public function get_url_parts($url, $is_amp = true) 358 { 359 $separator = ($is_amp) ? '&' : '&'; 360 $params = array(); 361 362 if (strpos($url, '?') !== false) 363 { 364 $base = substr($url, 0, strpos($url, '?')); 365 $args = substr($url, strlen($base) + 1); 366 $args = ($args) ? explode($separator, $args) : array(); 367 368 foreach ($args as $argument) 369 { 370 if (empty($argument)) 371 { 372 continue; 373 } 374 375 // some parameters don't have value 376 if (strpos($argument, '=') !== false) 377 { 378 list($key, $value) = explode('=', $argument, 2); 379 } 380 else 381 { 382 $key = $argument; 383 $value = null; 384 } 385 386 if ($key === '') 387 { 388 continue; 389 } 390 391 $params[$key] = $value; 392 } 393 } 394 else 395 { 396 $base = $url; 397 } 398 399 return array( 400 'base' => $base, 401 'params' => $params, 402 ); 403 } 404 405 /** 406 * Strip parameters from an already built URL. 407 * 408 * @param string $url URL to strip parameters from 409 * @param array|string $strip Parameters to strip. 410 * @param bool $is_amp Is the parameter separator &. Defaults to true. 411 * @return string Returns the new URL. 412 */ 413 public function strip_url_params($url, $strip, $is_amp = true) 414 { 415 $url_parts = $this->get_url_parts($url, $is_amp); 416 $params = $url_parts['params']; 417 418 if (!is_array($strip)) 419 { 420 $strip = array($strip); 421 } 422 423 if (!empty($params)) 424 { 425 // Strip the parameters off 426 foreach ($strip as $param) 427 { 428 unset($params[$param]); 429 } 430 } 431 432 return $url_parts['base'] . (($params) ? '?' . $this->glue_url_params($params) : ''); 433 } 434 435 /** 436 * Append parameters to an already built URL. 437 * 438 * @param string $url URL to append parameters to 439 * @param array $new_params Parameters to add in the form of array(name => value) 440 * @param bool $is_amp Is the parameter separator &. Defaults to true. 441 * @return string Returns the new URL. 442 */ 443 public function append_url_params($url, $new_params, $is_amp = true) 444 { 445 $url_parts = $this->get_url_parts($url, $is_amp); 446 $params = array_merge($url_parts['params'], $new_params); 447 448 // Move the sid to the end if it's set 449 if (isset($params['sid'])) 450 { 451 $sid = $params['sid']; 452 unset($params['sid']); 453 $params['sid'] = $sid; 454 } 455 456 return $url_parts['base'] . (($params) ? '?' . $this->glue_url_params($params) : ''); 457 } 458 459 /** 460 * Get a valid page 461 * 462 * @param string $page The page to verify 463 * @param bool $mod_rewrite Whether mod_rewrite is enabled, default: false 464 * 465 * @return string A valid page based on given page and mod_rewrite 466 */ 467 public function get_valid_page($page, $mod_rewrite = false) 468 { 469 // We need to be cautious here. 470 // On some situations, the redirect path is an absolute URL, sometimes a relative path 471 // For a relative path, let's prefix it with $phpbb_root_path to point to the correct location, 472 // else we use the URL directly. 473 $url_parts = parse_url($page); 474 475 // URL 476 if ($url_parts === false || empty($url_parts['scheme']) || empty($url_parts['host'])) 477 { 478 // Remove 'app.php/' from the page, when rewrite is enabled. 479 // Treat app.php as a reserved file name and remove on mod rewrite 480 // even if it might not be in the phpBB root. 481 if ($mod_rewrite && ($app_position = strpos($page, 'app.' . $this->php_ext . '/')) !== false) 482 { 483 $page = substr($page, 0, $app_position) . substr($page, $app_position + strlen('app.' . $this->php_ext . '/')); 484 } 485 486 // Remove preceding slashes from page name and prepend root path 487 $page = $this->get_phpbb_root_path() . ltrim($page, '/\\'); 488 } 489 490 return $page; 491 } 492 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jan 11 00:25:41 2018 | Cross-referenced by PHPXref 0.7.1 |