implemented Router::reverseToArray()

This commit is contained in:
Val Bancer 2017-01-26 21:52:26 +01:00
parent 8ee5259323
commit ebde8fdfb5
2 changed files with 94 additions and 24 deletions

View file

@ -1087,6 +1087,40 @@ class Router {
return $out; 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 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. * 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 * @return string The string that is the reversed result of the array
*/ */
public static function reverse($params, $full = false) { public static function reverse($params, $full = false) {
if ($params instanceof CakeRequest) { $params = Router::reverseToArray($params, $full);
$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 Router::url($params, $full); return Router::url($params, $full);
} }

View file

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