web-dev-qa-db-ja.com

laravel 5)のキューを使用してメールでパスワードリセットリンクを送信する方法

私はResetsPasswordsトレイトをlaravelで使用して、パスワードのリセットを実装しています。達成したいのは、キューを使用してメールを送信することです。コードを掘り下げると、関数postEmail()で次の行が見つかりました。 :

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

さらに掘り下げてみると、sendResetLink()関数がPasswordBrokerクラスに実装されており、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。この非プロジェクトファイルを変更せずにそれを行うためのより良い方法はありますか?

13
Fokwa Best

ここで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);
            }
        });
    }

}

アプリの他の場所に名前空間を配置する場合は、名前空間を任意の名前空間に変更します。

サービスを登録しているサービスプロバイダーは 据え置きサービスプロバイダー であるため、それを置き換えるために独自のプロバイダーを作成する必要があります。おそらくこれを行う最も簡単な方法は、次のようなもので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の実装を使用するようになり、フレームワークコードの変更について心配する必要はありません。

4
marcus.ramsden

私はこれが答えられたことを知っていますが、パスワードリセット通知をキューに入れる別の方法を見つけました。これははるかに簡単でした。私はそれをLaravel 5.でテストしました。

デフォルトでは、パスワードリセット通知はIlluminate\Auth\Notifications\ResetPasswordクラスによって実装されます。このクラスは、UserメソッドのsendPasswordResetNotificationモデルでインスタンス化され、Illuminate\Notifications\Notifiableトレイトのnotifyメソッドに渡されます。

したがって、パスワードリセット通知をキューに入れるには、artisan make:notification ResetPasswordを介して新しい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;
}

そして、App\UserクラスのsendPasswordResetNotificationメソッドをオーバーライドするだけです。

<?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));
}
19
fakemeta

キューfakemetaのソリューションを指定しようとした後、「nullでメンバー関数onQueue()を呼び出す」というメッセージが表示された場合は、クラスのコンストラクターでターゲットとするキューを指定するだけです。

<?php
namespace App;

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

class ResetPasswordNotification extends ResetPassword implements ShouldQueue
{
    use Queueable;

    public function __construct()
    {
        $this->queue = "authentication";
    }
}

次に、通知ファサードを使用して、オーバーライドする方法でメールを送信します。通知メソッドも機能します

<?php
namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\ResetPasswordNotification;

class User extends Authenticatable
{
    public function sendPasswordResetNotification($token)
    {
        // either of the two work
        // $this->notify(new ResetPasswordNotification($token));
        \Notification::send($this, new ResetPasswordNotification($token));
    }
}
1
Stephen Mudere