Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

path_helper.php

Zuletzt modifiziert: 09.10.2024, 12:51 - Dateigröße: 13.55 KiB


001  <?php
002  /**
003  *
004  * This file is part of the phpBB Forum Software package.
005  *
006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
007  * @license GNU General Public License, version 2 (GPL-2.0)
008  *
009  * For full copyright and license information, please see
010  * the docs/CREDITS.txt file.
011  *
012  */
013   
014  namespace phpbb;
015   
016  /**
017  * A class with various functions that are related to paths, files and the filesystem
018  */
019  class path_helper
020  {
021      /** @var \phpbb\symfony_request */
022      protected $symfony_request;
023   
024      /** @var \phpbb\filesystem\filesystem_interface */
025      protected $filesystem;
026   
027      /** @var \phpbb\request\request_interface */
028      protected $request;
029   
030      /** @var string */
031      protected $phpbb_root_path;
032   
033      /** @var string */
034      protected $adm_relative_path;
035   
036      /** @var string */
037      protected $php_ext;
038   
039      /** @var string */
040      protected $web_root_path;
041   
042      /**
043      * Constructor
044      *
045      * @param \phpbb\symfony_request $symfony_request
046      * @param \phpbb\filesystem\filesystem_interface $filesystem
047      * @param \phpbb\request\request_interface $request
048      * @param string $phpbb_root_path Relative path to phpBB root
049      * @param string $php_ext PHP file extension
050      * @param mixed $adm_relative_path Relative path admin path to adm/ root
051      */
052      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)
053      {
054          $this->symfony_request = $symfony_request;
055          $this->filesystem = $filesystem;
056          $this->request = $request;
057          $this->phpbb_root_path = $phpbb_root_path;
058          $this->php_ext = $php_ext;
059          $this->adm_relative_path = $adm_relative_path;
060      }
061   
062      /**
063      * Get the phpBB root path
064      *
065      * @return string
066      */
067      public function get_phpbb_root_path()
068      {
069          return $this->phpbb_root_path;
070      }
071   
072      /**
073      * Get the adm root path
074      *
075      * @return string
076      */
077      public function get_adm_relative_path()
078      {
079          return $this->adm_relative_path;
080      }
081   
082      /**
083      * Get the php extension
084      *
085      * @return string
086      */
087      public function get_php_ext()
088      {
089          return $this->php_ext;
090      }
091   
092      /**
093      * Update a web path to the correct relative root path
094      *
095      * This replaces $phpbb_root_path . some_url with
096      *    get_web_root_path() . some_url
097      *
098      * @param string $path The path to be updated
099      * @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