Browse Source

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.
Mark Story 10 years ago
parent
commit
54e26ce299

+ 1 - 1
src/Routing/Filter/RoutingFilter.php

@@ -52,7 +52,7 @@ class RoutingFilter extends DispatcherFilter
 
         try {
             if (empty($request->params['controller'])) {
-                $params = Router::parse($request->url);
+                $params = Router::parse($request->url, $request->method());
                 $request->addParams($params);
             }
         } catch (RedirectException $e) {

+ 3 - 2
src/Routing/Route/DashedRoute.php

@@ -56,11 +56,12 @@ class DashedRoute extends Route
      * 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;
         }

+ 2 - 1
src/Routing/Route/InflectedRoute.php

@@ -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) {

+ 3 - 2
src/Routing/Route/PluginShortRoute.php

@@ -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;
         }

+ 3 - 2
src/Routing/Route/RedirectRoute.php

@@ -64,13 +64,14 @@ class RedirectRoute extends Route
      * 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;
         }

+ 7 - 4
src/Routing/Route/Route.php

@@ -257,12 +257,11 @@ class Route
      * 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 @@ class Route
         }
 
         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;
             }

+ 3 - 2
src/Routing/RouteCollection.php

@@ -105,10 +105,11 @@ class RouteCollection
      * 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 @@ class RouteCollection
                 parse_str($queryParameters, $queryParameters);
             }
             foreach ($this->_paths[$path] as $route) {
-                $r = $route->parse($url);
+                $r = $route->parse($url, $method);
                 if ($r === false) {
                     continue;
                 }

+ 5 - 4
src/Routing/Router.php

@@ -323,11 +323,12 @@ class Router
     /**
      * 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();
@@ -335,7 +336,7 @@ class Router
         if (strpos($url, '/') !== 0) {
             $url = '/' . $url;
         }
-        return static::$_collection->parse($url);
+        return static::$_collection->parse($url, $method);
     }
 
     /**

+ 8 - 8
tests/TestCase/Routing/Route/DashedRouteTest.php

@@ -146,21 +146,21 @@ class DashedRouteTest extends TestCase
     {
         $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,10 +171,10 @@ class DashedRouteTest extends TestCase
             ['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']);
 
@@ -182,12 +182,12 @@ class DashedRouteTest extends TestCase
             '/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 @@ class DashedRouteTest extends TestCase
         ]);
         $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']);

+ 8 - 8
tests/TestCase/Routing/Route/InflectedRouteTest.php

@@ -146,21 +146,21 @@ class InflectedRouteTest extends TestCase
     {
         $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,10 +171,10 @@ class InflectedRouteTest extends TestCase
             ['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']);
 
@@ -182,12 +182,12 @@ class InflectedRouteTest extends TestCase
             '/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 @@ class InflectedRouteTest extends TestCase
         ]);
         $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']);

+ 2 - 2
tests/TestCase/Routing/Route/PluginShortRouteTest.php

@@ -48,12 +48,12 @@ class PluginShortRouteTest extends TestCase
     {
         $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');
     }
 

+ 29 - 31
tests/TestCase/Routing/Route/RouteTest.php

@@ -104,20 +104,20 @@ class RouteTest extends TestCase
             ['_ext' => ['json', 'xml']]
         );
 
-        $result = $route->parse('/posts/index');
+        $result = $route->parse('/posts/index', 'GET');
         $this->assertFalse(isset($result['_ext']));
 
-        $result = $route->parse('/posts/index.pdf');
+        $result = $route->parse('/posts/index.pdf', 'GET');
         $this->assertFalse(isset($result['_ext']));
 
         $route->extensions(['pdf', 'json', 'xml']);
-        $result = $route->parse('/posts/index.pdf');
+        $result = $route->parse('/posts/index.pdf', 'GET');
         $this->assertEquals('pdf', $result['_ext']);
 
-        $result = $route->parse('/posts/index.json');
+        $result = $route->parse('/posts/index.json', 'GET');
         $this->assertEquals('json', $result['_ext']);
 
-        $result = $route->parse('/posts/index.xml');
+        $result = $route->parse('/posts/index.xml', 'GET');
         $this->assertEquals('xml', $result['_ext']);
     }
 
@@ -222,7 +222,7 @@ class RouteTest extends TestCase
         );
         $result = $route->compile();
         $this->assertRegExp($result, '/posts/08/01/2007/title-of-post');
-        $result = $route->parse('/posts/08/01/2007/title-of-post');
+        $result = $route->parse('/posts/08/01/2007/title-of-post', 'GET');
 
         $this->assertEquals(count($result), 6);
         $this->assertEquals($result['controller'], 'posts');
@@ -257,7 +257,7 @@ class RouteTest extends TestCase
                 'action' => 'branches|history|branch|logs|view|start|add|edit|modify'
             ]
         );
-        $this->assertFalse($route->parse('/chaw_test/wiki'));
+        $this->assertFalse($route->parse('/chaw_test/wiki', 'GET'));
 
         $result = $route->compile();
         $this->assertNotRegExp($result, '/some_project/source');
@@ -694,7 +694,7 @@ class RouteTest extends TestCase
             ['id' => Router::ID]
         );
         $route->compile();
-        $result = $route->parse('/posts/view/1');
+        $result = $route->parse('/posts/view/1', 'GET');
         $this->assertEquals('posts', $result['controller']);
         $this->assertEquals('view', $result['action']);
         $this->assertEquals('1', $result['id']);
@@ -704,10 +704,10 @@ class RouteTest extends TestCase
             ['prefix' => 'admin', 'admin' => 1, 'action' => 'index']
         );
         $route->compile();
-        $result = $route->parse('/admin/');
+        $result = $route->parse('/admin/', 'GET');
         $this->assertFalse($result);
 
-        $result = $route->parse('/admin/posts');
+        $result = $route->parse('/admin/posts', 'GET');
         $this->assertEquals('posts', $result['controller']);
         $this->assertEquals('index', $result['action']);
 
@@ -715,12 +715,12 @@ class RouteTest extends TestCase
             '/media/search/*',
             ['controller' => 'Media', 'action' => 'search']
         );
-        $result = $route->parse('/media/search');
+        $result = $route->parse('/media/search', 'GET');
         $this->assertEquals('Media', $result['controller']);
         $this->assertEquals('search', $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', $result['action']);
         $this->assertEquals(['tv', 'shows'], $result['pass']);
@@ -738,12 +738,12 @@ class RouteTest extends TestCase
             ['action' => 'view']
         );
         $route->compile();
-        $result = $route->parse('/posts/%E2%88%82%E2%88%82');
+        $result = $route->parse('/posts/%E2%88%82%E2%88%82', 'GET');
         $this->assertEquals('posts', $result['controller']);
         $this->assertEquals('view', $result['action']);
         $this->assertEquals('∂∂', $result['slug']);
 
-        $result = $route->parse('/posts/∂∂');
+        $result = $route->parse('/posts/∂∂', 'GET');
         $this->assertEquals('posts', $result['controller']);
         $this->assertEquals('view', $result['action']);
         $this->assertEquals('∂∂', $result['slug']);
@@ -757,7 +757,7 @@ class RouteTest extends TestCase
     public function testParseWithPassDefaults()
     {
         $route = new Route('/:controller', ['action' => 'display', 'home']);
-        $result = $route->parse('/posts');
+        $result = $route->parse('/posts', 'GET');
         $expected = [
             'controller' => 'posts',
             'action' => 'display',
@@ -773,18 +773,16 @@ class RouteTest extends TestCase
      */
     public function testParseWithHttpHeaderConditions()
     {
-        $_SERVER['REQUEST_METHOD'] = 'GET';
         $route = new Route('/sample', ['controller' => 'posts', 'action' => 'index', '_method' => 'POST']);
-        $this->assertFalse($route->parse('/sample'));
+        $this->assertFalse($route->parse('/sample', 'GET'));
 
-        $_SERVER['REQUEST_METHOD'] = 'POST';
         $expected = [
             'controller' => 'posts',
             'action' => 'index',
             'pass' => [],
             '_method' => 'POST',
         ];
-        $this->assertEquals($expected, $route->parse('/sample'));
+        $this->assertEquals($expected, $route->parse('/sample', 'POST'));
     }
 
     /**
@@ -794,14 +792,14 @@ class RouteTest extends TestCase
      */
     public function testParseWithMultipleHttpMethodConditions()
     {
-        $_SERVER['REQUEST_METHOD'] = 'GET';
         $route = new Route('/sample', [
             'controller' => 'posts',
             'action' => 'index',
             '_method' => ['PUT', 'POST']
         ]);
-        $this->assertFalse($route->parse('/sample'));
+        $this->assertFalse($route->parse('/sample', 'GET'));
 
+        // Test for deprecated behavior
         $_SERVER['REQUEST_METHOD'] = 'POST';
         $expected = [
             'controller' => 'posts',
@@ -898,11 +896,11 @@ class RouteTest extends TestCase
         $result = $route->match(['controller' => 'blog_posts', 'action' => 'actions']);
         $this->assertNotEmpty($result);
 
-        $result = $route->parse('/blog/other');
+        $result = $route->parse('/blog/other', 'GET');
         $expected = ['controller' => 'blog_posts', 'action' => 'other', 'pass' => []];
         $this->assertEquals($expected, $result);
 
-        $result = $route->parse('/blog/foobar');
+        $result = $route->parse('/blog/foobar', 'GET');
         $this->assertFalse($result);
     }
 
@@ -914,7 +912,7 @@ class RouteTest extends TestCase
     public function testParsePassedArgument()
     {
         $route = new Route('/:controller/:action/*');
-        $result = $route->parse('/posts/edit/1/2/0');
+        $result = $route->parse('/posts/edit/1/2/0', 'GET');
         $expected = [
             'controller' => 'posts',
             'action' => 'edit',
@@ -970,7 +968,7 @@ class RouteTest extends TestCase
         $route = new Route('/:controller/:action/:slug', [], [
             'pass' => ['slug']
         ]);
-        $result = $route->parse('/posts/view/my-title');
+        $result = $route->parse('/posts/view/my-title', 'GET');
         $expected = [
             'controller' => 'posts',
             'action' => 'view',
@@ -988,7 +986,7 @@ class RouteTest extends TestCase
     public function testParseTrailing()
     {
         $route = new Route('/:controller/:action/**');
-        $result = $route->parse('/posts/index/1/2/3/foo:bar');
+        $result = $route->parse('/posts/index/1/2/3/foo:bar', 'GET');
         $expected = [
             'controller' => 'posts',
             'action' => 'index',
@@ -996,7 +994,7 @@ class RouteTest extends TestCase
         ];
         $this->assertEquals($expected, $result);
 
-        $result = $route->parse('/posts/index/http://example.com');
+        $result = $route->parse('/posts/index/http://example.com', 'GET');
         $expected = [
             'controller' => 'posts',
             'action' => 'index',
@@ -1013,7 +1011,7 @@ class RouteTest extends TestCase
     public function testParseTrailingUTF8()
     {
         $route = new Route('/category/**', ['controller' => 'categories', 'action' => 'index']);
-        $result = $route->parse('/category/%D9%85%D9%88%D8%A8%D8%A7%DB%8C%D9%84');
+        $result = $route->parse('/category/%D9%85%D9%88%D8%A8%D8%A7%DB%8C%D9%84', 'GET');
         $expected = [
             'controller' => 'categories',
             'action' => 'index',
@@ -1119,11 +1117,11 @@ class RouteTest extends TestCase
             ]
         );
 
-        $result = $route->parse('/%D8%A2%D9%85%D9%88%D8%B2%D8%B4');
+        $result = $route->parse('/%D8%A2%D9%85%D9%88%D8%B2%D8%B4', 'GET');
         $expected = ['section' => 'آموزش', 'plugin' => 'blogs', 'controller' => 'posts', 'action' => 'index', 'pass' => []];
         $this->assertEquals($expected, $result);
 
-        $result = $route->parse('/weblog');
+        $result = $route->parse('/weblog', 'GET');
         $expected = ['section' => 'weblog', 'plugin' => 'blogs', 'controller' => 'posts', 'action' => 'index', 'pass' => []];
         $this->assertEquals($expected, $result);
     }
@@ -1174,6 +1172,6 @@ class RouteTest extends TestCase
         $this->assertSame('/', $route->match(['controller' => 'pages', 'action' => 'display', 'home']));
         $this->assertFalse($route->match(['controller' => 'pages', 'action' => 'display', 'about']));
         $expected = ['controller' => 'pages', 'action' => 'display', 'pass' => ['home']];
-        $this->assertEquals($expected, $route->parse('/'));
+        $this->assertEquals($expected, $route->parse('/', 'GET'));
     }
 }

+ 84 - 87
tests/TestCase/Routing/RouterTest.php

@@ -139,7 +139,6 @@ class RouterTest extends TestCase
     {
         Router::mapResources('Posts');
 
-        $_SERVER['REQUEST_METHOD'] = 'GET';
         $expected = [
             'pass' => [],
             'plugin' => null,
@@ -147,10 +146,9 @@ class RouterTest extends TestCase
             'action' => 'index',
             '_method' => 'GET',
         ];
-        $result = Router::parse('/posts');
+        $result = Router::parse('/posts', 'GET');
         $this->assertEquals($expected, $result);
 
-        $_SERVER['REQUEST_METHOD'] = 'GET';
         $expected = [
             'pass' => ['13'],
             'plugin' => null,
@@ -159,10 +157,9 @@ class RouterTest extends TestCase
             'id' => '13',
             '_method' => 'GET',
         ];
-        $result = Router::parse('/posts/13');
+        $result = Router::parse('/posts/13', 'GET');
         $this->assertEquals($expected, $result);
 
-        $_SERVER['REQUEST_METHOD'] = 'POST';
         $expected = [
             'pass' => [],
             'plugin' => null,
@@ -170,10 +167,9 @@ class RouterTest extends TestCase
             'action' => 'add',
             '_method' => 'POST',
         ];
-        $result = Router::parse('/posts');
+        $result = Router::parse('/posts', 'POST');
         $this->assertEquals($expected, $result);
 
-        $_SERVER['REQUEST_METHOD'] = 'PUT';
         $expected = [
             'pass' => ['13'],
             'plugin' => null,
@@ -182,7 +178,7 @@ class RouterTest extends TestCase
             'id' => '13',
             '_method' => ['PUT', 'PATCH'],
         ];
-        $result = Router::parse('/posts/13');
+        $result = Router::parse('/posts/13', 'PUT');
         $this->assertEquals($expected, $result);
 
         $expected = [
@@ -193,10 +189,9 @@ class RouterTest extends TestCase
             'id' => '475acc39-a328-44d3-95fb-015000000000',
             '_method' => ['PUT', 'PATCH'],
         ];
-        $result = Router::parse('/posts/475acc39-a328-44d3-95fb-015000000000');
+        $result = Router::parse('/posts/475acc39-a328-44d3-95fb-015000000000', 'PUT');
         $this->assertEquals($expected, $result);
 
-        $_SERVER['REQUEST_METHOD'] = 'DELETE';
         $expected = [
             'pass' => ['13'],
             'plugin' => null,
@@ -205,13 +200,12 @@ class RouterTest extends TestCase
             'id' => '13',
             '_method' => 'DELETE',
         ];
-        $result = Router::parse('/posts/13');
+        $result = Router::parse('/posts/13', 'DELETE');
         $this->assertEquals($expected, $result);
 
         Router::reload();
         Router::mapResources('Posts', ['id' => '[a-z0-9_]+']);
 
-        $_SERVER['REQUEST_METHOD'] = 'GET';
         $expected = [
             'pass' => ['add'],
             'plugin' => null,
@@ -220,10 +214,9 @@ class RouterTest extends TestCase
             'id' => 'add',
             '_method' => 'GET',
         ];
-        $result = Router::parse('/posts/add');
+        $result = Router::parse('/posts/add', 'GET');
         $this->assertEquals($expected, $result);
 
-        $_SERVER['REQUEST_METHOD'] = 'PUT';
         $expected = [
             'pass' => ['name'],
             'plugin' => null,
@@ -232,7 +225,7 @@ class RouterTest extends TestCase
             'id' => 'name',
             '_method' => ['PUT', 'PATCH'],
         ];
-        $result = Router::parse('/posts/name');
+        $result = Router::parse('/posts/name', 'PUT');
         $this->assertEquals($expected, $result);
     }
 
@@ -245,8 +238,7 @@ class RouterTest extends TestCase
     {
         Router::mapResources('TestPlugin.TestPlugin');
 
-        $_SERVER['REQUEST_METHOD'] = 'GET';
-        $result = Router::parse('/test_plugin/test_plugin');
+        $result = Router::parse('/test_plugin/test_plugin', 'GET');
         $expected = [
             'pass' => [],
             'plugin' => 'TestPlugin',
@@ -256,8 +248,7 @@ class RouterTest extends TestCase
         ];
         $this->assertEquals($expected, $result);
 
-        $_SERVER['REQUEST_METHOD'] = 'GET';
-        $result = Router::parse('/test_plugin/test_plugin/13');
+        $result = Router::parse('/test_plugin/test_plugin/13', 'GET');
         $expected = [
             'pass' => ['13'],
             'plugin' => 'TestPlugin',
@@ -278,8 +269,7 @@ class RouterTest extends TestCase
     {
         Router::mapResources('Posts', ['prefix' => 'api']);
 
-        $_SERVER['REQUEST_METHOD'] = 'GET';
-        $result = Router::parse('/api/posts');
+        $result = Router::parse('/api/posts', 'GET');
 
         $expected = [
             'plugin' => null,
@@ -300,9 +290,7 @@ class RouterTest extends TestCase
     public function testMapResourcesWithExtension()
     {
         Router::extensions(['json', 'xml'], false);
-
         Router::mapResources('Posts', ['_ext' => 'json']);
-        $_SERVER['REQUEST_METHOD'] = 'GET';
 
         $expected = [
             'plugin' => null,
@@ -312,14 +300,14 @@ class RouterTest extends TestCase
             '_method' => 'GET',
         ];
 
-        $result = Router::parse('/posts');
+        $result = Router::parse('/posts', 'GET');
         $this->assertEquals($expected, $result);
 
-        $result = Router::parse('/posts.json');
+        $result = Router::parse('/posts.json', 'GET');
         $expected['_ext'] = 'json';
         $this->assertEquals($expected, $result);
 
-        $result = Router::parse('/posts.xml');
+        $result = Router::parse('/posts.xml', 'GET');
         $this->assertArrayNotHasKey('_method', $result, 'Not an extension/resource route.');
     }
 
@@ -350,8 +338,7 @@ class RouterTest extends TestCase
     {
         Router::mapResources('TestPlugin.TestPlugin', ['prefix' => 'api']);
 
-        $_SERVER['REQUEST_METHOD'] = 'GET';
-        $result = Router::parse('/api/test_plugin/test_plugin');
+        $result = Router::parse('/api/test_plugin/test_plugin', 'GET');
         $expected = [
             'pass' => [],
             'plugin' => 'TestPlugin',
@@ -364,8 +351,7 @@ class RouterTest extends TestCase
 
         $resources = Router::mapResources('Posts', ['prefix' => 'api']);
 
-        $_SERVER['REQUEST_METHOD'] = 'GET';
-        $result = Router::parse('/api/posts');
+        $result = Router::parse('/api/posts', 'GET');
         $expected = [
             'pass' => [],
             'plugin' => null,
@@ -386,8 +372,7 @@ class RouterTest extends TestCase
     {
         Router::connect('/:controller', ['action' => 'index', '_method' => ['GET', 'POST']]);
 
-        $_SERVER['REQUEST_METHOD'] = 'GET';
-        $result = Router::parse('/posts');
+        $result = Router::parse('/posts', 'GET');
         $expected = [
             'pass' => [],
             'plugin' => null,
@@ -397,8 +382,7 @@ class RouterTest extends TestCase
         ];
         $this->assertEquals($expected, $result);
 
-        $_SERVER['REQUEST_METHOD'] = 'POST';
-        $result = Router::parse('/posts');
+        $result = Router::parse('/posts', 'POST');
         $expected = [
             'pass' => [],
             'plugin' => null,
@@ -578,10 +562,10 @@ class RouterTest extends TestCase
             'action' => 'index',
             'pass' => ['0'],
         ];
-        $result = Router::parse('/0');
+        $result = Router::parse('/0', 'GET');
         $this->assertEquals($expected, $result);
 
-        $result = Router::parse('0');
+        $result = Router::parse('0', 'GET');
         $this->assertEquals($expected, $result);
     }
 
@@ -1313,7 +1297,7 @@ class RouterTest extends TestCase
             ['controller' => 'Posts', 'action' => 'view'],
             ['value', 'somevalue', 'othervalue']
         );
-        $result = Router::parse('/posts/2007/08/01/title-of-post-here');
+        $result = Router::parse('/posts/2007/08/01/title-of-post-here', 'GET');
         $expected = [
             'value' => '2007',
             'somevalue' => '08',
@@ -1331,7 +1315,7 @@ class RouterTest extends TestCase
             ['controller' => 'posts', 'action' => 'view'],
             ['year' => $Year, 'month' => $Month, 'day' => $Day]
         );
-        $result = Router::parse('/posts/2007/08/01/title-of-post-here');
+        $result = Router::parse('/posts/2007/08/01/title-of-post-here', 'GET');
         $expected = [
             'year' => '2007',
             'month' => '08',
@@ -1349,7 +1333,7 @@ class RouterTest extends TestCase
             ['controller' => 'posts', 'action' => 'view'],
             ['year' => $Year, 'month' => $Month, 'day' => $Day]
         );
-        $result = Router::parse('/posts/01/2007/08/title-of-post-here');
+        $result = Router::parse('/posts/01/2007/08/title-of-post-here', 'GET');
         $expected = [
             'day' => '01',
             'year' => '2007',
@@ -1367,7 +1351,7 @@ class RouterTest extends TestCase
             ['controller' => 'posts', 'action' => 'view'],
             ['year' => $Year, 'month' => $Month, 'day' => $Day]
         );
-        $result = Router::parse('/posts/08/01/2007/title-of-post-here');
+        $result = Router::parse('/posts/08/01/2007/title-of-post-here', 'GET');
         $expected = [
             'month' => '08',
             'day' => '01',
@@ -1384,7 +1368,7 @@ class RouterTest extends TestCase
             '/posts/:year/:month/:day/*',
             ['controller' => 'posts', 'action' => 'view']
         );
-        $result = Router::parse('/posts/2007/08/01/title-of-post-here');
+        $result = Router::parse('/posts/2007/08/01/title-of-post-here', 'GET');
         $expected = [
             'year' => '2007',
             'month' => '08',
@@ -1398,7 +1382,7 @@ class RouterTest extends TestCase
 
         Router::reload();
         $this->_connectDefaultRoutes();
-        $result = Router::parse('/pages/display/home');
+        $result = Router::parse('/pages/display/home', 'GET');
         $expected = [
             'plugin' => null,
             'pass' => ['home'],
@@ -1407,15 +1391,15 @@ class RouterTest extends TestCase
         ];
         $this->assertEquals($expected, $result);
 
-        $result = Router::parse('pages/display/home/');
+        $result = Router::parse('pages/display/home/', 'GET');
         $this->assertEquals($expected, $result);
 
-        $result = Router::parse('pages/display/home');
+        $result = Router::parse('pages/display/home', 'GET');
         $this->assertEquals($expected, $result);
 
         Router::reload();
         Router::connect('/page/*', ['controller' => 'test']);
-        $result = Router::parse('/page/my-page');
+        $result = Router::parse('/page/my-page', 'GET');
         $expected = ['pass' => ['my-page'], 'plugin' => null, 'controller' => 'test', 'action' => 'index'];
         $this->assertEquals($expected, $result);
 
@@ -1425,7 +1409,7 @@ class RouterTest extends TestCase
             ['language' => 'eng', 'plugin' => 'contact', 'controller' => 'contact', 'action' => 'index'],
             ['language' => '[a-z]{3}']
         );
-        $result = Router::parse('/eng/contact');
+        $result = Router::parse('/eng/contact', 'GET');
         $expected = [
             'pass' => [],
             'language' => 'eng',
@@ -1442,7 +1426,7 @@ class RouterTest extends TestCase
             ['month' => '0[1-9]|1[012]', 'year' => '[12][0-9]{3}']
         );
 
-        $result = Router::parse('/forestillinger/10/2007/min-forestilling');
+        $result = Router::parse('/forestillinger/10/2007/min-forestilling', 'GET');
         $expected = [
             'pass' => ['min-forestilling'],
             'plugin' => 'shows',
@@ -1456,11 +1440,11 @@ class RouterTest extends TestCase
         Router::reload();
         Router::connect('/:controller/:action/*');
         Router::connect('/', ['plugin' => 'pages', 'controller' => 'pages', 'action' => 'display']);
-        $result = Router::parse('/');
+        $result = Router::parse('/', 'GET');
         $expected = ['pass' => [], 'controller' => 'pages', 'action' => 'display', 'plugin' => 'pages'];
         $this->assertEquals($expected, $result);
 
-        $result = Router::parse('/posts/edit/0');
+        $result = Router::parse('/posts/edit/0', 'GET');
         $expected = ['pass' => [0], 'controller' => 'posts', 'action' => 'edit', 'plugin' => null];
         $this->assertEquals($expected, $result);
 
@@ -1470,7 +1454,7 @@ class RouterTest extends TestCase
             ['controller' => 'posts', 'action' => 'view'],
             ['pass' => ['id', 'url_title'], 'id' => '[\d]+']
         );
-        $result = Router::parse('/posts/5:sample-post-title');
+        $result = Router::parse('/posts/5:sample-post-title', 'GET');
         $expected = [
             'pass' => ['5', 'sample-post-title'],
             'id' => 5,
@@ -1487,7 +1471,7 @@ class RouterTest extends TestCase
             ['controller' => 'posts', 'action' => 'view'],
             ['pass' => ['id', 'url_title'], 'id' => '[\d]+']
         );
-        $result = Router::parse('/posts/5:sample-post-title/other/params/4');
+        $result = Router::parse('/posts/5:sample-post-title/other/params/4', 'GET');
         $expected = [
             'pass' => ['5', 'sample-post-title', 'other', 'params', '4'],
             'id' => 5,
@@ -1500,7 +1484,7 @@ class RouterTest extends TestCase
 
         Router::reload();
         Router::connect('/posts/view/*', ['controller' => 'posts', 'action' => 'view']);
-        $result = Router::parse('/posts/view/10?id=123&tab=abc');
+        $result = Router::parse('/posts/view/10?id=123&tab=abc', 'GET');
         $expected = ['pass' => [10], 'plugin' => null, 'controller' => 'posts', 'action' => 'view', '?' => ['id' => '123', 'tab' => 'abc']];
         $this->assertEquals($expected, $result);
 
@@ -1510,7 +1494,7 @@ class RouterTest extends TestCase
             ['controller' => 'posts', 'action' => 'view'],
             ['pass' => ['id', 'url_title'], 'id' => $UUID]
         );
-        $result = Router::parse('/posts/sample-post-title-(uuid:47fc97a9-019c-41d1-a058-1fa3cbdd56cb)');
+        $result = Router::parse('/posts/sample-post-title-(uuid:47fc97a9-019c-41d1-a058-1fa3cbdd56cb)', 'GET');
         $expected = [
             'pass' => ['47fc97a9-019c-41d1-a058-1fa3cbdd56cb', 'sample-post-title'],
             'id' => '47fc97a9-019c-41d1-a058-1fa3cbdd56cb',
@@ -1523,7 +1507,7 @@ class RouterTest extends TestCase
 
         Router::reload();
         Router::connect('/posts/view/*', ['controller' => 'posts', 'action' => 'view']);
-        $result = Router::parse('/posts/view/foo:bar/routing:fun');
+        $result = Router::parse('/posts/view/foo:bar/routing:fun', 'GET');
         $expected = [
             'pass' => ['foo:bar', 'routing:fun'],
             'plugin' => null,
@@ -1545,7 +1529,7 @@ class RouterTest extends TestCase
             ['controller' => 'subjects', 'action' => 'add'],
             ['category_id' => '\w{8}-\w{4}-\w{4}-\w{4}-\w{12}']
         );
-        $result = Router::parse('/subjects/add/4795d601-19c8-49a6-930e-06a8b01d17b7');
+        $result = Router::parse('/subjects/add/4795d601-19c8-49a6-930e-06a8b01d17b7', 'GET');
         $expected = [
             'pass' => [],
             'category_id' => '4795d601-19c8-49a6-930e-06a8b01d17b7',
@@ -1569,7 +1553,7 @@ class RouterTest extends TestCase
             ["extra" => '[a-z1-9_]*', "slug" => '[a-z1-9_]+', "action" => 'view']
         );
 
-        $result = Router::parse('/some_extra/page/this_is_the_slug');
+        $result = Router::parse('/some_extra/page/this_is_the_slug', 'GET');
         $expected = [
             'pass' => [],
             'plugin' => null,
@@ -1580,7 +1564,7 @@ class RouterTest extends TestCase
         ];
         $this->assertEquals($expected, $result);
 
-        $result = Router::parse('/page/this_is_the_slug');
+        $result = Router::parse('/page/this_is_the_slug', 'GET');
         $expected = [
             'pass' => [],
             'plugin' => null,
@@ -1629,7 +1613,20 @@ class RouterTest extends TestCase
     public function testParseError()
     {
         Router::connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);
-        Router::parse('/nope');
+        Router::parse('/nope', 'GET');
+    }
+
+    /**
+     * Test deprecated behavior
+     *
+     * @return void
+     */
+    public function testParseMethodCondition()
+    {
+        Router::connect('/posts', ['controller' => 'Posts', '_method' => 'POST']);
+
+        $_SERVER['REQUEST_METHOD'] = 'POST';
+        $this->assertNotEmpty(Router::parse('/posts'));
     }
 
     /**
@@ -1641,7 +1638,7 @@ class RouterTest extends TestCase
     public function testParseReverseSymmetry($url)
     {
         $this->_connectDefaultRoutes();
-        $this->assertSame($url, Router::reverse(Router::parse($url) + ['url' => []]));
+        $this->assertSame($url, Router::reverse(Router::parse($url, 'GET') + ['url' => []]));
     }
 
     /**
@@ -1671,10 +1668,10 @@ class RouterTest extends TestCase
 
         $this->_connectDefaultRoutes();
 
-        $result = Router::parse('/posts.rss');
+        $result = Router::parse('/posts.rss', 'GET');
         $this->assertEquals('rss', $result['_ext']);
 
-        $result = Router::parse('/posts.xml');
+        $result = Router::parse('/posts.xml', 'GET');
         $this->assertFalse(isset($result['_ext']));
 
         Router::extensions(['xml']);
@@ -1743,7 +1740,7 @@ class RouterTest extends TestCase
         Router::extensions('rss', false);
         $this->_connectDefaultRoutes();
 
-        $result = Router::parse('/posts.rss');
+        $result = Router::parse('/posts.rss', 'GET');
         $expected = [
             'plugin' => null,
             'controller' => 'Posts',
@@ -1753,7 +1750,7 @@ class RouterTest extends TestCase
         ];
         $this->assertEquals($expected, $result);
 
-        $result = Router::parse('/posts/view/1.rss');
+        $result = Router::parse('/posts/view/1.rss', 'GET');
         $expected = [
             'plugin' => null,
             'controller' => 'Posts',
@@ -1763,7 +1760,7 @@ class RouterTest extends TestCase
         ];
         $this->assertEquals($expected, $result);
 
-        $result = Router::parse('/posts/view/1.rss?query=test');
+        $result = Router::parse('/posts/view/1.rss?query=test', 'GET');
         $expected['?'] = ['query' => 'test'];
         $this->assertEquals($expected, $result);
 
@@ -1771,7 +1768,7 @@ class RouterTest extends TestCase
         Router::extensions(['rss', 'xml'], false);
         $this->_connectDefaultRoutes();
 
-        $result = Router::parse('/posts.xml');
+        $result = Router::parse('/posts.xml', 'GET');
         $expected = [
             'plugin' => null,
             'controller' => 'Posts',
@@ -1781,7 +1778,7 @@ class RouterTest extends TestCase
         ];
         $this->assertEquals($expected, $result);
 
-        $result = Router::parse('/posts.atom?hello=goodbye');
+        $result = Router::parse('/posts.atom?hello=goodbye', 'GET');
         $expected = [
             'plugin' => null,
             'controller' => 'Posts.atom',
@@ -1793,13 +1790,13 @@ class RouterTest extends TestCase
 
         Router::reload();
         Router::connect('/controller/action', ['controller' => 'controller', 'action' => 'action', '_ext' => 'rss']);
-        $result = Router::parse('/controller/action');
+        $result = Router::parse('/controller/action', 'GET');
         $expected = ['controller' => 'controller', 'action' => 'action', 'plugin' => null, '_ext' => 'rss', 'pass' => []];
         $this->assertEquals($expected, $result);
 
         Router::reload();
         Router::connect('/controller/action', ['controller' => 'controller', 'action' => 'action', '_ext' => 'rss']);
-        $result = Router::parse('/controller/action');
+        $result = Router::parse('/controller/action', 'GET');
         $expected = [
             'controller' => 'controller',
             'action' => 'action',
@@ -1812,7 +1809,7 @@ class RouterTest extends TestCase
         Router::reload();
         Router::extensions('rss', false);
         Router::connect('/controller/action', ['controller' => 'controller', 'action' => 'action', '_ext' => 'rss']);
-        $result = Router::parse('/controller/action');
+        $result = Router::parse('/controller/action', 'GET');
         $expected = [
             'controller' => 'controller',
             'action' => 'action',
@@ -2100,25 +2097,25 @@ class RouterTest extends TestCase
         Router::connect('/', ['controller' => 'pages', 'action' => 'display', 'home']);
         Router::connect('/pages/*', ['controller' => 'pages', 'action' => 'display']);
 
-        $result = Router::parse('/');
+        $result = Router::parse('/', 'GET');
         $expected = ['pass' => ['home'], 'plugin' => null, 'controller' => 'pages', 'action' => 'display'];
         $this->assertEquals($expected, $result);
 
-        $result = Router::parse('/pages/home/');
+        $result = Router::parse('/pages/home/', 'GET');
         $expected = ['pass' => ['home'], 'plugin' => null, 'controller' => 'pages', 'action' => 'display'];
         $this->assertEquals($expected, $result);
 
         Router::reload();
         Router::connect('/', ['controller' => 'pages', 'action' => 'display', 'home']);
 
-        $result = Router::parse('/');
+        $result = Router::parse('/', 'GET');
         $expected = ['pass' => ['home'], 'plugin' => null, 'controller' => 'pages', 'action' => 'display'];
         $this->assertEquals($expected, $result);
 
         Router::reload();
         Router::connect('/', ['controller' => 'posts', 'action' => 'index']);
         Router::connect('/pages/*', ['controller' => 'pages', 'action' => 'display']);
-        $result = Router::parse('/pages/contact/');
+        $result = Router::parse('/pages/contact/', 'GET');
 
         $expected = ['pass' => ['contact'], 'plugin' => null, 'controller' => 'pages', 'action' => 'display'];
         $this->assertEquals($expected, $result);
@@ -2133,10 +2130,10 @@ class RouterTest extends TestCase
     {
         Router::reload();
         Router::connect('/:controller/:action/*');
-        $result = Router::parse('/posts/view/something.');
+        $result = Router::parse('/posts/view/something.', 'GET');
         $this->assertEquals('something.', $result['pass'][0], 'Period was chopped off %s');
 
-        $result = Router::parse('/posts/view/something. . .');
+        $result = Router::parse('/posts/view/something. . .', 'GET');
         $this->assertEquals('something. . .', $result['pass'][0], 'Period was chopped off %s');
     }
 
@@ -2151,10 +2148,10 @@ class RouterTest extends TestCase
         Router::connect('/:controller/:action/*');
         Router::extensions('json', false);
 
-        $result = Router::parse('/posts/view/something.');
+        $result = Router::parse('/posts/view/something.', 'GET');
         $this->assertEquals('something.', $result['pass'][0], 'Period was chopped off %s');
 
-        $result = Router::parse('/posts/view/something. . .');
+        $result = Router::parse('/posts/view/something. . .', 'GET');
         $this->assertEquals('something. . .', $result['pass'][0], 'Period was chopped off %s');
     }
 
@@ -2172,7 +2169,7 @@ class RouterTest extends TestCase
             ['action' => 'other|actions']
         );
 
-        $result = Router::parse('/blog/other');
+        $result = Router::parse('/blog/other', 'GET');
         $expected = [
             'plugin' => null,
             'controller' => 'blog_posts',
@@ -2181,7 +2178,7 @@ class RouterTest extends TestCase
         ];
         $this->assertEquals($expected, $result);
 
-        Router::parse('/blog/foobar');
+        Router::parse('/blog/foobar', 'GET');
     }
 
     /**
@@ -2228,11 +2225,11 @@ class RouterTest extends TestCase
             ])
         );
 
-        $result = Router::parse('/admin/posts/');
+        $result = Router::parse('/admin/posts/', 'GET');
         $expected = ['pass' => [], 'prefix' => 'admin', 'plugin' => null, 'controller' => 'posts', 'action' => 'index'];
         $this->assertEquals($expected, $result);
 
-        $result = Router::parse('/admin/posts');
+        $result = Router::parse('/admin/posts', 'GET');
         $this->assertEquals($expected, $result);
 
         $result = Router::url(['prefix' => 'admin', 'controller' => 'posts']);
@@ -2257,7 +2254,7 @@ class RouterTest extends TestCase
             ])
         );
 
-        $result = Router::parse('/members/posts/index');
+        $result = Router::parse('/members/posts/index', 'GET');
         $expected = ['pass' => [], 'prefix' => 'members', 'plugin' => null, 'controller' => 'posts', 'action' => 'index'];
         $this->assertEquals($expected, $result);
 
@@ -2361,7 +2358,7 @@ class RouterTest extends TestCase
     {
         Router::connect('/:locale/:controller/:action/*', [], ['locale' => 'dan|eng']);
 
-        $result = Router::parse('/eng/test/test_action');
+        $result = Router::parse('/eng/test/test_action', 'GET');
         $expected = ['pass' => [], 'locale' => 'eng', 'controller' => 'test', 'action' => 'test_action', 'plugin' => null];
         $this->assertEquals($expected, $result);
     }
@@ -2375,7 +2372,7 @@ class RouterTest extends TestCase
     public function testRegexRouteMatchingError()
     {
         Router::connect('/:locale/:controller/:action/*', [], ['locale' => 'dan|eng']);
-        Router::parse('/badness/test/test_action');
+        Router::parse('/badness/test/test_action', 'GET');
     }
 
     /**
@@ -2424,7 +2421,7 @@ class RouterTest extends TestCase
             ['plugin' => 'TestPlugin', 'action' => 'index'],
             ['routeClass' => 'PluginShortRoute', 'slug' => '[a-z_-]+']
         );
-        $result = Router::parse('/the-best');
+        $result = Router::parse('/the-best', 'GET');
         $expected = [
             'plugin' => 'TestPlugin',
             'controller' => 'TestPlugin',
@@ -2730,11 +2727,11 @@ class RouterTest extends TestCase
         $result = $route->match(['controller' => 'blog_posts', 'action' => 'actions']);
         $this->assertEquals('/blog/actions/', $result);
 
-        $result = $route->parse('/blog/other');
+        $result = $route->parse('/blog/other', 'GET');
         $expected = ['controller' => 'blog_posts', 'action' => 'other', 'pass' => []];
         $this->assertEquals($expected, $result);
 
-        $result = $route->parse('/blog/foobar');
+        $result = $route->parse('/blog/foobar', 'GET');
         $this->assertFalse($result);
     }