Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixing issues where route elements could not have '-' in the paramete…

…r name because of limitations in pcre named capturing subpatterns. Tests added. Fixes #974
  • Loading branch information...
commit 522446e0c2847cb0eef456003a1e9c37a1955196 1 parent 86cae09
@markstory markstory authored
Showing with 37 additions and 13 deletions.
  1. +15 −12 cake/libs/router.php
  2. +22 −1 cake/tests/cases/libs/router.test.php
View
27 cake/libs/router.php
@@ -1352,9 +1352,9 @@ function _writeRoute() {
$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 @@ function _writeRoute() {
}
$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 @@ function parse($url) {
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 @@ function parse($url) {
}
}
}
- 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
23 cake/tests/cases/libs/router.test.php
@@ -2180,6 +2180,27 @@ function testBasicRouteCompiling() {
}
/**
+ * 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.
*
* @return void
@@ -2390,7 +2411,6 @@ function testMatchBasic() {
$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 @@ function testMatchBasic() {
'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);
Please sign in to comment.
Something went wrong with that request. Please try again.