2012-04-03 37 views
13

Tôi muốn kích hoạt email xác nhận trên FOSUserBundle /profile/chỉnh sửaxác nhận email trên FOSUserBundle Hồ Sơ Sửa

Trong /profile/chỉnh sửa bạn đã đăng nhập và bạn có thể chỉnh sửa tên người dùng hoặc email địa chỉ nhập mật khẩu hiện tại. Bây giờ tôi muốn gửi một email xác nhận nếu người dùng chỉnh sửa địa chỉ email :)

Trong FOSUserBundle Cấu hình tham khảo tôi đã không tìm thấy một thiết lập để làm điều này ... https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/configuration_reference.md

Những là cài đặt hiện tại của tôi:

fos_user: 
    db_driver: orm 
    firewall_name: main 
    user_class: Acme\CoreBundle\Entity\User 
    registration: 
    confirmation: { enabled: true } 
    from_email: 
    address: [email protected]%domain% 
    sender_name: %site_name% Staff 
    resetting: 
    token_ttl: %reset_password_ttl% 

Ai đó có thể giúp tôi?

Trả lời

17

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 %} 
+1

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

4

Chức năng để gửi một email xác nhận chỉ tồn tại trong

RegistrationFormHandler->onSucces 

nơi mà biến cấu hình được thông qua và kiểm tra. Chức năng tương tự không tồn tại trong tiểu sử/chỉnh sửa:

ProfileFormHandler->onSuccess. 

Do đó, bạn cần ghi đè FOS ProfileFormHandler và tự thêm chức năng này. Điều này được bao gồm trong số FOSUserBundle documentation: Overriding Forms.