make scheme and method requirements first-class citizen in Route
This commit is contained in:
parent
18c520a5e8
commit
10183ded68
@ -15,6 +15,7 @@ namespace Symfony\Component\Routing;
|
||||
* A Route describes a route and its parameters.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Tobias Schultze <http://tobion.de>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
@ -30,7 +31,17 @@ class Route implements \Serializable
|
||||
*/
|
||||
private $hostnamePattern = '';
|
||||
|
||||
/**
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $schemes = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $methods = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $defaults = array();
|
||||
@ -59,21 +70,32 @@ class Route implements \Serializable
|
||||
*
|
||||
* * compiler_class: A class name able to compile this route instance (RouteCompiler by default)
|
||||
*
|
||||
* @param string $pattern 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 $hostnamePattern The hostname pattern to match
|
||||
* @param string $pattern 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 $hostnamePattern The hostname 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
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct($pattern, array $defaults = array(), array $requirements = array(), array $options = array(), $hostnamePattern = '')
|
||||
public function __construct($pattern, array $defaults = array(), array $requirements = array(), array $options = array(),
|
||||
$hostnamePattern = '', $schemes = array(), $methods = array())
|
||||
{
|
||||
$this->setPattern($pattern);
|
||||
$this->setDefaults($defaults);
|
||||
$this->setRequirements($requirements);
|
||||
$this->setOptions($options);
|
||||
$this->setHostnamePattern($hostnamePattern);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
public function serialize()
|
||||
@ -84,6 +106,8 @@ class Route implements \Serializable
|
||||
'defaults' => $this->defaults,
|
||||
'requirements' => $this->requirements,
|
||||
'options' => $this->options,
|
||||
'schemes' => $this->schemes,
|
||||
'methods' => $this->methods,
|
||||
));
|
||||
}
|
||||
|
||||
@ -95,6 +119,8 @@ class Route implements \Serializable
|
||||
$this->defaults = $data['defaults'];
|
||||
$this->requirements = $data['requirements'];
|
||||
$this->options = $data['options'];
|
||||
$this->schemes = $data['schemes'];
|
||||
$this->methods = $data['methods'];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -149,6 +175,80 @@ class Route implements \Serializable
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the uppercased HTTP methods this route is restricted to.
|
||||
* So an empty array means that any method is allowed.
|
||||
*
|
||||
* @return array The schemes
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@ -454,6 +554,13 @@ class Route implements \Serializable
|
||||
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) {
|
||||
$this->setSchemes(explode('|', $regex));
|
||||
} elseif ('_method' === $key) {
|
||||
$this->setMethods(explode('|', $regex));
|
||||
}
|
||||
|
||||
return $regex;
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,14 @@ class RouteTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals(array('foo' => '\d+'), $route->getRequirements(), '__construct() takes requirements as its third argument');
|
||||
$this->assertEquals('bar', $route->getOption('foo'), '__construct() takes options as its fourth argument');
|
||||
$this->assertEquals('{locale}.example.com', $route->getHostnamePattern(), '__construct() takes a hostname pattern as its fifth argument');
|
||||
|
||||
$route = new Route('/', array(), array(), array(), '', array('Https'), array('POST', 'put'));
|
||||
$this->assertEquals(array('https'), $route->getSchemes(), '__construct() takes schemes as its sixth argument and lowercases it');
|
||||
$this->assertEquals(array('POST', 'PUT'), $route->getMethods(), '__construct() takes methods as its seventh argument and uppercases it');
|
||||
|
||||
$route = new Route('/', array(), array(), array(), '', 'Https', 'Post');
|
||||
$this->assertEquals(array('https'), $route->getSchemes(), '__construct() takes a single scheme as its sixth argument');
|
||||
$this->assertEquals(array('POST'), $route->getMethods(), '__construct() takes a single method as its seventh argument');
|
||||
}
|
||||
|
||||
public function testPattern()
|
||||
@ -129,6 +137,50 @@ class RouteTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('{locale}.example.net', $route->getHostnamePattern(), '->setHostnamePattern() sets the hostname pattern');
|
||||
}
|
||||
|
||||
public function testScheme()
|
||||
{
|
||||
$route = new Route('/');
|
||||
$this->assertEquals(array(), $route->getSchemes(), 'schemes is initialized with array()');
|
||||
$route->setSchemes('hTTp');
|
||||
$this->assertEquals(array('http'), $route->getSchemes(), '->setSchemes() accepts a single scheme string and lowercases it');
|
||||
$route->setSchemes(array('HttpS', 'hTTp'));
|
||||
$this->assertEquals(array('https', 'http'), $route->getSchemes(), '->setSchemes() accepts an array of schemes and lowercases them');
|
||||
}
|
||||
|
||||
public function testSchemeIsBC()
|
||||
{
|
||||
$route = new Route('/');
|
||||
$route->setRequirement('_scheme', 'http|https');
|
||||
$this->assertEquals('http|https', $route->getRequirement('_scheme'));
|
||||
$this->assertEquals(array('http', 'https'), $route->getSchemes());
|
||||
$route->setSchemes(array('hTTp'));
|
||||
$this->assertEquals('http', $route->getRequirement('_scheme'));
|
||||
$route->setSchemes(array());
|
||||
$this->assertNull($route->getRequirement('_scheme'));
|
||||
}
|
||||
|
||||
public function testMethod()
|
||||
{
|
||||
$route = new Route('/');
|
||||
$this->assertEquals(array(), $route->getMethods(), 'methods is initialized with array()');
|
||||
$route->setMethods('gEt');
|
||||
$this->assertEquals(array('GET'), $route->getMethods(), '->setMethods() accepts a single method string and uppercases it');
|
||||
$route->setMethods(array('gEt', 'PosT'));
|
||||
$this->assertEquals(array('GET', 'POST'), $route->getMethods(), '->setMethods() accepts an array of methods and uppercases them');
|
||||
}
|
||||
|
||||
public function testMethodIsBC()
|
||||
{
|
||||
$route = new Route('/');
|
||||
$route->setRequirement('_method', 'GET|POST');
|
||||
$this->assertEquals('GET|POST', $route->getRequirement('_method'));
|
||||
$this->assertEquals(array('GET', 'POST'), $route->getMethods());
|
||||
$route->setMethods(array('gEt'));
|
||||
$this->assertEquals('GET', $route->getRequirement('_method'));
|
||||
$route->setMethods(array());
|
||||
$this->assertNull($route->getRequirement('_method'));
|
||||
}
|
||||
|
||||
public function testCompile()
|
||||
{
|
||||
$route = new Route('/{foo}');
|
||||
|
Reference in New Issue
Block a user