Reputation: 3922
Is there any configuration in Symfony2 that allow use of case Insensitive routing?
For example, routes below should be treated as they are the same:
www.exmaple.com/all
www.exmaple.com/ALL
There is a pull request about this, but no reference how to make it happen.
Upvotes: 3
Views: 4667
Reputation: 3070
I found a nifty way to do this in pure symfony (no apache mod_rewrite) without having to create a case-insensitive forwarding rule for every route.
This utilizes the twig ExceptionController. Because this occures after the routing has failed to match (or a 404 exception has been thrown for some other reason) it won't break any existing routing urls that use capitals (though that would still be a bad idea).
namespace Application\Symfony\TwigBundle\Controller;
use Symfony\Component\HttpKernel\Exception\FlattenException;
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Bundle\TwigBundle\Controller\ExceptionController as BaseExceptionController;
/**
* ExceptionController.
*/
class ExceptionController extends BaseExceptionController
{
/**
* Redirects 404s on urls with uppercase letters to the lowercase verion,
* then uses it's parent class to
* Convert an Exception to a Response.
*
* @param Request $request The request
* @param FlattenException $exception A FlattenException instance
* @param DebugLoggerInterface $logger A DebugLoggerInterface instance
*
* @return Response
*
* @throws \InvalidArgumentException When the exception template does not exist
*/
public function showAction(Request $request, FlattenException $exception, DebugLoggerInterface $logger = null)
{
if ( (string) $exception->getStatusCode() === '404' && preg_match('/[A-Z]/', $request->getPathInfo())) {
$lowercaseUrl = strtolower($request->getPathInfo());
if ($request->isMethod('POST')) {
return new RedirectResponse(
$lowercaseUrl,
'307'//307 status code preserves post information.
);
}
$queryString = $request->getQueryString();
return new RedirectResponse(
$lowercaseUrl.( strlen($queryString)>0 ? '?'.$queryString : '' ),
'301'//301 status code plays nice with search engines
);
}
return parent::showAction($request, $exception, $logger);
}
}
The only other trick is that you need to configure this controller as a service you can inject the correct arguments into the parent class's constructor:
in services.yml
services:
application.custom.exception_controller:
class: Application\Symfony\TwigBundle\Controller\ExceptionController
arguments: [ "@twig", "%kernel.debug%" ]
in config.yml:
twig:
exception_controller: application.custom.exception_controller:showAction
Of course, you can stick this controller and service definition anywhere
Upvotes: 1
Reputation: 21
As of Symfony2.4, you can now define condition to your route and use the expression language to do complexe check. See Router: Completely Customized Route Matching with Conditions documentation.
Another solution would be to override the route compiler class to change/extend the php compilation of your route matcher:
contact:
path: /{media}
defaults: { _controller: AcmeDemoBundle:Main:contact, media: organic }
requirements:
media: email|organic|ad
options:
compiler_class: MyVendor\Component\Routing\CaseInsensitiveRouteCompiler
See Symfony\Component\Routing\RouteCompiler class.
Or, as fabpot said in the pull request comment, your could override Request::getPathInfo[1] method to always return a lowercase string (use the setFactory[2] to override default request class).
*1 github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpFoundation/Request.php#L866
*2 github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpFoundation/Request.php#L402
Upvotes: 2
Reputation: 2943
As far as I know, this isn't possible with Symfony 2. However, you should be able to accomplish it with Apache's mod_rewrite. See this blog post for details.
Make sure to read the comments, as there are some errors with the initial post.
Upvotes: 1