【问题标题】:Symfony Event Listener - populate entitySymfony 事件监听器 - 填充实体
【发布时间】:2016-07-09 02:19:04
【问题描述】:

谁能举个例子? 我有实体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 没有在 DB 中刷新:

/**
 * @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' 的项目更改状态 - 创建实体事件?

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

【问题讨论】:

  • 您正在将业务逻辑与数据库层混合。像user [x] closed a project 这样创建events 实际上不是教义的工作,而是您的应用程序的工作。您实际上应该创建单独的业务逻辑类,它们负责将数据持久化到您的实体,这不应该取决于您使用的数据库。您可以为此创建 dao。然后在 symfony 中注册一个事件监听器,它会在调用onUserClosedProject-event 时执行一些代码。您可以将用户和事件传递给该函数。
  • 我没有创建早期事件,如何为这个业务逻辑创建事件?
  • 更新我的问题

标签: php symfony doctrine-orm event-listener


【解决方案1】:

考虑到 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);
    }
}

【讨论】:

  • 但如果在控制器$potentialClient = $this->getDoctrine()->getManager() ->getRepository('ArtelProfileBundle:Project') ->find($id);$event->setProject($this); 何时设置存在项目?或者如何创建独立的监听器?
【解决方案2】:

在标题中您询问了 Symfony 事件侦听器,但您实际上使用了学说事件侦听器。

我的笔记在这里:

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

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

【讨论】:

  • 我尝试过,但我没有这么好的经验来做这一切,也许一些例子对我很有帮助
  • 我建议暂时在学说实体监听器中实现你的逻辑,不要绕过 Symfony 事件监听器。 (其实你已经在使用一个事件系统了,如果你不愿意做任何其他的逻辑,我认为留在那个事件系统中就足够了)。
  • 我没有足够的声望来评论你的开场白但是:php public function PreFlush(LifecycleEventArgs $event){ } 参数类型提示错误,这个监听器在实体上,所以应该是php public function PreFlush(PreFlushEventArgs $event){ }
  • 如果使用原则事件@ORM\PreFlush()如何刷新另一个实体,在哪里获取实体管理器或如何刷新?
  • 根据文档,在这个事件中使用 $em->flush() 是安全的,所以我想 $em->persist($event), $em->flush() 应该做这个伎俩。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-06
  • 2015-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-27
相关资源
最近更新 更多