Fixing issues where route elements could not have '-' in the parameter name because of limitations in pcre named capturing subpatterns. Tests added. Fixes #974

This commit is contained in:
mark_story 2010-07-31 13:03:45 -04:00
parent 86cae09d79
commit 522446e0c2
2 changed files with 37 additions and 13 deletions

View file

@ -1352,9 +1352,9 @@ class CakeRoute {
$names = $routeParams = array();
$parsed = preg_quote($this->template, '#');
preg_match_all('#:([A-Za-z0-9_-]+[A-Z0-9a-z])#', $route, $namedElements);
preg_match_all('#:([A-Za-z0-9_-]+[A-Z0-9a-z])#', $this->template, $namedElements);
foreach ($namedElements[1] as $i => $name) {
$search = '\\' . $namedElements[0][$i];
$search = '\\' . str_replace('-', '\\-', $namedElements[0][$i]);
if (isset($this->options[$name])) {
$option = null;
if ($name !== 'plugin' && array_key_exists($name, $this->defaults)) {
@ -1362,12 +1362,12 @@ class CakeRoute {
}
$slashParam = '/\\' . $namedElements[0][$i];
if (strpos($parsed, $slashParam) !== false) {
$routeParams[$slashParam] = '(?:/(?P<' . $name . '>' . $this->options[$name] . ')' . $option . ')' . $option;
$routeParams[$slashParam] = '(?:/(' . $this->options[$name] . ')' . $option . ')' . $option;
} else {
$routeParams[$search] = '(?:(?P<' . $name . '>' . $this->options[$name] . ')' . $option . ')' . $option;
$routeParams[$search] = '(?:(' . $this->options[$name] . ')' . $option . ')' . $option;
}
} else {
$routeParams[$search] = '(?:(?P<' . $name . '>[^/]+))';
$routeParams[$search] = '(?:([^/]+))';
}
$names[] = $name;
}
@ -1394,7 +1394,7 @@ class CakeRoute {
if (!$this->compiled()) {
$this->compile();
}
if (!preg_match($this->_compiledRoute, $url, $route)) {
if (!preg_match($this->_compiledRoute, $url, $parsed)) {
return false;
} else {
foreach ($this->defaults as $key => $val) {
@ -1418,15 +1418,18 @@ class CakeRoute {
}
}
}
array_shift($route);
$count = count($this->keys);
for ($i = 0; $i <= $count; $i++) {
unset($route[$i]);
array_shift($parsed);
$route = array();
foreach ($this->keys as $i => $key) {
if (isset($parsed[$i])) {
$route[$key] = $parsed[$i];
}
}
$route['pass'] = $route['named'] = array();
$route += $this->defaults;
//move numerically indexed elements from the defaults into pass.
if (isset($parsed['_args_'])) {
$route['_args_'] = $parsed['_args_'];
}
foreach ($route as $key => $value) {
if (is_integer($key)) {
$route['pass'][] = $value;

View file

@ -2179,6 +2179,27 @@ class CakeRouteTestCase extends CakeTestCase {
$this->assertPattern($result, '/test_plugin/posts/edit/5/name:value/nick:name');
}
/**
* test route names with - in them.
*
* @return void
*/
function testHyphenNames() {
$route =& new CakeRoute('/articles/:date-from/:date-to', array(
'controller' => 'articles', 'action' => 'index'
));
$expected = array(
'controller' => 'articles',
'action' => 'index',
'date-from' => '2009-07-31',
'date-to' => '2010-07-31',
'named' => array(),
'pass' => array()
);
$result = $route->parse('/articles/2009-07-31/2010-07-31');
$this->assertEqual($result, $expected);
}
/**
* test that route parameters that overlap don't cause errors.
*
@ -2390,7 +2411,6 @@ class CakeRouteTestCase extends CakeTestCase {
$result = $route->match(array('plugin' => 'fo', 'controller' => 'posts', 'action' => 'edit', 'id' => 1));
$this->assertFalse($result);
$route =& new CakeRoute('/admin/subscriptions/:action/*', array(
'controller' => 'subscribe', 'admin' => true, 'prefix' => 'admin'
));
@ -2409,6 +2429,7 @@ class CakeRouteTestCase extends CakeTestCase {
'date-from' => '2009-07-31',
'date-to' => '2010-07-31'
);
$result = $route->match($url);
$expected = '/articles/2009-07-31/2010-07-31';
$this->assertEqual($result, $expected);