2014-03-04 89 views
0

我建立了一個基於Symfony2和Sylius的內部唯一的Web應用程序。我的公司有4個不同的辦公室,使用靜態IP地址,我想跟蹤用戶正在使用哪個辦公室。一些員工在不同的日子搬到不同的地點,一些用戶也有筆記本電腦在一天之內從一個地方到另一個地方旅行。幾乎每個涉及寫入數據庫的頁面視圖都需要引用位置(應用程序需要知道事件發生的位置)。如何跟蹤內部symfony2應用程序的用戶位置?

我正在尋找關於如何最好地存儲和參考此信息的建議。我將獲得他們對應的IP地址和辦公室的靜態列表。這個列表可以存儲在yml或數據庫表中(我們預計每年一次添加位置,因此編輯該列表可以是手動任務)。如果這是我剛剛存儲在會話中的內容,或者通過$ container-> get('request') - > getClientIp()查找所有控制器中的每個頁面加載,或創建Symfony2 ROLE並在登錄時將其與用戶分配, 要麼 ?其他建議如何最好地完成這一點?

對於Symfony2來說,我還是很新的,所以如果這種邏輯有明顯的地方,我的道歉......我認爲它會有些獨特,因爲大多數面向公衆的網絡應用程序不會,也許在很多情況下在這種情況下,不應按照我需要的方式跟蹤IP地址...提前致謝。

回答

0

您不必修改控制器,只需創建一個event listener,並根據每個請求執行您想要的操作。

要獲得用戶,只需注入安全上下文服務並獲取令牌。如果請求位於防火牆後面,則可以獲取用戶。

這裏是根據官方公佈的資料(未測試,必須修改,以適應您的項目)爲例:

// src/Acme/DemoBundle/EventListener/AcmeRequestListener.php 
namespace Acme\DemoBundle\EventListener; 

use Symfony\Component\HttpKernel\Event\GetResponseEvent; 
use Symfony\Component\HttpKernel\HttpKernel; 
use Symfony\Component\Security\Core\SecurityContextInterface; 

class AcmeRequestListener 
{ 
    protected $sc; 

    public function __construct(SecurityContextInterface $sc) 
    { 
     $this->sc = $sc; 
    } 

    public function onKernelRequest(GetResponseEvent $event) 
    { 
     if (HttpKernel::MASTER_REQUEST != $event->getRequestType()) { 
      // don't do anything if it's not the master request 
      return; 
     } 

     if(null === ($token = $this->sc->getToken())) { 
      // don't do anything if you are not behind a firewall 
      return; 
     } 

     // do anything with $token to get the user and check he is authenticated 
     $user = $token->getUser(); 

     // Client IP 
     $ip = $event->getRequest()->getClientIp(); 
    } 
} 

而且你的服務定義:

<!-- app/config/config.xml --> 
<service id="kernel.listener.your_listener_name" class="Acme\DemoBundle\EventListener\AcmeExceptionListener"> 
    <argument type="service" id="security.context" /> 
    <tag name="kernel.event_listener" event="kernel.exception" method="onKernelException" /> 
</service> 
+0

謝謝你,這是我的第一個「聽衆」似乎在工作......這將很好地「設置」位置數據,但是當我需要「獲取」這個位置數據時(IE需要寫點東西的時候,你會推薦什麼?到數據庫並記錄它發生的地方)會話變量?或者是其他東西? – markjwill

+0

好吧,我將容器注入到我的EventListener中,並添加了這個 '$ session = $ this-> container-> get('session'); $ session-> set('location',$ ip); // $ IP將變成「位置對象」有一次我讓it' 然後作爲概念驗證,我決定在我的樹枝導航欄中顯示的位置(目前只是IP) '樹枝: 全局: 位置:「@ astound.location_name」 services: astound.location_name: class:Astound \ Bundle \ LocationBundle \ Manager \ LocationName arguments:['@service_container']' – markjwill

+0

'<?PHP /* * 注入參數: * - @service_container */ 命名震驚\包\ LocationBundle \經理; 使用Symfony \ Component \ DependencyInjection \ ContainerInterface; class LocationName { private $ container; public function __construct(ContainerInterface $ container) { $ this-> container = $ container; } \t \t公共職能getLocationName() \t { \t \t回$這個 - >容器 - >獲得( '會議') - >獲取( '位置'); \t} \t公共函數__toString() \t { \t \t返回$這 - > getLocationName(); \t} }' 這是「獲取」和「設置」這個位置數據的「最佳實踐」方式嗎? – markjwill