5

Using Laravel 5, I need 2 different views for password reset email. The default path to the email view is emails.password. But upon some conditions, I want to send emails.password_alternative.

How can I do this? (with PasswordBroker from Laravel)

This is my current code:

public function __construct(Guard $auth, PasswordBroker $passwords)
{
    $this->auth = $auth;
    $this->passwords = $passwords;
}

public function sendReset(PasswordResetRequest $request)
{
    //HERE : If something, use another email view instead of the default one from the config file
    $response = $this->passwords->sendResetLink($request->only('email'), function($m)
    {
        $m->subject($this->getEmailSubject());
    });
}
Kalzem
  • 7,320
  • 6
  • 54
  • 79

2 Answers2

7

For anyone interested in Laravel 5.2 you can set a custom html and text email view for password reset by adding

config(['auth.passwords.users.email' => ['auth.emails.password.html', 'auth.emails.password.text']]);

to the PasswordController.php in the constructor before the middleware call.

This overrides the app/config/auth.php setup for the PasswordBroker.

Blade Template for the password reset email is then located at:

yourprojectname/resources/views/auth/emails/password/html.blade.php yourprojectname/resources/views/auth/emails/password/text.blade.php

Took me long enough.

Credits: http://ericlbarnes.com/2015/10/14/how-to-send-both-html-and-plain-text-password-reset-emails-in-laravel-5-1/ http://academe.co.uk/2014/01/laravel-multipart-registration-and-reminder-emails/

metanerd
  • 713
  • 1
  • 6
  • 21
4

Using PasswordBroker and based on the Illuminate/Auth/Passwords/PasswordBroker.php class, the $emailView is a protected variable, so you can't change the value once the class is instantiated.

However, you have a couple of solutions:

  1. You can create your own class that extends PasswordBroker and use that.

    class MyPasswordBroker extends PasswordBroker {
        public function setEmailView($view) {
            $this->emailView = $view;
        }
    }
    
    // (...)
    
    public function __construct(Guard $auth, MyPasswordBroker $passwords)
    {
        $this->auth = $auth;
        $this->passwords = $passwords;
    }
    
    public function sendReset(PasswordResetRequest $request)
    {
        if ($someConditionHere) {
            $this->passwords->setEmailView('emails.password_alternative');
        }
        $response = $this->passwords->sendResetLink($request->only('email'), function($m)
        {
            $m->subject($this->getEmailSubject());
        });
    }
    
  2. You could create the PasswordBroker within your method, without using Dependency Injection.

    public function sendReset(PasswordResetRequest $request)
    {
        $emailView = 'emails.password';
    
        if ($someConditionHere) {
            $emailView = 'emails.password_alternative';
        }
    
        $passwords = new PasswordBroker(
            App::make('TokenRepositoryInterface'),
            App::make('UserProvider'),
            App::make('MailerContract'),
            $emailView
        );
    
        $response = $passwords->sendResetLink($request->only('email'), function($m)
        {
            $m->subject($this->getEmailSubject());
        });
    }
    

    This is an uglier solution and if you have automated tests this will be a pain to work with.

Disclaimer: I've not tested any of this code.

Luís Cruz
  • 14,780
  • 16
  • 68
  • 100
  • Oh, I forgot to mention I am using Laravel PasswordBroker – Kalzem Mar 27 '16 at 00:19
  • Is there a reason why the variable is protected with no setter? Or did Laravel set it to protected because they didn't think of a case where people would like to change it? – Kalzem Mar 27 '16 at 12:03
  • I'm guessing they didn't thought about that. The best way to find out is to create a GitHub Issue and discuss that with Laravel's main developers. – Luís Cruz Mar 27 '16 at 14:20