Php 如何让当前用户进入我的实体类?
我正在开发我的第一个Symfony 4应用程序,并从Symfony 2+和Symfony 3+进行迁移 现在我正在开发一个后端,我的所有实体类都有一个Php 如何让当前用户进入我的实体类?,php,symfony,doctrine-orm,doctrine,symfony4,Php,Symfony,Doctrine Orm,Doctrine,Symfony4,我正在开发我的第一个Symfony 4应用程序,并从Symfony 2+和Symfony 3+进行迁移 现在我正在开发一个后端,我的所有实体类都有一个addedBy()和updatedBy()方法,我需要记录当前登录的管理员 我希望有一个类似事件监听器的东西,我不必在所有控制器中设置这些方法 如何做到这一点?首先,为了简化问题并帮助解决问题,我将创建一个用户跟踪实体需要遵守的界面: interface UserTracking { public function addedBy(User
addedBy()
和updatedBy()
方法,我需要记录当前登录的管理员
我希望有一个类似事件监听器的东西,我不必在所有控制器中设置这些方法
如何做到这一点?首先,为了简化问题并帮助解决问题,我将创建一个用户跟踪实体需要遵守的界面:
interface UserTracking
{
public function addedBy(UserInterface $user);
public function updatedby(UserInterface $user);
public function getAddedBy(): ?UserInterface;
public function getUpdatedBy(): ?UserInterface;
}
然后,您可以创建一个条令事件侦听器,并将安全性
组件注入其中:
class UserDataListener
{
protected $security;
public function __construct(Security $security)
{
$this->security = $security;
}
public function prePersist(LifecycleEventArgs $event): void
{
$entity = $event->getObject();
$user = $this->security->getUser();
// only do stuff if $entity cares about user data and we have a logged in user
if ( ! $entity instanceof UserTracking || null === $user ) {
return;
}
$this->setUserData($entity, $user);
}
private function preUpdate(LifecycleEventArgs $event) {
$this->prePersist($event);
}
private function setUserData(UserTracking $entity, UserInterface $user)
{
if (null === $entity->getAddedBy()) {
$entity->addedBy($user);
}
$entity->updatedBy($user);
}
}
您需要适当地标记侦听器,以便它在prePersist
和preUpdate
上触发:
services:
user_data_listener:
class: App\Infrastructure\Doctrine\Listener\UserDataListener
tags:
- { name: doctrine.event_listener, event: prePersist }
- { name: doctrine.event_listener, event: preUpdate }
虽然上述方法应该有效,但我认为以这种方式使用条令事件通常不是一个好主意,因为您将域逻辑与条令相耦合,并且将更改隐藏在一层魔法之下,这对于其他使用您的应用程序的开发人员来说可能并不明显 我会将
createdBy
作为构造函数参数,并在需要时显式设置updateBy
。每次只需要一行代码,但您可以获得清晰性和表达能力,并且您拥有一个更简单的系统,其中移动部件更少
class FooEntity
{
private $addedBy;
private $updatedBy;
public function __construct(UserInterface $user)
{
$this->addedBy = $user;
}
public function updatedBy(UserInterface $user)
{
$this->updatedBy = $user;
}
}
这更好地表达了域中正在发生的事情,应用程序中的未来程序员不必到处寻找您可能已安装和启用的扩展,或者正在触发的事件。您可能不想重新发明轮子。有一种方法已经做到了这一点。您可以通过以下方式安装它:
composer require antishov/doctrine-extensions-bundle
因为已经有一个配方来配置它。然后您可以将其与以下内容一起使用:
可归咎扩展的特定文档
我选择了事件监听器,一切正常。谢谢!
use Gedmo\Mapping\Annotation as Gedmo;
class Post {
/**
* @var User $createdBy
*
* @Gedmo\Blameable(on="create")
* @ORM\ManyToOne(targetEntity="App\Entity\User")
*/
private $createdBy;
}