Изменение письма сброса пароля (Reset Password) в Laravel 5
- DeveloperNotes »
- Laravel 5 »
- Изменение письма сброса пароля (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-файл, думаю с этим не составит труда разобраться самостоятельно.
Комментарии