Symfony 4 Doctrine EventSubscriber не используется

Пытаюсь зарегистрировать 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, но у него не может быть конструктора с аргументами, нет доступа к контейнеру, и мне не должно быть; это должно работать: /

Пожалуйста, покажите все связанные файлы конфигурации. Вы сказали что-то об autowire и что-то о "ручной" настройке, но вы не указали здесь связанный код ...

DonCallisto 09.07.2018 16:49

Нет никакой конфигурации для публикации, это актуально, на данный момент, так как ее нет. В приведенном ниже ответе содержится предложение (которое включает настройку), которое я собираюсь попробовать. В автоматическом подключении Symfony 3.3 внес некоторые новые изменения, касающиеся автоматического внедрения объектов в классы без конфигурации (или дополнительной конфигурации). Прямо сейчас я выбираю конфигурацию по умолчанию. Подробнее читайте здесь symfony.com/doc/current/service_container/3.3-di-changes.htm‌ l

MattBoothDev 10.07.2018 19:27
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
1
2
4 358
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы должны зарегистрировать свой прослушиватель событий как службу и пометить его как doctrine.event_listener.

https://symfony.com/doc/current/doctrine/event_listeners_subscribers.html#configuring-the-listener-subscriber

Я сделал это, если вы проверите последнее предложение в вопросе :( Я вижу это в выводе bin / console debug: autowiring, но не вижу, подключены ли также теги. Документация Symfony Events утверждает, что теги подключаются автоматически, исходя из предположения, что они реализуют требуемые интерфейсы. Я попробую сделать это еще раз сегодня вечером с точным форматом на той странице, которую вы связали.

MattBoothDev 09.07.2018 15:16
Ответ принят как подходящий

В итоге я понял это. Поле, которое я специально обновлял, было временным, и поэтому 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']

Другие вопросы по теме