如何使当前用户进入我的实体类? [英] How I can get the current user into my entity classes?

查看:92
本文介绍了如何使当前用户进入我的实体类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发我的第一个Symfony 4应用程序,并从Symfony 2+和symfony 3+迁移。

I am developing my first Symfony 4 application and I migrating from Symfony 2+ and symfony 3+.

现在我正在开发一个后端,所有我的实体类具有 addedBy() updatedBy()方法,我需要在其中记录当前登录的管理员。

Right now I am developing a back-end and all of my entity classes have a addedBy() and updatedBy() methods where I need to record the current logged in administrator.

我想要一个类似事件监听器的东西,而不必在所有控制器中都设置这些方法。

I would like to have something like an event listener where I do not have to set those methods in all of my controllers.

如何完成此操作?

推荐答案

首先,为了简化流程并帮助我创建一个接口该用户跟踪实体将需要遵守:

First, to simplify matters and help down the road I would create an interface this user-tracking entities would need to comply with:

interface UserTracking
{
    public function addedBy(UserInterface $user);
    public function updatedby(UserInterface $user);
    public function getAddedBy(): ?UserInterface;
    public function getUpdatedBy(): ?UserInterface;
}

然后您可以创建一个Doctrine事件侦听器,并注入 Security 组件:

Then you can create a Doctrine event listener, and inject the Security component there:

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 上触发:

You'd need to tag the listener appropriately, so it triggers on prePersist and preUpdate:

services:
  user_data_listener:
    class: App\Infrastructure\Doctrine\Listener\UserDataListener
    tags:
      - { name: doctrine.event_listener, event: prePersist }
      - { name: doctrine.event_listener, event: preUpdate }






虽然上述方法可行,但我相信以这种方式使用Doctrine事件通常不是一个好主意,因为您要将域逻辑与Doctrine结合在一起,并且隐藏了一层不可思议的变化,对于使用您的应用程序的其他开发人员来说,这可能不是立即可见的。


While the above should work, I believe it's generally not such a great idea to use Doctrine events this way, since you are coupling your domain logic with Doctrine, and are hiding changing under a layer of magic that may not be immediately evident for other developers working with your application.

我将 createdBy 作为构造函数参数,并在需要时显式设置 updateBy 。每次只是一行代码,但是您可以获得清晰和表达力,并且系统更简单,移动部件更少。

I'd put the createdBy as a constructor parameter, and set updateBy explicitly when needed. It's just one line of code each time, but you gain clarity and expressiveness, and you have a simpler system with less moving parts.

class FooEntity
{    
    private $addedBy;
    private $updatedBy;
    public function __construct(UserInterface $user)
    {
        $this->addedBy = $user;
    }

    public function updatedBy(UserInterface $user)
    {
        $this->updatedBy = $user;
    }
}

这更好地表达了域的状况,并且您的应用程序中将来的编码人员不必挖掘您可能已安装和启用的扩展名或正在触发的事件。

This expresses much better what's happening with the domain, and future coders in your application do no have to dig around for the possible extensions you may have installed and enabled, or what events are being triggered.

这篇关于如何使当前用户进入我的实体类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆