PageRenderTime 44ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/symfony/routing/Symfony/Component/Routing/Router.php

https://gitlab.com/HatemProjects/hatem
PHP | 323 lines | 165 code | 45 blank | 113 comment | 19 complexity | 9b51c26aa2191d64af984056b663559f MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Routing;
  11. use Symfony\Component\Config\Loader\LoaderInterface;
  12. use Symfony\Component\Config\ConfigCache;
  13. use Psr\Log\LoggerInterface;
  14. use Symfony\Component\Routing\Generator\ConfigurableRequirementsInterface;
  15. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  16. use Symfony\Component\Routing\Generator\Dumper\GeneratorDumperInterface;
  17. use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
  18. use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
  19. use Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface;
  20. use Symfony\Component\HttpFoundation\Request;
  21. /**
  22. * The Router class is an example of the integration of all pieces of the
  23. * routing system for easier use.
  24. *
  25. * @author Fabien Potencier <fabien@symfony.com>
  26. */
  27. class Router implements RouterInterface, RequestMatcherInterface
  28. {
  29. /**
  30. * @var UrlMatcherInterface|null
  31. */
  32. protected $matcher;
  33. /**
  34. * @var UrlGeneratorInterface|null
  35. */
  36. protected $generator;
  37. /**
  38. * @var RequestContext
  39. */
  40. protected $context;
  41. /**
  42. * @var LoaderInterface
  43. */
  44. protected $loader;
  45. /**
  46. * @var RouteCollection|null
  47. */
  48. protected $collection;
  49. /**
  50. * @var mixed
  51. */
  52. protected $resource;
  53. /**
  54. * @var array
  55. */
  56. protected $options = array();
  57. /**
  58. * @var LoggerInterface|null
  59. */
  60. protected $logger;
  61. /**
  62. * Constructor.
  63. *
  64. * @param LoaderInterface $loader A LoaderInterface instance
  65. * @param mixed $resource The main resource to load
  66. * @param array $options An array of options
  67. * @param RequestContext $context The context
  68. * @param LoggerInterface $logger A logger instance
  69. */
  70. public function __construct(LoaderInterface $loader, $resource, array $options = array(), RequestContext $context = null, LoggerInterface $logger = null)
  71. {
  72. $this->loader = $loader;
  73. $this->resource = $resource;
  74. $this->logger = $logger;
  75. $this->context = $context ?: new RequestContext();
  76. $this->setOptions($options);
  77. }
  78. /**
  79. * Sets options.
  80. *
  81. * Available options:
  82. *
  83. * * cache_dir: The cache directory (or null to disable caching)
  84. * * debug: Whether to enable debugging or not (false by default)
  85. * * resource_type: Type hint for the main resource (optional)
  86. *
  87. * @param array $options An array of options
  88. *
  89. * @throws \InvalidArgumentException When unsupported option is provided
  90. */
  91. public function setOptions(array $options)
  92. {
  93. $this->options = array(
  94. 'cache_dir' => null,
  95. 'debug' => false,
  96. 'generator_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
  97. 'generator_base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
  98. 'generator_dumper_class' => 'Symfony\\Component\\Routing\\Generator\\Dumper\\PhpGeneratorDumper',
  99. 'generator_cache_class' => 'ProjectUrlGenerator',
  100. 'matcher_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher',
  101. 'matcher_base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher',
  102. 'matcher_dumper_class' => 'Symfony\\Component\\Routing\\Matcher\\Dumper\\PhpMatcherDumper',
  103. 'matcher_cache_class' => 'ProjectUrlMatcher',
  104. 'resource_type' => null,
  105. 'strict_requirements' => true,
  106. );
  107. // check option names and live merge, if errors are encountered Exception will be thrown
  108. $invalid = array();
  109. foreach ($options as $key => $value) {
  110. if (array_key_exists($key, $this->options)) {
  111. $this->options[$key] = $value;
  112. } else {
  113. $invalid[] = $key;
  114. }
  115. }
  116. if ($invalid) {
  117. throw new \InvalidArgumentException(sprintf('The Router does not support the following options: "%s".', implode('", "', $invalid)));
  118. }
  119. }
  120. /**
  121. * Sets an option.
  122. *
  123. * @param string $key The key
  124. * @param mixed $value The value
  125. *
  126. * @throws \InvalidArgumentException
  127. */
  128. public function setOption($key, $value)
  129. {
  130. if (!array_key_exists($key, $this->options)) {
  131. throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key));
  132. }
  133. $this->options[$key] = $value;
  134. }
  135. /**
  136. * Gets an option value.
  137. *
  138. * @param string $key The key
  139. *
  140. * @return mixed The value
  141. *
  142. * @throws \InvalidArgumentException
  143. */
  144. public function getOption($key)
  145. {
  146. if (!array_key_exists($key, $this->options)) {
  147. throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key));
  148. }
  149. return $this->options[$key];
  150. }
  151. /**
  152. * {@inheritdoc}
  153. */
  154. public function getRouteCollection()
  155. {
  156. if (null === $this->collection) {
  157. $this->collection = $this->loader->load($this->resource, $this->options['resource_type']);
  158. }
  159. return $this->collection;
  160. }
  161. /**
  162. * {@inheritdoc}
  163. */
  164. public function setContext(RequestContext $context)
  165. {
  166. $this->context = $context;
  167. if (null !== $this->matcher) {
  168. $this->getMatcher()->setContext($context);
  169. }
  170. if (null !== $this->generator) {
  171. $this->getGenerator()->setContext($context);
  172. }
  173. }
  174. /**
  175. * {@inheritdoc}
  176. */
  177. public function getContext()
  178. {
  179. return $this->context;
  180. }
  181. /**
  182. * {@inheritdoc}
  183. */
  184. public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
  185. {
  186. return $this->getGenerator()->generate($name, $parameters, $referenceType);
  187. }
  188. /**
  189. * {@inheritdoc}
  190. */
  191. public function match($pathinfo)
  192. {
  193. return $this->getMatcher()->match($pathinfo);
  194. }
  195. /**
  196. * {@inheritdoc}
  197. */
  198. public function matchRequest(Request $request)
  199. {
  200. $matcher = $this->getMatcher();
  201. if (!$matcher instanceof RequestMatcherInterface) {
  202. // fallback to the default UrlMatcherInterface
  203. return $matcher->match($request->getPathInfo());
  204. }
  205. return $matcher->matchRequest($request);
  206. }
  207. /**
  208. * Gets the UrlMatcher instance associated with this Router.
  209. *
  210. * @return UrlMatcherInterface A UrlMatcherInterface instance
  211. */
  212. public function getMatcher()
  213. {
  214. if (null !== $this->matcher) {
  215. return $this->matcher;
  216. }
  217. if (null === $this->options['cache_dir'] || null === $this->options['matcher_cache_class']) {
  218. return $this->matcher = new $this->options['matcher_class']($this->getRouteCollection(), $this->context);
  219. }
  220. $class = $this->options['matcher_cache_class'];
  221. $cache = new ConfigCache($this->options['cache_dir'].'/'.$class.'.php', $this->options['debug']);
  222. if (!$cache->isFresh()) {
  223. $dumper = $this->getMatcherDumperInstance();
  224. $options = array(
  225. 'class' => $class,
  226. 'base_class' => $this->options['matcher_base_class'],
  227. );
  228. $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources());
  229. }
  230. require_once $cache;
  231. return $this->matcher = new $class($this->context);
  232. }
  233. /**
  234. * Gets the UrlGenerator instance associated with this Router.
  235. *
  236. * @return UrlGeneratorInterface A UrlGeneratorInterface instance
  237. */
  238. public function getGenerator()
  239. {
  240. if (null !== $this->generator) {
  241. return $this->generator;
  242. }
  243. if (null === $this->options['cache_dir'] || null === $this->options['generator_cache_class']) {
  244. $this->generator = new $this->options['generator_class']($this->getRouteCollection(), $this->context, $this->logger);
  245. } else {
  246. $class = $this->options['generator_cache_class'];
  247. $cache = new ConfigCache($this->options['cache_dir'].'/'.$class.'.php', $this->options['debug']);
  248. if (!$cache->isFresh()) {
  249. $dumper = $this->getGeneratorDumperInstance();
  250. $options = array(
  251. 'class' => $class,
  252. 'base_class' => $this->options['generator_base_class'],
  253. );
  254. $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources());
  255. }
  256. require_once $cache;
  257. $this->generator = new $class($this->context, $this->logger);
  258. }
  259. if ($this->generator instanceof ConfigurableRequirementsInterface) {
  260. $this->generator->setStrictRequirements($this->options['strict_requirements']);
  261. }
  262. return $this->generator;
  263. }
  264. /**
  265. * @return GeneratorDumperInterface
  266. */
  267. protected function getGeneratorDumperInstance()
  268. {
  269. return new $this->options['generator_dumper_class']($this->getRouteCollection());
  270. }
  271. /**
  272. * @return MatcherDumperInterface
  273. */
  274. protected function getMatcherDumperInstance()
  275. {
  276. return new $this->options['matcher_dumper_class']($this->getRouteCollection());
  277. }
  278. }