Sử dụng sự kiện FOSUserBundle mới (tính năng FOS 2.0), bạn có thể tạo ChangeProfileListener
xử lý các thay đổi email.
Ý tưởng: sử dụng cùng một logic như một quá trình đăng ký: vô hiệu hóa người dùng của chúng tôi, gửi cho anh ta một mã thông báo (và đăng xuất-anh ta ra cho trường hợp của chúng tôi).
Có hai điều cần làm:
- tạo một sự kiện suscriber
- ghi đè lên mail.txt.twig để thay thế cho "đăng ký" Thông điệp của một "xác nhận email" trung lập tin nhắn.
Đây là người nghe của tôi, đừng quên thay thế không gian tên.
EventListener/ChangeProfileListener.php:
<?php
// src/Fuz/HomeBundle/EventListener/ChangeProfileListener.php
namespace Fuz\HomeBundle\EventListener;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\GetResponseUserEvent;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Mailer\MailerInterface;
use FOS\UserBundle\Util\TokenGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class ChangeProfileListener implements EventSubscriberInterface
{
private $mailer;
private $tokenGenerator;
private $router;
private $session;
private $tokenStorage;
public function __construct(MailerInterface $mailer, TokenGeneratorInterface $tokenGenerator,
UrlGeneratorInterface $router, SessionInterface $session, TokenStorageInterface $tokenStorage)
{
$this->mailer = $mailer;
$this->tokenGenerator = $tokenGenerator;
$this->router = $router;
$this->session = $session;
$this->tokenStorage = $tokenStorage;
}
public static function getSubscribedEvents()
{
return array(
FOSUserEvents::PROFILE_EDIT_INITIALIZE => 'onProfileEditInitialize',
FOSUserEvents::PROFILE_EDIT_SUCCESS => 'onProfileEditSuccess',
);
}
public function onProfileEditInitialize(GetResponseUserEvent $event)
{
// required, because when Success's event is called, session already contains new email
$this->email = $event->getUser()->getEmail();
}
public function onProfileEditSuccess(FormEvent $event)
{
$user = $event->getForm()->getData();
if ($user->getEmail() !== $this->email)
{
// disable user
$user->setEnabled(false);
// send confirmation token to new email
$user->setConfirmationToken($this->tokenGenerator->generateToken());
$this->mailer->sendConfirmationEmailMessage($user);
// force user to log-out
$this->tokenStorage->setToken();
// redirect user to check email page
$this->session->set('fos_user_send_confirmation_email/email', $user->getEmail());
$url = $this->router->generate('fos_user_registration_check_email');
$event->setResponse(new RedirectResponse($url));
}
}
}
services.yml:
parameters:
fuz_home.email_change.listener.class: Fuz\HomeBundle\EventListener\ChangeProfileListener
services:
fuz_home.email_change.listener:
class: %fuz_home.email_change.listener.class%
arguments: ['@fos_user.mailer', '@fos_user.util.token_generator', '@router', '@session', '@security.token_storage']
tags:
- { name: kernel.event_subscriber }
Về overwritting mẫu email, đó chỉ là việc tạo ra ứng dụng/Resources/FOSUserBundle/views/đăng ký/email.txt. cành và đặt, ví dụ:
{% block subject %}
Email Confirmation
{% endblock %}
{% block body_text %}
Welcome to example.com, {{ user.username }}!
To confirm your email, please follow this link:
{{ confirmationUrl }}
You will be able to log-in using the username or email you given:
Username : {{ user.username }}
Email : {{ user.email }}
If you received this e-mail in error just ignore this message. No further actions are required from you.
*****
See you soon!
{% endblock %}
Giải pháp này có vấn đề khi người dùng thay đổi ail db được cập nhật. Nếu email sai thì làm cách nào để họ quay lại hệ thống? Nó sẽ không tốt hơn để lưu trữ email mới trong một lĩnh vực khác? – lookbadgers