使用事件侦听器创建preUpdate或preFlush事件 [英] Creating preUpdate or preFlush event with Event Listener

查看:153
本文介绍了使用事件侦听器创建preUpdate或preFlush事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个可以正常工作的onFlush()事件,但我需要做的就是将其转换成preFlush()或preUpdate()都可以接受。我做了preFlush(),但由于某种原因,它没有做任何事情。甚至不是错误。我缺少什么?



测试:我将退出 preFlush(),看看它是否全部被调用。结果是: 1 所以 foreach()永远不会运行!它是一个空数组。我还测试了preUpdate()和所有的行,但是没有插入数据。

  public function preFlush(PreFlushEventArgs $ args )
{
$ em = $ args-> getEntityManager();
$ uow = $ em-> getUnitOfWork();
echo'1';
foreach($ uow-> getScheduledEntityUpdates()as $ entity){
echo'2';
if($ entity instanceof User){
echo'3';
}
}
exit;
}

我在阅读了文档



service.yml

  services:
entity.event_listener.user:
class:Site\FrontBundle \EventListener\Entity\UserListener
标签:
- {name:doctrine.event_listener,event:preUpdate}
- {name:doctrine.event_listener,event:onFlush}
- {name:doctrine.event_listener,event:preFlush}

Working onFlush()示例:

  class UserListener 
{
public function onFlush(OnFlushEventArgs $ args)
{
$ em = $ args-> getEntityManager();
$ uow = $ em-> getUnitOfWork();

foreach($ uow-> getScheduledEntityUpdates()as $ entity){
if($ entity instanceof User){
$ userLog = new UserLog();
$ userLog-> setDescription($ entity-> getId()。'正在更新。

$ em-> persist($ userLog);

//代替$ em-> flush()cos我们已经在flush进程
$ userLogMetadata = $ em-> getClassMetadata(get_class($ userLog));
$ uow-> computeChangeSet($ userLogMetadata,$ userLog);
}
}
}
}

strong>不工作preFlush()示例:

  class UserListener 
{
public function preFlush(PreFlushEventArgs $ args)
{
$ em = $ args-> getEntityManager();
$ uow = $ em-> getUnitOfWork();

foreach($ uow-> getScheduledEntityUpdates()as $ entity){
if($ entity instanceof User){
$ userLog = new UserLog();
$ userLog-> setDescription($ entity-> getId()。'正在更新。

$ em-> persist($ userLog);

//代替$ em-> flush()cos我们已经在flush进程
$ userLogMetadata = $ em-> getClassMetadata(get_class($ userLog));
$ uow-> computeChangeSet($ userLogMetadata,$ userLog);
}
}
}
}

strong>不工作preUpdate()示例

  class UserListener 
{
public function preUpdate (LifecycleEventArgs $ args)
{
$ entity = $ args-> getEntity();
$ em = $ args-> getEntityManager();
$ uow = $ em-> getUnitOfWork();

if($ entity instanceof User){
$ userLog = new UserLog();
$ userLog-> setDescription($ entity-> getId()。')已更新。

$ em = $ args-> getEntityManager();
$ em-> persist($ userLog);
$ userLogMetadata = $ em-> getClassMetadata(get_class($ userLog));
$ uow-> computeChangeSet($ userLogMetadata,$ userLog);
}
}
}


解决方案

解决方案:



诀窍是,在 preUpdate() postFlush()事件中。



注意: 虽然这可能不是最好的解决方案,但它可以解决这个问题,但是可以使用事件订阅者或简单的 onFlush() - > $ uow - > getScheduledEntityUpdates()在事件监听器中。



Service.yml

 服务:

entity.event_listener.user_update:
class:Site\FrontBundle\EventListener\Entity\\ \\ UserUpdateListener
标签:
- {name:doctrine.event_listener,event:preUpdate}
- {name:doctrine.event_listener,event:postFlush}

事件监听器

 code><?php 

命名空间Site\FrontBundle\EventListener\Entity;

使用Doctrine\ORM\Event\LifecycleEventArgs;
使用Doctrine\ORM\Event\PostFlushEventArgs;
使用Site\FrontBundle\Entity\User;
使用Site\FrontBundle\Entity\UserLog;

class UserUpdateListener
{
private $ log = array();

public function preUpdate(LifecycleEventArgs $ args)
{
$ entity = $ args-> getEntity();

//虚假检查是强制的,否则重复出现
if(($ entity instanceof User)=== false){
$ userLog = new UserLog();
$ userLog-> setDescription($ entity-> getId()。'正在更新。

$ this-> log [] = $ userLog;
}
}

public function postFlush(PostFlushEventArgs $ args)
{
if(!empty($ this-> log)){
$ em = $ args-> getEntityManager();
foreach($ this-> log as $ log){
$ em-> persist($ log);
}
$ em-> flush();
}
}
}


I have a onFlush() event which works fine but what I need to do is to turn that into preFlush() or preUpdate() both acceptable. I did preFlush() but for some reason it doesn't do anything. Not even an error. What am I missing?

TEST: I placed exit in preFlush() to see if it is being called at all or not. Outcome is: 1 so foreach() is never run! It is an empty array. I also tested preUpdate() and all the lines in that get runed but no data inserted.

public function preFlush(PreFlushEventArgs $args)
{
    $em = $args->getEntityManager();
    $uow = $em->getUnitOfWork();
    echo '1';
    foreach ($uow->getScheduledEntityUpdates() as $entity) {
        echo '2';
        if ($entity instanceof User) {
            echo '3';
        }
    }
    exit;
}

I created them after reading the documentation.

service.yml

services:
    entity.event_listener.user:
        class:  Site\FrontBundle\EventListener\Entity\UserListener
        tags:
            - { name: doctrine.event_listener, event: preUpdate }
            - { name: doctrine.event_listener, event: onFlush }
            - { name: doctrine.event_listener, event: preFlush }

Working onFlush() example:

class UserListener
{
    public function onFlush(OnFlushEventArgs $args)
    {
        $em = $args->getEntityManager();
        $uow = $em->getUnitOfWork();

        foreach ($uow->getScheduledEntityUpdates() as $entity) {
            if ($entity instanceof User) {
                $userLog = new UserLog();
                $userLog->setDescription($entity->getId() . ' being updated.');

                $em->persist($userLog);

                // Instead of $em->flush() cos we're already in flush process
                $userLogMetadata = $em->getClassMetadata(get_class($userLog));
                $uow->computeChangeSet($userLogMetadata, $userLog);
            }
        }
    }
}

Not working preFlush() example:

class UserListener
{
    public function preFlush(PreFlushEventArgs $args)
    {
        $em = $args->getEntityManager();
        $uow = $em->getUnitOfWork();

        foreach ($uow->getScheduledEntityUpdates() as $entity) {
            if ($entity instanceof User) {
                $userLog = new UserLog();
                $userLog->setDescription($entity->getId() . ' being updated.');

                $em->persist($userLog);

                // Instead of $em->flush() cos we're already in flush process
                $userLogMetadata = $em->getClassMetadata(get_class($userLog));
                $uow->computeChangeSet($userLogMetadata, $userLog);
            }
        }
    }
}

Not working preUpdate() example

class UserListener
{
    public function preUpdate(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();
        $em = $args->getEntityManager();
        $uow = $em->getUnitOfWork();

        if ($entity instanceof User) {
            $userLog = new UserLog();
            $userLog->setDescription($entity->getId() . ') been updated.');

            $em = $args->getEntityManager();
            $em->persist($userLog);
            $userLogMetadata = $em->getClassMetadata(get_class($userLog));
            $uow->computeChangeSet($userLogMetadata, $userLog);
        }
    }
}

解决方案

SOLUTION:

The trick is, persisting after preUpdate() within postFlush() event.

Note: Although this might not be the best solution, it answers the question however it could be done with an Event Subscriber or simple onFlush() -> $uow->getScheduledEntityUpdates() in an Event Listener.

Service.yml

services:

    entity.event_listener.user_update:
        class:  Site\FrontBundle\EventListener\Entity\UserUpdateListener
        tags:
            - { name: doctrine.event_listener, event: preUpdate }
            - { name: doctrine.event_listener, event: postFlush }

Event Listener

<?php

namespace Site\FrontBundle\EventListener\Entity;

use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PostFlushEventArgs;
use Site\FrontBundle\Entity\User;
use Site\FrontBundle\Entity\UserLog;

class UserUpdateListener
{
    private $log = array();

    public function preUpdate(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();

        // False check is compulsory otherwise duplication occurs
        if (($entity instanceof User) === false) {
            $userLog = new UserLog();
            $userLog->setDescription($entity->getId() . ' being updated.');

            $this->log[] = $userLog;
        }
    }

    public function postFlush(PostFlushEventArgs $args)
    {
        if (! empty($this->log)) {
            $em = $args->getEntityManager();
            foreach ($this->log as $log) {
                $em->persist($log);
            }
            $em->flush();
        }
    }
} 

这篇关于使用事件侦听器创建preUpdate或preFlush事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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