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

router.php

Zuletzt modifiziert: 09.10.2024, 12:52 - Dateigröße: 9.15 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\routing;
015   
016  use phpbb\routing\resources_locator\resources_locator_interface;
017  use Symfony\Component\Config\ConfigCache;
018  use Symfony\Component\Config\Loader\LoaderInterface;
019  use Symfony\Component\DependencyInjection\ContainerInterface;
020  use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
021  use Symfony\Component\DependencyInjection\Exception\RuntimeException;
022  use Symfony\Component\Filesystem\Exception\IOException;
023  use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper;
024  use Symfony\Component\Routing\Generator\UrlGenerator;
025  use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
026  use Symfony\Component\Routing\Matcher\UrlMatcher;
027  use Symfony\Component\Routing\RequestContext;
028  use Symfony\Component\Routing\RouteCollection;
029  use Symfony\Component\Routing\RouterInterface;
030   
031  /**
032   * Integration of all pieces of the routing system for easier use.
033   */
034  class router implements RouterInterface
035  {
036      /**
037       * @var ContainerInterface
038       */
039      protected $container;
040   
041      /**
042       * @var resources_locator_interface
043       */
044      protected $resources_locator;
045   
046      /**
047       * @var LoaderInterface
048       */
049      protected $loader;
050   
051      /**
052       * PHP file extensions
053       *
054       * @var string
055       */
056      protected $php_ext;
057   
058      /**
059       * @var \Symfony\Component\Routing\Matcher\UrlMatcherInterface|null
060       */
061      protected $matcher;
062   
063      /**
064       * @var \Symfony\Component\Routing\Generator\UrlGeneratorInterface|null
065       */
066      protected $generator;
067   
068      /**
069       * @var RequestContext
070       */
071      protected $context;
072   
073      /**
074       * @var RouteCollection
075       */
076      protected $route_collection;
077   
078      /**
079       * @var string
080       */
081      protected $cache_dir;
082   
083      /**
084       * Construct method
085       *
086       * @param ContainerInterface            $container            DI container
087       * @param resources_locator_interface    $resources_locator    Resources locator
088       * @param LoaderInterface                $loader                Resources loader
089       * @param string                        $php_ext            PHP file extension
090       * @param string                        $cache_dir            phpBB cache directory
091       */
092      public function __construct(ContainerInterface $container, resources_locator_interface $resources_locator, LoaderInterface $loader, $php_ext, $cache_dir)
093      {
094          $this->container            = $container;
095          $this->resources_locator    = $resources_locator;
096          $this->loader                = $loader;
097          $this->php_ext                = $php_ext;
098          $this->context                = new RequestContext();
099          $this->cache_dir            = $cache_dir;
100      }
101   
102      /**
103       * Get the list of routes
104       *
105       * @return RouteCollection Get the route collection
106       */
107      public function get_routes()
108      {
109          if ($this->route_collection === null /*|| $this->route_collection->count() === 0*/)
110          {
111              $this->route_collection = new RouteCollection;
112              foreach ($this->resources_locator->locate_resources() as $resource)
113              {
114                  if (is_array($resource))
115                  {
116                      $this->route_collection->addCollection($this->loader->load($resource[0], $resource[1]));
117                  }
118                  else
119                  {
120                      $this->route_collection->addCollection($this->loader->load($resource));
121                  }
122              }
123   
124              $this->resolveParameters($this->route_collection);
125          }
126   
127          return $this->route_collection;
128      }
129   
130      /**
131       * {@inheritdoc}
132       */
133      public function getRouteCollection()
134      {
135          return $this->get_routes();
136      }
137   
138      /**
139       * {@inheritdoc}
140       */
141      public function setContext(RequestContext $context)
142      {
143          $this->context = $context;
144   
145          if ($this->matcher !== null)
146          {
147              $this->get_matcher()->setContext($context);
148          }
149          if ($this->generator !== null)
150          {
151              $this->get_generator()->setContext($context);
152          }
153      }
154   
155      /**
156       * {@inheritdoc}
157       */
158      public function getContext()
159      {
160          return $this->context;
161      }
162   
163      /**
164       * {@inheritdoc}
165       */
166      public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
167      {
168          return $this->get_generator()->generate($name, $parameters, $referenceType);
169      }
170   
171      /**
172       * {@inheritdoc}
173       */
174      public function match($pathinfo)
175      {
176          return $this->get_matcher()->match($pathinfo);
177      }
178   
179      /**
180       * Gets the UrlMatcher instance associated with this Router.
181       *
182       * @return \Symfony\Component\Routing\Matcher\UrlMatcherInterface A UrlMatcherInterface instance
183       */
184      public function get_matcher()
185      {
186          if ($this->matcher !== null)
187          {
188              return $this->matcher;
189          }
190   
191          $this->create_dumped_url_matcher();
192   
193          return $this->matcher;
194      }
195   
196      /**
197       * Creates a new dumped URL Matcher (dump it if necessary)
198       */
199      protected function create_dumped_url_matcher()
200      {
201          try
202          {
203              $cache = new ConfigCache("{$this->cache_dir}url_matcher.{$this->php_ext}", defined('DEBUG'));
204              if (!$cache->isFresh())
205              {
206                  $dumper = new PhpMatcherDumper($this->get_routes());
207   
208                  $options = array(
209                      'class'      => 'phpbb_url_matcher',
210                      'base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher',
211                  );
212   
213                  $cache->write($dumper->dump($options), $this->get_routes()->getResources());
214              }
215   
216              require_once($cache->getPath());
217   
218              $this->matcher = new \phpbb_url_matcher($this->context);
219          }
220          catch (IOException $e)
221          {
222              $this->create_new_url_matcher();
223          }
224      }
225   
226      /**
227       * Creates a new URL Matcher
228       */
229      protected function create_new_url_matcher()
230      {
231          $this->matcher = new UrlMatcher($this->get_routes(), $this->context);
232      }
233   
234      /**
235       * Gets the UrlGenerator instance associated with this Router.
236       *
237       * @return \Symfony\Component\Routing\Generator\UrlGeneratorInterface A UrlGeneratorInterface instance
238       */
239      public function get_generator()
240      {
241          if ($this->generator !== null)
242          {
243              return $this->generator;
244          }
245   
246          $this->create_dumped_url_generator();
247   
248          return $this->generator;
249      }
250   
251      /**
252       * Creates a new dumped URL Generator (dump it if necessary)
253       */
254      protected function create_dumped_url_generator()
255      {
256          try
257          {
258              $cache = new ConfigCache("{$this->cache_dir}url_generator.{$this->php_ext}", defined('DEBUG'));
259              if (!$cache->isFresh())
260              {
261                  $dumper = new PhpGeneratorDumper($this->get_routes());
262   
263                  $options = array(
264                      'class'      => 'phpbb_url_generator',
265                      'base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
266                  );
267   
268                  $cache->write($dumper->dump($options), $this->get_routes()->getResources());
269              }
270   
271              require_once($cache->getPath());
272   
273              $this->generator = new \phpbb_url_generator($this->context);
274          }
275          catch (IOException $e)
276          {
277              $this->create_new_url_generator();
278          }
279      }
280   
281      /**
282       * Creates a new URL Generator
283       */
284      protected function create_new_url_generator()
285      {
286          $this->generator = new UrlGenerator($this->get_routes(), $this->context);
287      }
288   
289      /**
290       * Replaces placeholders with service container parameter values in:
291       * - the route defaults,
292       * - the route requirements,
293       * - the route path,
294       * - the route host,
295       * - the route schemes,
296       * - the route methods.
297       *
298       * @param RouteCollection $collection
299       */
300      protected function resolveParameters(RouteCollection $collection)
301      {
302          /** @var \Symfony\Component\Routing\Route $route */
303          foreach ($collection as $route)
304          {
305              foreach ($route->getDefaults() as $name => $value)
306              {
307                  $route->setDefault($name, $this->resolve($value));
308              }
309   
310              $requirements = $route->getRequirements();
311              unset($requirements['_scheme']);
312              unset($requirements['_method']);
313   
314              foreach ($requirements as $name => $value)
315              {
316                  $route->setRequirement($name, $this->resolve($value));
317              }
318   
319              $route->setPath($this->resolve($route->getPath()));
320              $route->setHost($this->resolve($route->getHost()));
321   
322              $schemes = array();
323              foreach ($route->getSchemes() as $scheme)
324              {
325                  $schemes = array_merge($schemes, explode('|', $this->resolve($scheme)));
326              }
327   
328              $route->setSchemes($schemes);
329              $methods = array();
330              foreach ($route->getMethods() as $method)
331              {
332                  $methods = array_merge($methods, explode('|', $this->resolve($method)));
333              }
334   
335              $route->setMethods($methods);
336              $route->setCondition($this->resolve($route->getCondition()));
337          }
338      }
339   
340      /**
341       * Recursively replaces placeholders with the service container parameters.
342       *
343       * @param mixed $value The source which might contain "%placeholders%"
344       *
345       * @return mixed The source with the placeholders replaced by the container
346       *               parameters. Arrays are resolved recursively.
347       *
348       * @throws ParameterNotFoundException When a placeholder does not exist as a container parameter
349       * @throws RuntimeException           When a container value is not a string or a numeric value
350       */
351      private function resolve($value)
352      {
353          if (is_array($value))
354          {
355              foreach ($value as $key => $val)
356              {
357                  $value[$key] = $this->resolve($val);
358              }
359   
360              return $value;
361          }
362   
363          if (!is_string($value))
364          {
365              return $value;
366          }
367   
368          $container = $this->container;
369          $escapedValue = preg_replace_callback('/%%|%([^%\s]++)%/', function ($match) use ($container, $value)
370          {
371              // skip %%
372              if (!isset($match[1]))
373              {
374                  return '%%';
375              }
376   
377              $resolved = $container->getParameter($match[1]);
378              if (is_string($resolved) || is_numeric($resolved))
379              {
380                  return (string) $resolved;
381              }
382   
383              throw new RuntimeException(sprintf(
384                      'The container parameter "%s", used in the route configuration value "%s", '.
385                      'must be a string or numeric, but it is of type %s.',
386                      $match[1],
387                      $value,
388                      gettype($resolved)
389                  )
390              );
391          }, $value);
392   
393          return str_replace('%%', '%', $escapedValue);
394      }
395  }
396