Как создать пользовательскую операцию обновления, которая может быть отклонена в зависимости от текущего статуса объекта? - PullRequest
0 голосов
/ 24 июня 2019

Я создаю пользовательскую операцию PUT.

Не использовать встроенные операции, поскольку затронутое свойство не включено в нормализацию по умолчанию для этого объекта, а также потому, что эта операция имеет несколько побочных эффектов, выходящих за рамки этого объекта / модели.

Кроме того, операция обновления должна завершиться успешно, только если текущее состояние объекта в БД соответствует определенным ожиданиям.

например. для субъекта

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

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

}

Я создаю пользовательскую операцию 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.

И прежде чем я сохраню объект и выполню все остальные операции, мне нужно проверить, что Lead не было ранее отклонено.

Как я могу это сделать? Можно ли это сделать на уровне операционного контроллера? Полагаю, я мог бы внедрить EntityManager и снова получить объект, но кажется расточительным, учитывая, что в этот момент объект уже был получен.

1 Ответ

0 голосов
/ 03 июля 2019

Вы можете добавить 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);
    }
}

И просто добавьте эту строку в блок вашей сущности. Doc Block

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

Вы можете увидеть больше информации о событиях доктрины здесь:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...