Route.php 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  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. /**
  12. * A Route describes a route and its parameters.
  13. *
  14. * @author Fabien Potencier <fabien@symfony.com>
  15. *
  16. * @api
  17. */
  18. class Route
  19. {
  20. private $pattern;
  21. private $defaults;
  22. private $requirements;
  23. private $options;
  24. private $compiled;
  25. static private $compilers = array();
  26. /**
  27. * Constructor.
  28. *
  29. * Available options:
  30. *
  31. * * compiler_class: A class name able to compile this route instance (RouteCompiler by default)
  32. *
  33. * @param string $pattern The pattern to match
  34. * @param array $defaults An array of default parameter values
  35. * @param array $requirements An array of requirements for parameters (regexes)
  36. * @param array $options An array of options
  37. *
  38. * @api
  39. */
  40. public function __construct($pattern, array $defaults = array(), array $requirements = array(), array $options = array())
  41. {
  42. $this->setPattern($pattern);
  43. $this->setDefaults($defaults);
  44. $this->setRequirements($requirements);
  45. $this->setOptions($options);
  46. }
  47. /**
  48. * Returns the pattern.
  49. *
  50. * @return string The pattern
  51. */
  52. public function getPattern()
  53. {
  54. return $this->pattern;
  55. }
  56. /**
  57. * Sets the pattern.
  58. *
  59. * This method implements a fluent interface.
  60. *
  61. * @param string $pattern The pattern
  62. *
  63. * @return Route The current Route instance
  64. */
  65. public function setPattern($pattern)
  66. {
  67. $this->pattern = trim($pattern);
  68. // a route must start with a slash
  69. if (empty($this->pattern) || '/' !== $this->pattern[0]) {
  70. $this->pattern = '/'.$this->pattern;
  71. }
  72. return $this;
  73. }
  74. /**
  75. * Returns the options.
  76. *
  77. * @return array The options
  78. */
  79. public function getOptions()
  80. {
  81. return $this->options;
  82. }
  83. /**
  84. * Sets the options.
  85. *
  86. * This method implements a fluent interface.
  87. *
  88. * @param array $options The options
  89. *
  90. * @return Route The current Route instance
  91. */
  92. public function setOptions(array $options)
  93. {
  94. $this->options = array_merge(array(
  95. 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler',
  96. ), $options);
  97. return $this;
  98. }
  99. /**
  100. * Sets an option value.
  101. *
  102. * This method implements a fluent interface.
  103. *
  104. * @param string $name An option name
  105. * @param mixed $value The option value
  106. *
  107. * @return Route The current Route instance
  108. *
  109. * @api
  110. */
  111. public function setOption($name, $value)
  112. {
  113. $this->options[$name] = $value;
  114. return $this;
  115. }
  116. /**
  117. * Get an option value.
  118. *
  119. * @param string $name An option name
  120. *
  121. * @return mixed The option value
  122. */
  123. public function getOption($name)
  124. {
  125. return isset($this->options[$name]) ? $this->options[$name] : null;
  126. }
  127. /**
  128. * Returns the defaults.
  129. *
  130. * @return array The defaults
  131. */
  132. public function getDefaults()
  133. {
  134. return $this->defaults;
  135. }
  136. /**
  137. * Sets the defaults.
  138. *
  139. * This method implements a fluent interface.
  140. *
  141. * @param array $defaults The defaults
  142. *
  143. * @return Route The current Route instance
  144. */
  145. public function setDefaults(array $defaults)
  146. {
  147. $this->defaults = array();
  148. foreach ($defaults as $name => $default) {
  149. $this->defaults[(string) $name] = $default;
  150. }
  151. return $this;
  152. }
  153. /**
  154. * Gets a default value.
  155. *
  156. * @param string $name A variable name
  157. *
  158. * @return mixed The default value
  159. */
  160. public function getDefault($name)
  161. {
  162. return isset($this->defaults[$name]) ? $this->defaults[$name] : null;
  163. }
  164. /**
  165. * Checks if a default value is set for the given variable.
  166. *
  167. * @param string $name A variable name
  168. *
  169. * @return Boolean true if the default value is set, false otherwise
  170. */
  171. public function hasDefault($name)
  172. {
  173. return array_key_exists($name, $this->defaults);
  174. }
  175. /**
  176. * Sets a default value.
  177. *
  178. * @param string $name A variable name
  179. * @param mixed $default The default value
  180. *
  181. * @return Route The current Route instance
  182. *
  183. * @api
  184. */
  185. public function setDefault($name, $default)
  186. {
  187. $this->defaults[(string) $name] = $default;
  188. return $this;
  189. }
  190. /**
  191. * Returns the requirements.
  192. *
  193. * @return array The requirements
  194. */
  195. public function getRequirements()
  196. {
  197. return $this->requirements;
  198. }
  199. /**
  200. * Sets the requirements.
  201. *
  202. * This method implements a fluent interface.
  203. *
  204. * @param array $requirements The requirements
  205. *
  206. * @return Route The current Route instance
  207. */
  208. public function setRequirements(array $requirements)
  209. {
  210. $this->requirements = array();
  211. foreach ($requirements as $key => $regex) {
  212. $this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
  213. }
  214. return $this;
  215. }
  216. /**
  217. * Returns the requirement for the given key.
  218. *
  219. * @param string $key The key
  220. * @return string The regex
  221. */
  222. public function getRequirement($key)
  223. {
  224. return isset($this->requirements[$key]) ? $this->requirements[$key] : null;
  225. }
  226. /**
  227. * Sets a requirement for the given key.
  228. *
  229. * @param string $key The key
  230. * @param string $regex The regex
  231. *
  232. * @return Route The current Route instance
  233. *
  234. * @api
  235. */
  236. public function setRequirement($key, $regex)
  237. {
  238. $this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
  239. return $this;
  240. }
  241. /**
  242. * Compiles the route.
  243. *
  244. * @return CompiledRoute A CompiledRoute instance
  245. */
  246. public function compile()
  247. {
  248. if (null !== $this->compiled) {
  249. return $this->compiled;
  250. }
  251. $class = $this->getOption('compiler_class');
  252. if (!isset(static::$compilers[$class])) {
  253. static::$compilers[$class] = new $class;
  254. }
  255. return $this->compiled = static::$compilers[$class]->compile($this);
  256. }
  257. private function sanitizeRequirement($key, $regex)
  258. {
  259. if (is_array($regex)) {
  260. throw new \InvalidArgumentException(sprintf('Routing requirements must be a string, array given for "%s"', $key));
  261. }
  262. if ('^' == $regex[0]) {
  263. $regex = substr($regex, 1);
  264. }
  265. if ('$' == substr($regex, -1)) {
  266. $regex = substr($regex, 0, -1);
  267. }
  268. return $regex;
  269. }
  270. }