Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
20.00% |
3 / 15 |
CRAP | |
53.12% |
51 / 96 |
| router | |
0.00% |
0 / 1 |
|
20.00% |
3 / 15 |
178.00 | |
53.12% |
51 / 96 |
| __construct | |
100.00% |
1 / 1 |
1 | |
100.00% |
7 / 7 |
|||
| get_routes | |
0.00% |
0 / 1 |
4.03 | |
87.50% |
7 / 8 |
|||
| getRouteCollection | |
0.00% |
0 / 1 |
2.00 | |
0.00% |
0 / 1 |
|||
| setContext | |
0.00% |
0 / 1 |
3.04 | |
83.33% |
5 / 6 |
|||
| getContext | |
0.00% |
0 / 1 |
2.00 | |
0.00% |
0 / 1 |
|||
| generate | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| match | |
0.00% |
0 / 1 |
2.00 | |
0.00% |
0 / 1 |
|||
| get_matcher | |
0.00% |
0 / 1 |
6.00 | |
0.00% |
0 / 4 |
|||
| create_dumped_url_matcher | |
0.00% |
0 / 1 |
12.00 | |
0.00% |
0 / 10 |
|||
| create_new_url_matcher | |
0.00% |
0 / 1 |
2.00 | |
0.00% |
0 / 2 |
|||
| get_generator | |
0.00% |
0 / 1 |
2.50 | |
50.00% |
2 / 4 |
|||
| create_dumped_url_generator | |
0.00% |
0 / 1 |
12.00 | |
0.00% |
0 / 10 |
|||
| create_new_url_generator | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| resolveParameters | |
0.00% |
0 / 1 |
6.12 | |
85.00% |
17 / 20 |
|||
| resolve | |
0.00% |
0 / 1 |
12.21 | |
52.63% |
10 / 19 |
|||
| <?php | |
| /** | |
| * | |
| * This file is part of the phpBB Forum Software package. | |
| * | |
| * @copyright (c) phpBB Limited <https://www.phpbb.com> | |
| * @license GNU General Public License, version 2 (GPL-2.0) | |
| * | |
| * For full copyright and license information, please see | |
| * the docs/CREDITS.txt file. | |
| * | |
| */ | |
| namespace phpbb\routing; | |
| use phpbb\routing\resources_locator\resources_locator_interface; | |
| use Symfony\Component\Config\ConfigCache; | |
| use Symfony\Component\Config\Loader\LoaderInterface; | |
| use Symfony\Component\DependencyInjection\ContainerInterface; | |
| use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; | |
| use Symfony\Component\DependencyInjection\Exception\RuntimeException; | |
| use Symfony\Component\Filesystem\Exception\IOException; | |
| use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper; | |
| use Symfony\Component\Routing\Generator\UrlGenerator; | |
| use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper; | |
| use Symfony\Component\Routing\Matcher\UrlMatcher; | |
| use Symfony\Component\Routing\RequestContext; | |
| use Symfony\Component\Routing\RouteCollection; | |
| use Symfony\Component\Routing\RouterInterface; | |
| /** | |
| * Integration of all pieces of the routing system for easier use. | |
| */ | |
| class router implements RouterInterface | |
| { | |
| /** | |
| * @var ContainerInterface | |
| */ | |
| protected $container; | |
| /** | |
| * @var resources_locator_interface | |
| */ | |
| protected $resources_locator; | |
| /** | |
| * @var LoaderInterface | |
| */ | |
| protected $loader; | |
| /** | |
| * PHP file extensions | |
| * | |
| * @var string | |
| */ | |
| protected $php_ext; | |
| /** | |
| * @var \Symfony\Component\Routing\Matcher\UrlMatcherInterface|null | |
| */ | |
| protected $matcher; | |
| /** | |
| * @var \Symfony\Component\Routing\Generator\UrlGeneratorInterface|null | |
| */ | |
| protected $generator; | |
| /** | |
| * @var RequestContext | |
| */ | |
| protected $context; | |
| /** | |
| * @var RouteCollection | |
| */ | |
| protected $route_collection; | |
| /** | |
| * @var string | |
| */ | |
| protected $cache_dir; | |
| /** | |
| * Construct method | |
| * | |
| * @param ContainerInterface $container DI container | |
| * @param resources_locator_interface $resources_locator Resources locator | |
| * @param LoaderInterface $loader Resources loader | |
| * @param string $php_ext PHP file extension | |
| * @param string $cache_dir phpBB cache directory | |
| */ | |
| public function __construct(ContainerInterface $container, resources_locator_interface $resources_locator, LoaderInterface $loader, $php_ext, $cache_dir) | |
| { | |
| $this->container = $container; | |
| $this->resources_locator = $resources_locator; | |
| $this->loader = $loader; | |
| $this->php_ext = $php_ext; | |
| $this->context = new RequestContext(); | |
| $this->cache_dir = $cache_dir; | |
| } | |
| /** | |
| * Get the list of routes | |
| * | |
| * @return RouteCollection Get the route collection | |
| */ | |
| public function get_routes() | |
| { | |
| if ($this->route_collection === null /*|| $this->route_collection->count() === 0*/) | |
| { | |
| $this->route_collection = new RouteCollection; | |
| foreach ($this->resources_locator->locate_resources() as $resource) | |
| { | |
| if (is_array($resource)) | |
| { | |
| $this->route_collection->addCollection($this->loader->load($resource[0], $resource[1])); | |
| } | |
| else | |
| { | |
| $this->route_collection->addCollection($this->loader->load($resource)); | |
| } | |
| } | |
| $this->resolveParameters($this->route_collection); | |
| } | |
| return $this->route_collection; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getRouteCollection() | |
| { | |
| return $this->get_routes(); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function setContext(RequestContext $context) | |
| { | |
| $this->context = $context; | |
| if ($this->matcher !== null) | |
| { | |
| $this->get_matcher()->setContext($context); | |
| } | |
| if ($this->generator !== null) | |
| { | |
| $this->get_generator()->setContext($context); | |
| } | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getContext() | |
| { | |
| return $this->context; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH) | |
| { | |
| return $this->get_generator()->generate($name, $parameters, $referenceType); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function match($pathinfo) | |
| { | |
| return $this->get_matcher()->match($pathinfo); | |
| } | |
| /** | |
| * Gets the UrlMatcher instance associated with this Router. | |
| * | |
| * @return \Symfony\Component\Routing\Matcher\UrlMatcherInterface A UrlMatcherInterface instance | |
| */ | |
| public function get_matcher() | |
| { | |
| if ($this->matcher !== null) | |
| { | |
| return $this->matcher; | |
| } | |
| $this->create_dumped_url_matcher(); | |
| return $this->matcher; | |
| } | |
| /** | |
| * Creates a new dumped URL Matcher (dump it if necessary) | |
| */ | |
| protected function create_dumped_url_matcher() | |
| { | |
| try | |
| { | |
| $cache = new ConfigCache("{$this->cache_dir}url_matcher.{$this->php_ext}", defined('DEBUG')); | |
| if (!$cache->isFresh()) | |
| { | |
| $dumper = new PhpMatcherDumper($this->get_routes()); | |
| $options = array( | |
| 'class' => 'phpbb_url_matcher', | |
| 'base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher', | |
| ); | |
| $cache->write($dumper->dump($options), $this->get_routes()->getResources()); | |
| } | |
| require_once($cache->getPath()); | |
| $this->matcher = new \phpbb_url_matcher($this->context); | |
| } | |
| catch (IOException $e) | |
| { | |
| $this->create_new_url_matcher(); | |
| } | |
| } | |
| /** | |
| * Creates a new URL Matcher | |
| */ | |
| protected function create_new_url_matcher() | |
| { | |
| $this->matcher = new UrlMatcher($this->get_routes(), $this->context); | |
| } | |
| /** | |
| * Gets the UrlGenerator instance associated with this Router. | |
| * | |
| * @return \Symfony\Component\Routing\Generator\UrlGeneratorInterface A UrlGeneratorInterface instance | |
| */ | |
| public function get_generator() | |
| { | |
| if ($this->generator !== null) | |
| { | |
| return $this->generator; | |
| } | |
| $this->create_dumped_url_generator(); | |
| return $this->generator; | |
| } | |
| /** | |
| * Creates a new dumped URL Generator (dump it if necessary) | |
| */ | |
| protected function create_dumped_url_generator() | |
| { | |
| try | |
| { | |
| $cache = new ConfigCache("{$this->cache_dir}url_generator.{$this->php_ext}", defined('DEBUG')); | |
| if (!$cache->isFresh()) | |
| { | |
| $dumper = new PhpGeneratorDumper($this->get_routes()); | |
| $options = array( | |
| 'class' => 'phpbb_url_generator', | |
| 'base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator', | |
| ); | |
| $cache->write($dumper->dump($options), $this->get_routes()->getResources()); | |
| } | |
| require_once($cache->getPath()); | |
| $this->generator = new \phpbb_url_generator($this->context); | |
| } | |
| catch (IOException $e) | |
| { | |
| $this->create_new_url_generator(); | |
| } | |
| } | |
| /** | |
| * Creates a new URL Generator | |
| */ | |
| protected function create_new_url_generator() | |
| { | |
| $this->generator = new UrlGenerator($this->get_routes(), $this->context); | |
| } | |
| /** | |
| * Replaces placeholders with service container parameter values in: | |
| * - the route defaults, | |
| * - the route requirements, | |
| * - the route path, | |
| * - the route host, | |
| * - the route schemes, | |
| * - the route methods. | |
| * | |
| * @param RouteCollection $collection | |
| */ | |
| protected function resolveParameters(RouteCollection $collection) | |
| { | |
| /** @var \Symfony\Component\Routing\Route $route */ | |
| foreach ($collection as $route) | |
| { | |
| foreach ($route->getDefaults() as $name => $value) | |
| { | |
| $route->setDefault($name, $this->resolve($value)); | |
| } | |
| $requirements = $route->getRequirements(); | |
| unset($requirements['_scheme']); | |
| unset($requirements['_method']); | |
| foreach ($requirements as $name => $value) | |
| { | |
| $route->setRequirement($name, $this->resolve($value)); | |
| } | |
| $route->setPath($this->resolve($route->getPath())); | |
| $route->setHost($this->resolve($route->getHost())); | |
| $schemes = array(); | |
| foreach ($route->getSchemes() as $scheme) | |
| { | |
| $schemes = array_merge($schemes, explode('|', $this->resolve($scheme))); | |
| } | |
| $route->setSchemes($schemes); | |
| $methods = array(); | |
| foreach ($route->getMethods() as $method) | |
| { | |
| $methods = array_merge($methods, explode('|', $this->resolve($method))); | |
| } | |
| $route->setMethods($methods); | |
| $route->setCondition($this->resolve($route->getCondition())); | |
| } | |
| } | |
| /** | |
| * Recursively replaces placeholders with the service container parameters. | |
| * | |
| * @param mixed $value The source which might contain "%placeholders%" | |
| * | |
| * @return mixed The source with the placeholders replaced by the container | |
| * parameters. Arrays are resolved recursively. | |
| * | |
| * @throws ParameterNotFoundException When a placeholder does not exist as a container parameter | |
| * @throws RuntimeException When a container value is not a string or a numeric value | |
| */ | |
| private function resolve($value) | |
| { | |
| if (is_array($value)) | |
| { | |
| foreach ($value as $key => $val) | |
| { | |
| $value[$key] = $this->resolve($val); | |
| } | |
| return $value; | |
| } | |
| if (!is_string($value)) | |
| { | |
| return $value; | |
| } | |
| $container = $this->container; | |
| $escapedValue = preg_replace_callback('/%%|%([^%\s]++)%/', function ($match) use ($container, $value) | |
| { | |
| // skip %% | |
| if (!isset($match[1])) | |
| { | |
| return '%%'; | |
| } | |
| $resolved = $container->getParameter($match[1]); | |
| if (is_string($resolved) || is_numeric($resolved)) | |
| { | |
| return (string) $resolved; | |
| } | |
| throw new RuntimeException(sprintf( | |
| 'The container parameter "%s", used in the route configuration value "%s", '. | |
| 'must be a string or numeric, but it is of type %s.', | |
| $match[1], | |
| $value, | |
| gettype($resolved) | |
| ) | |
| ); | |
| }, $value); | |
| return str_replace('%%', '%', $escapedValue); | |
| } | |
| } |