Initial port of Router::getArgs() to CakeRoute.

This commit is contained in:
mark_story 2011-03-03 06:11:41 -05:00
parent 155db76825
commit cf26a8e430
2 changed files with 108 additions and 5 deletions

View file

@ -214,19 +214,93 @@ class CakeRoute {
unset($route[$i]);
}
$route['pass'] = $route['named'] = array();
$route += $this->defaults;
//move numerically indexed elements from the defaults into pass.
foreach ($route as $key => $value) {
// Assign defaults, set passed args to pass
foreach ($this->defaults as $key => $value) {
if (isset($route[$key])) {
continue;
}
if (is_integer($key)) {
$route['pass'][] = $value;
unset($route[$key]);
continue;
}
$route[$key] = $value;
}
if (isset($route['_args_'])) {
list($pass, $named) = $this->parseArgs($route['_args_'], $route['controller'], $route['action']);
$route['pass'] = array_merge($route['pass'], $pass);
$route['named'] = $named;
unset($route['_args_']);
}
return $route;
}
}
/**
* Parse passed and Named parameters into a list of passed args, and a hash of named parameters.
* The local and global configuration for named parameters will be used.
*
* @param string $args A string with the passed & named params. eg. /1/page:2
* @return array Array of ($pass, $named)
*/
public function parseArgs($args, $controller = null, $action = null) {
$pass = $named = array();
$args = explode('/', $args);
$context = compact('controller', 'action');
$namedConfig = Router::namedConfig();
$greedy = isset($this->options['greedy']) ? $this->options['greedy'] : $namedConfig['greedy'];
$rules = $namedConfig['rules'];
if (isset($this->options['named'])) {
$greedy = isset($this->options['greedy']) && $this->options['greedy'] === true;
foreach ((array)$this->options['named'] as $key => $val) {
if (is_numeric($key)) {
$rules[$val] = true;
continue;
}
$rules[$key] = $val;
}
}
foreach ($args as $param) {
if (empty($param) && $param !== '0' && $param !== 0) {
continue;
}
$separatorIsPresent = strpos($param, $namedConfig['separator']) !== false;
if ((!isset($options['named']) || !empty($this->options['named'])) && $separatorIsPresent) {
list($key, $val) = explode($namedConfig['separator'], $param, 2);
$hasRule = isset($rules[$key]);
$passIt = (!$hasRule && !$greedy) || ($hasRule && !Router::matchNamed($key, $val, $rules[$key], $context));
if ($passIt) {
$pass[] = $param;
} else {
if (preg_match_all('/\[([A-Za-z0-9_-]+)?\]/', $key, $matches, PREG_SET_ORDER)) {
$matches = array_reverse($matches);
$parts = explode('[', $key);
$key = array_shift($parts);
$arr = $val;
foreach ($matches as $match) {
if (empty($match[1])) {
$arr = array($arr);
} else {
$arr = array(
$match[1] => $arr
);
}
}
$val = $arr;
}
$named = array_merge_recursive($named, array($key => $val));
}
} else {
$pass[] = $param;
}
}
return array($pass, $named);
}
/**
* Apply persistent parameters to a url array. Persistant parameters are a special
* key used during route creation to force route parameters to persist when omitted from

View file

@ -171,12 +171,14 @@ class CakeRouteTestCase extends CakeTestCase {
$this->assertPattern($result, '/posts/08/01/2007/title-of-post');
$result = $route->parse('/posts/08/01/2007/title-of-post');
$this->assertEqual(count($result), 8);
$this->assertEqual(count($result), 7);
$this->assertEqual($result['controller'], 'posts');
$this->assertEqual($result['action'], 'view');
$this->assertEqual($result['year'], '2007');
$this->assertEqual($result['month'], '08');
$this->assertEqual($result['day'], '01');
$this->assertEquals($result['pass'][0], 'title-of-post');
$route = new CakeRoute(
"/:extra/page/:slug/*",
@ -473,4 +475,31 @@ class CakeRouteTestCase extends CakeTestCase {
$this->assertFalse($result);
}
/**
* test the parseArgs method
*
* @return void
*/
function testPassedArgumentParsing() {
$route = new CakeRoute('/:controller/:action/*');
$result = $route->parse('/posts/edit/1/2/0');
$expected = array(
'controller' => 'posts',
'action' => 'edit',
'pass' => array('1', '2', '0'),
'named' => array()
);
$this->assertEquals($expected, $result);
$result = $route->parse('/posts/edit/a-string/page:1');
$expected = array(
'controller' => 'posts',
'action' => 'edit',
'pass' => array('a-string'),
'named' => array(
'page' => 1
)
);
$this->assertEquals($expected, $result);
}
}