2015-08-18 00:00:26 +00:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Component\Routing ;
/**
* A Route describes a route and its parameters .
*
* @ author Fabien Potencier < fabien @ symfony . com >
* @ author Tobias Schultze < http :// tobion . de >
*/
class Route implements \Serializable
{
/**
* @ var string
*/
private $path = '/' ;
/**
* @ var string
*/
private $host = '' ;
/**
* @ var array
*/
private $schemes = array ();
/**
* @ var array
*/
private $methods = array ();
/**
* @ var array
*/
private $defaults = array ();
/**
* @ var array
*/
private $requirements = array ();
/**
* @ var array
*/
private $options = array ();
/**
* @ var null | CompiledRoute
*/
private $compiled ;
/**
* @ var string
*/
private $condition = '' ;
/**
* Constructor .
*
* Available options :
*
* * compiler_class : A class name able to compile this route instance ( RouteCompiler by default )
*
* @ param string $path The path pattern to match
* @ param array $defaults An array of default parameter values
* @ param array $requirements An array of requirements for parameters ( regexes )
* @ param array $options An array of options
* @ param string $host The host pattern to match
* @ param string | array $schemes A required URI scheme or an array of restricted schemes
* @ param string | array $methods A required HTTP method or an array of restricted methods
* @ param string $condition A condition that should evaluate to true for the route to match
*/
public function __construct ( $path , array $defaults = array (), array $requirements = array (), array $options = array (), $host = '' , $schemes = array (), $methods = array (), $condition = '' )
{
$this -> setPath ( $path );
$this -> setDefaults ( $defaults );
$this -> setRequirements ( $requirements );
$this -> setOptions ( $options );
$this -> setHost ( $host );
// The conditions make sure that an initial empty $schemes/$methods does not override the corresponding requirement.
// They can be removed when the BC layer is removed.
if ( $schemes ) {
$this -> setSchemes ( $schemes );
}
if ( $methods ) {
$this -> setMethods ( $methods );
}
$this -> setCondition ( $condition );
}
/**
* { @ inheritdoc }
*/
public function serialize ()
{
return serialize ( array (
'path' => $this -> path ,
'host' => $this -> host ,
'defaults' => $this -> defaults ,
'requirements' => $this -> requirements ,
'options' => $this -> options ,
'schemes' => $this -> schemes ,
'methods' => $this -> methods ,
'condition' => $this -> condition ,
'compiled' => $this -> compiled ,
));
}
/**
* { @ inheritdoc }
*/
public function unserialize ( $serialized )
{
$data = unserialize ( $serialized );
$this -> path = $data [ 'path' ];
$this -> host = $data [ 'host' ];
$this -> defaults = $data [ 'defaults' ];
$this -> requirements = $data [ 'requirements' ];
$this -> options = $data [ 'options' ];
$this -> schemes = $data [ 'schemes' ];
$this -> methods = $data [ 'methods' ];
if ( isset ( $data [ 'condition' ])) {
$this -> condition = $data [ 'condition' ];
}
if ( isset ( $data [ 'compiled' ])) {
$this -> compiled = $data [ 'compiled' ];
}
}
/**
* Returns the pattern for the path .
*
* @ return string The pattern
*
* @ deprecated since version 2.2 , to be removed in 3.0 . Use getPath instead .
*/
public function getPattern ()
{
2015-08-27 19:03:05 +00:00
@ 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 );
2015-08-18 00:00:26 +00:00
return $this -> path ;
}
/**
* Sets the pattern for the path .
*
* This method implements a fluent interface .
*
* @ param string $pattern The path pattern
*
* @ return Route The current Route instance
*
* @ deprecated since version 2.2 , to be removed in 3.0 . Use setPath instead .
*/
public function setPattern ( $pattern )
{
2015-08-27 19:03:05 +00:00
@ 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 );
2015-08-18 00:00:26 +00:00
return $this -> setPath ( $pattern );
}
/**
* Returns the pattern for the path .
*
* @ return string The path pattern
*/
public function getPath ()
{
return $this -> path ;
}
/**
* Sets the pattern for the path .
*
* This method implements a fluent interface .
*
* @ param string $pattern The path pattern
*
* @ return Route The current Route instance
*/
public function setPath ( $pattern )
{
// A pattern must start with a slash and must not have multiple slashes at the beginning because the
// generated path for this route would be confused with a network path, e.g. '//domain.com/path'.
$this -> path = '/' . ltrim ( trim ( $pattern ), '/' );
$this -> compiled = null ;
return $this ;
}
/**
* Returns the pattern for the host .
*
* @ return string The host pattern
*/
public function getHost ()
{
return $this -> host ;
}
/**
* Sets the pattern for the host .
*
* This method implements a fluent interface .
*
* @ param string $pattern The host pattern
*
* @ return Route The current Route instance
*/
public function setHost ( $pattern )
{
$this -> host = ( string ) $pattern ;
$this -> compiled = null ;
return $this ;
}
/**
* Returns the lowercased schemes this route is restricted to .
* So an empty array means that any scheme is allowed .
*
* @ return array The schemes
*/
public function getSchemes ()
{
return $this -> schemes ;
}
/**
* Sets the schemes ( e . g . 'https' ) this route is restricted to .
* So an empty array means that any scheme is allowed .
*
* This method implements a fluent interface .
*
* @ param string | array $schemes The scheme or an array of schemes
*
* @ return Route The current Route instance
*/
public function setSchemes ( $schemes )
{
$this -> schemes = array_map ( 'strtolower' , ( array ) $schemes );
// this is to keep BC and will be removed in a future version
if ( $this -> schemes ) {
$this -> requirements [ '_scheme' ] = implode ( '|' , $this -> schemes );
} else {
unset ( $this -> requirements [ '_scheme' ]);
}
$this -> compiled = null ;
return $this ;
}
/**
* Checks if a scheme requirement has been set .
*
* @ param string $scheme
*
* @ return bool true if the scheme requirement exists , otherwise false
*/
public function hasScheme ( $scheme )
{
return in_array ( strtolower ( $scheme ), $this -> schemes , true );
}
/**
* Returns the uppercased HTTP methods this route is restricted to .
* So an empty array means that any method is allowed .
*
* @ return array The methods
*/
public function getMethods ()
{
return $this -> methods ;
}
/**
* Sets the HTTP methods ( e . g . 'POST' ) this route is restricted to .
* So an empty array means that any method is allowed .
*
* This method implements a fluent interface .
*
* @ param string | array $methods The method or an array of methods
*
* @ return Route The current Route instance
*/
public function setMethods ( $methods )
{
$this -> methods = array_map ( 'strtoupper' , ( array ) $methods );
// this is to keep BC and will be removed in a future version
if ( $this -> methods ) {
$this -> requirements [ '_method' ] = implode ( '|' , $this -> methods );
} else {
unset ( $this -> requirements [ '_method' ]);
}
$this -> compiled = null ;
return $this ;
}
/**
* Returns the options .
*
* @ return array The options
*/
public function getOptions ()
{
return $this -> options ;
}
/**
* Sets the options .
*
* This method implements a fluent interface .
*
* @ param array $options The options
*
* @ return Route The current Route instance
*/
public function setOptions ( array $options )
{
$this -> options = array (
'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler' ,
);
return $this -> addOptions ( $options );
}
/**
* Adds options .
*
* This method implements a fluent interface .
*
* @ param array $options The options
*
* @ return Route The current Route instance
*/
public function addOptions ( array $options )
{
foreach ( $options as $name => $option ) {
$this -> options [ $name ] = $option ;
}
$this -> compiled = null ;
return $this ;
}
/**
* Sets an option value .
*
* This method implements a fluent interface .
*
* @ param string $name An option name
* @ param mixed $value The option value
*
* @ return Route The current Route instance
*/
public function setOption ( $name , $value )
{
$this -> options [ $name ] = $value ;
$this -> compiled = null ;
return $this ;
}
/**
* Get an option value .
*
* @ param string $name An option name
*
* @ return mixed The option value or null when not given
*/
public function getOption ( $name )
{
return isset ( $this -> options [ $name ]) ? $this -> options [ $name ] : null ;
}
/**
* Checks if an option has been set .
*
* @ param string $name An option name
*
* @ return bool true if the option is set , false otherwise
*/
public function hasOption ( $name )
{
return array_key_exists ( $name , $this -> options );
}
/**
* Returns the defaults .
*
* @ return array The defaults
*/
public function getDefaults ()
{
return $this -> defaults ;
}
/**
* Sets the defaults .
*
* This method implements a fluent interface .
*
* @ param array $defaults The defaults
*
* @ return Route The current Route instance
*/
public function setDefaults ( array $defaults )
{
$this -> defaults = array ();
return $this -> addDefaults ( $defaults );
}
/**
* Adds defaults .
*
* This method implements a fluent interface .
*
* @ param array $defaults The defaults
*
* @ return Route The current Route instance
*/
public function addDefaults ( array $defaults )
{
foreach ( $defaults as $name => $default ) {
$this -> defaults [ $name ] = $default ;
}
$this -> compiled = null ;
return $this ;
}
/**
* Gets a default value .
*
* @ param string $name A variable name
*
* @ return mixed The default value or null when not given
*/
public function getDefault ( $name )
{
return isset ( $this -> defaults [ $name ]) ? $this -> defaults [ $name ] : null ;
}
/**
* Checks if a default value is set for the given variable .
*
* @ param string $name A variable name
*
* @ return bool true if the default value is set , false otherwise
*/
public function hasDefault ( $name )
{
return array_key_exists ( $name , $this -> defaults );
}
/**
* Sets a default value .
*
* @ param string $name A variable name
* @ param mixed $default The default value
*
* @ return Route The current Route instance
*/
public function setDefault ( $name , $default )
{
$this -> defaults [ $name ] = $default ;
$this -> compiled = null ;
return $this ;
}
/**
* Returns the requirements .
*
* @ return array The requirements
*/
public function getRequirements ()
{
return $this -> requirements ;
}
/**
* Sets the requirements .
*
* This method implements a fluent interface .
*
* @ param array $requirements The requirements
*
* @ return Route The current Route instance
*/
public function setRequirements ( array $requirements )
{
$this -> requirements = array ();
return $this -> addRequirements ( $requirements );
}
/**
* Adds requirements .
*
* This method implements a fluent interface .
*
* @ param array $requirements The requirements
*
* @ return Route The current Route instance
*/
public function addRequirements ( array $requirements )
{
foreach ( $requirements as $key => $regex ) {
$this -> requirements [ $key ] = $this -> sanitizeRequirement ( $key , $regex );
}
$this -> compiled = null ;
return $this ;
}
/**
* Returns the requirement for the given key .
*
* @ param string $key The key
*
* @ return string | null The regex or null when not given
*/
public function getRequirement ( $key )
{
if ( '_scheme' === $key ) {
2015-08-27 19:03:05 +00:00
@ trigger_error ( 'The "_scheme" requirement is deprecated since version 2.2 and will be removed in 3.0. Use getSchemes() instead.' , E_USER_DEPRECATED );
2015-08-18 00:00:26 +00:00
} elseif ( '_method' === $key ) {
2015-08-27 19:03:05 +00:00
@ trigger_error ( 'The "_method" requirement is deprecated since version 2.2 and will be removed in 3.0. Use getMethods() instead.' , E_USER_DEPRECATED );
2015-08-18 00:00:26 +00:00
}
return isset ( $this -> requirements [ $key ]) ? $this -> requirements [ $key ] : null ;
}
/**
* Checks if a requirement is set for the given key .
*
* @ param string $key A variable name
*
* @ return bool true if a requirement is specified , false otherwise
*/
public function hasRequirement ( $key )
{
return array_key_exists ( $key , $this -> requirements );
}
/**
* Sets a requirement for the given key .
*
* @ param string $key The key
* @ param string $regex The regex
*
* @ return Route The current Route instance
*/
public function setRequirement ( $key , $regex )
{
$this -> requirements [ $key ] = $this -> sanitizeRequirement ( $key , $regex );
$this -> compiled = null ;
return $this ;
}
/**
* Returns the condition .
*
* @ return string The condition
*/
public function getCondition ()
{
return $this -> condition ;
}
/**
* Sets the condition .
*
* This method implements a fluent interface .
*
* @ param string $condition The condition
*
* @ return Route The current Route instance
*/
public function setCondition ( $condition )
{
$this -> condition = ( string ) $condition ;
$this -> compiled = null ;
return $this ;
}
/**
* Compiles the route .
*
* @ return CompiledRoute A CompiledRoute instance
*
* @ throws \LogicException If the Route cannot be compiled because the
* path or host pattern is invalid
*
* @ see RouteCompiler which is responsible for the compilation process
*/
public function compile ()
{
if ( null !== $this -> compiled ) {
return $this -> compiled ;
}
$class = $this -> getOption ( 'compiler_class' );
return $this -> compiled = $class :: compile ( $this );
}
private function sanitizeRequirement ( $key , $regex )
{
if ( ! is_string ( $regex )) {
throw new \InvalidArgumentException ( sprintf ( 'Routing requirement for "%s" must be a string.' , $key ));
}
if ( '' !== $regex && '^' === $regex [ 0 ]) {
$regex = ( string ) substr ( $regex , 1 ); // returns false for a single character
}
if ( '$' === substr ( $regex , - 1 )) {
$regex = substr ( $regex , 0 , - 1 );
}
if ( '' === $regex ) {
throw new \InvalidArgumentException ( sprintf ( 'Routing requirement for "%s" cannot be empty.' , $key ));
}
// this is to keep BC and will be removed in a future version
if ( '_scheme' === $key ) {
2015-08-27 19:03:05 +00:00
@ 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 );
2015-08-18 00:00:26 +00:00
$this -> setSchemes ( explode ( '|' , $regex ));
} elseif ( '_method' === $key ) {
2015-08-27 19:03:05 +00:00
@ 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 );
2015-08-18 00:00:26 +00:00
$this -> setMethods ( explode ( '|' , $regex ));
}
return $regex ;
}
}