Поскольку вашей форме смены пароля требуется только два поля, мы будем использовать массив вместо пользовательского объекта.Нужна небольшая настройка ChangePasswordType:
// ChangePasswordType
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
//'data_class' => User::class
));
}
Вот рабочее забытое действие:
public function forgot(
Request $request,
UserPasswordEncoderInterface $encoder,
UserRepository $userRepository)
{
$userInfo = ['username' => null, 'plainPassword' => null];
$form = $this->createForm(ChangePasswordType::class, $userInfo);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$userInfo = $form->getData();
$username = $userInfo['username'];
$plainPassword = $userInfo['plainPassword'];
$user = $userRepository->findOneBy(['username' => $username]);
if ($user === null) {
$this->addFlash('danger', 'Invalid username');
return $this->redirectToRoute('forgot');
}
$password = $encoder->encodePassword($user, $plainPassword);
$user->setPassword($password);
$userRepository->flush();
return $this->redirectToRoute('login');
}
return $this->render('user/forgot.html.twig', array('form' => $form->createView()));
}
Введен UserRepository, который избавляет от всей чепухи доктрины.Здесь есть одна оговорка, к которой я вернусь.
Мы создаем массив userInfo и позволяем обработке формы делать свое дело.Мы действительно не хотим возиться с получением атрибутов непосредственно из объекта запроса, если нам не нужно.
Тогда мы получим нашу актуальную пользовательскую сущность для обновления.Обратите внимание на использование findOneBy вместо findBy.Мы проверяем, чтобы убедиться в правильности имени пользователя.Если вы действительно хотите получить фантазию, то можете добавить в форму ограничение проверки, чтобы автоматически выполнить эту проверку.
Я избавился от всего, что касается try / catch.Это просто загромождает ваш код.К этому моменту, если выдается исключение, оно становится действительно исключительным и может обрабатываться обработчиками исключений по умолчанию.
Вы правильно разбираетесь в кодировщике паролей.
И тогда вместо $ entityManager-> flush () Я использовал $ userRepository-> flush ();В хранилище нет встроенного метода очистки, поэтому вам нужно добавить один:
// UserRepository
public function flush()
{
$this->_em->flush();
}
Мне лично нравится иметь дело только с хранилищами, а не с менеджером сущностей.Но если хотите, вы можете просто вернуться и ввести менеджер вместо репозитория.Ваш звонок.
И, как уже упоминалось в комментариях, вы хотите добавить некоторую защиту, чтобы пользователи не могли изменять пароли других пользователей.