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!