Skip to content
This repository
Browse code

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
Mark Story authored July 31, 2010
27  cake/libs/router.php
@@ -1352,9 +1352,9 @@ function _writeRoute() {
1352 1352
 		$names = $routeParams = array();
1353 1353
 		$parsed = preg_quote($this->template, '#');
1354 1354
 
1355  
-		preg_match_all('#:([A-Za-z0-9_-]+[A-Z0-9a-z])#', $route, $namedElements);
  1355
+		preg_match_all('#:([A-Za-z0-9_-]+[A-Z0-9a-z])#', $this->template, $namedElements);
1356 1356
 		foreach ($namedElements[1] as $i => $name) {
1357  
-			$search = '\\' . $namedElements[0][$i];
  1357
+			$search = '\\' . str_replace('-', '\\-', $namedElements[0][$i]);
1358 1358
 			if (isset($this->options[$name])) {
1359 1359
 				$option = null;
1360 1360
 				if ($name !== 'plugin' && array_key_exists($name, $this->defaults)) {
@@ -1362,12 +1362,12 @@ function _writeRoute() {
1362 1362
 				}
1363 1363
 				$slashParam = '/\\' . $namedElements[0][$i];
1364 1364
 				if (strpos($parsed, $slashParam) !== false) {
1365  
-					$routeParams[$slashParam] = '(?:/(?P<' . $name . '>' . $this->options[$name] . ')' . $option . ')' . $option;
  1365
+					$routeParams[$slashParam] = '(?:/(' . $this->options[$name] . ')' . $option . ')' . $option;
1366 1366
 				} else {
1367  
-					$routeParams[$search] = '(?:(?P<' . $name . '>' . $this->options[$name] . ')' . $option . ')' . $option;
  1367
+					$routeParams[$search] = '(?:(' . $this->options[$name] . ')' . $option . ')' . $option;
1368 1368
 				}
1369 1369
 			} else {
1370  
-				$routeParams[$search] = '(?:(?P<' . $name . '>[^/]+))';
  1370
+				$routeParams[$search] = '(?:([^/]+))';
1371 1371
 			}
1372 1372
 			$names[] = $name;
1373 1373
 		}
@@ -1394,7 +1394,7 @@ function parse($url) {
1394 1394
 		if (!$this->compiled()) {
1395 1395
 			$this->compile();
1396 1396
 		}
1397  
-		if (!preg_match($this->_compiledRoute, $url, $route)) {
  1397
+		if (!preg_match($this->_compiledRoute, $url, $parsed)) {
1398 1398
 			return false;
1399 1399
 		} else {
1400 1400
 			foreach ($this->defaults as $key => $val) {
@@ -1418,15 +1418,18 @@ function parse($url) {
1418 1418
 					}
1419 1419
 				}
1420 1420
 			}
1421  
-			array_shift($route);
1422  
-			$count = count($this->keys);
1423  
-			for ($i = 0; $i <= $count; $i++) {
1424  
-				unset($route[$i]);
  1421
+			array_shift($parsed);
  1422
+			$route = array();
  1423
+			foreach ($this->keys as $i => $key) {
  1424
+				if (isset($parsed[$i])) {
  1425
+					$route[$key] = $parsed[$i];
  1426
+				}
1425 1427
 			}
1426 1428
 			$route['pass'] = $route['named'] = array();
1427 1429
 			$route += $this->defaults;
1428  
-
1429  
-			//move numerically indexed elements from the defaults into pass.
  1430
+			if (isset($parsed['_args_'])) {
  1431
+				$route['_args_'] = $parsed['_args_'];
  1432
+			}
1430 1433
 			foreach ($route as $key => $value) {
1431 1434
 				if (is_integer($key)) {
1432 1435
 					$route['pass'][] = $value;
23  cake/tests/cases/libs/router.test.php
@@ -2180,6 +2180,27 @@ function testBasicRouteCompiling() {
2180 2180
 	}
2181 2181
 
2182 2182
 /**
  2183
+ * test route names with - in them.
  2184
+ *
  2185
+ * @return void
  2186
+ */
  2187
+	function testHyphenNames() {
  2188
+		$route =& new CakeRoute('/articles/:date-from/:date-to', array(
  2189
+			'controller' => 'articles', 'action' => 'index'
  2190
+		));
  2191
+		$expected = array(
  2192
+			'controller' => 'articles',
  2193
+			'action' => 'index',
  2194
+			'date-from' => '2009-07-31',
  2195
+			'date-to' => '2010-07-31',
  2196
+			'named' => array(),
  2197
+			'pass' => array()
  2198
+		);
  2199
+		$result = $route->parse('/articles/2009-07-31/2010-07-31');
  2200
+		$this->assertEqual($result, $expected);
  2201
+	}
  2202
+
  2203
+/**
2183 2204
  * test that route parameters that overlap don't cause errors.
2184 2205
  *
2185 2206
  * @return void
@@ -2390,7 +2411,6 @@ function testMatchBasic() {
2390 2411
 		$result = $route->match(array('plugin' => 'fo', 'controller' => 'posts', 'action' => 'edit', 'id' => 1));
2391 2412
 		$this->assertFalse($result);
2392 2413
 
2393  
-
2394 2414
 		$route =& new CakeRoute('/admin/subscriptions/:action/*', array(
2395 2415
 			'controller' => 'subscribe', 'admin' => true, 'prefix' => 'admin'
2396 2416
 		));
@@ -2409,6 +2429,7 @@ function testMatchBasic() {
2409 2429
 			'date-from' => '2009-07-31',
2410 2430
 			'date-to' => '2010-07-31'
2411 2431
 		);
  2432
+
2412 2433
 		$result = $route->match($url);
2413 2434
 		$expected = '/articles/2009-07-31/2010-07-31';
2414 2435
 		$this->assertEqual($result, $expected);

0 notes on commit 522446e

Please sign in to comment.
Something went wrong with that request. Please try again.