Skip to content

Commit

Permalink
Add setMethod() to Route.
Browse files Browse the repository at this point in the history
Add a fluent setter to define HTTP methods on routes.
  • Loading branch information
markstory committed May 24, 2017
1 parent e23f836 commit 45474a4
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 4 deletions.
39 changes: 35 additions & 4 deletions src/Routing/Route/Route.php
Expand Up @@ -16,6 +16,7 @@

use Cake\Http\ServerRequest;
use Cake\Routing\Router;
use InvalidArgumentException;
use Psr\Http\Message\ServerRequestInterface;

/**
Expand Down Expand Up @@ -86,6 +87,13 @@ class Route
*/
protected $_extensions = [];

/**
* Valid HTTP methods.
*
* @var array
*/
const VALID_METHODS = ['GET', 'PUT', 'POST', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD'];

/**
* Constructor for a Route
*
Expand All @@ -104,11 +112,12 @@ class Route
public function __construct($template, $defaults = [], array $options = [])
{
$this->template = $template;
$this->defaults = (array)$defaults;
if (isset($this->defaults['[method]'])) {
$this->defaults['_method'] = $this->defaults['[method]'];
unset($this->defaults['[method]']);
// @deprecated The `[method]` format should be removed in 4.0.0
if (isset($defaults['[method]'])) {
$defaults['_method'] = $defaults['[method]'];
unset($defaults['[method]']);
}
$this->defaults = (array)$defaults;
$this->options = $options + ['_ext' => []];
$this->setExtensions((array)$this->options['_ext']);
}
Expand Down Expand Up @@ -151,6 +160,27 @@ public function getExtensions()
return $this->_extensions;
}

/**
* Set the accepted HTTP methods for this route.
*
* @param array $methods The HTTP methods to accept.
* @return $this
* @throws \InvalidArgumentException
*/
public function setMethods(array $methods)
{
$methods = array_map('strtoupper', $methods);
$diff = array_diff($methods, static::VALID_METHODS);
if ($diff !== []) {
throw new InvalidArgumentException(
sprintf('Invalid HTTP method received. %s is invalid.', implode(', ', $diff))
);
}
$this->defaults['_method'] = $methods;

return $this;
}

/**
* Check if a Route has been compiled into a regular expression.
*
Expand Down Expand Up @@ -623,6 +653,7 @@ protected function _matchMethod($url)
if (empty($this->defaults['_method'])) {
return true;
}
// @deprecated The `[method]` support should be removed in 4.0.0
if (isset($url['[method]'])) {
$url['_method'] = $url['[method]'];
}
Expand Down
30 changes: 30 additions & 0 deletions tests/TestCase/Routing/Route/RouteTest.php
Expand Up @@ -1523,4 +1523,34 @@ public function testSetState()
];
$this->assertEquals($expected, $route->parse('/', 'GET'));
}

/**
* Test setting the method on a route.
*
* @return void
*/
public function testSetMethods()
{
$route = new Route('/books/reviews', ['controller' => 'Reviews', 'action' => 'index']);
$result = $route->setMethods(['put']);

$this->assertSame($result, $route, 'Should return this');
$this->assertSame(['PUT'], $route->defaults['_method'], 'method is wrong');

$route->setMethods(['post', 'get', 'patch']);
$this->assertSame(['POST', 'GET', 'PATCH'], $route->defaults['_method']);
}

/**
* Test setting the method on a route to an invalid method
*
* @expectedException InvalidArgumentException
* @expectedExceptionMessage Invalid HTTP method received. NOPE is invalid
* @return void
*/
public function testSetMethodsInvalid()
{
$route = new Route('/books/reviews', ['controller' => 'Reviews', 'action' => 'index']);
$route->setMethods(['nope']);
}
}

0 comments on commit 45474a4

Please sign in to comment.