[ Index ]

PHP Cross Reference of phpBB-3.3.0-deutsch

title

Body

[close]

/phpbb/routing/ -> router.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\routing;
  15  
  16  use phpbb\routing\resources_locator\resources_locator_interface;
  17  use Symfony\Component\Config\ConfigCache;
  18  use Symfony\Component\Config\Loader\LoaderInterface;
  19  use Symfony\Component\DependencyInjection\ContainerInterface;
  20  use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
  21  use Symfony\Component\DependencyInjection\Exception\RuntimeException;
  22  use Symfony\Component\Filesystem\Exception\IOException;
  23  use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper;
  24  use Symfony\Component\Routing\Generator\UrlGenerator;
  25  use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
  26  use Symfony\Component\Routing\Matcher\UrlMatcher;
  27  use Symfony\Component\Routing\RequestContext;
  28  use Symfony\Component\Routing\RouteCollection;
  29  use Symfony\Component\Routing\RouterInterface;
  30  
  31  /**
  32   * Integration of all pieces of the routing system for easier use.
  33   */
  34  class router implements RouterInterface
  35  {
  36      /**
  37       * @var ContainerInterface
  38       */
  39      protected $container;
  40  
  41      /**
  42       * @var resources_locator_interface
  43       */
  44      protected $resources_locator;
  45  
  46      /**
  47       * @var LoaderInterface
  48       */
  49      protected $loader;
  50  
  51      /**
  52       * PHP file extensions
  53       *
  54       * @var string
  55       */
  56      protected $php_ext;
  57  
  58      /**
  59       * @var \Symfony\Component\Routing\Matcher\UrlMatcherInterface|null
  60       */
  61      protected $matcher;
  62  
  63      /**
  64       * @var \Symfony\Component\Routing\Generator\UrlGeneratorInterface|null
  65       */
  66      protected $generator;
  67  
  68      /**
  69       * @var RequestContext
  70       */
  71      protected $context;
  72  
  73      /**
  74       * @var RouteCollection
  75       */
  76      protected $route_collection;
  77  
  78      /**
  79       * @var string
  80       */
  81      protected $cache_dir;
  82  
  83      /**
  84       * Construct method
  85       *
  86       * @param ContainerInterface            $container            DI container
  87       * @param resources_locator_interface    $resources_locator    Resources locator
  88       * @param LoaderInterface                $loader                Resources loader
  89       * @param string                        $php_ext            PHP file extension
  90       * @param string                        $cache_dir            phpBB cache directory
  91       */
  92  	public function __construct(ContainerInterface $container, resources_locator_interface $resources_locator, LoaderInterface $loader, $php_ext, $cache_dir)
  93      {
  94          $this->container            = $container;
  95          $this->resources_locator    = $resources_locator;
  96          $this->loader                = $loader;
  97          $this->php_ext                = $php_ext;
  98          $this->context                = new RequestContext();
  99          $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  }


Generated: Tue Apr 7 19:44:41 2020 Cross-referenced by PHPXref 0.7.1