Изменение письма сброса пароля (Reset Password) в Laravel 5

Laravel 5 предсотавляет стандартную реализацию регистрации и авторизации пользователей, которую можно добавить в проект через команду:

php artisan make:auth

И это очень удобно. Но в ней отсутствует две критически важные вещи: подтверждение почты пользователя и письмо сброса пароля. В этот раз поговорим о втором и попробуем переписать код полность, чтобы мы могли изменять это письмо как нам угодно и отсылать его самостоятельно.

В чем проблема изменения письма сброса пароля?

Если дизайн письма сброса пароля собирается по шаблонам, которые можно опубликовать и изменить, то с текстом письма дело обстоит гораздо хуже. Текст письма "вшит" в код намертво, а его и располагается в файле:

/vendor/laravel/framework/src/Illuminate/Auth/Notifications/ResetPassword.php

И метод выглядит вот так:


public function toMail($notifiable)
{
    if (static::$toMailCallback) {
        return call_user_func(static::$toMailCallback, $notifiable, $this->token);
    }

    return (new MailMessage)
        ->line('You are receiving this email because we received a password reset request for your account.')
        ->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.');
}

Разумеется, нельзя менять текст прямо тут. Иначе при установке вашего проекта на другой сервер и исполнении composer update вы потеряете все изменения, внесенные в файлы каталога vendor.

Давайте изменим это чертово письмо!

Изменения, которые нужно внести в код, сначала могут показаться очень странными и даже не логичными. Поэтому сначала проследим логику работы этой страшной машины.

Во-первых, обратим внимание, что модель User наследует определенный класс:


use Illuminate\Foundation\Auth\User as Authenticatable;
...
class User extends Authenticatable{

Обратите внимание, наследуется Authenticatable, но на самом деле это Illuminate\Foundation\Auth\User.

Если мы откроем класс Illuminate\Foundation\Auth\User, то мы увидим следующий код:


use Illuminate\Auth\Passwords\CanResetPassword;
...
class User extends Model implements
    AuthenticatableContract,
    AuthorizableContract,
    CanResetPasswordContract
{
    use Authenticatable, Authorizable, CanResetPassword;
}

Мы видим, что этот класс наследуется от Model и его наследование нас не интересует. Зато он включает в себя три трейта и один из них называется CanResetPassword и располагается по адресу

Illuminate\Auth\Passwords\CanResetPassword

Давайте откроем его.

Открыв его, мы видим следующий код:


use Illuminate\Auth\Notifications\ResetPassword as ResetPasswordNotification;

trait CanResetPassword
{
  public function getEmailForPasswordReset()
    {
        return $this->email;
    }

    public function sendPasswordResetNotification($token)
    {
        $this->notify(new ResetPasswordNotification($token));
    }
}

Смотрите, здесь есть метод sendPasswordResetNotification, принимающий токен сброса пароля. И внутри него как раз и происходит отсылка того самого Notification, который мы видели в самом начале статьи! Вот оно, ура!

Получается, что нам нужно изменить файл модели пользователя User.php и переопределить там именно этот метод. Давайте сделаем это. Я не стал приводить весь код, привел только необходимый нам метод.


namespace App;

class User extends Authenticatable
{
	...
    public function sendPasswordResetNotification($token)
    {
 		Mail::send('emails.reset_password', ['user' => $user], function ($m) use ($user) {
            $m->from('hello@app.com', 'Your Application');
            $m->to($user->email, $user->name)->subject('Your Password Reset!');
        });
    }
	...
}

Замечу только, что хорошей идеей было бы отправлять письма через очереди (queue), но об этом как-нибудь в другой раз.

Вуаля, дело сделано! Теперь при отсылке письма восстановления пароля обращение будет совершаться к нашему переопределенному методу. Где мы можем отправить такое письмо, какое хотим. Приводить пример непосредственно отправки я не буду, как и прикладывать view-файл, думаю с этим не составит труда разобраться самостоятельно.

Комментарии

Комментариев пока нет. Станьте первым! Конечно, если вы не хотите написать мне гадости.
Обязательное поле.
Подсказка по Markdown, используется для оформления.

DeveloperNotes.ru © 2018 — 2020