[Routing] Make trailing slashes in urls optional

This commit is contained in:
Jordi Boggiano 2011-02-05 19:06:40 +01:00 committed by Fabien Potencier
parent b91f082be5
commit fe694de746
2 changed files with 59 additions and 3 deletions

View File

@ -54,4 +54,35 @@ class RedirectController extends ContainerAware
return $response;
}
/**
* Redirects to a URL.
*
* It expects a url path parameter.
* By default, the response status code is 301.
*
* If the url is empty, the status code will be 410.
* If the permanent path parameter is set, the status code will be 302.
*
* @param string $url The url to redirect to
* @param Boolean $permanent Whether the redirect is permanent or not
*
* @return Response A Response instance
*/
public function urlRedirectAction($url, $permanent = false)
{
if (!$url) {
$response = $this->container->get('response');
$response->setStatusCode(410);
return $response;
}
$code = $permanent ? 301 : 302;
$response = $this->container->get('response');
$response->setRedirect($url, $code);
return $response;
}
}

View File

@ -60,8 +60,14 @@ class PhpMatcherDumper extends MatcherDumper
$conditions[] = sprintf("isset(\$this->context['method']) && preg_match('#^(%s)$#xi', \$this->context['method'])", $req);
}
$hasTrailingSlash = false;
if (!count($compiledRoute->getVariables()) && false !== preg_match('#^(.)\^(?P<url>.*?)\$\1#', $compiledRoute->getRegex(), $m)) {
$conditions[] = sprintf("\$url === '%s'", str_replace('\\', '', $m['url']));
if (substr($m['url'], -1) === '/' && $m['url'] !== '/') {
$conditions[] = sprintf("rtrim(\$url, '/') === '%s'", rtrim(str_replace('\\', '', $m['url']), '/'));
$hasTrailingSlash = true;
} else {
$conditions[] = sprintf("\$url === '%s'", str_replace('\\', '', $m['url']));
}
$matches = 'array()';
} else {
@ -69,15 +75,34 @@ class PhpMatcherDumper extends MatcherDumper
$conditions[] = sprintf("0 === strpos(\$url, '%s')", $compiledRoute->getStaticPrefix());
}
$conditions[] = sprintf("preg_match('%s', \$url, \$matches)", $compiledRoute->getRegex());
$regex = $compiledRoute->getRegex();
if ($pos = strpos($regex, '/$')) {
$regex = substr($regex, 0, $pos) . '/?$' . substr($regex, $pos+2);
$conditions[] = sprintf("preg_match('%s', \$url, \$matches)", $regex);
$hasTrailingSlash = true;
} else {
$conditions[] = sprintf("preg_match('%s', \$url, \$matches)", $regex);
}
$matches = '$matches';
}
$conditions = implode(' && ', $conditions);
$code[] = sprintf(<<<EOF
$code[] = <<<EOF
if ($conditions) {
EOF;
if ($hasTrailingSlash) {
$code[] = sprintf(<<<EOF
if (substr(\$url, -1) !== '/') {
return array('_controller' => 'Symfony\\Bundle\\FrameworkBundle\\Controller\\RedirectController::urlRedirectAction', 'url' => \$this->context['base_url'].\$url.'/', 'permanent' => true, '_route' => '%s');
}
EOF
, $name);
}
$code[] = sprintf(<<<EOF
return array_merge(\$this->mergeDefaults($matches, %s), array('_route' => '%s'));
}