Redirect with Event Listener for all "No route found 404 Not Found - NotFoundHttpException"
How can I trigger redirect to a specific router in event listener?
There are many examples but I couldn't find one for "GetResponseForExceptionEvent". For exampe, when I pass @roter
as an argument $this->router....
doesn't seem to be working so on.
I checked these but I probably missed something:
- Show a specific route instead of error page (404) - Symfony2
- symfony2: hook into NotFoundHttpException for redirection
- Symfony2 redirect for event listener?
- Symfony2: Getting Route in Page Load Event Listener
- Redirect if the user is logged in
service.yml
services:
kernel.listener.kernel_request:
class: Booking\AdminBundle\EventListener\ErrorRedirect
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException }
Event listener:
namespace Booking\AdminBundle\EventListener;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class ErrorRedirect
{
public function onKernelException(GetResponseForExceptionEvent $event)
{
$exception = $event->getException();
if ($exception instanceof NotFoundHttpException) {
// redirect to '/' router or '/error'
//$event->setResponse(...........);
}
}
}
You have 2 options:
- Use an Event Listener
- Use a route that matches all the routes that don't exist and trigger an action in a controller.
Let me know if that works.
Option 1
Note: Have a look at Symfony2 redirect for event listener
1 Pass the router to your event listener:
kernel.listener.kernel_request:
class: Booking\AdminBundle\EventListener\ErrorRedirect
arguments:
router: "@router"
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException }
2 Use the router within the listener to redirect users:
namespace Booking\AdminBundle\EventListener;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
class ErrorRedirect
{
/**
* Holds Symfony2 router
*
*@var Router
*/
protected $router;
/**
* @param Router
*/
public function __construct(Router $router)
{
$this->router = $router;
}
public function onKernelException(GetResponseForExceptionEvent $event)
{
$exception = $event->getException();
if ($exception instanceof NotFoundHttpException) {
/** Choose your router here */
$route = 'route_name';
if ($route === $event->getRequest()->get('_route')) {
return;
}
$url = $this->router->generate($route);
$response = new RedirectResponse($url);
$event->setResponse($response);
}
}
}
Option 2
You can create a special route that will match all routes that don't exist; You can then handle the redirect the way you want within the controller of your choice, here PageNotFoundController:
1 At the end of app/config/routing.yml
pageNotFound:
pattern: /{path}
defaults: { _controller: AcmeDemoBundle:PageNotFound:pageNotFound, path: '' }
requirements:
path: .*
2
<?php
namespace Acme\DemoBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class PageNotFoundController extends Controller
{
public function pageNotFoundAction()
{
// redirect the way you want
}
}