From 33c67f7c47181870da9f7257d86268a8c1d5ef44 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 28 Nov 2009 09:40:15 -0500 Subject: [PATCH] More tests passing and more code moved from Router to RouterRoute. Switching RouterRoute to used named capture groups. This simplifies the route processing internals as there are fewer loops used to merge array sets together. --- cake/libs/router.php | 63 ++++++++++++--------------- cake/tests/cases/libs/router.test.php | 21 ++++++--- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/cake/libs/router.php b/cake/libs/router.php index fbf349c67..8194dcb6a 100644 --- a/cake/libs/router.php +++ b/cake/libs/router.php @@ -423,34 +423,14 @@ class Router { $argOptions['greedy'] = $params['greedy']; unset($params['greedy']); } - array_shift($r); + $out = $r; - foreach ($names as $name) { - $out[$name] = null; - } - if (is_array($defaults)) { - foreach ($defaults as $name => $value) { - if (preg_match('#[a-zA-Z_\-]#i', $name)) { - $out[$name] = $value; - } else { - $out['pass'][] = $value; - } - } - } - - foreach ($r as $key => $found) { - if (empty($found) && $found != 0) { - continue; - } - - if (isset($names[$key])) { - $out[$names[$key]] = $self->stripEscape($found); - } else { - $argOptions['context'] = array('action' => $out['action'], 'controller' => $out['controller']); - extract($self->getArgs($found, $argOptions)); - $out['pass'] = array_merge($out['pass'], $pass); - $out['named'] = $named; - } + if (isset($out['_args_'])) { + $argOptions['context'] = array('action' => $out['action'], 'controller' => $out['controller']); + $parsedArgs = $self->getArgs($out['_args_'], $argOptions); + $out['pass'] = array_merge($out['pass'], $parsedArgs['pass']); + $out['named'] = $parsedArgs['named']; + unset($out['_args_']); } if (isset($params['pass'])) { @@ -1281,27 +1261,27 @@ class RouterRoute { preg_match_all('#:([A-Za-z0-9_-]+[A-Z0-9a-z])#', $route, $namedElements); foreach ($namedElements[1] as $i => $name) { - $option = null; if (isset($params[$name])) { + $option = null; if ($name !== 'plugin' && array_key_exists($name, $default)) { $option = '?'; } $slashParam = '/\\' . $namedElements[0][$i]; if (strpos($parsed, $slashParam) !== false) { - $replacements[] = '(?:/(' . $params[$name] . ')' . $option . ')' . $option; + $replacements[] = '(?:/(?P<' . $name . '>' . $params[$name] . ')' . $option . ')' . $option; $search[] = $slashParam; } else { $search[] = '\\' . $namedElements[0][$i]; - $replacements[] = '(?:(' . $params[$name] . ')' . $option . ')' . $option; + $replacements[] = '(?:(?P<' . $name . '>' . $params[$name] . ')' . $option . ')' . $option; } } else { - $replacements[] = '(?:([^/]+))?'; + $replacements[] = '(?:(?P<' . $name . '>[^/]+))?'; $search[] = '\\' . $namedElements[0][$i]; } $names[] = $name; } if (preg_match('#\/\*#', $route, $m)) { - $parsed = preg_replace('#/\\\\\*#', '(?:/(.*))?', $parsed); + $parsed = preg_replace('#/\\\\\*#', '(?:/(?P<_args_>.*))?', $parsed); } $parsed = str_replace($search, $replacements, $parsed); $this->_compiledRoute = '#^' . $parsed . '[/]*$#'; @@ -1321,11 +1301,11 @@ class RouterRoute { $this->compile(); } - if (!preg_match($this->_compiledRoute, $url, $r)) { + if (!preg_match($this->_compiledRoute, $url, $route)) { return false; } else { foreach ($this->defaults as $key => $val) { - if ($key{0} === '[' && preg_match('/^\[(\w+)\]$/', $key, $header)) { + if ($key[0] === '[' && preg_match('/^\[(\w+)\]$/', $key, $header)) { if (isset($this->__headerMap[$header[1]])) { $header = $this->__headerMap[$header[1]]; } else { @@ -1345,8 +1325,21 @@ class RouterRoute { } } } + array_shift($route); + $count = count($this->keys); + for ($i = 0; $i <= $count; $i++) { + unset($route[$i]); + } + $route['pass'] = $route['named'] = array(); + $route += $this->defaults; + foreach ($route as $key => $value) { + if (is_integer($key)) { + $route['pass'][] = $value; + unset($route[$key]); + } + } + return $route; } - return $r; } /** diff --git a/cake/tests/cases/libs/router.test.php b/cake/tests/cases/libs/router.test.php index 208bd406a..f3e5fcd6c 100644 --- a/cake/tests/cases/libs/router.test.php +++ b/cake/tests/cases/libs/router.test.php @@ -1649,7 +1649,7 @@ class RouterTest extends CakeTestCase { Router::connect('/pages/*/:event', array('controller' => 'pages', 'action' => 'display'), array('event' => '[a-z0-9_-]+')); $result = Router::parse('/'); - $expected = array('pass'=>array('home'), 'named' => array(), 'plugin' => null, 'controller' => 'pages', 'action' => 'display'); + $expected = array('pass' => array('home'), 'named' => array(), 'plugin' => null, 'controller' => 'pages', 'action' => 'display'); $this->assertEqual($result, $expected); $result = Router::parse('/pages/home'); @@ -1951,7 +1951,7 @@ class RouterTest extends CakeTestCase { } } -// SimpleTest::ignore('RouterTest'); + /** * Test case for RouterRoute * @@ -2103,7 +2103,7 @@ class RouterRouteTestCase extends CakeTestCase { /** * test more complex route compiling & parsing with mid route greedy stars - * and // + * and optional routing parameters * * @return void */ @@ -2127,7 +2127,14 @@ class RouterRouteTestCase extends CakeTestCase { $result = $route->compile(); $this->assertPattern($result, '/posts/08/01/2007/title-of-post'); $result = $route->parse('/posts/08/01/2007/title-of-post'); - $this->assertEqual(count($result), 5); + + $this->assertEqual(count($result), 9); + $this->assertEqual($result['controller'], 'posts'); + $this->assertEqual($result['action'], 'view'); + $this->assertEqual($result['plugin'], null); + $this->assertEqual($result['year'], '2007'); + $this->assertEqual($result['month'], '08'); + $this->assertEqual($result['day'], '01'); $route =& new RouterRoute( "/:extra/page/:slug/*", @@ -2179,9 +2186,9 @@ class RouterRouteTestCase extends CakeTestCase { $route = new RouterRoute('/:controller/:action/:id', array('controller' => 'testing4', 'id' => null), array('id' => $ID)); $route->compile(); $result = $route->parse('/posts/view/1'); - $this->assertEqual($result[1], 'posts'); - $this->assertEqual($result[2], 'view'); - $this->assertEqual($result[3], '1'); + $this->assertEqual($result['controller'], 'posts'); + $this->assertEqual($result['action'], 'view'); + $this->assertEqual($result['id'], '1'); } }