首页 > 解决方案 > Symfony 似乎注册了,但没有触发我的学说事件

问题描述

对不起,如果有些东西不是那么准确,但我对 Symfony 的经验较少

我有以下 orm 映射:

src/app/ExampleBundle/Resources/config/doctrine/Base.orm.yml

app\ExampleBundle\Entity\Base:
type: mappedSuperclass
fields:
    createdAt:
        type: datetime
        nullable: true
        options:
            default: null
    updatedAt:
        type: datetime
        nullable: true
        options:
            default: null

这将创建一个实体 Base,我将其修改为抽象

src/app/ExampleBundle/Entity/Base.php

abstract class Base {
    ...
}

我有一些其他实体,它们扩展了这个抽象类,例如

src/app/ExampleBundle/Entity/Category.php

class Category extends Base
{
    ...
}

现在我尝试添加一个侦听器,为扩展基本实体的每个实体在每个持久化上设置 createdAt/updatedAt 日期时间

src/app/ExampleBundle/EventListener/BaseListener.php

namespace app\ExampleBundle\EventListener;

use Doctrine\ORM\Event\LifecycleEventArgs;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\User\UserInterface;
use app\ExampleBundle\Entity\Base;

class BaseListener
{
    protected $tokenStorage;

    public function __construct(TokenStorage $tokenStorage)
    {
        $this->tokenStorage = $tokenStorage;
    }

    public function prePersist(Base $base, LifecycleEventArgs $event)
    {
        $user = $this->tokenStorage->getToken()->getUser();
        if (!$user instanceof UserInterface) {
            $user = null;
        }

        if ($base->getCreatedAt() === null) {
            $base->setCreated($user, new \DateTime());
        } else {
            $base->setUpdated($user, new \DateTime());
        }
    }
}

并将其添加到 bundles services.yml

src/app/ExampleBundle/Resources/config

services:
    app\ExampleBundle\EventListener\BaseListener:
        arguments: ['@security.token_storage']
        tags:
            - { name: doctrine.orm.entity_listener, entity: app\ExampleBundle\Entity\Base, event: prePersist }

Symfony 没有抛出异常,但定义的事件似乎也没有被触发。

我试图将服务中的实体参数更改为“真实”实体类别,但仍然没有错误,也没有触发事件。

我想,我做了所有文档中描述的事情。但它仍然无法正常工作。

命令

debug:event-dispatcher

也不显示事件

所以,问题是:我做错了什么?

标签: symfonyormevent-listenersymfony-3.4

解决方案


这里是我遵循的文档https://symfony.com/doc/3.4/doctrine/event_listeners_subscribers.html

为所有实体调用 prePersist 方法,因此您必须排除 app\ExampleBundle\Entity\Base 的非实例。第一个参数是 LifecycleEventArgs。

public function prePersist(LifecycleEventArgs $event)
{
    $base = $event->getObject();
    if (!$base instanceof Base) {
        return;
    }
    $user = $this->tokenStorage->getToken()->getUser();
    if (!$user instanceof UserInterface) {
        $user = null;
    }

    if ($base->getCreatedAt() === null) {
        $base->setCreated($user, new \DateTime());
    } else {
        $base->setUpdated($user, new \DateTime());
    }
}

我可以向您推荐StofDoctrineExtensionsBundle (Timestampable),它完全符合您的要求。它基于DoctrineExtensions

甚至还有一个像魅力一样起作用的特质。


推荐阅读