Skip to content
Advertisement

Symfony how to return all logged in Active Users

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!

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement