2014-12-04 26 views
0

我目前正在處理自定義邏輯模擬監聽器。Symfony2用參數模擬監聽器注入

我overrided的的Symfony \分量\安全\ HTTP \防火牆\ SwitchUserListener因爲我想執行調用某些實體倉庫(不是用戶實體)之前授權切換事件:

例如,我想授權交換機當且僅當用戶模擬已經授權用戶請求交換機。

是否有可能將新參數(如doctrine service或某些數組值)注入到被覆蓋的偵聽器?

調用我的自定義SwitchUserListenener:

in services.yml 

parameters: 
    security.authentication.switchuser_listener.class: acme\appBundle\EventListener\SwitchUserListener 

回答

0

您的解決方案可能是在這裏:
https://github.com/symfony/symfony/blob/2.6/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php#L597

由Symfony的定義的服務security.authentication.switchuser_listener是一個抽象的服務。它實際上並不是被用作監聽器的服務,但它是同一個類。

代碼上去位:
https://github.com/symfony/symfony/blob/2.6/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php#L233

foreach ($firewalls as $name => $firewall) { 
    list($matcher, $listeners, $exceptionListener) = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds); 

這是你創建的防火牆當用戶切換將有可能的名稱。

現在您有幾個選項來覆蓋偵聽器。 您可以繼續覆蓋類參數,然後操縱參數如Symfony的已經做:

$listener->replaceArgument(1, new Reference($userProvider)); 
$listener->replaceArgument(3, $id); 
$listener->replaceArgument(6, $config['parameter']); 
$listener->replaceArgument(7, $config['role']); 

或者更簡單地說,編譯額外的方法在你的分機呼叫。

另一種解決方案是創建一個CompilerPass系統地刪除原始偵聽器並用您自己的替換它們。只要在SecurityBundle之後加載,您可以在自己的捆綁擴展中實現此功能。

$container->removeDefinition($id); 

編輯:

另一種解決方案,也許比上述更簡單,是創建另一個事件偵聽器。 其中一個觸發請求。這裏最重要的是監聽器必須對你重寫的監聽器有更高的優先級(我使用了監聽器,因爲可能有多個交換機用戶監聽器)。

棘手的部分將獲取重寫的偵聽器ID的列表,因爲您需要遍歷它們並調用自己的方法在偵聽器實例化之後,但在它們觸發之前注入新的依賴項。

+0

我會試試這個謝謝你 – 2015-01-21 12:57:33