Symfony Event Listener - 填充实体


Symfony Event Listener - populate entity

谁能举个例子?我有一个项目ProjectEvent - 多个事件的实体,所以当状态项目更改为'closed_by_client'时,我需要为此项目创建一个事件。

在控制器中:

$project = $this
    ->getDoctrine()
    ->getManager()
    ->getRepository('ArtelProfileBundle:Project')
    ->find($id);
        $project->setCurrentStatus('closed_by_client');
        $manager->persist($project);
        $manager->flush();

项目实体:

/**
 * Project.
 *
 * @ORM'Table(name="project")
 * @ORM'HasLifecycleCallbacks
 * @Gedmo'SoftDeleteable(fieldName="deletedAt")
 * @ORM'Entity(repositoryClass="Artel'ProfileBundle'Entity'Repository'ProjectRepository")
* @ExclusionPolicy("all")
*/
class Project
{
const STATE_TO_BE_INDEXED_IN_ELA_NOT_APPROVED = 'not_approved';
const STATE_TO_BE_INDEXED_IN_ELA_CLOSED_BY_CLIENT = 'closed_by_client';
use Timestampable;
/**
 * @var int
 *
 * @ORM'Column(name="id", type="integer")
 * @ORM'Id
 * @Expose()
 * @ORM'GeneratedValue(strategy="AUTO")
 */
private $id;
/**
 * @ORM'Column(name="current_status", type="string", length=100, nullable = true)
 * @Expose()
 * @Type("string")
 */
protected $currentStatus = 'not_approved';
/**
 * @ORM'OneToMany(targetEntity="CodeEvents", mappedBy="project", cascade={"persist", "remove"})
 */
protected $events;
/**
 * @ORM'PrePersist()
 */
public function PrePersist(){
    if($this->getCurrentStatus() == self::STATE_TO_BE_INDEXED_IN_ELA_CLOSED_BY_CLIENT){
        $event = new CodeEvents();
        $event
            ->setProject($this)
            ->setEvent(self::STATE_TO_BE_INDEXED_IN_ELA_CLOSED_BY_CLIENT)
        ;
    }
}
/**
 * @ORM'PreFlush()
 */
public function PreFlush(){
    if($this->getCurrentStatus() == self::STATE_TO_BE_INDEXED_IN_ELA_CLOSED_BY_CLIENT){
        $event = new CodeEvents();
        $event
            ->setProject($this)
            ->setEvent(self::STATE_TO_BE_INDEXED_IN_ELA_CLOSED_BY_CLIENT)
        ;
    }
}

我认为我也许可以做这样的事情,但实体Event不会在数据库中刷新:

/**
 * @ORM'PrePersist()
 */
public function PrePersist(){
    if($this->getCurrentStatus() == self::STATE_TO_BE_INDEXED_IN_ELA_CLOSED_BY_CLIENT){
        $event = new CodeEvents();
        $event
            ->setProject($this)
            ->setEvent(self::STATE_TO_BE_INDEXED_IN_ELA_CLOSED_BY_CLIENT)
        ;
    }
}
/**
 * @ORM'PreFlush()
 */
public function PreFlush(){
    if($this->getCurrentStatus() == self::STATE_TO_BE_INDEXED_IN_ELA_CLOSED_BY_CLIENT){
        $event = new CodeEvents();
        $event
            ->setProject($this)
            ->setEvent(self::STATE_TO_BE_INDEXED_IN_ELA_CLOSED_BY_CLIENT)
        ;
    }
}

我加

    /**
 * @ORM'PreFlush()
 */
public function PreFlush(LifecycleEventArgs $event){
    $entityManager = $event->getEntityManager();
    if($this->getCurrentStatus() == self::STATE_TO_BE_INDEXED_IN_ELA_CLOSED_BY_CLIENT){
        $event = new CodeEvents();
        $event
            ->setProject($this)
            ->setEvent(self::STATE_TO_BE_INDEXED_IN_ELA_CLOSED_BY_CLIENT)
        ;
        $entityManager->persist($event);
        $entityManager->flush();
    }
}

但是当刷新实体有错误时

`Catchable Fatal Error: Argument 1 passed to Proxies'__CG__'Artel'ProfileBundle'Entity'Project::PreFlush() must be an instance of Doctrine'ORM'Event'LifecycleEventArgs, instance of Doctrine'ORM'Event'PreFlushEventArgs given, called in /home/ivan/host/aog-code/vendor/doctrine/orm/lib/Doctrine/ORM/Event/ListenersInvoker.php on line 102 and defined`

如何为事件创建侦听器 - 实体 "closed_by_client"的项目更改状态 - 创建实体事件?

我没有创建早期事件,如何为此业务逻辑创建事件?

考虑到 prePersist 和 preFlush 方法位于 Project 类本身中。为了将其添加到事件的对象中,您只需要使用$this

public function PrePersist(){
    if($this->getCurrentStatus() == self::STATE_TO_BE_INDEXED_IN_ELA_CLOSED_BY_CLIENT){
        $event = new CodeEvents();
        $event->setProject($this);
    }
}

在标题中,你询问了Symfony事件监听器,但实际上你使用了doctrine事件监听器。

我的笔记在这里:

1,你需要创建一个symfony2事件,并从你的教义事件中触发它。如果你想触发symfony2事件会使事情变得有点复杂,因为你需要访问框架事件调度器,你需要把它注入到你的LifeCycleEventListener。所以:

  • 为此状态更改创建您自己的Symfony事件http://symfony.com/doc/current/components/event_dispatcher/introduction.html#creating-and-dispatching-an-event
  • 为您的项目实体创建一个单独的 Doctrine 实体事件侦听器,您可以在其中注入 SF 框架事件调度程序
  • 在 SF2 配置中定义它http://symfony.com/doc/current/bundles/DoctrineBundle/entity-listeners.html
  • 在 Doctrine 侦听器中使用事件调度程序 调度状态更改事件
  • 在Symfony中创建您的事件订阅者或侦听器,它将处理状态更改事件(与第一个点的链接相同)。

2,我会考虑检查状态字段是否发生了变化,否则当项目实体的任何其他属性更改并且状态已经为"closed_by_client"时,您将创建大量CodeEvent()实例看这里:http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/events.html#lifecycle-callbacks-event-argument