2015-12-22 9 views
9

Я использую свойство ResetsPasswords от laravel для реализации сброса пароля. То, что я хотел бы достичь, - отправить электронное письмо с помощью очереди. Рытье через код, который я нашел строку ниже в функции postEmail():Как отправить ссылку на сброс пароля по электронной почте с помощью очереди в laravel 5

$response = Password::sendResetLink($request->only('email'), function (Message $message) { 
      $message->subject($this->getEmailSubject()); 
     }); 

Копаем дальше, я заметил, что функция sendResetLink() реализован в классе PasswordBroker, который в свою очередь вызывает функцию emailResetLink(). Функция emailResetLink возвращает следующее:

return $this->mailer->send($view, compact('token', 'user'), function ($m) use ($user, $token, $callback) { 
      $m->to($user->getEmailForPasswordReset()); 

, который я могу просто изменить mailer->send к mailer->queue. Это лучший способ сделать это без изменения этого непроектного файла?

ответ

4

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

Первые вещи сначала вам нужно будет создать свой собственный PasswordBroker:

namespace App\Auth\Passwords; 

use Illuminate\Auth\Passwords\PasswordBroker as IlluminatePasswordBroker; 

class PasswordBroker extends IlluminatePasswordBroker 
{ 

    public function emailResetLink() 
    { 
     $view = $this->emailView; 

     return $this->mailer->queue($view, compact('token', 'user'), function ($m) use ($user, $token, $callback) { 
      $m->to($user->getEmailForPasswordReset()); 
      if (! is_null($callback)) { 
       call_user_func($callback, $m, $user, $token); 
      } 
     }); 
    } 

} 

Измените пространство имен, что вы хотите, если вы хотите разместить его в другом месте в вашем приложении.

Поскольку поставщик услуг, зарегистрировавший услугу, является deferred service provider, вам необходимо будет создать своего собственного поставщика, чтобы его заменить. Возможно, самый простой способ сделать это продлить Illuminate\Auth\Passwords\PasswordResetServiceProvider с чем-то вроде следующего:

namespace App\Providers; 

use App\Auth\Passwords\PasswordBroker; 

class PasswordResetServiceProvider extends \Illuminate\Auth\Passwords\PasswordResetServiceProvider 
{ 

    protected function registerPasswordBroker() 
    { 
     $this->app->singleton('auth.password', function ($app) { 
      $tokens = $app['auth.password.tokens']; 

      $users = $app['auth']->driver()->getProvider(); 

      $view = $app['config']['auth.password.email']; 

      return new PasswordBroker(
       $tokens, $users, $app['mailer'], $view 
      ); 
     }); 
    } 

} 

Наконец, в файле config/app.php удалить Illuminate\Auth\Passwords\PasswordResetServiceProvider::class и добавить App\Providers\PasswordResetServiceProvider::class в свой 'providers' массив.

Laravel теперь будет использовать вашу реализацию PasswordBroker, а не базу данных, и вам не придется беспокоиться о модификации кода рамки.

+0

Спасибо @ marcus.ramsden за ваш вклад. Я следил за вашим подходом, но я не могу понять, почему он не работает. Я не ошибаюсь. Кажется, что он по-прежнему вызывает 'emailResetLink' родительского класса вместо перезаписанного. –

+0

Извините, моя ошибка на примере в регистрационной части вашего поставщика услуг, которая должна быть '$ this-> app-> singleton' вместо' $ this-> app-> bind'.Также основным поставщиком услуг, регистрирующим вещи, является [отложенный поставщик] (http://laravel.com/docs/master/providers#deferred-providers). Через мгновение я кое-что обновлю. –

+0

Еще раз спасибо за ваш ввод. '$ this-> app-> singleton' тоже не делает этого. Все еще вызов родительского метода. –

5

Я знаю, что на это был дан ответ, но я нашел другой способ оповестить об ошибке сброса пароля, который я нашел намного проще. Я тестировал его на Laravel 5.3.

По умолчанию уведомление о сбросе пароля реализовано классом Illuminate\Auth\Notifications\ResetPassword. Этот класс создается в вашей модели User в sendPasswordResetNotification и передан методу notifyIlluminate\Notifications\Notifiable.

Так, в очередь пароль уведомления сброса вы можете просто создать новый класс ResetPassword уведомления через artisan make:notification ResetPassword и заменить его код с этим:

<?php 

namespace App\Notifications; 

use Illuminate\Bus\Queueable; 
use Illuminate\Contracts\Queue\ShouldQueue; 
use Illuminate\Auth\Notifications\ResetPassword as ResetPasswordNotification; 

class ResetPassword extends ResetPasswordNotification implements ShouldQueue 
{ 
    use Queueable; 
} 

А теперь просто переопределить sendPasswordResetNotification метод в App\User классе:

<?php 

... 
use App\Notifications\ResetPassword as ResetPasswordNotification; 
...  

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

Я думаю, что это лучший и простой, эта работа как шарм в L5.4. – Nisam

+0

. Соответствующая документация: https://laravel.com/docs/5.5/notifications#queueing -notifications – Lemmings19

+0

Чтобы указать очередь: '$ this- > notify ((new ResetPasswordNotification ($ token)) -> onQueue ('queue-name')); ' – Lemmings19

Смежные вопросы