[ Index ]

PHP Cross Reference of phpBB-3.1.10-deutsch

title

Body

[close]

/phpbb/ -> path_helper.php (source)

   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&amp;name2&amp;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('&amp;', $_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 &amp;. 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) ? '&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 &amp;. 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 &amp;. 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  }


Generated: Sun Feb 19 19:52:41 2017 Cross-referenced by PHPXref 0.7.1