Skip to content
Permalink
Browse files

Add HTTP method to Route::parse()

This makes route parsing independent of global state and allows for
dependencies to be explicit. This change follows our backwards
compatibility guidelines as the new argument has a default parameter.
I've updated most of the tests to use the new method signature, but I've
also left a few tests behind for the now deprecated functionality.

This is also a necessary step for the PSR7 work I've been prototyping.
  • Loading branch information...
markstory committed Feb 26, 2016
1 parent fe81e40 commit 54e26ce29938ccd8fa8769a7f52d27dbbc8a5983
@@ -52,7 +52,7 @@ public function beforeDispatch(Event $event)
try {
if (empty($request->params['controller'])) {
$params = Router::parse($request->url);
$params = Router::parse($request->url, $request->method());
$request->addParams($params);
}
} catch (RedirectException $e) {
@@ -56,11 +56,12 @@ protected function _camelizePlugin($plugin)
* camelBacked form.
*
* @param string $url The URL to parse
* @param string $method The HTTP method.
* @return array|false An array of request parameters, or false on failure.
*/
public function parse($url)
public function parse($url, $method = '')
{
$params = parent::parse($url);
$params = parent::parse($url, $method);
if (!$params) {
return false;
}
@@ -38,9 +38,10 @@ class InflectedRoute extends Route
* plugin keys to their camelized form.
*
* @param string $url The URL to parse
* @param string $method The HTTP method being matched.
* @return array|false An array of request parameters, or false on failure.
*/
public function parse($url)
public function parse($url, $method = '')
{
$params = parent::parse($url);
if (!$params) {
@@ -27,11 +27,12 @@ class PluginShortRoute extends InflectedRoute
* controller parameter.
*
* @param string $url The URL to parse
* @param string $method The HTTP method
* @return array|false An array of request parameters, or boolean false on failure.
*/
public function parse($url)
public function parse($url, $method = '')
{
$params = parent::parse($url);
$params = parent::parse($url, $method);
if (!$params) {
return false;
}
@@ -64,13 +64,14 @@ public function __construct($template, $defaults = [], array $options = [])
* redirection.
*
* @param string $url The URL to parse.
* @param string $method The HTTP method being used.
* @return false|null False on failure. An exception is raised on a successful match.
* @throws \Cake\Routing\Exception\RedirectException An exception is raised on successful match.
* This is used to halt route matching and signal to the middleware that a redirect should happen.
*/
public function parse($url)
public function parse($url, $method = '')
{
$params = parent::parse($url);
$params = parent::parse($url, $method);
if (!$params) {
return false;
}
@@ -257,12 +257,11 @@ public function getName()
* false will be returned. String URLs are parsed if they match a routes regular expression.
*
* @param string $url The URL to attempt to parse.
* @param string $method The HTTP method of the request being parsed.
* @return array|false An array of request parameters, or false on failure.
*/
public function parse($url)
public function parse($url, $method = '')
{
$request = Router::getRequest(true) ?: Request::createFromGlobals();
if (empty($this->_compiledRoute)) {
$this->compile();
}
@@ -273,7 +272,11 @@ public function parse($url)
}
if (isset($this->defaults['_method'])) {
$method = $request->env('REQUEST_METHOD');
if (empty($method)) {
// Deprecated reading the global state is deprecated and will be removed in 4.x
$request = Router::getRequest(true) ?: Request::createFromGlobals();
$method = $request->env('REQUEST_METHOD');
}
if (!in_array($method, (array)$this->defaults['_method'], true)) {
return false;
}
@@ -105,10 +105,11 @@ public function add(Route $route, array $options = [])
* Takes the URL string and iterates the routes until one is able to parse the route.
*
* @param string $url URL to parse.
* @param string $method The HTTP method to use.
* @return array An array of request parameters parsed from the URL.
* @throws \Cake\Routing\Exception\MissingRouteException When a URL has no matching route.
*/
public function parse($url)
public function parse($url, $method = '')
{
$decoded = urldecode($url);
foreach (array_keys($this->_paths) as $path) {
@@ -122,7 +123,7 @@ public function parse($url)
parse_str($queryParameters, $queryParameters);
}
foreach ($this->_paths[$path] as $route) {
$r = $route->parse($url);
$r = $route->parse($url, $method);
if ($r === false) {
continue;
}
@@ -323,19 +323,20 @@ public static function mapResources($controller, $options = [])
/**
* Parses given URL string. Returns 'routing' parameters for that URL.
*
* @param string $url URL to be parsed
* @return array Parsed elements from URL
* @param string $url URL to be parsed.
* @param string $method The HTTP method being used.
* @return array Parsed elements from URL.
* @throws \Cake\Routing\Exception\MissingRouteException When a route cannot be handled
*/
public static function parse($url)
public static function parse($url, $method = '')
{
if (!static::$initialized) {
static::_loadRoutes();
}
if (strpos($url, '/') !== 0) {
$url = '/' . $url;
}
return static::$_collection->parse($url);
return static::$_collection->parse($url, $method);
}
/**
@@ -146,21 +146,21 @@ public function testParse()
{
$route = new DashedRoute('/:controller/:action/:id', [], ['id' => Router::ID]);
$route->compile();
$result = $route->parse('/my-posts/my-view/1');
$result = $route->parse('/my-posts/my-view/1', 'GET');
$this->assertEquals('MyPosts', $result['controller']);
$this->assertEquals('myView', $result['action']);
$this->assertEquals('1', $result['id']);
$route = new DashedRoute('/:controller/:action-:id');
$route->compile();
$result = $route->parse('/my-posts/my-view-1');
$result = $route->parse('/my-posts/my-view-1', 'GET');
$this->assertEquals('MyPosts', $result['controller']);
$this->assertEquals('myView', $result['action']);
$this->assertEquals('1', $result['id']);
$route = new DashedRoute('/:controller/:action/:slug-:id', [], ['id' => Router::ID]);
$route->compile();
$result = $route->parse('/my-posts/my-view/the-slug-1');
$result = $route->parse('/my-posts/my-view/the-slug-1', 'GET');
$this->assertEquals('MyPosts', $result['controller']);
$this->assertEquals('myView', $result['action']);
$this->assertEquals('1', $result['id']);
@@ -171,23 +171,23 @@ public function testParse()
['prefix' => 'admin', 'action' => 'index']
);
$route->compile();
$result = $route->parse('/admin/');
$result = $route->parse('/admin/', 'GET');
$this->assertFalse($result);
$result = $route->parse('/admin/my-posts');
$result = $route->parse('/admin/my-posts', 'GET');
$this->assertEquals('MyPosts', $result['controller']);
$this->assertEquals('index', $result['action']);
$route = new DashedRoute(
'/media/search/*',
['controller' => 'Media', 'action' => 'searchIt']
);
$result = $route->parse('/media/search');
$result = $route->parse('/media/search', 'GET');
$this->assertEquals('Media', $result['controller']);
$this->assertEquals('searchIt', $result['action']);
$this->assertEquals([], $result['pass']);
$result = $route->parse('/media/search/tv_shows');
$result = $route->parse('/media/search/tv_shows', 'GET');
$this->assertEquals('Media', $result['controller']);
$this->assertEquals('searchIt', $result['action']);
$this->assertEquals(['tv_shows'], $result['pass']);
@@ -208,7 +208,7 @@ public function testMatchThenParse()
]);
$expectedUrl = '/plugin/controller-name/action-name';
$this->assertEquals($expectedUrl, $url);
$result = $route->parse($expectedUrl);
$result = $route->parse($expectedUrl, 'GET');
$this->assertEquals('ControllerName', $result['controller']);
$this->assertEquals('actionName', $result['action']);
$this->assertEquals('Vendor/PluginName', $result['plugin']);
@@ -146,21 +146,21 @@ public function testParse()
{
$route = new InflectedRoute('/:controller/:action/:id', [], ['id' => Router::ID]);
$route->compile();
$result = $route->parse('/my_posts/my_view/1');
$result = $route->parse('/my_posts/my_view/1', 'GET');
$this->assertEquals('MyPosts', $result['controller']);
$this->assertEquals('my_view', $result['action']);
$this->assertEquals('1', $result['id']);
$route = new InflectedRoute('/:controller/:action-:id');
$route->compile();
$result = $route->parse('/my_posts/my_view-1');
$result = $route->parse('/my_posts/my_view-1', 'GET');
$this->assertEquals('MyPosts', $result['controller']);
$this->assertEquals('my_view', $result['action']);
$this->assertEquals('1', $result['id']);
$route = new InflectedRoute('/:controller/:action/:slug-:id', [], ['id' => Router::ID]);
$route->compile();
$result = $route->parse('/my_posts/my_view/the-slug-1');
$result = $route->parse('/my_posts/my_view/the-slug-1', 'GET');
$this->assertEquals('MyPosts', $result['controller']);
$this->assertEquals('my_view', $result['action']);
$this->assertEquals('1', $result['id']);
@@ -171,23 +171,23 @@ public function testParse()
['prefix' => 'admin', 'action' => 'index']
);
$route->compile();
$result = $route->parse('/admin/');
$result = $route->parse('/admin/', 'GET');
$this->assertFalse($result);
$result = $route->parse('/admin/my_posts');
$result = $route->parse('/admin/my_posts', 'GET');
$this->assertEquals('MyPosts', $result['controller']);
$this->assertEquals('index', $result['action']);
$route = new InflectedRoute(
'/media/search/*',
['controller' => 'Media', 'action' => 'search_it']
);
$result = $route->parse('/media/search');
$result = $route->parse('/media/search', 'GET');
$this->assertEquals('Media', $result['controller']);
$this->assertEquals('search_it', $result['action']);
$this->assertEquals([], $result['pass']);
$result = $route->parse('/media/search/tv_shows');
$result = $route->parse('/media/search/tv_shows', 'GET');
$this->assertEquals('Media', $result['controller']);
$this->assertEquals('search_it', $result['action']);
$this->assertEquals(['tv_shows'], $result['pass']);
@@ -208,7 +208,7 @@ public function testMatchThenParse()
]);
$expectedUrl = '/plugin/controller_name/action_name';
$this->assertEquals($expectedUrl, $url);
$result = $route->parse($expectedUrl);
$result = $route->parse($expectedUrl, 'GET');
$this->assertEquals('ControllerName', $result['controller']);
$this->assertEquals('action_name', $result['action']);
$this->assertEquals('Vendor/PluginName', $result['plugin']);
@@ -48,12 +48,12 @@ public function testParsing()
{
$route = new PluginShortRoute('/:plugin', ['action' => 'index'], ['plugin' => 'foo|bar']);
$result = $route->parse('/foo');
$result = $route->parse('/foo', 'GET');
$this->assertEquals('Foo', $result['plugin']);
$this->assertEquals('Foo', $result['controller']);
$this->assertEquals('index', $result['action']);
$result = $route->parse('/wrong');
$result = $route->parse('/wrong', 'GET');
$this->assertFalse($result, 'Wrong plugin name matched %s');
}
Oops, something went wrong.

0 comments on commit 54e26ce

Please sign in to comment.
You can’t perform that action at this time.