在生命周期事件中调用服务

时间:2016-08-10 15:05:18

标签: php symfony

我有一个生命周期事件。创建订单后,prePersist生命周期事件会在订单持久保存到数据库之前向订单添加更多详细信息。

这是我的prePersist事件类;

<?php

namespace Qi\Bss\BaseBundle\Lib\PurchaseModule;

use Qi\Bss\BaseBundle\Entity\Business\PmodOrder;
use Doctrine\ORM\Event\LifecycleEventArgs;

/**
 * Listener class
 * Handles events related to list prices
 */
class OrderUserListener
{

    /**
     * Service container
     * @var type 
     */
    private $serviceContainer;

    /**
     * Performs tasks before destruction
     * @ORM\PrePersist
     */
    public function prePersist(LifecycleEventArgs $args)
    {
        $order = $args->getEntity();

        if ($order instanceof PmodOrder) {
            $user = $this->serviceContainer->get('security.token_storage')->getToken()->getUser();

            if ($user) {
                $order->setCreatedBy($user);
                $order->setCreatedAt(new \DateTime(date('Y-m-d H:i:s')));
                $order->setDepartment($user->getDepartment());
                $order->setStatus(PmodOrder::STATUS_AWAITING_APPROVAL);

                $this->serviceContainer->get('bss.pmod.order_logger')->log($order, 'Order Created');
            }
        }
    }

    /**
     * Sets the sales order exporter object
     * @param type $serviceContainer
     */
    public function setServiceContainer($serviceContainer)
    {
        $this->serviceContainer = $serviceContainer;
    }
}

它完美无缺,但这部分$this->serviceContainer->get('bss.pmod.order_logger')->log($order, 'Order Created');并不想工作。我试着在里面调用一个服务。我知道该服务在我的控制器内完美运行,但在这里我收到错误;

  

通过这种关系找到了一个新的实体   &#39;气虚\ BSS \ BaseBundle \实体\企业\ PmodLog#为了&#39;那不是   配置为级联实体的持久化操作:Nuwe Test vir   记录仪。解决此问题:显式调用   EntityManager#persist()在此未知实体上或配置级联   例如,在映射中保持此关联   @ManyToOne(..,级联= {&#34;坚持&#34;})。

这就是我的OrderLogger服务类的样子;

<?php

namespace Qi\Bss\BaseBundle\Lib\PurchaseModule;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Doctrine\ORM\EntityManager;
use Qi\Bss\BaseBundle\Entity\Business\PmodLog;

/**
 * Class AppLogger. Purchase Module logger.
 * @package FcConnectBundle\Lib
 */
class OrderLogger {

    private $em;
    private $tokenStorage;

    /**
     * Constructor.
     *
     * @param EntityManager $em
     * @param TokenStorage $securityTokenStorage
     */
    public function __construct(EntityManager $em, TokenStorage $securityTokenStorage)
    {
        $this->em = $em;
        $this->tokenStorage = $securityTokenStorage;
    }

    /**
     * Log an order action.
     *
     * @param string $text
     */
    public function log($order, $action)
    {
        $logRecord = new PmodLog();
        if (is_object($this->tokenStorage->getToken())) {
            $user = $this->tokenStorage->getToken()->getUser();
            if (is_object($user)) {
                $logRecord->setUser($user);
            }
        }
        $logRecord->setOrder($order);
        $logRecord->setAction($action);
        $logRecord->setTime(new \DateTime());

        $this->em->persist($logRecord);
        $this->em->flush();
    }

}

我已经尝试更改我的日志中的持久性以进行合并,但这也不起作用。有人可以帮忙解释我做错了吗?

2 个答案:

答案 0 :(得分:0)

这不是最好的架构,但它会起作用:

在prePersist上将所有消息添加到某种私有变量(如$ logMessages),并添加另一个事件

/**
 * @param PostFlushEventArgs $args
 */
public function postFlush(PostFlushEventArgs $args)
{
    $logMessages = $this->logMessages;

    $this->logMessages = array(); //clean to avoid double logging

    if (!empty($logMessages)) {
        foreach ($logMessages as $message) {
            $this->serviceContainer->get('bss.pmod.order_logger')->log($message);
        }

    }
}

答案 1 :(得分:0)

我通过添加postPersist并在那里调用记录器而不是在prePersist中修复了问题;

/**
 * Performs tasks before destruction
 * @ORM\PostPersist
 */
public function postPersist(LifecycleEventArgs $args)
{
    $order = $args->getEntity();

    if ($order instanceof PmodOrder) {                
        $this->serviceContainer->get('bss.pmod.order_logger')->log($order, 'Order Created');
    }
}

因为我认为正在发生的事情是记录器尝试执行但记录器中的顺序尚未存在,因为它尚未保留。这种方式对我来说更有意义,我认为这是最容易解决的问题。我可能错了,欢迎任何评论和其他意见。