2

所以,

我有一个带有时间戳字段的实体,如下所示:

<?php
namespace Acme\Bundle\Entity;

use Acme\PathEnumerableInterface as EnumerableInterface;
use Acme\PathEnumerable as PathEnumerableTrait;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;

/**
 * SomeEntity
 *
 * @ORM\Table()
 * @ORM\HasLifecycleCallbacks
 */
class SomeEntity implements EnumerableInterface
{
    use PathEnumerableTrait;

    /**
     * @var \DateTime
     *
     * @Gedmo\Timestampable(on="create")
     * @ORM\Column(name="created_at", type="datetime")
     */
    private $createdAt;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="updated_at", type="datetime")
     * @Gedmo\Timestampable(on="update")
     */
    private $updatedAt;


    /**
     * Get createdAt
     *
     * @return \DateTime
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    /**
     * Get updatedAt
     *
     * @return \DateTime
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }
}

然后,我为 postPersist、postUpdate 和 postFlush 事件设置了生命周期订阅者。service.yml 看起来像这样:

services:
    acme.element_listener:
        class: %iacme.element_listener.class%
        arguments:
            manager: "@doctrine.orm.default_entity_manager"
        tags:
            - { name: doctrine.event_subscriber, connection: default }

实际的侦听器如下所示:

<?php

namespace Acme\Bundle\EventListener;

use Acme\PathEnumerableInterface;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Event\PostFlushEventArgs;

class EventListener
{
    /**
     * @var Doctrine\ORM\EntityManager
     */
    private $entityManager;

    /**
     * @var array
     */
    private $paths = [];

    public function __construct(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    public function getSubscribedEvents()
    {
        return ['postPersist'];
    }

    private function postPersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();
        // Set $newPath to a generated path and check so we don't end up in an infinite loop
        if ($entity->getPath() != $newPath) {
            //... Do some stuff with the entity
            $this->entityManager->persist($entity);
            $this->entityManager->flush();
        }
    }
}

当我删除事件侦听器时,一切都很好,并且可以正确填写时间戳字段。但是,当我创建一个启用了侦听器的新实体时,未填写可时间戳字段。

那么,我的问题是,什么会导致事件侦听器停止 Gedmo 填充可时间戳字段?我可能正在做一些非常愚蠢的事情,但到目前为止我还看不出那可能是什么......

4

1 回答 1

1

好的,所以这里有一些问题导致我出现问题:

  1. 我的 EventListener 类没有实现 EventSubscriber。该类应该像这样声明:

    <?php
    
    namespace Acme\Bundle\EventListener;
    
    use Acme\PathEnumerableInterface;
    use Doctrine\ORM\Event\LifecycleEventArgs;
    use Doctrine\ORM\EntityManager;
    use Doctrine\ORM\Event\PostFlushEventArgs;
    use Doctrine\Common\EventSubscriber;
    
    class EventListener implements EventSubscriber
    {
        // .....
    }
    
  2. 您不能将 EntityManager 作为构造参数传递。当您考虑它时,这实际上很有意义,并且并没有真正阻碍我所做的事情,因为 getEntityManager 事件在 LifecycleEventArgs 对象和 PostFlushEventArgs 对象中可用

于 2013-06-24T09:30:37.197 回答