4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\Routing;
15 * A Route describes a route and its parameters.
17 * @author Fabien Potencier <fabien@symfony.com>
18 * @author Tobias Schultze <http://tobion.de>
20 class Route implements \Serializable
35 private $schemes = array();
40 private $methods = array();
45 private $defaults = array();
50 private $requirements = array();
55 private $options = array();
58 * @var null|CompiledRoute
65 private $condition = '';
72 * * compiler_class: A class name able to compile this route instance (RouteCompiler by default)
74 * @param string $path The path pattern to match
75 * @param array $defaults An array of default parameter values
76 * @param array $requirements An array of requirements for parameters (regexes)
77 * @param array $options An array of options
78 * @param string $host The host pattern to match
79 * @param string|array $schemes A required URI scheme or an array of restricted schemes
80 * @param string|array $methods A required HTTP method or an array of restricted methods
81 * @param string $condition A condition that should evaluate to true for the route to match
83 public function __construct($path, array $defaults = array(), array $requirements = array(), array $options = array(), $host = '', $schemes = array(), $methods = array(), $condition = '')
85 $this->setPath($path);
86 $this->setDefaults($defaults);
87 $this->setRequirements($requirements);
88 $this->setOptions($options);
89 $this->setHost($host);
90 // The conditions make sure that an initial empty $schemes/$methods does not override the corresponding requirement.
91 // They can be removed when the BC layer is removed.
93 $this->setSchemes($schemes);
96 $this->setMethods($methods);
98 $this->setCondition($condition);
104 public function serialize()
106 return serialize(array(
107 'path' => $this->path,
108 'host' => $this->host,
109 'defaults' => $this->defaults,
110 'requirements' => $this->requirements,
111 'options' => $this->options,
112 'schemes' => $this->schemes,
113 'methods' => $this->methods,
114 'condition' => $this->condition,
115 'compiled' => $this->compiled,
122 public function unserialize($serialized)
124 $data = unserialize($serialized);
125 $this->path = $data['path'];
126 $this->host = $data['host'];
127 $this->defaults = $data['defaults'];
128 $this->requirements = $data['requirements'];
129 $this->options = $data['options'];
130 $this->schemes = $data['schemes'];
131 $this->methods = $data['methods'];
133 if (isset($data['condition'])) {
134 $this->condition = $data['condition'];
136 if (isset($data['compiled'])) {
137 $this->compiled = $data['compiled'];
142 * Returns the pattern for the path.
144 * @return string The pattern
146 * @deprecated since version 2.2, to be removed in 3.0. Use getPath instead.
148 public function getPattern()
150 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. Use the getPath() method instead.', E_USER_DEPRECATED);
156 * Sets the pattern for the path.
158 * This method implements a fluent interface.
160 * @param string $pattern The path pattern
164 * @deprecated since version 2.2, to be removed in 3.0. Use setPath instead.
166 public function setPattern($pattern)
168 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. Use the setPath() method instead.', E_USER_DEPRECATED);
170 return $this->setPath($pattern);
174 * Returns the pattern for the path.
176 * @return string The path pattern
178 public function getPath()
184 * Sets the pattern for the path.
186 * This method implements a fluent interface.
188 * @param string $pattern The path pattern
192 public function setPath($pattern)
194 // A pattern must start with a slash and must not have multiple slashes at the beginning because the
195 // generated path for this route would be confused with a network path, e.g. '//domain.com/path'.
196 $this->path = '/'.ltrim(trim($pattern), '/');
197 $this->compiled = null;
203 * Returns the pattern for the host.
205 * @return string The host pattern
207 public function getHost()
213 * Sets the pattern for the host.
215 * This method implements a fluent interface.
217 * @param string $pattern The host pattern
221 public function setHost($pattern)
223 $this->host = (string) $pattern;
224 $this->compiled = null;
230 * Returns the lowercased schemes this route is restricted to.
231 * So an empty array means that any scheme is allowed.
233 * @return array The schemes
235 public function getSchemes()
237 return $this->schemes;
241 * Sets the schemes (e.g. 'https') this route is restricted to.
242 * So an empty array means that any scheme is allowed.
244 * This method implements a fluent interface.
246 * @param string|array $schemes The scheme or an array of schemes
250 public function setSchemes($schemes)
252 $this->schemes = array_map('strtolower', (array) $schemes);
254 // this is to keep BC and will be removed in a future version
255 if ($this->schemes) {
256 $this->requirements['_scheme'] = implode('|', $this->schemes);
258 unset($this->requirements['_scheme']);
261 $this->compiled = null;
267 * Checks if a scheme requirement has been set.
269 * @param string $scheme
271 * @return bool true if the scheme requirement exists, otherwise false
273 public function hasScheme($scheme)
275 return in_array(strtolower($scheme), $this->schemes, true);
279 * Returns the uppercased HTTP methods this route is restricted to.
280 * So an empty array means that any method is allowed.
282 * @return array The methods
284 public function getMethods()
286 return $this->methods;
290 * Sets the HTTP methods (e.g. 'POST') this route is restricted to.
291 * So an empty array means that any method is allowed.
293 * This method implements a fluent interface.
295 * @param string|array $methods The method or an array of methods
299 public function setMethods($methods)
301 $this->methods = array_map('strtoupper', (array) $methods);
303 // this is to keep BC and will be removed in a future version
304 if ($this->methods) {
305 $this->requirements['_method'] = implode('|', $this->methods);
307 unset($this->requirements['_method']);
310 $this->compiled = null;
316 * Returns the options.
318 * @return array The options
320 public function getOptions()
322 return $this->options;
328 * This method implements a fluent interface.
330 * @param array $options The options
334 public function setOptions(array $options)
336 $this->options = array(
337 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler',
340 return $this->addOptions($options);
346 * This method implements a fluent interface.
348 * @param array $options The options
352 public function addOptions(array $options)
354 foreach ($options as $name => $option) {
355 $this->options[$name] = $option;
357 $this->compiled = null;
363 * Sets an option value.
365 * This method implements a fluent interface.
367 * @param string $name An option name
368 * @param mixed $value The option value
372 public function setOption($name, $value)
374 $this->options[$name] = $value;
375 $this->compiled = null;
381 * Get an option value.
383 * @param string $name An option name
385 * @return mixed The option value or null when not given
387 public function getOption($name)
389 return isset($this->options[$name]) ? $this->options[$name] : null;
393 * Checks if an option has been set.
395 * @param string $name An option name
397 * @return bool true if the option is set, false otherwise
399 public function hasOption($name)
401 return array_key_exists($name, $this->options);
405 * Returns the defaults.
407 * @return array The defaults
409 public function getDefaults()
411 return $this->defaults;
417 * This method implements a fluent interface.
419 * @param array $defaults The defaults
423 public function setDefaults(array $defaults)
425 $this->defaults = array();
427 return $this->addDefaults($defaults);
433 * This method implements a fluent interface.
435 * @param array $defaults The defaults
439 public function addDefaults(array $defaults)
441 foreach ($defaults as $name => $default) {
442 $this->defaults[$name] = $default;
444 $this->compiled = null;
450 * Gets a default value.
452 * @param string $name A variable name
454 * @return mixed The default value or null when not given
456 public function getDefault($name)
458 return isset($this->defaults[$name]) ? $this->defaults[$name] : null;
462 * Checks if a default value is set for the given variable.
464 * @param string $name A variable name
466 * @return bool true if the default value is set, false otherwise
468 public function hasDefault($name)
470 return array_key_exists($name, $this->defaults);
474 * Sets a default value.
476 * @param string $name A variable name
477 * @param mixed $default The default value
481 public function setDefault($name, $default)
483 $this->defaults[$name] = $default;
484 $this->compiled = null;
490 * Returns the requirements.
492 * @return array The requirements
494 public function getRequirements()
496 return $this->requirements;
500 * Sets the requirements.
502 * This method implements a fluent interface.
504 * @param array $requirements The requirements
508 public function setRequirements(array $requirements)
510 $this->requirements = array();
512 return $this->addRequirements($requirements);
518 * This method implements a fluent interface.
520 * @param array $requirements The requirements
524 public function addRequirements(array $requirements)
526 foreach ($requirements as $key => $regex) {
527 $this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
529 $this->compiled = null;
535 * Returns the requirement for the given key.
537 * @param string $key The key
539 * @return string|null The regex or null when not given
541 public function getRequirement($key)
543 if ('_scheme' === $key) {
544 @trigger_error('The "_scheme" requirement is deprecated since version 2.2 and will be removed in 3.0. Use getSchemes() instead.', E_USER_DEPRECATED);
545 } elseif ('_method' === $key) {
546 @trigger_error('The "_method" requirement is deprecated since version 2.2 and will be removed in 3.0. Use getMethods() instead.', E_USER_DEPRECATED);
549 return isset($this->requirements[$key]) ? $this->requirements[$key] : null;
553 * Checks if a requirement is set for the given key.
555 * @param string $key A variable name
557 * @return bool true if a requirement is specified, false otherwise
559 public function hasRequirement($key)
561 return array_key_exists($key, $this->requirements);
565 * Sets a requirement for the given key.
567 * @param string $key The key
568 * @param string $regex The regex
572 public function setRequirement($key, $regex)
574 $this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
575 $this->compiled = null;
581 * Returns the condition.
583 * @return string The condition
585 public function getCondition()
587 return $this->condition;
591 * Sets the condition.
593 * This method implements a fluent interface.
595 * @param string $condition The condition
599 public function setCondition($condition)
601 $this->condition = (string) $condition;
602 $this->compiled = null;
608 * Compiles the route.
610 * @return CompiledRoute A CompiledRoute instance
612 * @throws \LogicException If the Route cannot be compiled because the
613 * path or host pattern is invalid
615 * @see RouteCompiler which is responsible for the compilation process
617 public function compile()
619 if (null !== $this->compiled) {
620 return $this->compiled;
623 $class = $this->getOption('compiler_class');
625 return $this->compiled = $class::compile($this);
628 private function sanitizeRequirement($key, $regex)
630 if (!is_string($regex)) {
631 throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" must be a string.', $key));
634 if ('' !== $regex && '^' === $regex[0]) {
635 $regex = (string) substr($regex, 1); // returns false for a single character
638 if ('$' === substr($regex, -1)) {
639 $regex = substr($regex, 0, -1);
643 throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" cannot be empty.', $key));
646 // this is to keep BC and will be removed in a future version
647 if ('_scheme' === $key) {
648 @trigger_error('The "_scheme" requirement is deprecated since version 2.2 and will be removed in 3.0. Use the setSchemes() method instead.', E_USER_DEPRECATED);
650 $this->setSchemes(explode('|', $regex));
651 } elseif ('_method' === $key) {
652 @trigger_error('The "_method" requirement is deprecated since version 2.2 and will be removed in 3.0. Use the setMethods() method instead.', E_USER_DEPRECATED);
654 $this->setMethods(explode('|', $regex));