Symfony设置实体的`createdBy`和`modifiedBy`属性

huangapple go评论57阅读模式
英文:

Symfony set `createdBy` and `modifiedBy` properties of entity

问题

我想要自动设置实体的createdBymodifiedBy属性。

要设置这些属性,我使用了Doctrine生命周期钩子prePersistpreUpdate,如此处所述:https://symfony.com/doc/current/doctrine/events.html#doctrine-lifecycle-callbacks。
我还创建了setCreatedByValuesetModifiedByValue函数来设置这些字段...

关于如何将当前登录的用户写入这些属性,是否有最佳实践?
是否有比将安全服务注入实体更加"优雅"的方法?

你会如何做呢?

英文:

I want to automatically set the createdBy and modifiedBy properties of an entity.

To set these properties I use the doctrine lifecycle hooks prePersist and preUseras described here: https://symfony.com/doc/current/doctrine/events.html#doctrine-lifecycle-callbacks.
I also created a setCreatedByValue and setModifiedByValue functions to set the fields ...

Is there any best practice on how to write the currently logged-in user into these properties?
Is there a let's say "more elegant" way than injecting the security service into the entity?

How would you do that?

答案1

得分: 1

我建议你使用优秀的Gedmo监听器,这正是你想要的。

跟踪上次编辑你的实体的用户

请查看这个文档

额外的updatedAt:DateTime字段

你可以使用一个updatedAt字段来实现相同的行为,你可以希望自动填充它,有一个这个扩展可以为你完成这项工作。这不是必需的。

如果有什么不清楚的地方,请告诉我。

英文:

I would recommand you the excellent Gedmo listeners, it's exactly what you want.

Tracking which user edited your entity the last time

Have a look at this documentation.

Bonus an updatedAt: DateTime field

You can have the same behavior with an updatedAt field that you could want to fill automatically, you have this extension that do the job for you. This isn't required

Let me know if something isn't clear

答案2

得分: 1

我现在查看了Symfony文档,并选择了以下方法:

我创建了一个EntitySubscriber,如下所述:https://symfony.com/doc/current/doctrine/events.html#doctrine-lifecycle-subscribers

之后,我创建了两个接口TimestampInterface(用于createdAtmodifiedAt)和UserAwareInterface(用于createdBymodifiedBy)。
我还创建了一个AbstractEntity,它实现了上面提到的接口。现在我可以扩展每个需要此功能的实体,使用AbstractEntity类...

然后,我简单地创建了一个doctrine.event_subscriber(如文档中所述),并检查接口以设置特定字段。

为了设置createdBymodifiedBy字段,我使用了安全容器。
效果还不错,而且使用这种解决方案,我不依赖于任何第三方库。

你对这个解决方案有什么看法?

英文:

I now searched through the Symfony docs once again and chose the following approach for me:

I created an EntitySubscriber as described here: https://symfony.com/doc/current/doctrine/events.html#doctrine-lifecycle-subscribers

After that, I created two interfaces TimestampInterface (for createdAt and modifiedAt) and a UserAwareInterface (for createdBy and modifiedBy).
I also created an AbstractEntity that implements the interfaces mentioned above. Now I can extend each entity (which needs this functionality) with the AbstractEntity class ...

Then I simply created a doctrine.event_subscriber (as described in the docs) and checked for the interfaces to set certain fields.

To set the createdBy and modifiedBy fields I used the Security container.
Works pretty well - and with this solution, I don't rely on any third-party libs.

<?php 

namespace Foo\Bar\EventListener;

use Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterface;
use Doctrine\ORM\Event\PrePersistEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Doctrine\ORM\Events;
use Symfony\Bundle\SecurityBundle\Security;
use Foo\Bar\Entity\TimestampInterface;
use Foo\Bar\Entity\UserAwareInterface;

class EntitySubscriber implements EventSubscriberInterface
{
    public function __construct(
        public Security $security,
    ) {}

    public function getSubscribedEvents(): array
    {
        return [
            Events::prePersist,
            Events::preUpdate
        ];
    }

    public function prePersist(PrePersistEventArgs $prePersistEventArgs): void
    {
        $object = $prePersistEventArgs->getObject();

        if($object instanceof TimestampInterface){
            $object->setCreatedAt(time());
            $object->setModifiedAt(time());
        }

        if($object instanceof UserAwareInterface){
            $object->setCreatedBy($this->security->getUser()->getId());
            $object->setModifiedBy($this->security->getUser()->getId());
        }
    }

    public function preUpdate(PreUpdateEventArgs $preUpdateEventArgs): void
    {
        $object = $preUpdateEventArgs->getObject();

        if($object instanceof TimestampInterface){
            $object->setModifiedAt(time());
        }

        if($object instanceof UserAwareInterface){
            $object->setModifiedBy($this->security->getUser()->getId());
        }
    }
}

What do you think about that solution?

huangapple
  • 本文由 发表于 2023年3月4日 01:04:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/75629954.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定