2012-04-03 11 views
13

Ich mag würde die E-Mail-Bestätigung auf FOSUserBundle /profile/bearbeitenE-Mail Bestätigung auf FOSUserBundle Profil bearbeiten

In /profile/bearbeiten aktivieren Sie bereits angemeldet sind, und Sie können den Benutzernamen oder die E-Mail bearbeiten Adresse eingeben, um das aktuelle Passwort einzugeben. Nun würde Ich mag eine Bestätigungs-Email zu senden, wenn der Benutzer die E-Mail-Adresse bearbeiten :)

Im FOSUserBundle Konfigurationsreferenz ich eine Einstellung nicht, dies zu tun ... https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/configuration_reference.md

These gefunden habe sind meine aktuellen Einstellungen:

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% 

Jemand kann mir helfen?

Antwort

17

Mithilfe der neuen FOSUserBundle-Ereignisse (FOS 2.0-Funktion) können Sie eine ChangeProfileListener erstellen, die E-Mail-Änderungen verarbeitet.

Die Idee: Verwenden Sie die gleiche Logik wie ein Registrierungsprozess: deaktivieren Sie unseren Benutzer, senden Sie ihm ein Token (und ihn für unseren Fall abmelden).

Es gibt zwei Dinge zu tun:

  • ein Ereignis erstellen Subscriber
  • die mail.txt.twig überschreibt die „Registrierung“ Nachricht durch einen neutralen „E-Mail-Bestätigung“ -Nachricht zu ersetzen.

Hier ist mein Listener, vergessen Sie nicht, Namespace zu ersetzen.

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 } 

Über E-Mail-Vorlage overwritting, das ist die Erstellung nur app/Resources/FOSUserBundle/views/Anmeldung/email.txt. twig and put, zum Beispiel:

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

Diese Lösung hat jedoch ein Problem, wenn der Benutzer die em ändert ail die db wird aktualisiert. Wenn die E-Mail falsch ist, wie kommen sie wieder ins System? Wäre es nicht besser, die neue E-Mail in einem anderen Feld zu speichern? – lookbadgers

4

Die Funktionalität eine Bestätigungsmail existiert nur in

RegistrationFormHandler->onSucces 

wo die Konfigurationsvariable übergeben wird und geprüft, um zu senden. Eine ähnliche Funktionalität existiert nicht im Profil/edit:

ProfileFormHandler->onSuccess. 

Sie daher die FOS ProfileFormHandler und fügen Sie diese Funktionalität selbst außer Kraft zu setzen müssten. Dies ist in der FOSUserBundle documentation: Overriding Forms abgedeckt.