Symfony,Doctrine:如何禁用实体侦听器?

vct*_*tls 8 symfony doctrine-orm

我需要使用 Alice Fixtures Bundle 保留一些装置,而不触发特定的实体侦听器。
侦听器通过EntityListeners注释与我的实体相关联。
我宁愿不改变听众本身。

我创建了一个可以访问容器的自定义加载器,希望在创建对象之前禁用所有侦听器。

我已经尝试过这个答案,但$em->getEventManager()->getListeners()没有返回实体监听器。

ClassMetadata 为我提供了该实体的订阅实体侦听器列表,但它只是一个只读数组。

有没有办法禁用那些实体侦听器?

vct*_*tls 6

我找到了一个方法。
这就是我在加载器中所做的:

$em = $this->container->get('doctrine.orm.default_entity_manager');

$entitiesWithListeners = [
    Post::class,
    Comment::class
];

$listenersToDisable = [
    MyListener::class
];

foreach ($entitiesWithListeners as $entity) {
    $metadata = $em->getMetadataFactory()->getMetadataFor($entity);

    foreach ($metadata->entityListeners as $event => $listeners) {
        
        foreach ($listeners as $key => $listener) {
            if (in_array($listener['class'], $listenersToDisable)) {
                unset($listeners[$key]);
            }
        }
        $metadata->entityListeners[$event] = $listeners;
    }
    $em->getMetadataFactory()->setMetadataFor($entity, $metadata);
}
Run Code Online (Sandbox Code Playgroud)

我只是获取每个实体的元数据,将其从我的实体侦听器中剥离,然后将其设置回其对应的类。

这很丑陋,但嘿,它有效。由于我目前坚持使用 AliceBundle v1.4,并且当我们更新项目时我将不得不更改所有内容,因此可以这样做。

  • 由于 $metadata 是一个对象,并且由于对象如何在此行传递 $em->getMetadataFactory()->setMetadataFor($entity, $metadata); 是多余的。非常感谢您发布此内容,它节省了我很多时间。 (2认同)