Symfony, как вернуть всех зарегистрированных активных пользователей

Я хочу вернуть всех зарегистрированных пользователей моего приложения и отобразить их в своей панели инструментов. user_id и user_id должны быть извлечены из сеанса (я использую внешнюю библиотеку LDAP для аутентификации)

Я создал поле в базе данных, называемое lastActivity которое будет содержать последнее время входа в систему, а затем я могу запросить базу данных для пользователей последних пользователей, которые вошли в систему за последние 2 минуты.

ActivityListener.php

  <?php namespace Bnpp\SecurityBundle\EventListener; use Doctrine\ORM\EntityManager; //use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\SecurityContext; use Symfony\Component\HttpKernel\Event\FilterControllerEvent; use Symfony\Component\HttpKernel\HttpKernel; use Acme\SecurityBundle\Entity\User; use Doctrine\Bundle\DoctrineBundle\Registry; /** * 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: Bnpp\SecurityBundle\EventListener\ActivityListener arguments: [@security.context, @doctrine.orm.entity_manager] tags: - { name: kernel.event_listener, event: kernel.controller, method: onCoreController } 

Пользовательский объект

 <?php namespace Acme\SecurityBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\UserInterface; /** * User * * @ORM\Table(name="users") * @ORM\Entity(repositoryClass="Acme\SecurityBundle\Entity\UserRepository") */ class User implements UserInterface { /** * @var \DateTime * @ORM\Column(name="LASTACTIVITY", type="datetime") */ private $lastActivity; /** * @return bool whether the user is active or not */ public function isActiveNow() { $delay = new\DateTime('2 minutes ago'); return($this->getlastActivity()>$delay); } /** * Set lastActivity * * @param\Datetime $lastActivity * @return User */ public function setlastActivity($lastActivity) { $this->lastActivity = $lastActivity; return $this; } /** * Get lastActivity * * @return \DateTime */ public function getlastActivity() { return $this->lastActivity; } } 

Здесь есть отличный пост: Список онлайн-пользователей .

Вы можете создать Listener, который прослушивает событие kernel.controller и обновляет поле пользователя lastActivity каждый раз, когда пользователь активен. Вы можете проверить lastActivity < now()- 2 minutes и обновить временную метку lastActivity.

Также: реализация пользовательской активности в symfony 2

Вот как это сделать

Примечание. Если вы не используете FOSUserBundle, см. Раздел «Редактировать» ниже.

1 Добавьте это в свой пользовательский объект

 /** * 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 Создать прослушиватель событий

 <?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 Заявить событие Слушатель как услуга

 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 } 

И ты в порядке!

Изменить (без FOSUserBundle)

1 Добавьте это в свой пользовательский объект

 Same as Step 1 Above 

2 Создать прослушиватель событий

 <?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 Заявить событие Слушатель как услуга

 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 } 

И ты в порядке!

Поскольку я не могу комментировать сообщения, я все равно хотел бы дать ответ на ответ Мика через этот ответ.

Поскольку Symfony 2.6 класс SecurityContext устарел, и в этом случае вместо этого следует использовать класс TokenStorage.

Таким образом, services.yml будет выглядеть следующим образом:

 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 } 

И вместо

 use Symfony\Component\Security\Core\SecurityContext; 

Надо

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

(также замените SecurityContext внутри класса классом TokenStorage)

Затем, в строке 38, доступность токена будет проверяться с использованием

 $this->tokenStorage->getToken() 

И, в строке 39, пользовательский экземпляр будет получен с использованием

 $this->tokenStorage->getToken()->getUser()