Route.php 6.4 KB

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