Laravel 5.7 パスワードリセットの日本語化

[こちらはブログでも掲載しています。](https://ksysnote.com/php/reset-password/)

<!-- wp:paragraph -->
<p>前回、メールアドレスの確認と日本語化したのですが、パスワードリセットでも英文のメールが送られていたので、こちらも日本語化をしたいと思います。</p>
<!-- /wp:paragraph -->

<!-- wp:embed {"url":"https://ksysnote.com/php/verify-email/","type":"rich","providerNameSlug":"開発ログ","className":""} -->
<figure class="wp-block-embed is-type-rich is-provider-開発ログ"><div class="wp-block-embed__wrapper">
</div></figure>
<!-- /wp:embed -->


[Laravel 5.7 メールアドレスの確認を日本語化も含めて実装する](https://ksysnote.com/php/verify-email)

<!-- wp:paragraph -->
<p>ユーザー認証は以下のコマンドで実装されているものとします。</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>php artisan make:auth</code></pre>
<!-- /wp:code -->

<!-- wp:heading -->
<h2>ビューの日本語化</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>まずは、パスワードリセットの画面を日本語化します。</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>./resources/views/auth
├── passwords
│   ├── email.blade.php
│   └── reset.blade.php</code></pre>
<!-- /wp:code -->

<!-- wp:code -->
<pre class="wp-block-code"><code>@extends('layouts.app')

@section('content')
&lt;div class="container">
    &lt;div class="row justify-content-center">
        &lt;div class="col-md-8">
            &lt;div class="card">
                &lt;div class="card-header">{{ __('message.password_reset.title') }}&lt;/div>

                &lt;div class="card-body">
                    @if (session('status'))
                        &lt;div class="alert alert-success" role="alert">
                            {{ session('status') }}
                        &lt;/div>
                    @endif

                    &lt;form method="POST" action="{{ route('password.email') }}">
                        @csrf

                        &lt;div class="form-group row">
                            &lt;label for="email" class="col-md-4 col-form-label text-md-right">{{ __('message.user.field.email') }}&lt;/label>

                            &lt;div class="col-md-6">
                                &lt;input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required>

                                @if ($errors->has('email'))
                                    &lt;span class="invalid-feedback" role="alert">
                                        &lt;strong>{{ $errors->first('email') }}&lt;/strong>
                                    &lt;/span>
                                @endif
                            &lt;/div>
                        &lt;/div>

                        &lt;div class="form-group row mb-0">
                            &lt;div class="col-md-6 offset-md-4">
                                &lt;button type="submit" class="btn btn-primary">
                                    {{ __('message.button.send') }}
                                &lt;/button>
                            &lt;/div>
                        &lt;/div>
                    &lt;/form>
                &lt;/div>
            &lt;/div>
        &lt;/div>
    &lt;/div>
&lt;/div>
@endsection</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>翻訳ファイルも変更します。(./resources/lang/ja/message.php）</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>&lt;?php
return [
    // ボタン
    "button" => [
        "send" => '　送信　',
    ],
    // ユーザ情報
    "user" => [
        "field" => [
            "email" => "メールアドレス",
        ]
    ],
    // パスワードリセット
    "password_reset" => [
        'title' => 'パスワードリセット'
    ],
];
</code></pre>
<!-- /wp:code -->

<!-- wp:heading -->
<h2>送信メールの日本語化</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>まずは、パスワードリセットをしたときにどこでメールを送っているのかを確認します。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Userモデルが<em>Authenticatable（</em>Illuminate\Foundation\Auth\User）を継承しています。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>その中で、CanResetPasswordというtraitを呼び出しています。</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>class User extends Model implements
    AuthenticatableContract,
    AuthorizableContract,
    CanResetPasswordContract
{
    use Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail;
}</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>CanResetPasswordの中身を見ると、sendPasswordResetNotificationでメールを送っているので、こちらをカスタマイズしていきます。</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>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));
    }
}</code></pre>
<!-- /wp:code -->

<!-- wp:heading {"level":3} -->
<h3>カスタムのNotificationを作成する</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>artisanを利用して、カスタムのNotificationを作成します。</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>php artisan make:notification RestPasswordCustom</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>./app/Notifications/にファイルが作成されるので、もともとパスワードリセットで使用されているRestPasswordNotification(Illuminate\Auth\Notifications\ResetPassword)を参考に編集をいたします。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>変更箇所はtoMailの中で、英文をセットしている箇所を日本語に置き換えるだけです。</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>namespace App\Notifications;

use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Support\Facades\Lang;

class RestPasswordCustom extends Notification
{
    /**
     * The password reset token.
     *
     * @var string
     */
    public $token;

    /**
     * The callback that should be used to build the mail message.
     *
     * @var \Closure|null
     */
    public static $toMailCallback;

    /**
     * Create a notification instance.
     *
     * @param  string  $token
     * @return void
     */
    public function __construct($token)
    {
        $this->token = $token;
    }

    /**
     * Get the notification's channels.
     *
     * @param  mixed  $notifiable
     * @return array|string
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * Build the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        if (static::$toMailCallback) {
            return call_user_func(static::$toMailCallback, $notifiable, $this->token);
        }

        return (new MailMessage)
            ->subject(Lang::getFromJson('message.mail.password_reset.title'))
            ->line(Lang::getFromJson('message.mail.password_reset.line'))
            ->action(Lang::getFromJson('message.mail.password_reset.action'), url(config('app.url').route('password.reset', $this->token, false)))
            ->line(Lang::getFromJson('message.mail.password_reset.out_line1', ['count' => config('auth.passwords.users.expire')]))
            ->line(Lang::getFromJson('message.mail.password_reset.out_line2'));
    }

    /**
     * Set a callback that should be used when building the notification mail message.
     *
     * @param  \Closure  $callback
     * @return void
     */
    public static function toMailUsing($callback)
    {
        static::$toMailCallback = $callback;
    }
}</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>翻訳ファイルは</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>&lt;?php

return [
    // メール
    "mail" => [
        // パスワードリセット
        "password_reset" => [
            "title" => "パスワードリセットのお知らせ",
            "line" => "パスワードリセットの受け付けました。",
            "action" => "パスワードリセット",
            "out_line1" => "こちらのパスワードリセットの有効期限は :count 分です。",
            "out_line2" => "こちらのメールに身に覚えがない場合は、無視をしてください。"
        ]
    ],
];
</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>以上、パスワードリセットの日本語化は終わりです。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Laravelはtraitを多様していますので、何かあればその中身を調査するようにしています（ーー；</p>
<!-- /wp:paragraph -->