繁体   English   中英

Symfony2 事件监听器 preUpdate

[英]Symfony2 Event Listener preUpdate

我在service.yml 中配置了一些事件监听器

registerproduct.listener:
        class: App\AppBundle\Listener\RegisterProductListener
        arguments: [ @service_container ]
        tags:
            - { name: doctrine.event_listener, event: prePersist }
            - { name: doctrine.event_listener, event: preUpdate }

当我执行 prePersist 而不是 preUpdate 时,我的方法decrementProductQuantity()非常有效。

在更新过程中,产品数量减少得很好,但数据库中没有变化。

这是我的事件代码:

public function prePersist(LifecycleEventArgs $args)
{
    $this->decrementProductQuantity($args);
}

public function preUpdate(LifecycleEventArgs $args)
{
    $this->decrementProductQuantity($args);
}

public function decrementProductQuantity(LifecycleEventArgs $args)
{
    /** @var RegisterProduct $registerProduct */
    $registerProduct = $args->getEntity();

    if (!($registerProduct instanceof RegisterProduct))
        return;

    if ($registerProduct->getStatus() == 'inscription') {
        $product = $registerProduct->getProduct();
        $product->setQuantityStock($product->getQuantityStock() - $registerProduct->getQuantity());
    }
}

这是我的控制器中的更新代码:

/**
 * @param Register $register
 * @return \Symfony\Component\HttpFoundation\Response
 */
public function confirmAction(Request $request, Register $register)
{
    $em   = $this->getDoctrine()->getManager();

    foreach($register->getRegisterProducts() as $registerProduct){
        $registerProduct->setStatus('inscription');
        $em->persist($registerProduct);
        $em->flush();
    }       
    return $this->redirectWithMode($this->generateUrl('asc_activity_register_show', array('register' => $register->getId())));
}

我不知道为什么当我在数据库中添加一些东西时它会起作用,但不能用于更新。

谢谢你的帮助。

在您的 preUpdate 侦听器上,您应该重新计算产品实体的变更集

public function decrementProductQuantity(LifecycleEventArgs $args)
{
    /** @var RegisterProduct $registerProduct */
    $registerProduct = $args->getEntity();

    if (!($registerProduct instanceof RegisterProduct))
        return;

    if ($registerProduct->getStatus() == 'inscription') {
        $product = $registerProduct->getProduct();
        $product->setQuantityStock($product->getQuantityStock() - $registerProduct->getQuantity());
        $em = $args->getEntityManager();
        $uow = $em->getUnitOfWork();
        $className = \Doctrine\Common\Util\ClassUtils::getClass($product);
        $classMetadata = $em->getClassMetadata($className);
        $uow->recomputeSingleEntityChangeSet($classMetadata, $product);
    }
}

这是因为在您的控制器(或其他地方)中,您的代码没有更新产品实体。 在侦听器执行学说之前计算每个实体的更改集。 因此,在您的preUpdate侦听器原则中对产品一无所知(因为它没有改变)。

尝试更改 preUpdate 方法的签名:

use Doctrine\ORM\Event\PreUpdateEventArgs;

/.../

public function preUpdate(PreUpdateEventArgs $args)
{
    $this->decrementProductQuantity($args);
}

/.../

因为没找到awnser所以最后选择直接在controller里面做:

    /**
     * @param Register $register
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function confirmAction(Request $request, Register $register)
    {
        $mode = $this->getMode($request);
        $em   = $this->getDoctrine()->getManager();

        foreach ($register->getRegisterProducts() as $registerProduct) {
            if($registerProduct->getStatus() != 'inscription'){
                $product = $registerProduct->getProduct();
                $product->setQuantityStock($product->getQuantityStock() - $registerProduct->getQuantity());
            }

            $registerProduct->setStatus('inscription');
        }

        $em->flush();

        return $this->redirectWithMode($this->generateUrl('asc_activity_register_show', array('register' => $register->getId())), $mode);
    }

如果有人找到答案,请告诉我。

暂无
暂无

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

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