2012-04-03 13 views
13

chciałbym aktywować potwierdzenie pocztą elektroniczną na FOSUserBundle /profile/editpotwierdzenie email na FOSUserBundle profil Edytuj

W /profile/edit jesteś już zalogowany i można edytować nazwę użytkownika lub e-mail adres wpisujący bieżące hasło. Teraz chciałbym wysłać email z potwierdzeniem, jeśli użytkownik zmień adres e-mail :)

W FOSUserBundle Reference Configuration nie znalazłem ustawienie to zrobić ... https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/configuration_reference.md

These są moje bieżące ustawienia:

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% 

Ktoś może mi pomóc?

Odpowiedz

17

Korzystając z nowych zdarzeń FOSUserBundle (funkcja FOS 2.0), można utworzyć ChangeProfileListener, które obsługują zmiany e-mail.

Pomysł: użyj tej samej logiki co proces rejestracji: wyłącz naszego użytkownika, wyślij mu token (i wyloguj go dla naszej sprawy).

Nie ma dwie rzeczy do zrobienia:

  • utworzyć wydarzenie suscriber
  • nadpisać mail.txt.twig zastąpić komunikat „Rejestracja” za pomocą wiadomości e-mail „neutralnym” potwierdzeniem.

Oto mój słuchacz, nie zapomnij zastąpić przestrzeni nazw.

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 } 

O overwritting szablonu e-mail, który jest po prostu tworzenie aplikacji/Resources/FOSUserBundle/widoki/rejestracji/email.txt. twig and put, na przykład:

{% 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

To rozwiązanie ma jednak problem, gdy użytkownik zmieni je o ile baza danych jest zaktualizowana. Jeśli adres e-mail jest błędny, w jaki sposób odzyskają system? Czy nie byłoby lepiej przechowywać nowy e-mail w innym polu? – lookbadgers

4

Funkcjonalność, aby wysłać e-mail z potwierdzeniem istnieje tylko w

RegistrationFormHandler->onSucces 

gdzie zmienna konfiguracja jest przekazywana i sprawdzone. Podobną funkcjonalność nie istnieje w profilu/edit:

ProfileFormHandler->onSuccess. 

Można by zatem trzeba zastąpić FOS ProfileFormHandler i dodać tę funkcjonalność siebie. Jest to opisane w FOSUserBundle documentation: Overriding Forms.