2012-04-03 17 views
13

Vorrei attivare conferma l'e-mail sul FOSUserBundle /profile/modificareconferma email su FOSUserBundle Modifica profilo

In /profile/modificare si è già connessi in ed è possibile modificare il nome utente o l'e-mail indirizzo che inserisce la password corrente. Ora vorrei inviare una mail di conferma se l'utente modificare l'indirizzo e-mail :)

Nel FOSUserBundle configurazione di riferimento non ho trovato un ambiente per fare questo ... https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/configuration_reference.md

Questi sono le mie impostazioni correnti:

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% 

Qualcuno può aiutarmi?

risposta

17

Utilizzando i nuovi eventi di FOSUserBundle (funzione FOS 2.0), è possibile creare un ChangeProfileListener che gestisca le modifiche all'e-mail.

L'idea: utilizzare la stessa logica di un processo di registrazione: disabilitare il nostro utente, inviarlo un token (e registrarlo per il nostro caso).

Ci sono due cose da fare:

  • creare un evento Subscriber
  • sovrascrivere il mail.txt.twig per sostituire il messaggio "registrazione" di un messaggio neutrale "e-mail di conferma".

Ecco il mio ascoltatore, non dimenticare di sostituire lo spazio dei nomi.

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 } 

Chi overwritting modello di email, che è solo la creazione di app/Resources/FOSUserBundle/views/registrazione/email.txt. ramoscello e mettere, ad esempio:

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

Questa soluzione ha comunque un problema quando l'utente cambia tutto il db è aggiornato. Se l'e-mail è sbagliata, come fanno a rientrare nel sistema? Non sarebbe meglio memorizzare la nuova email in un campo diverso? – lookbadgers

4

La funzionalità di inviare una mail di conferma esiste solo in

RegistrationFormHandler->onSucces 

in cui tale variabile di configurazione è passato e controllata. Una funzionalità simile non esiste nel profilo/edit:

ProfileFormHandler->onSuccess. 

Si avrebbe quindi bisogno di ignorare il FOS ProfileFormHandler e aggiungere questa funzionalità da soli. Questo è coperto nel FOSUserBundle documentation: Overriding Forms.

Problemi correlati