fixed route regex when the pattern is only made of optional segments

This commit is contained in:
Fabien Potencier 2012-05-20 05:43:44 +02:00
parent 22294617ad
commit f433f6b059
3 changed files with 18 additions and 2 deletions

View File

@ -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));
}
}

View File

@ -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()

View File

@ -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')),
'', '#^/(?<foo>[^/]+)?(?:/(?<bar>[^/]+))?$#s', array('foo', 'bar'), array(
array('variable', '/', '[^/]+', 'bar'),
array('variable', '/', '[^/]+', 'foo'),
)),
array(
'Route with a variable in last position',
array('/foo-{bar}'),