如何创建可以根据实体当前状态拒绝的自定义更新操作? [英] How to create custom update operation that can be rejected depending on the entity current status?

查看:22
本文介绍了如何创建可以根据实体当前状态拒绝的自定义更新操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个自定义的 PUT 操作.

I'm creating a custom PUT operation.

不使用内置操作,因为受影响的属性未包含在此实体的默认规范化中,还因为此操作有一些超出此实体/模型的副作用.

Not using the built-in operations because the affected property is not included in the default normalization for this entity, and also because this operation has a few side-effects that go beyond this entity/model.

此外,只有当 DB 上实体的当前状态符合某些预期时,更新操作才会成功.

Additionally, the update operation should only succeed if the current state of the entity on the DB matches certain expectations.

例如对于实体

class Lead {
    /**
    * @ORM\Column(type="integer", nullable=true)
    * @Groups({"lead", "leadReject" })
    **/
    private $rejectionReason

    public function isRejected() {
       return $this->rejectionReason !== null;

}

我正在创建自定义操作 PUT/lead/{id}/reject.

I'm creating the custom operation PUT /lead/{id}/reject.


class LeadReject {
     public function __invoke( Lead $data ): Lead {

           // if lead is rejected, we need not only to update its status
           // but create an entry in a LeadLog table, and update the state
           // for the Lead owner
     }
}

问题是,当我们到达 __invoke() 时,我得到的 $data 已经将来自用户的输入与来自数据库的值合并了.因此,任何对 $data->isRejected() 的调用都会返回 true,即使它在数据库中仍然是 null.

Problem is, by the time we get to __invoke() the $data I get has already merged the input from the user with the values from the database. Thus, any call to $data->isRejected() returns true, even if it's still null on the database.

在我持久化对象并执行所有其他操作之前,我需要检查 Lead 之前没有被拒绝.

And before I persist the object and I perform all the other operations, I need to check that Lead has not been rejected previously.

我该怎么做?可以在操作控制器级别完成吗?我想我可以注入 EntityManager 并再次检索该对象,但考虑到此时该对象已经被检索,似乎很浪费.

How can I do this? Can it be done at the operation controller level? I guess I could inject the EntityManager and retrieve the object again, but seems wasteful considering at this point the object has already been retrieved.

推荐答案

您可以添加 Doctrine Listener:

You can add a Doctrine Listener:

<?php

namespace App\Listener;

use App\Entity\MyEntity;
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;

class EntityPreUpdateListener
{
    /**
     * @param MyEntity $entity
     * @param LifecycleEventArgs $args
     */
    public function preUpdate($entity, LifecycleEventArgs $args)
    {
        $entityManager = $args->getObjectManager();
        // do whatever you need

        // you can persist your entity to the database if you need
        $entityManager->flush();

        // detach your entity, so it won't be updated
        $entityManager->detach($entity);
    }
}

只需在您的实体文档块中添加这一行

And just add this line in your entity Doc Block

@ORM\EntityListeners({"App\Listener\EntityPreUpdateListener"})

您可以在此处查看有关学说事件的更多信息:

You can see more information about the doctrine events here:

https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/events.html

这篇关于如何创建可以根据实体当前状态拒绝的自定义更新操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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