11
votes

I am trying to customize password reset email in Laravel.

I have to override this function:

namespace Illuminate\Auth\Passwords;

use Illuminate\Auth\Notifications\ResetPassword as ResetPasswordNotification;
use Illuminate\Http\Request;


trait CanResetPassword
{
    /**
     * Get the e-mail address where password reset links are sent.
     *
     * @return string
     */
    public function getEmailForPasswordReset()
    {
        return $this->email;
    }

    /**
     * Send the password reset notification.
     *
     * @param  string  $token
     * @return void
     */

public function sendPasswordResetNotification($token)
{

    $this->notify(new ResetPasswordNotification($token));

}

This is my attempt:

 public function sendPasswordResetNotification($token, Requests $request)
{
Mail::to($request->email)->send(new newpassword($token));
}

I get this error:

Declaration of Illuminate\Foundation\Auth\User::sendPasswordResetNotification($token, Illuminate\Http\Request $request) must be compatible with Illuminate\Contracts\Auth\CanResetPassword::sendPasswordResetNotification($token)

2

2 Answers

14
votes

If you read the error, it's telling you your class is not compatible with CanResetPassword. If you look at that....

interface CanResetPassword
{
    /**
     * Get the e-mail address where password reset links are sent.
     *
     * @return string
     */
    public function getEmailForPasswordReset();
    /**
     * Send the password reset notification.
     *
     * @param  string  $token
     * @return void
     */
    public function sendPasswordResetNotification($token);
}

You can see the function sendPasswordResetNotification should only take one parameter, $token. So you need to remove Request $request as a parameter from the method's signature.

In order to get the request, you will want to use the function request() inside the sendPasswordResetNotification method.

public function sendPasswordResetNotification($token)
{
    Mail::to(request()->email)->send(new newpassword($token));
}
11
votes

I'm surprised you're going to that length to customize the email.

Try this instead:

php artisan vendor:publish

Then modify the file here

/resources/views/vendor/notifications/email.blade.php

Works great for our usage.

user@default:~/laravel_5.4$ php artisan vendor:publish
Copied Directory [/vendor/laravel/framework/src/Illuminate/Pagination/resources/views] To [/resources/views/vendor/pagination]
Copied Directory [/vendor/laravel/framework/src/Illuminate/Notifications/resources/views] To [/resources/views/vendor/notifications]
Copied Directory [/vendor/laravel/framework/src/Illuminate/Mail/resources/views] To [/resources/views/vendor/mail]
Publishing complete.

Now if you NEED to change the copy and you want the fancy button that the original ResetPassword class uses, you can extend the mail class in your User.php class like the following example.

Here's a copy of ours that works great AS AN EXAMPLE ONLY:

<?php

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Auth\Notifications\ResetPassword;
use Illuminate\Notifications\Messages\MailMessage;

class User extends Authenticatable
{
    use Notifiable;

    protected $table = 'Users';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'firstName',
        'lastName',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * Sends the password reset notification.
     *
     * @param  string $token
     *
     * @return void
     */
    public function sendPasswordResetNotification($token)
    {
        $this->notify(new CustomPassword($token));
    }
}

class CustomPassword extends ResetPassword
{
    public function toMail($notifiable)
    {
        return (new MailMessage)
            ->line('We are sending this email because we recieved a forgot password request.')
            ->action('Reset Password', url(config('app.url') . route('password.reset', $this->token, false)))
            ->line('If you did not request a password reset, no further action is required. Please contact us if you did not submit this request.');
    }
}