* @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 Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper; use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper; use Symfony\Component\Routing\Matcher\UrlMatcher; use Symfony\Component\Routing\Generator\UrlGenerator; use Symfony\Component\Routing\RequestContext; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\RouterInterface; use Symfony\Component\Routing\Loader\YamlFileLoader; use Symfony\Component\Config\FileLocator; use phpbb\extension\manager; /** * Integration of all pieces of the routing system for easier use. */ class router implements RouterInterface { /** * @var manager Extension manager */ protected $extension_manager; /** * @var string phpBB root path */ protected $phpbb_root_path; /** * @var string PHP file extensions */ protected $php_ext; /** * @var array YAML file(s) containing route information */ protected $routing_files; /** * @var \Symfony\Component\Routing\Matcher\UrlMatcherInterface|null */ protected $matcher; /** * @var \Symfony\Component\Routing\Generator\UrlGeneratorInterface|null */ protected $generator; /** * @var RequestContext */ protected $context; /** * @var RouteCollection|null */ protected $route_collection; /** * Construct method * * @param manager $extension_manager The extension manager * @param string $phpbb_root_path phpBB root path * @param string $php_ext PHP file extension * @param array $routing_files Array of strings containing paths to YAML files holding route information */ public function __construct(manager $extension_manager, $phpbb_root_path, $php_ext, $routing_files = array()) { $this->extension_manager = $extension_manager; $this->routing_files = $routing_files; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; $this->context = new RequestContext(); } /** * Find the list of routing files * * @param \phpbb\finder $finder * @return router */ public function find_routing_files(\phpbb\finder $finder) { if ($this->routing_files === null || empty($this->routing_files)) { // We hardcode the path to the core config directory // because the finder cannot find it $this->routing_files = array_merge($this->routing_files, array('config/routing.yml'), array_keys($finder ->directory('/config') ->suffix('routing.yml') ->find() )); } return $this; } /** * Find a list of controllers * * @param string $base_path Base path to prepend to file paths * @return router */ public function find($base_path = '') { if ($this->route_collection === null || $this->route_collection->count() === 0) { $this->route_collection = new RouteCollection; foreach ($this->routing_files as $file_path) { $loader = new YamlFileLoader(new FileLocator(phpbb_realpath($base_path))); $this->route_collection->addCollection($loader->load($file_path)); } } return $this; } /** * Get the list of routes * * @return RouteCollection Get the route collection */ public function get_routes() { if ($this->route_collection == null || empty($this->routing_files)) { $this->find_routing_files($this->extension_manager->get_finder()) ->find($this->phpbb_root_path); } 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; } if (defined('DEBUG')) { $this->create_new_url_matcher(); } else { $this->create_dumped_url_matcher(); } return $this->matcher; } /** * Creates a new dumped URL Matcher (dump it if necessary) */ protected function create_dumped_url_matcher() { if (!file_exists($this->phpbb_root_path . 'cache/url_matcher.' . $this->php_ext)) { $dumper = new PhpMatcherDumper($this->get_routes()); $options = array( 'class' => 'phpbb_url_matcher', ); $dump = $dumper->dump($options); file_put_contents($this->phpbb_root_path . 'cache/url_matcher.' . $this->php_ext, $dump); } require_once($this->phpbb_root_path . 'cache/url_matcher.' . $this->php_ext); $this->matcher = new phpbb_url_matcher($this->context); } /** * 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; } if (defined('DEBUG')) { $this->create_new_url_generator(); } else { $this->create_dumped_url_generator(); } return $this->generator; } /** * Creates a new dumped URL Generator (dump it if necessary) */ protected function create_dumped_url_generator() { if (!file_exists($this->phpbb_root_path . 'cache/url_generator.' . $this->php_ext)) { $dumper = new PhpGeneratorDumper($this->get_routes()); $options = array( 'class' => 'phpbb_url_generator', ); $dump = $dumper->dump($options); file_put_contents($this->phpbb_root_path . 'cache/url_generator.' . $this->php_ext, $dump); } require_once($this->phpbb_root_path . 'cache/url_generator.' . $this->php_ext); $this->generator = new phpbb_url_generator($this->context); } /** * Creates a new URL Generator */ protected function create_new_url_generator() { $this->generator = new UrlGenerator($this->get_routes(), $this->context); } }