Я пытаюсь отправить пользователю электронное письмо, чтобы он мог сбросить свой пароль, Я сгенерировал событие с помощью swiftmailer, но когда я набираю адрес электронной почты в форме электронной почты, чтобы отправить электронное письмо пользователю, у меня возникают следующие ошибки: когда я набираю адрес электронной почты, который существует в базе данных: ошибка = адрес электронной почты уже принят
когда я набираю электронное письмо, которого нет в базе данных: error = Вызов функции-члена getUsername () с нулевым значением.
пожалуйста, мне нужна помощь
class ChangepasswordController extends Controller
{
public function sendMailAction(Request $request, EventDispatcherInterface
$eventDispatcher, $email)
{
$user = new User();
$form = $this->createForm(SendmailType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
try {
$user = $this->getDoctrine()->getRepository(User::class)
->findOneBy(array('email' => $email));
} catch (ExceptionInterface $e) {
$this->addFlash('danger', "Cet email n'existe pas.");
}
$event = new GenericEvent($user);
$eventDispatcher->dispatch(Events::USER_RESETPASSWORD , $event);
return $this->redirect('connexion');
}
return $this->render(
'security/changePassword.html.twig',
array('form' => $form->createView())
);
}
}
мое мероприятие:
class EventResetpassword implements EventSubscriberInterface
{
private $mailer;
private $sender;
private $twig;
public function __construct(\Swift_Mailer $mailer, $sender, Environment $twig)
{
$this->mailer = $mailer;
$this->sender = $sender;
$this->twig = $twig;
}
public static function getSubscribedEvents()
{
return [
Events:: USER_RESETPASSWORD => 'userResetPassword'
];
}
/**
* @param GenericEvent $event
* @throws \Twig_Error_Loader
* @throws \Twig_Error_Runtime
* @throws \Twig_Error_Syntax
*/
public function userResetPassword(GenericEvent $event): void
{
/** @var User $user */
$user = $event->getSubject();
$username = $user->getUsername();
$message = (new \Swift_Message())
->setSubject($username)
->setTo($user->getEmail())
->setFrom($this->sender)
->setBody($this->twig->render('security/sendemail.html.twig', [
'username' => $username
]));
$this->mailer->send($message);
}
}





Одна из проблем заключается в том, что findOnyBy вернет null, когда нет пользователя с адресом электронной почты, и не вызовет исключение.
вам нужно выполнить нулевую проверку:
$user = $this->getDoctrine()->getRepository(User::class)
->findOneBy(array('email' => $email));
if (null !== $user){
$event = new GenericEvent($user);
$eventDispatcher->dispatch(Events::USER_RESETPASSWORD , $event);
return $this->redirect('connexion');
}
$this->addFlash('danger', "Cet email n'existe pas.");
Другая проблема заключается в том, что $email не может быть введен в действие магией, если это не параметр вашего маршрута.
Поскольку вы используете форму, вам необходимо получить данные из вашей формы. $form->getData() в вашем случае это вернет экземпляр User с установленным адресом электронной почты. Это тоже неправильно, так как это не пользователь, поэтому в этом нет никакого смысла. Вы должны использовать простой объект значения / DTO, который будет иметь только электронную почту, таким образом вы можете избежать путаницы.
Вам действительно стоит прочитать документацию о формах в symfony:
https://symfony.com/doc/current/forms.html
https://symfony.com/doc/current/best_practices/forms.html
Это также хорошее чтение о том, как это сделать (и вы должны делать это таким образом :))
https://blog.martinhujer.cz/symfony-forms-with-request-objects/
Еще одна вещь: никогда не используйте ExceptionInterface, только исключения, которые вы можете исключить, таким образом вы можете подавить неожиданные вещи и впоследствии иметь гораздо более серьезные проблемы, которые трудно отлаживать.
Я обновил свой ответ, в вашем примере больше проблем, чем я замечаю впервые.
Если это решило вашу проблему, вы должны принять ответ.
I update my Code:
/**
* @Route("/send-mail", name = "send_mail")
* @Method({"GET", "POST"})
* @param Request $request
* @return Response
*/
public function sendMailAction(Request $request, EventDispatcherInterface $eventDispatcher, GenerateToken $token)
{
$form = $this->createForm(SendMailType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$email = $form->get('email')->getData();
$em = $this->getDoctrine()->getManager();
/** @var User $user */
if ($user = $em->getRepository(User::class)->findOneByEmail($email)) {
$user->setToken($token->generateToken());
$em->persist($user);
$em->flush();
$event = new GenericEvent($user);
$eventDispatcher->dispatch(Events::USER_RESETPASSWORD, $event);
}
return $this->redirectToRoute('check_email');
}
return $this->render('security/change_password.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @Route("/change-password/{token}", name = "change_password")
* @Method = {"POST"}
* @param Request $request
* @param string $token
* @return Response
*/
public function changePasswordAction(Request $request, UserPasswordEncoderInterface $passwordEncoder, $token)
{
$em = $this->getDoctrine()->getManager();
/** @var User $user */
$user = $em->getRepository(User::class)->findOneByToken($token);
$form = $this->createForm(ResetPasswordType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$password = $form->get('password')->getData();
$passwordencoded = $passwordEncoder->encodePassword($user, $password);
$user->setPassword($passwordencoded);
$user->setToken(null);
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
$this->addFlash(
'success',
'votre mot de passe est bien réinitialisé vous pouvez vous connecter'
);
return $this->redirectToRoute('login');
}
return $this->render('security/reset_password.html.twig', [
'form' => $form->createView(),
]);
}
класс GenerateToken {
public function generateToken()
{
$token= md5(uniqid(rand(), true));
return $token;
}
}
Спасибо, но мой объект имеет значение null, когда я набираю электронное письмо в форме, я не могу отправить письмо пользователю с моим событием из-за $ email = null