I want to return all Logged in users of my application and render it in my Dashboard. The user_id
and user_name
should be retrieved from the session (I am using an external LDAP Library for authentication)
I have created a field in the database called lastActivity
which will contain the last login time and then I can query the database for lastActivity
display users logged in in the last 2 minutes.
ActivityListener.php
<?php namespace BnppSecurityBundleEventListener; use DoctrineORMEntityManager; //use SymfonyComponentSecurityCoreUserUserInterface; use SymfonyComponentSecurityCoreSecurityContext; use SymfonyComponentHttpKernelEventFilterControllerEvent; use SymfonyComponentHttpKernelHttpKernel; use AcmeSecurityBundleEntityUser; use DoctrineBundleDoctrineBundleRegistry; /** * Listener that updates the last activity of the authenticated user */ class ActivityListener { protected $securityContext; protected $entityManager; public function __construct(SecurityContext $securityContext, EntityManager $entityManager) { $this->securityContext = $securityContext; $this->entityManager = $entityManager; } /** * Update the user "lastActivity" on each request * @param FilterControllerEvent $event */ public function onCoreController(FilterControllerEvent $event) { // Check that the current request is a "MASTER_REQUEST" // Ignore any sub-request if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) { return; } // Check token authentication availability if ($this->securityContext->getToken()) { $user = $this->securityContext->getToken()->getUser(); if ( ($user instanceof User) && !($user->isActiveNow()) ) { $user->setLastActivity(new DateTime('now')); $this->entityManager->flush($user); } } } }
Services.yml
services: activity_listener: class: BnppSecurityBundleEventListenerActivityListener arguments: [@security.context, @doctrine.orm.entity_manager] tags: - { name: kernel.event_listener, event: kernel.controller, method: onCoreController }
User Entity
<?php namespace AcmeSecurityBundleEntity; use DoctrineORMMapping as ORM; use SymfonyComponentSecurityCoreUserUserInterface; /** * User * * @ORMTable(name="users") * @ORMEntity(repositoryClass="AcmeSecurityBundleEntityUserRepository") */ class User implements UserInterface { /** * @var DateTime * @ORMColumn(name="LASTACTIVITY", type="datetime") */ private $lastActivity; /** * @return bool whether the user is active or not */ public function isActiveNow() { $delay = newDateTime('2 minutes ago'); return($this->getlastActivity()>$delay); } /** * Set lastActivity * * @paramDatetime $lastActivity * @return User */ public function setlastActivity($lastActivity) { $this->lastActivity = $lastActivity; return $this; } /** * Get lastActivity * * @return DateTime */ public function getlastActivity() { return $this->lastActivity; } }
Advertisement
Answer
There is a great post here: List online users.
You can create a Listener that listens on the kernel.controller
event and updates a user field lastActivity every time a user is active. You can check lastActivity < now()- 2 minutes
and update lastActivity timestamp.
Also: Implementing user activity in symfony 2
Here is how to do it
Note: If you’re not using FOSUserBundle, see Edit below.
1 Add this to your User Entity
/** * Date/Time of the last activity * * @var Datetime * @ORMColumn(name="last_activity_at", type="datetime") */ protected $lastActivityAt; /** * @param Datetime $lastActivityAt */ public function setLastActivityAt($lastActivityAt) { $this->lastActivityAt = $lastActivityAt; } /** * @return Datetime */ public function getLastActivityAt() { return $this->lastActivityAt; } /** * @return Bool Whether the user is active or not */ public function isActiveNow() { // Delay during wich the user will be considered as still active $delay = new DateTime('2 minutes ago'); return ( $this->getLastActivityAt() > $delay ); }
2 Create Event Listener
<?php namespace AcmeUserBundleEventListener; use SymfonyComponentSecurityCoreSecurityContext; use SymfonyComponentHttpKernelEventFilterControllerEvent; use SymfonyComponentHttpKernelHttpKernel; use FOSUserBundleModelUserManagerInterface; use FOSUserBundleModelUserInterface; /** * Listener that updates the last activity of the authenticated user */ class ActivityListener { protected $securityContext; protected $userManager; public function __construct(SecurityContext $securityContext, UserManagerInterface $userManager) { $this->securityContext = $securityContext; $this->userManager = $userManager; } /** * Update the user "lastActivity" on each request * @param FilterControllerEvent $event */ public function onCoreController(FilterControllerEvent $event) { // Check that the current request is a "MASTER_REQUEST" // Ignore any sub-request if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) { return; } // Check token authentication availability if ($this->securityContext->getToken()) { $user = $this->securityContext->getToken()->getUser(); if ( ($user instanceof UserInterface) && !($user->isActiveNow()) ) { $user->setLastActivityAt(new DateTime()); $this->userManager->updateUser($user); } } } }
3 Declare event Listener as a service
parameters: acme_user.activity_listener.class: AcmeUserBundleEventListenerActivityListener services: acme_user.activity_listener: class: %acme_user.activity_listener.class% arguments: [@security.context, @fos_user.user_manager] tags: - { name: kernel.event_listener, event: kernel.controller, method: onCoreController }
And you’re good to go!
Edit (without FOSUserBundle)
1 Add this to your User Entity
Same as Step 1 Above
2 Create Event Listener
<?php namespace AcmeUserBundleEventListener; use SymfonyComponentSecurityCoreSecurityContext; use SymfonyComponentHttpKernelEventFilterControllerEvent; use SymfonyComponentHttpKernelHttpKernel; use DoctrineORMEntityManager; use AcmeUserBundleEntityUser; /** * Listener that updates the last activity of the authenticated user */ class ActivityListener { protected $securityContext; protected $entityManager; public function __construct(SecurityContext $securityContext, EntityManager $entityManager) { $this->securityContext = $securityContext; $this->entityManager = $entityManager; } /** * Update the user "lastActivity" on each request * @param FilterControllerEvent $event */ public function onCoreController(FilterControllerEvent $event) { // Check that the current request is a "MASTER_REQUEST" // Ignore any sub-request if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) { return; } // Check token authentication availability if ($this->securityContext->getToken()) { $user = $this->securityContext->getToken()->getUser(); if ( ($user instanceof User) && !($user->isActiveNow()) ) { $user->setLastActivityAt(new DateTime()); $this->entityManager->flush($user); } } } }
3 Declare event Listener as a service
parameters: acme_user.activity_listener.class: AcmeUserBundleEventListenerActivityListener services: acme_user.activity_listener: class: %acme_user.activity_listener.class% arguments: [@security.context, @doctrine.orm.entity_manager] tags: - { name: kernel.event_listener, event: kernel.controller, method: onCoreController }
And you’re good to go!