diff --git a/src/Symfony/Component/Routing/RouteCompiler.php b/src/Symfony/Component/Routing/RouteCompiler.php index 50b90ad953..8910b10d76 100644 --- a/src/Symfony/Component/Routing/RouteCompiler.php +++ b/src/Symfony/Component/Routing/RouteCompiler.php @@ -114,7 +114,7 @@ class RouteCompiler implements RouteCompilerInterface return preg_quote($token[1], self::REGEX_DELIMITER); } else { // Variable tokens - if (0 === $index && 0 === $firstOptional && 1 == count($tokens)) { + if (0 === $index && 0 === $firstOptional) { // When the only token is an optional variable token, the separator is required return sprintf('%s(?<%s>%s)?', preg_quote($token[1], self::REGEX_DELIMITER), $token[3], $token[2]); } else { @@ -127,7 +127,7 @@ class RouteCompiler implements RouteCompilerInterface $nbTokens = count($tokens); if ($nbTokens - 1 == $index) { // Close the optional subpatterns - $regexp .= str_repeat(")?", $nbTokens - $firstOptional); + $regexp .= str_repeat(")?", $nbTokens - $firstOptional - (0 === $firstOptional ? 1 : 0)); } } diff --git a/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php index e38c75a030..3e9f49d071 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php @@ -118,6 +118,14 @@ class UrlMatcherTest extends \PHPUnit_Framework_TestCase $matcher = new UrlMatcher($collection, new RequestContext(), array()); $this->assertEquals(array('_route' => 'bar', 'bar' => 'foo'), $matcher->match('/foo')); $this->assertEquals(array('_route' => 'bar', 'bar' => 'bar'), $matcher->match('/')); + + // route with only optional variables + $collection = new RouteCollection(); + $collection->add('bar', new Route('/{foo}/{bar}', array('foo' => 'foo', 'bar' => 'bar'), array())); + $matcher = new UrlMatcher($collection, new RequestContext(), array()); + $this->assertEquals(array('_route' => 'bar', 'foo' => 'foo', 'bar' => 'bar'), $matcher->match('/')); + $this->assertEquals(array('_route' => 'bar', 'foo' => 'a', 'bar' => 'bar'), $matcher->match('/a')); + $this->assertEquals(array('_route' => 'bar', 'foo' => 'a', 'bar' => 'b'), $matcher->match('/a/b')); } public function testMatchWithPrefixes() diff --git a/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php b/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php index 6b90bb3083..5288ca68fa 100644 --- a/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php +++ b/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php @@ -97,6 +97,14 @@ class RouteCompilerTest extends \PHPUnit_Framework_TestCase array('variable', '/', '(foo|bar)', 'bar'), )), + array( + 'Route with only optional variables', + array('/{foo}/{bar}', array('foo' => 'foo', 'bar' => 'bar')), + '', '#^/(?[^/]+)?(?:/(?[^/]+))?$#s', array('foo', 'bar'), array( + array('variable', '/', '[^/]+', 'bar'), + array('variable', '/', '[^/]+', 'foo'), + )), + array( 'Route with a variable in last position', array('/foo-{bar}'),