Adding query string generation into CakeRoute. This removes one more task from Router. Tests added

Adding constants for the named param and querystring param sigils.
This commit is contained in:
mark_story 2010-12-18 16:44:21 -05:00
parent 9c1516e6a8
commit eb9fe07472
2 changed files with 65 additions and 12 deletions

View file

@ -73,6 +73,16 @@ class CakeRoute {
*/ */
protected $_compiledRoute = null; protected $_compiledRoute = null;
/**
* Constant for the sigil that indicates a route param is a named parameter.
*/
const SIGIL_NAMED = ':';
/**
* Constant for the sigil that indicates a route param is a query string parameter.
*/
const SIGIL_QUERYSTRING = '?';
/** /**
* HTTP header shortcut map. Used for evaluating header-based route expressions. * HTTP header shortcut map. Used for evaluating header-based route expressions.
* *
@ -274,22 +284,27 @@ class CakeRoute {
return false; return false;
} }
$named = $pass = $diff = array(); $named = $pass = $_query = array();
foreach ($url as $key => $value) { foreach ($url as $key => $value) {
// pull out named params so comparisons later on are faster. // pull out named params so comparisons later on are faster.
if ($key[0] === ':' && ($value !== false && $value !== null)) { if ($key[0] === CakeRoute::SIGIL_NAMED && ($value !== false && $value !== null)) {
$named[substr($key, 1)] = $value; $named[substr($key, 1)] = $value;
unset($url[$key]); unset($url[$key]);
continue; continue;
} }
// pull out querystring params
if ($key[0] === CakeRoute::SIGIL_QUERYSTRING && ($value !== false && $value !== null)) {
$_query[substr($key, 1)] = $value;
unset($url[$key]);
continue;
}
// keys that exist in the defaults and have different values cause match failures. // keys that exist in the defaults and have different values cause match failures.
$keyExists = array_key_exists($key, $defaults); $keyExists = array_key_exists($key, $defaults);
if ($keyExists && $defaults[$key] != $value) { if ($keyExists && $defaults[$key] != $value) {
return false; return false;
$diff[$key] = $value;
continue;
} }
// If the key is a routed key, its not different yet. // If the key is a routed key, its not different yet.
@ -310,17 +325,11 @@ class CakeRoute {
// keys that don't exist are different. // keys that don't exist are different.
if (!$keyExists && !empty($value)) { if (!$keyExists && !empty($value)) {
return false; return false;
$diff[$key] = $value;
} }
} }
//if a not a greedy route, no extra params are allowed. //if a not a greedy route, no extra params are allowed.
if (!$this->_greedy && ( (!empty($pass) || !empty($named)) || array_diff_key($diff, $keyNames) != array()) ) { if (!$this->_greedy && (!empty($pass) || !empty($named))) {
return false;
}
//still some left over parameters that weren't named or passed args, bail.
if (!empty($diff)) {
return false; return false;
} }
@ -332,7 +341,7 @@ class CakeRoute {
} }
} }
} }
return $this->_writeUrl(array_merge($url, compact('pass', 'named'))); return $this->_writeUrl(array_merge($url, compact('pass', 'named', '_query')));
} }
/** /**
@ -385,7 +394,27 @@ class CakeRoute {
if (strpos($this->template, '*')) { if (strpos($this->template, '*')) {
$out = str_replace('*', $params['pass'], $out); $out = str_replace('*', $params['pass'], $out);
} }
if (!empty($params['_query'])) {
$out .= $this->queryString($params['_query']);
}
$out = str_replace('//', '/', $out); $out = str_replace('//', '/', $out);
return $out; return $out;
} }
/**
* Generates a well-formed querystring from $q
*
* Will compose an array or nested array into a proper querystring.
*
* @param mixed $q An array of parameters to compose into a query string.
* @param bool $escape Whether or not to use escaped &
* @return string
*/
public function queryString($q, $escape = false) {
$join = '&';
if ($escape === true) {
$join = '&';
}
return '?' . http_build_query($q, null, $join);
}
} }

View file

@ -472,4 +472,28 @@ class CakeRouteTestCase extends CakeTestCase {
$result = $route->parse('/blog/foobar'); $result = $route->parse('/blog/foobar');
$this->assertFalse($result); $this->assertFalse($result);
} }
/**
* test sigil based query string params
*
* @return void
*/
function testQueryStringParams() {
$route = new CakeRoute('/:controller/:action/*');
$result = $route->match(array('controller' => 'posts', 'action' => 'index', '?test' => 'value'));
$expected = '/posts/index/?test=value';
$this->assertEquals($expected, $result);
$result = $route->match(array(
'controller' => 'posts', 'action' => 'index', '?test' => array(1, 2, 3)
));
$expected = '/posts/index/?test%5B0%5D=1&test%5B1%5D=2&test%5B2%5D=3';
$this->assertEquals($expected, $result);
$result = $route->match(array(
'controller' => 'posts', 'action' => 'index', '?test' => 'value', '?other' => 'value'
));
$expected = '/posts/index/?test=value&other=value';
$this->assertEquals($expected, $result);
}
} }