2012-11-12 12 views
15

Mam wylogowanie Odbiornika, w którym chciałbym ustawić wiadomość flash pokazującą komunikat potwierdzenia wylogowania.Symfony 2 - Ustawianie komunikatu Flash poza kontrolerem

namespace Acme\MyBundle\Security\Listeners; 

use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface; 
use Symfony\Component\Security\Core\SecurityContext; 
use Symfony\Component\HttpFoundation\Response; 
use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpFoundation\RedirectResponse; 

class LogoutListener implements LogoutSuccessHandlerInterface 
{ 
    private $security; 

    public function __construct(SecurityContext $security) 
    { 
    $this->security = $security; 
    } 

    public function onLogoutSuccess(Request $request) 
    { 
    $request->get('session')->getFlashBag()->add('notice', 'You have been successfully been logged out.'); 

    $response = new RedirectResponse('login'); 
    return $response; 
    } 
} 

Oto moja services.yml (jak to odnosi się do tego):

logout_listener: 
    class: ACME\MyBundle\Security\Listeners\LogoutListener 
    arguments: [@security.context] 

ten generuje błąd:

Fatal error: Call to a member function getFlashBag() on a non-object 

Jak ustawić wiadomość flashBag w ten kontekst?

Co więcej, jak uzyskać dostęp do routera, aby wygenerować adres URL (za pośrednictwem $ this-> router-> generate ("login")) zamiast podawać zakodowany adres URL?

Rozdzielczość Uwaga

Aby dostać się do pracy lampy błyskowej, należy poinformować o tym security.yml config nie unieważnić sesję na wylogowania; w przeciwnym razie sesja zostanie zniszczona, a Twoja lampa błyskowa nigdy się nie pojawi.

logout: 
    path: /logout 
     success_handler: logout_listener 
     invalidate_session: false 

Odpowiedz

21

powinien wstrzyknąć usługi dla sesji i router do LogoutListener i wykorzystywać je do wykonywania tych zadań. Jest to sposób, aby to zrobić w yml:

logout_listener: 
class: ACME\MyBundle\Security\Listeners\LogoutListener 
arguments: [@security.context, @router, @session] 

Następnie w swojej klasie piszesz:

class LogoutListener implements LogoutSuccessHandlerInterface 
{ 
    private $security; 
    private $router; 
    private $session; 

    public function __construct(SecurityContext $security, Router $router, Session $session) 
    { 
     $this->security = $security; 
     $this->router = $router; 
     $this->session = $session; 
    } 
    [...] 

Kiedy chcesz użyć sesję teraz można po prostu powiedzieć:

$this->session->getFlashBag()->add('notice', 'You have been successfully been logged out.'); 

I w ten sam sposób możesz użyć usługi routera do generowania tras.

+0

dodałam mój services.yml. Jak dodać wstrzyknąć usługi? Zakładam, że potrzebuję użyć argumentów, ale nie jestem pewien składni, aby je wprowadzić. – doremi

+0

To pokazuje podstawowy przykład na temat wstrzykiwania usług, przeczytaj więcej tutaj: http://symfony.com/doc/current/book/service_container.html –

+1

Moja sesja najwyraźniej ulega zniszczeniu, więc flashowanie jest wymazywane. Myślałem, że faktyczne wylogowanie zostało już wykonane przed wywołaniem metody onLogoutSuccess()? – doremi

2

można uzyskać obiekt Session (a także wszelkie inne usługi) koryta kontener serwisowy:

$session = $ServiceContainer->get('session'); 
$session->setFlash('notice', 'Message'); 

Sposób, można uzyskać dostęp do pojemnika usług na różne sposoby:

  • Z kontroler lub dowolna klasa świadoma kontenera: po prostu użyj $ this-> get ('session');
  • z usługi: trzeba wstrzyknąć obiekt kontenera usługi jak Aldo Wspomniany
+4

To podejście działa, ale nie jest prawidłowym sposobem wykonania iniekcji zależności. Powinieneś unikać wstrzykiwania pojemnika wszędzie, używając kontenera do implementacji wzoru lokalizatora usług, który ma dwie główne wady: wszystkie twoje klasy (tj. Twój model) będą zależeć od usługi, a nie od innych istotnych części systemu (czyniąc go niemożliwe do ponownego użycia poza symfony) i wszystkie zależności zostaną rozwiązane w czasie wykonywania, a nie w "czasie kompilacji", tj. gdy symfony zrzuci kontener przed bootstrapem. Wprowadź tylko te usługi, które potrzebujesz, to najlepsza praktyka! –

+1

Masz rację :) – Xocoatzin