diff --git a/AltoRouter.php b/AltoRouter.php index 04f9bba..8b3f631 100644 --- a/AltoRouter.php +++ b/AltoRouter.php @@ -139,7 +139,7 @@ class AltoRouter { if (preg_match_all('`(/|\.|)\[([^:\]]*+)(?::([^:\]]*+))?\](\?|)`', $route, $matches, PREG_SET_ORDER)) { - foreach($matches as $match) { + foreach($matches as $index => $match) { list($block, $pre, $type, $param, $optional) = $match; if ($pre) { @@ -147,13 +147,17 @@ class AltoRouter { } if(isset($params[$param])) { + // Part is found, replace for param value $url = str_replace($block, $params[$param], $url); - } elseif ($optional) { + } elseif ($optional && $index !== 0) { + // Only strip preceeding slash if it's not at the base $url = str_replace($pre . $block, '', $url); + } else { + // Strip match block + $url = str_replace($block, '', $url); } } - } return $url; @@ -250,14 +254,18 @@ class AltoRouter { $pre = '\.'; } + $optional = $optional !== '' ? '?' : null; + //Older versions of PCRE require the 'P' in (?P) $pattern = '(?:' . ($pre !== '' ? $pre : null) . '(' . ($param !== '' ? "?P<$param>" : null) . $type - . '))' - . ($optional !== '' ? '?' : null); + . ')' + . $optional + . ')' + . $optional; $route = str_replace($block, $pattern, $route); } diff --git a/tests/AltoRouterTest.php b/tests/AltoRouterTest.php index 2a9160c..9444549 100644 --- a/tests/AltoRouterTest.php +++ b/tests/AltoRouterTest.php @@ -233,7 +233,27 @@ class AltoRouterTest extends PHPUnit_Framework_TestCase $this->assertEquals('/test/someaction.json', $this->router->generate('bar_route', $params)); } - + + /** + * GitHub #98 + */ + public function testGenerateWithOptionalPartOnBareUrl() + { + $this->router->map('GET', '/[i:page]?', function(){}, 'bare_route'); + + $params = array( + 'page' => 1 + ); + + $this->assertEquals('/1', + $this->router->generate('bare_route', $params)); + + $params = array(); + + $this->assertEquals('/', + $this->router->generate('bare_route', $params)); + } + public function testGenerateWithNonexistingRoute() { try{ @@ -364,6 +384,35 @@ class AltoRouterTest extends PHPUnit_Framework_TestCase 'name' => 'bar_route' ), $this->router->match('/bar/test/do.json', 'GET')); + $this->assertEquals(array( + 'target' => 'bar_action', + 'params' => array( + 'controller' => 'test', + 'action' => 'do' + ), + 'name' => 'bar_route' + ), $this->router->match('/bar/test/do', 'GET')); + } + + /** + * GitHub #98 + */ + public function testMatchWithOptionalPartOnBareUrl(){ + $this->router->map('GET', '/[i:page]?', 'bare_action', 'bare_route'); + + $this->assertEquals(array( + 'target' => 'bare_action', + 'params' => array( + 'page' => 1 + ), + 'name' => 'bare_route' + ), $this->router->match('/1', 'GET')); + + $this->assertEquals(array( + 'target' => 'bare_action', + 'params' => array(), + 'name' => 'bare_route' + ), $this->router->match('/', 'GET')); } public function testMatchWithWildcard()