尝试注册Doctrine EventSubscriber,但实际上没有触发任何事情。
我要在实体上设置@ORM\HasLifeCycleCallbacks
批注。
这里是订户:
<?php
namespace App\Subscriber;
use App\Entity\User;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Doctrine\ORM\Events;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
class UserPasswordChangedSubscriber implements EventSubscriber
{
private $passwordEncoder;
public function __construct(UserPasswordEncoderInterface $passwordEncoder)
{
$this->passwordEncoder = $passwordEncoder;
}
public function getSubscribedEvents()
{
return [Events::prePersist, Events::preUpdate, Events::postLoad];
}
public function prePersist(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if (!$entity instanceof User) {
return null;
}
$this->updateUserPassword($entity);
}
public function preUpdate(PreUpdateEventArgs $event)
{
$entity = $event->getEntity();
if (!$entity instanceof User) {
return null;
}
$this->updateUserPassword($entity);
}
private function updateUserPassword(User $user)
{
$plainPassword = $user->getPlainPassword();
if (!empty($plainPassword)) {
$encodedPassword = $this->passwordEncoder->encodePassword($user, $plainPassword);
$user->setPassword($encodedPassword);
$user->eraseCredentials();
}
}
}
使这一点特别令人沮丧的部分是,在Symfony 3中,相同的代码和配置在自动装配已关闭并且我对所有服务进行手动编码时都很好。
但是,现在,即使我以常规方式为此手动编写了一个服务条目,仍然没有任何反应。
编辑:
尝试了Symfony文档中建议的Domagoj之后,这是我的services.yaml:
App\Subscriber\UserPasswordChangedSubscriber:
tags:
- { name: doctrine.event_subscriber, connection: default }
它没有用。有趣的是,如果我未实现EventSubscriber接口,则Symfony会抛出一个异常(正确)。但是我在代码中的断点被完全忽略了。
我已经考虑过EntityListener,但是它不能具有带参数的构造函数,不能访问Container,我也不必这样做;这应该工作:/
答案 0 :(得分:1)
我最终弄清楚了这一点。我专门更新的字段是瞬态的,因此,Doctrine不认为这是实体更改(正确)。
要解决此问题,我放了
// Set the updatedAt time to trigger the PreUpdate event
$this->updatedAt = new DateTimeImmutable();
在Entity字段的set方法中,这迫使进行更新。
我还需要使用以下代码在services.yaml中手动注册订户。对于学说事件订阅者,symfony 4自动装配还不够自动化。
App\Subscriber\UserPasswordChangedSubscriber:
tags:
- { name: doctrine.event_subscriber, connection: default }
答案 1 :(得分:0)
您必须将事件监听器注册为服务并将其标记为doctrine.event_listener
答案 2 :(得分:0)
对于第一个问题,没有自动配置/自动标记学说事件订阅者。由于这些原因和解决方案,您会有一些回复here。
Personnaly,我只有一个Doctrine ORM映射器,所以我将其放入我的services.yaml
文件中:
services:
_instanceof:
Doctrine\Common\EventSubscriber:
tags: ['doctrine.event_subscriber']