symfony - 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
也不显示事件
所以,问题是:我做错了什么?
解决方案
这里是我遵循的文档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。
甚至还有一个像魅力一样起作用的特质。
推荐阅读
- mysql - 如何使用 MySQL 确定字符串中是否有数字
- terraform - Terraform 私有提供者如何获取 GKE 集群的 kubeconfig
- python - 这是在 python 中重新创建 C 数据类型的可行方法吗?
- regex - 使用 RegExr 跳过第一个位置匹配 Javascript
- swift - “形状”变量如何在引擎盖下工作?
- python - 如何使用 lambda 函数将文件上传到 Amazon S3?
- spring-boot - 您如何断言将对象添加到另一个对象多对多
- python - 我可以有效地进行多维切片吗?
- python - 火炬 | 使用数据集 Omniglot 获取“RuntimeError: Found dtype Long but expected Float”
- windows - 在安全桌面(登录屏幕)上的 Windows 10 轻松访问菜单中添加自定义条目