未使用 Symfony 4 Doctrine EventSubscriber
Symfony 4 Doctrine EventSubscriber not used
正在尝试注册一个 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 中很好。
然而,现在,即使我以通常的方式为此手动编写一个服务条目,仍然没有任何反应。
编辑:
这是我的 services.yaml 在尝试了 Symfony 文档中建议的 Domagoj 之后:
App\Subscriber\UserPasswordChangedSubscriber:
tags:
- { name: doctrine.event_subscriber, connection: default }
没用。有趣的是,如果我取消实现 EventSubscriber 接口,Symfony 会抛出异常(正确地)。然而我在代码中的断点被完全忽略了。
我考虑过 EntityListener,但它不能有带参数的构造函数,不能访问 Container,我不应该这样做;这应该有效:/
您必须将事件侦听器注册为服务并将其标记为 doctrine.event_listener
我终于弄明白了。我专门更新的字段是暂时的,因此 Doctrine 不认为这是实体更改(正确)。
为了解决这个问题,我输入了
// Set the updatedAt time to trigger the PreUpdate event
$this->updatedAt = new DateTimeImmutable();
在实体字段的设置方法中,这强制更新了。
我还需要使用以下代码在 services.yaml 中手动注册订阅者。 symfony 4 自动装配对于 Doctrine 事件订阅者来说不够自动。
App\Subscriber\UserPasswordChangedSubscriber:
tags:
- { name: doctrine.event_subscriber, connection: default }
对于您的第一个问题,学说事件订阅者不是 autoconfigured/auto-tagged。原因及解决办法,大家有一些回应here.
Personnaly,我只有一个 Doctrine ORM 映射器,所以我把它放在我的 services.yaml
文件中:
services:
_instanceof:
Doctrine\Common\EventSubscriber:
tags: ['doctrine.event_subscriber']
正在尝试注册一个 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 中很好。
然而,现在,即使我以通常的方式为此手动编写一个服务条目,仍然没有任何反应。
编辑:
这是我的 services.yaml 在尝试了 Symfony 文档中建议的 Domagoj 之后:
App\Subscriber\UserPasswordChangedSubscriber:
tags:
- { name: doctrine.event_subscriber, connection: default }
没用。有趣的是,如果我取消实现 EventSubscriber 接口,Symfony 会抛出异常(正确地)。然而我在代码中的断点被完全忽略了。
我考虑过 EntityListener,但它不能有带参数的构造函数,不能访问 Container,我不应该这样做;这应该有效:/
您必须将事件侦听器注册为服务并将其标记为 doctrine.event_listener
我终于弄明白了。我专门更新的字段是暂时的,因此 Doctrine 不认为这是实体更改(正确)。
为了解决这个问题,我输入了
// Set the updatedAt time to trigger the PreUpdate event
$this->updatedAt = new DateTimeImmutable();
在实体字段的设置方法中,这强制更新了。
我还需要使用以下代码在 services.yaml 中手动注册订阅者。 symfony 4 自动装配对于 Doctrine 事件订阅者来说不够自动。
App\Subscriber\UserPasswordChangedSubscriber:
tags:
- { name: doctrine.event_subscriber, connection: default }
对于您的第一个问题,学说事件订阅者不是 autoconfigured/auto-tagged。原因及解决办法,大家有一些回应here.
Personnaly,我只有一个 Doctrine ORM 映射器,所以我把它放在我的 services.yaml
文件中:
services:
_instanceof:
Doctrine\Common\EventSubscriber:
tags: ['doctrine.event_subscriber']