[ Index ]

PHP Cross Reference of phpBB-3.2.11-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\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&amp;name2&amp;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('&amp;', $_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 &amp;. 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) ? '&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 &amp;. 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 &amp;. 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  }


Generated: Wed Nov 11 20:33:01 2020 Cross-referenced by PHPXref 0.7.1