在Symfony2.8 / Doctrine2应用程序中,我需要在我的SQL表的每一行中存储创建或更新该行的用户的ID(用户可以使用Ldap连接)。
所以我继承了GenericEntity
的所有实体都包含这个变量(如果我想存储Ldap用户名,则类型为string):
/**
* @var integer
*
* @ORM\Column(name="zzCreationId", type="string", nullable=false)
*/
private $creationId;
我使用prePersistCallback()
自动指定此值:
/**
* @ORM\PrePersist
*/
public function prePersistCallback()
{
$currentUser = /* ...... ????? ....... */ ;
if ($currentUser->getId() != null) {
$this->creationId = $currentUser->getId() ;
} else {
$this->creationId = 'unknown' ;
}
return $this;
}
但我不知道如何检索已连接的用户,或者如何自动将其注入实体......我该怎么做?
答案 0 :(得分:3)
您可以使用Doctrine实体侦听器/订阅者来注入安全令牌并获取当前用户的记录:
// src/AppBundle/EventListener/EntityListener.php
namespace AppBundle\EventListener;
use Doctrine\ORM\Event\LifecycleEventArgs;
use AppBundle\Entity\GenericEntity;
class EntityListener
{
private $tokenStorage;
public function __construct(TokenStorageInterface $tokenStorage = null)
{
$this->tokenStorage = $tokenStorage;
}
public function prePersist(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
// only act on some "GenericEntity" entity
if (!$entity instanceof GenericEntity) {
return;
}
if (null !== $currentUser = $this->getUser()) {
$entity->setCreationId($currentUser->getId());
} else {
$entity->setCreationId(0);
}
}
public function getUser()
{
if (!$this->tokenStorage) {
throw new \LogicException('The SecurityBundle is not registered in your application.');
}
if (null === $token = $this->tokenStorage->getToken()) {
return;
}
if (!is_object($user = $token->getUser())) {
// e.g. anonymous authentication
return;
}
return $user;
}
}
接下来注册你的听众:
# app/config/services.yml
services:
my.listener:
class: AppBundle\EventListener\EntityListener
arguments: ['@security.token_storage']
tags:
- { name: doctrine.event_listener, event: prePersist }
答案 1 :(得分:1)
@ORM\PrePersist
以及实体中使用的其他回调方法假设包含简单逻辑并且与其他服务无关。
您需要创建事件侦听器或订阅者以侦听postPersist
doctrine事件并填写相应的属性。查看How to Register Event Listeners and Subscribers
答案 2 :(得分:1)
您可以从gedmo / doctrine-extensions软件包中查看BlameableListener,它几乎可以按照您想要的方式工作,但使用用户名而不是用户ID。