Symfony how to return all logged in Active Users

前端 未结 5 2031
-上瘾入骨i
-上瘾入骨i 2020-12-05 01:31

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 retrieve

相关标签:
5条回答
  • 2020-12-05 01:43

    Update for Symfony 3.4

    1. Add this to your User Entity

    Same as Step 1 Above

    2. Create Event Listener

    <?php
    namespace Acme\UserBundle\EventListener;
    
    use Symfony\Component\Security\Core\SecurityContext;
    use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
    use Symfony\Component\HttpKernel\HttpKernel;
    use Doctrine\ORM\EntityManager;
    use Acme\UserBundle\Entity\User;
    
    /**
     * Listener that updates the last activity of the authenticated user
     */
    class ActivityListener
    {
        protected $tokenContext;
        protected $doctrine;
    
        public function __construct(TokenyContext $tokenContext, $doctrine)
        {
            $this->tokenContext= $tokenContext;
            $this->doctrine= $doctrine;
        }
    
        /**
        * 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->tokenContext->getToken()) {
                $user = $this->tokenContext->getToken()->getUser();
    
                if ( ($user instanceof User) && !($user->isActiveNow()) ) {
                    $user->setLastActivityAt(new \DateTime());
                    $this->doctrine->getManager()->flush($user);
                }
            }
        }
    }
    

    3. Declare event Listener as a service

    parameters:
        acme_user.activity_listener.class: Acme\UserBundle\EventListener\ActivityListener
    
    services:
        acme_user.activity_listener:
            class: %acme_user.activity_listener.class%
            arguments: ['@security.token_storage', '@doctrine']
            tags:
                - { name: kernel.event_listener, event: kernel.controller, method: onCoreController }
    
    0 讨论(0)
  • 2020-12-05 01:46

    In Symfony 4 I solved the problem in the following way.

    <?php
    
    namespace App\EventSubscriber;
    
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    use Symfony\Component\HttpKernel\KernelEvents;
    use Doctrine\ORM\EntityManagerInterface;
    use Symfony\Component\Security\Core\Security;
    
    class ActivitySubscriber implements EventSubscriberInterface {
    
        private $em;
        private $security;
    
        public function __construct(
        EntityManagerInterface $em, Security $security) {
            $this->em = $em;
            $this->security = $security;
        }
    
        public function onTerminate() {
            $user = $this->security->getUser();
    
            if (!$user->isActiveNow()) {
                $user->setLastActivityAt(new \DateTime());
                $this->em->persist($user);
                $this->em->flush($user);
            }
        }
    
        public static function getSubscribedEvents() {
            return [
                // must be registered before (i.e. with a higher priority than) the default Locale listener
                KernelEvents::TERMINATE => [['onTerminate', 20]],
            ];
        }
    
    }
    
    0 讨论(0)
  • 2020-12-05 02:01

    As I can't comment on posts, I'd still like to give a remark on the answer by Mick via this answer.

    Since Symfony 2.6 the SecurityContext class is deprecated and, in this case, the TokenStorage class should be used instead.

    Thus, the services.yml would be as follows:

    services:
        acme_user.activity_listener:
            class: %acme_user.activity_listener.class%
            arguments: ['@security.token_storage', '@doctrine.orm.entity_manager']
            tags:
                - { name: kernel.event_listener, event: kernel.controller, method: onCoreController }
    

    And, instead of

    use Symfony\Component\Security\Core\SecurityContext;
    

    One should

    use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
    

    (also replace the SecurityContext inside the class with the TokenStorage class)

    Then, on line 38, the token availability would be checked using

    $this->tokenStorage->getToken()
    

    And, on line 39, the user instance would be obtained using

    $this->tokenStorage->getToken()->getUser()
    
    0 讨论(0)
  • 2020-12-05 02:02

    For Symfony3.4 (4), I used EntityManagerInterface to update user, and Security to get user, following codes worked for me :

    app/config/services.yml

    AppBundle\Service\ActivityListener:
        tags:
            - { name: 'kernel.event_listener', event: 'kernel.controller', method: onCoreController }
    

    Service/ActivityListener.php

    <?php
    namespace AppBundle\Service;
    
    use AppBundle\Entity\User;
    use Doctrine\ORM\EntityManagerInterface;
    use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
    use Symfony\Component\HttpKernel\HttpKernel;
    use Symfony\Component\Security\Core\Security;
    
    class ActivityListener
    {
        private $em;
        private $security;
    
      public function __construct(EntityManagerInterface $em, Security $security)
      {
        $this->em = $em;
        $this->security = $security;
      }
    
      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->security->getToken()) {
            $user = $this->security->getToken()->getUser();
    
            if ( ($user instanceof User) && !($user->isActiveNow()) ) {
                $user->setLastActivityAt(new \DateTime());
                $this->em->flush($user);
            }
        }
      }
    }
    
    0 讨论(0)
  • 2020-12-05 02:06

    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
     * @ORM\Column(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 Acme\UserBundle\EventListener;
    
    use Symfony\Component\Security\Core\SecurityContext;
    use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
    use Symfony\Component\HttpKernel\HttpKernel;
    use FOS\UserBundle\Model\UserManagerInterface;
    use FOS\UserBundle\Model\UserInterface;
    
    /**
     * 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: Acme\UserBundle\EventListener\ActivityListener
    
    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 Acme\UserBundle\EventListener;
    
    use Symfony\Component\Security\Core\SecurityContext;
    use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
    use Symfony\Component\HttpKernel\HttpKernel;
    use Doctrine\ORM\EntityManager;
    use Acme\UserBundle\Entity\User;
    
    /**
     * 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: Acme\UserBundle\EventListener\ActivityListener
    
    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!

    0 讨论(0)
提交回复
热议问题