2012-11-12 32 views
15

我有一個註銷監聽器,我想在其中設置一條顯示註銷確認消息的Flash消息。Symfony 2 - 在控制器之外設置閃存消息

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

這裏是我的services.yml(因爲它涉及到這一點):

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

這是產生錯誤:

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

如何在這個設置flashBag消息背景?

另外,如何獲得路由器的訪問權限,以便我可以生成url(通過$ this-> router-> generate('login')),而不是傳入硬編碼的url?

分辨率注意

爲了獲得閃光燈的工作,你必須告訴你的security.yml配置不壞就註銷了會議;否則,會話將被銷燬,您的閃光燈將永遠不會出現。

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

回答

21

您應該將會話和路由器的服務注入LogoutListener並使用它們來執行這些任務。這是做在陽明路:

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

然後在您的類你寫:

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; 
    } 
    [...] 

當你想現在使用會話你可以說:

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

以同樣的方式,您可以使用路由器服務來生成路由。

+0

我添加了我的services.yml。我如何添加註入服務?我認爲我需要使用參數,但我不確定注入這些參數的語法。 – doremi

+0

這會向您顯示有關注入服務的基本示例,請在此處閱讀更多信息:http://symfony.com/doc/current/book/service_container.html –

+1

我的會話顯然正在被破壞,因此閃存正在被擦除。我認爲實際登出已經完成之前onLogoutSuccess()被調用? – doremi

2

你可以得到Session對象(以及任何其他服務)槽服務容器:

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

您可以訪問該服務容器以不同的方式方法:從

  • 一個控制器或任何容器感知類:只需使用$ this-> get('session');
  • 從服務:你必須注入服務容器對象爲Aldo Said
+4

此方法可行,但不是執行依賴注入的正確方法。你應該避免在任何地方注入容器,這就是使用容器來實現一個服務定位器模式,它有兩個主要缺點:所有類(即你的模型)將取決於服務而不是系統的其他相關部分(使它不可能在symfony之外重用它們),並且所有的依賴都將在運行時而不是「編譯時」解決,也就是說,當symfony在引導之前轉儲容器時。只注入您需要的服務,這是最佳實踐! –

+1

你有一個觀點:) – Xocoatzin