Symfony2 - 从控制器到监听器的变量

时间:2015-02-18 10:43:52

标签: php symfony

我有一个我想解决的情况。我有一个带有标准createAction的控制器

 public function createAction(Request $request)
 {
    try {

        $em = $this->getDoctrine()->getManager();
        $alert = new AvailabilityAlert();
        $alert->setLastUpdated();
        $alert->setIsDeleted(0);
        $alert->setAlertStatus('Active');

        $em->persist($alert);
        $em->flush();

        return new JsonResponse('Success');

    }catch (Exception $e) {
    }

}

然后我有一个事件监听器来执行此操作

<?php

namespace Nick\AlertBundle\EventListener;

use Doctrine\ORM\Event\OnFlushEventArgs;
use Nick\AlertBundle\Entity\AvailabilityAlert;
use Nick\AlertBundle\Service\UapiService;

class AvailabilityAlertListener
{
    protected $api_service;

    public function __construct(UapiService $api_service)
    {
        $this->api_service = $api_service;
    }

    public function onFlush(OnFlushEventArgs $args)
    {
        $em = $args->getEntityManager();

        foreach ($em->getUnitOfWork()->getScheduledEntityInsertions() as $entity) {
            if ($entity instanceof AvailabilityAlert) {
                var_dump($entity->getId());
                $this->api_service->addFlightsAction($entity);
            }
        }
    }
}

此事件侦听器调用addFlightAction。这只是

public function addFlightsAction($alert){
    $em = $this->sc->get('doctrine.orm.entity_manager');
    $worldspanCommand = $em->getRepository("NickAlertBundle:AvailabilityAlert")->getSpecificAlert($alert->getId());

}

这会调用自定义仓库,并使用新创建的警报的ID。功能是

public function getSpecificAlert($id)
{
    $active = "Active";

    return $this->getEntityManager()
        ->createQuery(
            'SELECT a.id, a.searchCommand,
                GROUP_CONCAT(DISTINCT c.classLetter) AS classes,
                GROUP_CONCAT(DISTINCT p.pseudo) AS pseudos,
                GROUP_CONCAT(DISTINCT f.flightNumber) AS flight_number
                    FROM NickAlertBundle:AvailabilityAlert a
                        JOIN NickAlertBundle:AvailabilityAlertBookingClass c
                          WITH a.id = c.availabilityAlert
                        JOIN NickAlertBundle:AvailabilityAlertPseudos p
                          WITH a.id = p.availabilityAlert
                        JOIN NickAlertBundle:AvailabilityAlertFlightNumbers f
                          WITH a.id = f.availabilityAlert
                    WHERE a.alertStatus = :active
                    AND a.id = :id
                    GROUP BY a.id'
        )
        ->setParameter('active', $active)
        ->setParameter('id', $id)
        ->getResult();
}

如果我var_dump上述查询的结果,我得到一个空响应。如果我将id的setParameter更改为$ id-1,那么它会给我正确的响应,但是对于最后添加的警报,不是当前的警报。所以查询可以工作,但不能使用当前的id。所以这告诉我,当执行此查询时,警报不在数据库中?

更新

我无法找到关于postFlush的更多信息,但这似乎没有触发var_dump

public function postFlush(PostFlushEventArgs $args)
{
    $em = $args->getEntityManager();

    foreach ($em->getUnitOfWork()->getScheduledEntityInsertions() as $entity) {
        if ($entity instanceof AvailabilityAlert) {
            var_dump("TEST");
            $this->api_service->addFlightsAction($entity);
        }
    }
}

我没有收到任何错误。

2 个答案:

答案 0 :(得分:2)

在实际刷新实体之前触发/捕获OnFlush。所以还没有id。

尝试使用postFlush事件。您将在学说文档中找到所有可用的事件。

http://doctrine-orm.readthedocs.org/en/latest/reference/events.html

答案 1 :(得分:2)

postPersist是enaugh,我知道你已经尝试但是我确定你搞砸了什么。这是因为:

  

postPersist - postPersist事件发生在一个实体之后   实体已经坚持不懈。它将在数据库之后调用   插入操作。 生成的主键值可在   postPersist活动。

来自http://doctrine-orm.readthedocs.org/en/latest/reference/events.html

所以,对我来说,你还没有为你的实体分配PK值。或者某些内容配置不正确


更新

在OP更新问题之后,很明显只有达到他想要的方式才能听取postFlush()事件。

我还建议只将整数$id传递给addFlightsAction(),因为您似乎对整个$entity对象不执行任何操作