Пытаюсь зарегистрировать 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 после попытки того, что предложил Domagoj из документации Symfony:
App\Subscriber\UserPasswordChangedSubscriber:
tags:
- { name: doctrine.event_subscriber, connection: default }
Это не сработало. Интересно, что если я не реализую интерфейс EventSubscriber, Symfony выдаст исключение (правильно). Тем не менее, мои точки останова в коде полностью игнорируются.
Я рассматривал EntityListener, но у него не может быть конструктора с аргументами, нет доступа к контейнеру, и мне не должно быть; это должно работать: /
Нет никакой конфигурации для публикации, это актуально, на данный момент, так как ее нет. В приведенном ниже ответе содержится предложение (которое включает настройку), которое я собираюсь попробовать. В автоматическом подключении Symfony 3.3 внес некоторые новые изменения, касающиеся автоматического внедрения объектов в классы без конфигурации (или дополнительной конфигурации). Прямо сейчас я выбираю конфигурацию по умолчанию. Подробнее читайте здесь symfony.com/doc/current/service_container/3.3-di-changes.htm l




Вы должны зарегистрировать свой прослушиватель событий как службу и пометить его как doctrine.event_listener.
Я сделал это, если вы проверите последнее предложение в вопросе :( Я вижу это в выводе bin / console debug: autowiring, но не вижу, подключены ли также теги. Документация Symfony Events утверждает, что теги подключаются автоматически, исходя из предположения, что они реализуют требуемые интерфейсы. Я попробую сделать это еще раз сегодня вечером с точным форматом на той странице, которую вы связали.
В итоге я понял это. Поле, которое я специально обновлял, было временным, и поэтому Doctrine не считала это изменением сущности (справедливо).
Чтобы исправить это, я поставил
// Set the updatedAt time to trigger the PreUpdate event
$this->updatedAt = new DateTimeImmutable();
В методе набора поля Entity, и это вызвало обновление.
Мне также нужно было вручную зарегистрировать подписчика в services.yaml, используя следующий код. Автоматическое подключение symfony 4 было недостаточным для подписчика событий Doctrine.
App\Subscriber\UserPasswordChangedSubscriber:
tags:
- { name: doctrine.event_subscriber, connection: default }
Для вашей первой проблемы подписчики событий доктрины не настраиваются автоматически / не помечаются автоматически. По причинам и решениям у вас есть отзывы здесь.
Лично у меня есть только один Doctrine ORM mapper, поэтому я поместил его в свой файл services.yaml:
services:
_instanceof:
Doctrine\Common\EventSubscriber:
tags: ['doctrine.event_subscriber']
Пожалуйста, покажите все связанные файлы конфигурации. Вы сказали что-то об autowire и что-то о "ручной" настройке, но вы не указали здесь связанный код ...