2014-10-20 11 views
5

Jak mogę wywołać przekierowanie do określonego routera w detektorze zdarzeń?Przekierowanie za pomocą detektora zdarzeń dla wszystkich "Nie znaleziono trasy Nie znaleziono 404 - NotFoundHttpException"

Istnieje wiele przykładów, ale nie mogłem znaleźć jednego dla "GetResponseForExceptionEvent". Dla przykładu, kiedy przekazuję @roter jako argument $this->router...., wydaje się, że tak nie działa.

Sprawdziłem te ale prawdopodobnie coś przeoczyć:

service.yml

services: 
    kernel.listener.kernel_request: 
     class: Booking\AdminBundle\EventListener\ErrorRedirect 
     tags: 
      - { name: kernel.event_listener, event: kernel.exception, method: onKernelException } 

słuchacz zdarzenia:

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(...........); 
     } 
    } 
} 

Odpowiedz

31

Masz 2 opcje:

  • użyć zdarzenia Listener
  • Użyj trasy, która pasuje do wszystkich tras, które nie istnieją, i uruchom akcję w kontrolerze.

Daj mi znać, jeśli to działa.


Wariant 1

Uwaga: Wystarczy popatrzeć na Symfony2 redirect for event listener

Przepuścić router do detektora zdarzeń:

kernel.listener.kernel_request: 
     class: Booking\AdminBundle\EventListener\ErrorRedirect 
     arguments: 
      router: "@router" 
     tags: 
      - { name: kernel.event_listener, event: kernel.exception, method: onKernelException } 

wykorzystać router w słuchaczu, aby to przerobić ct użytkownicy:

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

     } 
    } 
} 

Wariant 2

Można utworzyć specjalną trasę, która będzie pasował wszystkie trasy, które nie istnieją; Następnie możesz obsłużyć przekierowanie w wybranym przez siebie sterowniku, tutaj: Na końcu aplikacji/config/routing.yml

pageNotFound: 
    pattern: /{path} 
    defaults: { _controller: AcmeDemoBundle:PageNotFound:pageNotFound, path: '' } 
    requirements: 
     path: .* 

<?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 

    } 

} 
+4

Co doskonałą odpowiedź! Dziękuję Ci bardzo. +++ 1 – BentCoder

+0

Ale czy to nie działa tylko w Dev, a nie w środowiskach Prod? –

+0

Opcja 2 działała dobrze. Dzięki! – TechyTee

Powiązane problemy