Merge pull request #10113 from bancer/request-url-to-array

implemented Router::reverseToArray()
This commit is contained in:
Mark Story 2017-03-02 23:07:40 -05:00 committed by GitHub
commit 8d0e1fadf7
2 changed files with 95 additions and 24 deletions

View file

@ -1087,6 +1087,40 @@ class Router {
return $out;
}
/**
* Reverses a parsed parameter array into an array.
*
* Works similarly to Router::url(), but since parsed URL's contain additional
* 'pass' and 'named' 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 CakeRequest|array $params The params array or CakeRequest object that needs to be reversed.
* @return array The URL array ready to be used for redirect or HTML link.
*/
public static function reverseToArray($params) {
if ($params instanceof CakeRequest) {
$url = $params->query;
$params = $params->params;
} else {
$url = $params['url'];
}
$pass = isset($params['pass']) ? $params['pass'] : array();
$named = isset($params['named']) ? $params['named'] : array();
unset(
$params['pass'], $params['named'], $params['paging'], $params['models'], $params['url'], $url['url'],
$params['autoRender'], $params['bare'], $params['requested'], $params['return'],
$params['_Token']
);
$params = array_merge($params, $pass, $named);
if (!empty($url)) {
$params['?'] = $url;
}
return $params;
}
/**
* Reverses a parsed parameter array into a string.
*
@ -1103,24 +1137,7 @@ class Router {
* @return string The string that is the reversed result of the array
*/
public static function reverse($params, $full = false) {
if ($params instanceof CakeRequest) {
$url = $params->query;
$params = $params->params;
} else {
$url = $params['url'];
}
$pass = isset($params['pass']) ? $params['pass'] : array();
$named = isset($params['named']) ? $params['named'] : array();
unset(
$params['pass'], $params['named'], $params['paging'], $params['models'], $params['url'], $url['url'],
$params['autoRender'], $params['bare'], $params['requested'], $params['return'],
$params['_Token']
);
$params = array_merge($params, $pass, $named);
if (!empty($url)) {
$params['?'] = $url;
}
$params = Router::reverseToArray($params, $full);
return Router::url($params, $full);
}

View file

@ -2464,9 +2464,8 @@ class RouterTest extends CakeTestCase {
*
* @return void
*/
public function testRouterReverse() {
public function testReverseToken() {
Router::$initialized = true;
$params = array(
'controller' => 'posts',
'action' => 'view',
@ -2481,17 +2480,21 @@ class RouterTest extends CakeTestCase {
);
$result = Router::reverse($params);
$this->assertEquals('/posts/view/1', $result);
}
public function testReverseNamed() {
$params = array(
'controller' => 'posts',
'action' => 'index',
'pass' => array(1),
'named' => array('page' => 1, 'sort' => 'Article.title', 'direction' => 'desc'),
'url' => array()
'url' => array(),
);
$result = Router::reverse($params);
$this->assertEquals('/posts/index/1/page:1/sort:Article.title/direction:desc', $result);
}
public function testReverseLocalized() {
Router::connect('/:lang/:controller/:action/*', array(), array('lang' => '[a-z]{3}'));
$params = array(
'lang' => 'eng',
@ -2499,11 +2502,14 @@ class RouterTest extends CakeTestCase {
'action' => 'view',
'pass' => array(1),
'named' => array(),
'url' => array('url' => 'eng/posts/view/1')
'url' => array('url' => 'eng/posts/view/1'),
);
$result = Router::reverse($params);
$this->assertEquals('/eng/posts/view/1', $result);
}
public function testReverseArrayQuery() {
Router::connect('/:lang/:controller/:action/*', array(), array('lang' => '[a-z]{3}'));
$params = array(
'lang' => 'eng',
'controller' => 'posts',
@ -2512,11 +2518,14 @@ class RouterTest extends CakeTestCase {
'named' => array(),
'url' => array('url' => 'eng/posts/view/1', 'foo' => 'bar', 'baz' => 'quu'),
'paging' => array(),
'models' => array()
'models' => array(),
);
$result = Router::reverse($params);
$this->assertEquals('/eng/posts/view/1?foo=bar&baz=quu', $result);
}
public function testReverseCakeRequestQuery() {
Router::connect('/:lang/:controller/:action/*', array(), array('lang' => '[a-z]{3}'));
$request = new CakeRequest('/eng/posts/view/1');
$request->addParams(array(
'lang' => 'eng',
@ -2529,19 +2538,64 @@ class RouterTest extends CakeTestCase {
$result = Router::reverse($request);
$expected = '/eng/posts/view/1?test=value';
$this->assertEquals($expected, $result);
}
public function testReverseFull() {
Router::connect('/:lang/:controller/:action/*', array(), array('lang' => '[a-z]{3}'));
$params = array(
'lang' => 'eng',
'controller' => 'posts',
'action' => 'view',
'pass' => array(1),
'named' => array(),
'url' => array('url' => 'eng/posts/view/1')
'url' => array('url' => 'eng/posts/view/1'),
);
$result = Router::reverse($params, true);
$this->assertRegExp('/^http(s)?:\/\//', $result);
}
public function testReverseToArrayNamed() {
$params = array(
'controller' => 'posts',
'action' => 'index',
'pass' => array(123),
'named' => array('page' => 123, 'sort' => 'Article.title', 'direction' => 'desc'),
'url' => array(),
);
$result = Router::reverseToArray($params);
$expected = array(
'controller' => 'posts',
'action' => 'index',
123,
'page' => 123,
'sort' => 'Article.title',
'direction' => 'desc',
);
$this->assertEquals($expected, $result);
}
public function testReverseToArrayCakeRequestQuery() {
$request = new CakeRequest('/posts/view/123');
$request->addParams(array(
'controller' => 'posts',
'action' => 'view',
'pass' => array(123),
'named' => array(),
));
$request->query = array('url' => 'eng/posts/view/123', 'test' => 'value');
$result = Router::reverseToArray($request);
$expected = array(
'plugin' => null,
'controller' => 'posts',
'action' => 'view',
123,
'?' => array(
'test' => 'value',
),
);
$this->assertEquals($expected, $result);
}
/**
* Test that extensions work with Router::reverse()
*