Clo*_*edi 11 php doctrine symfony symfony-2.3
我想返回我的应用程序的所有登录用户并在我的仪表板中呈现它.在user_id与user_name应该从会话中检索(我使用的是外部LDAP库进行验证)
我在数据库中创建了一个字段,该字段lastActivity将包含上次登录时间,然后我可以在数据库中查询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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
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 }
Run Code Online (Sandbox Code Playgroud)
用户实体
<?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;
}
}
Run Code Online (Sandbox Code Playgroud)
Mic*_*ick 22
这里有一个很棒的帖子:列出在线用户.
您可以创建侦听kernel.controller事件的侦听器,并在每次用户处于活动状态时更新用户字段lastActivity.您可以检查lastActivity < now()- 2 minutes并更新lastActivity时间戳.
注意:如果您未使用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 );
}
Run Code Online (Sandbox Code Playgroud)
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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
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 }
Run Code Online (Sandbox Code Playgroud)
你很高兴去!
1 将此添加到您的用户实体
Same as Step 1 Above
Run Code Online (Sandbox Code Playgroud)
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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
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 }
Run Code Online (Sandbox Code Playgroud)
你很高兴去!
由于我无法对帖子发表评论,我仍然想通过这个答案对Mick的回答发表评论.
从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 }
Run Code Online (Sandbox Code Playgroud)
并且,而不是
use Symfony\Component\Security\Core\SecurityContext;
Run Code Online (Sandbox Code Playgroud)
一个应该
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
Run Code Online (Sandbox Code Playgroud)
(还用TokenStorage类替换类中的SecurityContext)
然后,在第38行,将使用检查令牌可用性
$this->tokenStorage->getToken()
Run Code Online (Sandbox Code Playgroud)
并且,在第39行,将使用获得用户实例
$this->tokenStorage->getToken()->getUser()
Run Code Online (Sandbox Code Playgroud)