简体   繁体   English

Symfony2-主义-更新后无变更集

[英]Symfony2 - Doctrine - no changeset in post update

So i am sending an email when a certain value on an entity is changed. 因此,当实体上的某个值更改时,我正在发送电子邮件。 I only want the email to send after the update in case the update fails for what ever reason. 我只希望在更新后发送电子邮件,以防万一更新由于某种原因而失败。 so on the preUpdate I can do this 所以在preUpdate上我可以做到这一点

public function preUpdate(LifecycleEventArgs $args){

    if ($args->hasChangedField('value') && is_null($args->getOldValue('value'))) {
        $this->sendEmail();
    }

}

but i need to do this on postUpdate and as these methods are not available on postUpdate i refactored it to look like this: 但是我需要在postUpdate上执行此操作,并且由于这些方法在postUpdate上不可用,因此我将其重构为如下所示:

public function postUpdate(LifecycleEventArgs $args){

    $entity      = $args->getEntity();
    $changeSet = $args->getEntityManager()->getUnitOfWork()->getEntityChangeSet($entity);

    if ($entity  instanceof Entity && isset( $changeSet['value'] ) && empty( $changeSet['value'][0] )) {
        $this->sendEmail();
    }
}

However this returns an empty change set, but changes have been made and can be seen in preUpdate. 但是,这将返回一个空的更改集,但是已进行了更改并且可以在preUpdate中看到。 Can anyone see what i am doing wrong? 谁能看到我在做什么错? help would be much appreciated :) 帮助将不胜感激:)

On preUpdate event you get event object of class PreUpdateEventArgs where You have change set for entity. preUpdate事件上,您将获得PreUpdateEventArgs类的事件对象,其中已为实体设置了更改。

On postUpdate you just get event object of class LifecycleEventArgs where you can ask only for Updated entity (and get latest state of it). postUpdate您仅获得LifecycleEventArgs类的事件对象,在postUpdate事件对象中,您仅可要求提供更新的实体(并获取其最新状态)。

If you want to play with changeset then you need to do it before actual updating entity ( preUpdate event). 如果要使用变更集,则需要在实际更新实体( preUpdate事件)之前进行操作。

A workaround could be to save change set somewhere by yourself and later retrieve it in postUpdate . 一种解决方法是自己保存更改集,然后在postUpdate检索它。 It is a siplified exaple I've implement once: 这是我实现过的简化示例:

<?php

namespace Awesome\AppBundle\EventListener;

use Doctrine\Common\Cache\ArrayCache;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Doctrine\ORM\Events;

/**
 * Store last entity change set in memory, so that it could be
 * usable in postUpdate event.
 */
class EntityChangeSetStorageListener implements EventSubscriber
{
    /**
     * @var ArrayCache
     */
    private $cache;

    /**
     * @param ArrayCache $cacheStorage
     */
    public function __construct(ArrayCache $cacheStorage)
    {
        $this->cache = $cacheStorage;
    }

    /**
     * Store last entity change set in memory.
     *
     * @param PreUpdateEventArgs $event
     */
    public function preUpdate(PreUpdateEventArgs $event)
    {
        $entity = $event->getEntity();

        $this->cache->setNamespace(get_class($entity));
        $this->cache->save($entity->getId(), $event->getEntityChangeSet());
    }

    /**
     * Release the memory.
     */
    public function onClear()
    {
        $this->clearCache();
    }

    /**
     * Clear cache.
     */
    private function clearCache()
    {
        $this->cache->flushAll();
    }

    /**
     * {@inheritdoc}
     */
    public function getSubscribedEvents()
    {
        return [
            Events::preUpdate,
            Events::onClear,
        ];
    }
}

Later inject ChangeSetStorage service to the listener where it is necessary on postUpdate event. 稍后将ChangeSetStorage服务注入到postUpdate事件中必要的侦听器中。

I had a really annoying issue with the changeset data, sometimes I got the collection of changes and sometimes not. 我对变更集数据有一个非常烦人的问题,有时我收到了变更的集合,有时没有。

I sorted out by adding this line $event->getEntityManager()->refresh($entity); 我通过添加以下行来进行整理: $ event-> getEntityManager()-> refresh($ entity); in the prePersist and preUpdate events inside a doctrine.event_subscriber doctrine.event_subscriberprePersist更新前的事件

After the refresh line, changesetdata was updated so the following line started to work: 刷新行之后,更改集数据已更新,因此以下行开始工作:

/** @var array $changeSet */
$changeSet = $this->em->getUnitOfWork()->getEntityChangeSet($entity);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM