Я работаю над переносом проекта Symfony 2.8
на Symfony 3.4
.В проекте используются Doctrine 2.6.3
и FOSUserBundle 2.1.2
.
. Проект прислушивается к FOSUserEvents::REGISTRATION_CONFIRMED
для выполнения дополнительной настройки при создании и подтверждении новой учетной записи пользователя.
public static function getSubscribedEvents() {
return array(
FOSUserEvents::REGISTRATION_CONFIRMED => 'onRegistrationConfirmed',
);
}
public function onRegistrationConfirmed(FilterUserResponseEvent $event) {
$this->logger->info("onRegistrationConfirmed");
$user = $event->getUser();
// Do some additional setup. While the confirmed user in known here,
// other setup classes / methods get the current user from tokenStorage
ThirdPartySetupCode();
}
// Some 3rd party class I cannot change
public function ThirdPartySetupCode() {
$token = $this->tokenStorage->getToken();
if (!$token) {
$user = $token->getUser();
...
}
}
Кажется, что есть некоторые различия в том, как события обрабатываются в Symfony 2.8
и Symfony 3.4
:
Хотя приведенный выше код работает без проблем в Symfony 2.8
, он не работает в Symfony 3.4
, поскольку $token->getUser()
не возвращает действительный объект пользователя, а только строку anon.
, анонимный пользователь.
Вот как события обрабатываются в Symfony 2.8:
dispatch: kernel.request
dispatch: security.authentication.success
dispatch: kernel.controller
dispatch: fos_user.registration.confirm
dispatch: fos_user.registration.confirmed
dispatch: fos_user.security.implicit_login
onRegistrationConfirmed
Удивительно, что вывод журнала onRegistrationConfirmed
появляется сразу после fos_user.registration.confirmed
.Не должен ли обработчик выполняться сразу после того, как событие было запущено?
Вместо этого сначала отправляется (и обрабатывается) событие fos_user.security.implicit_login
, и только затем обработчик onRegistrationConfirmed
?
Почему это так? Однако, хотя я не понимаю этого поведения, оно приводит к желаемому результату: поскольку обработчик (и вместе с ним сторонний код) запускается после завершения входа в систему, токен возвращает правильного пользователя..
Вот как события обрабатываются в Symfony 3.4:
dispatch: kernel.request
dispatch: security.authentication.success
dispatch: kernel.controller
dispatch: kernel.controller_arguments
dispatch: fos_user.registration.confirm
dispatch: fos_user.registration.confirmed
onRegistrationConfirmed
dispatch: fos_user.security.implicit_login
Здесь обработчик onRegistrationConfirmed
выполняется непосредственно после события fos_user.registration.confirmed
.
Хотя я понимаю это поведение, оно приводит к неверному результату: обработчик (и вместе с ним сторонний код) запускает БЕЗ входа в систему полностью, и поэтому токен не возвращает действительного пользователя.
Как решить эту проблему? Поскольку я не могу изменить сторонний код, мне придется как-то отложить обработку fos_user.registration.confirmed
, чтобы сначала выполнить вход в систему.Можно ли это сделать?
Это различие в диспетчеризации событий и обработке предполагаемого изменения между Symfony 2.8
и Symfony 3.4
?Я не нашел никакой информации по этому вопросу.