diff --git a/src/Routing/Router.php b/src/Routing/Router.php index a43536f0379..fca8aa93ee6 100644 --- a/src/Routing/Router.php +++ b/src/Routing/Router.php @@ -723,8 +723,9 @@ public static function fullBaseUrl($base = null) return static::$_fullBaseUrl; } + /** - * Reverses a parsed parameter array into a string. + * Reverses a parsed parameter array into an array. * * Works similarly to Router::url(), but since parsed URL's contain additional * 'pass' as well as 'url.url' keys. Those keys need to be specially @@ -735,11 +736,9 @@ public static function fullBaseUrl($base = null) * * @param \Cake\Http\ServerRequest|array $params The params array or * Cake\Network\Request object that needs to be reversed. - * @param bool $full Set to true to include the full URL including the - * protocol when reversing the URL. - * @return string The string that is the reversed result of the array + * @return array The URL array ready to be used for redirect or HTML link. */ - public static function reverse($params, $full = false) + public static function reverseToArray($params) { $url = []; if ($params instanceof ServerRequest) { @@ -768,6 +767,29 @@ public static function reverse($params, $full = false) $params['?'] = $url; } + return $params; + } + + /** + * Reverses a parsed parameter array into a string. + * + * Works similarly to Router::url(), but since parsed URL's contain additional + * 'pass' as well as 'url.url' keys. Those keys need to be specially + * handled in order to reverse a params array into a string URL. + * + * This will strip out 'autoRender', 'bare', 'requested', and 'return' param names as those + * are used for CakePHP internals and should not normally be part of an output URL. + * + * @param \Cake\Http\ServerRequest|array $params The params array or + * Cake\Network\Request object that needs to be reversed. + * @param bool $full Set to true to include the full URL including the + * protocol when reversing the URL. + * @return string The string that is the reversed result of the array + */ + public static function reverse($params, $full = false) + { + $params = static::reverseToArray($params); + return static::url($params, $full); } diff --git a/tests/TestCase/Routing/RouterTest.php b/tests/TestCase/Routing/RouterTest.php index fe57415f618..0fcd34719c0 100644 --- a/tests/TestCase/Routing/RouterTest.php +++ b/tests/TestCase/Routing/RouterTest.php @@ -2656,7 +2656,7 @@ public function testCustomRouteException() * * @return void */ - public function testReverse() + public function testReverseToken() { Router::connect('/:controller/:action/*'); $params = [ @@ -2672,7 +2672,10 @@ public function testReverse() ]; $result = Router::reverse($params); $this->assertEquals('/posts/view/1', $result); + } + public function testReverseLocalized() + { Router::reload(); Router::connect('/:lang/:controller/:action/*', [], ['lang' => '[a-z]{3}']); $params = [ @@ -2684,7 +2687,11 @@ public function testReverse() ]; $result = Router::reverse($params); $this->assertEquals('/eng/posts/view/1', $result); + } + public function testReverseArrayQuery() + { + Router::connect('/:lang/:controller/:action/*', [], ['lang' => '[a-z]{3}']); $params = [ 'lang' => 'eng', 'controller' => 'posts', @@ -2706,7 +2713,11 @@ public function testReverse() ]; $result = Router::reverse($params); $this->assertEquals('/eng/posts/view/1?foo=bar&baz=quu', $result); + } + public function testReverseCakeRequestQuery() + { + Router::connect('/:lang/:controller/:action/*', [], ['lang' => '[a-z]{3}']); $request = new Request('/eng/posts/view/1'); $request->addParams([ 'lang' => 'eng', @@ -2718,7 +2729,10 @@ public function testReverse() $result = Router::reverse($request); $expected = '/eng/posts/view/1?test=value'; $this->assertEquals($expected, $result); + } + public function testReverseFull() + { $params = [ 'lang' => 'eng', 'controller' => 'posts', @@ -2753,6 +2767,53 @@ public function testReverseWithExtension() $this->assertEquals($expected, $result); } + public function testReverseToArrayQuery() + { + Router::connect('/:lang/:controller/:action/*', [], ['lang' => '[a-z]{3}']); + $params = [ + 'lang' => 'eng', + 'controller' => 'posts', + 'action' => 'view', + 123, + '?' => ['foo' => 'bar'], + ]; + $actual = Router::reverseToArray($params); + $expected = [ + 'lang' => 'eng', + 'controller' => 'posts', + 'action' => 'view', + 123, + '?' => ['foo' => 'bar'], + ]; + $this->assertEquals($expected, $actual); + } + + public function testReverseToArrayRequestQuery() + { + Router::connect('/:lang/:controller/:action/*', [], ['lang' => '[a-z]{3}']); + $request = new Request('/eng/posts/view/1'); + $request->addParams([ + 'lang' => 'eng', + 'controller' => 'posts', + 'action' => 'view', + 'pass' => [123], + ]); + $request->query = ['url' => 'eng/posts/view/1', 'test' => 'value']; + $actual = Router::reverseToArray($request); + $expected = [ + 'lang' => 'eng', + 'plugin' => null, + 'controller' => 'posts', + 'action' => 'view', + 123, + '_ext' => null, + '?' => [ + 'test' => 'value', + ], + ]; + $this->assertEquals($expected, $actual); + } + /** * test that setRequestInfo can accept arrays and turn that into a Request object. *