【laravel5.8】ログイン関連ページ、バリデーションメッセージ、メールの日本語化

```php artisan make:auth```でログイン機能を追加して、```$this->middleware('verified');```
などでメール認証を追加した。
その際に追加されたログイン関連ページ、バリデーションメッセージ、メールが英語だったので日本語化する。

ログイン関連ページとバリデーションメッセージの日本語化は簡単にできたけど、メールが大変だった。

# 環境
- PHP: 7.3.8
- Laravel: 5.8.35

# ログイン関連ページとバリデーションメッセージの日本語化

`config/app.php`の`locale`と`fallback_locale`を`en`から`ja`に変更する。

```config/app.php
/*
// 省略
    |--------------------------------------------------------------------------
    | Application Locale Configuration
    |--------------------------------------------------------------------------
    |
    | The application locale determines the default locale that will be used
    | by the translation service provider. You are free to set this value
    | to any of the locales which will be supported by the application.
    |
    */

    'locale' => 'ja',

    /*
    |--------------------------------------------------------------------------
    | Application Fallback Locale
    |--------------------------------------------------------------------------
    |
    | The fallback locale determines the locale to use when the current one
    | is not available. You may change the value to correspond to any of
    | the language folders that are provided through your application.
    |
    */

    'fallback_locale' => 'ja',
// 省略
```

`resource/lang`直下に`ja`ディレクトリを作成し、`resource/lang/en`ディレクトリ直下のファイルを`ja`ディレクトリに全てコピーする。

```resource/lang/en/validation.php
<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Validation Language Lines
    |--------------------------------------------------------------------------
    |
    | The following language lines contain the default error messages used by
    | the validator class. Some of these rules have multiple versions such
    | as the size rules. Feel free to tweak each of these messages here.
    |
    */

    'accepted' => 'The :attribute must be accepted.', // 右側のvalueを日本語化する
    'active_url' => 'The :attribute is not a valid URL.',
    'after' => 'The :attribute must be a date after :date.',
    'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
    'alpha' => 'The :attribute may only contain letters.',
    // 省略
];

```

`validation.php`を例に挙げると、戻り値の配列に連想配列が指定されており、
その連想配列のvalueを日本語に直す。
有志が日本語に直してくれているので、ググって持ってきてもよい。

`resources/views/auth/login.blade.php`などにある`{{ __('E-Mail Address') }}`や`{{ __('Password') }}`の日本語化を行う。`resources/lang`直下に`ja.json`を作成する。

```resources/lang/ja.json
{
    "E-Mail Address": "メールアドレス",
    "Password": "パスワード"
} 
```

他にも日本語化したい内容があれば、追加で記述する。


# メールの日本語化
以下の2つの作業が必要。
1. 新規にNotificationを作成し、Userモデルで継承しメソッドを使用するようにする
2. viewの日本語化

## Notificationの作成と継承
```
php artisan make:notification [好きな名前]
```

上記のコマンドでNotificationを作成する。名前を好きなものでよい。
パスワードリセットメールとメール認証メールのために、2つ作成する。
ここでは、パスワードリセット用を、`ResetPasswordJa`とし、メール認証用を`VerifyEmailJa`とした。
基のResetPassword(`vendor/laravel/framework/src/Illuminate/Auth/Notifications/ResetPassword.php`)とVerifyEmail(`vendor/laravel/framework/src/Illuminate/Auth/Notifications/VerifyEmail.php`)の内容をコピペし、`toMail`メソッドの中身を日本語に書き換える。


```app/Notifications/ResetPasswordJa.php
<?php
namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
class ResetPasswordJa extends Notification
{
    use Queueable;
    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct($token)
    {
        $this->token = $token;
    }
    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail'];
    }
    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        return (new MailMessage)
            ->from('admin@example.com', config('app.name'))
            ->subject('パスワード再発行')
            ->line('パスワード再発行リクエストがありましたので、メッセージ送信しました。')
            ->action('パスワード再設定', url(config('app.url').route('password.reset', $this->token, false)))
            ->line('もし心当たりがない場合は、本メッセージは破棄してください。');
    }
    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}
```

```app/Notifications/VerifyEmailJa.php

<?php
namespace App\Notifications;

use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Facades\Lang;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;
class VerifyEmailJa extends Notification
{
    /**
     * The callback that should be used to build the mail message.
     *
     * @var \Closure|null
     */
    public static $toMailCallback;
    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    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);
        }
        return (new MailMessage)
            ->subject(Lang::getFromJson('本登録メール'))
            ->line(Lang::getFromJson('以下の認証リンクをクリックして本登録を完了させてください。'))
            ->action(
                Lang::getFromJson('メールアドレスを認証する'),
                $this->verificationUrl($notifiable)
            )
            ->line(Lang::getFromJson('もしこのメールに覚えが無い場合は破棄してください。'));
    }
    
    /**
     * Get the verification URL for the given notifiable.
     *
     * @param  mixed  $notifiable
     * @return string
     */
    protected function verificationUrl($notifiable)
    {
        return URL::temporarySignedRoute(
            'verification.verify', Carbon::now()->addMinutes(60), ['id' => $notifiable->getKey()]
        );
    }
    /**
     * 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;
    }
}
```

`app/User.php`においてこの2つを`use`宣言し、`sendPasswordResetNotification`メソッドと`sendEmailVerificationNotification`メソッドをオーバーライドして書き換える。

```app/User.php
// 省略
use App\Notifications\ResetPasswordJa as ResetPasswordNotificationJa;
use App\Notifications\VerifyEmailJa as VerifyEmailNotificationJa;
// 省略
public function sendPasswordResetNotification($token)
    {
        $this->notify(new ResetPasswordNotificationJa($token));
    }

public function sendEmailVerificationNotification()
    {
        $this->notify(new VerifyEmailNotificationJa());
    }
```



## viewの日本語化
メールのviewが見えていないので、`php artisan vendor:publish`を実行する。
`resources/views/vendor/notifications/email.blade.php`が作成されるので編集する。
以下のように英語の部分を書き換える。

```resources/views/vendor/notifications/email.blade.php
@component('mail::message')
{{-- Greeting --}}
@if (! empty($greeting))
# {{ $greeting }}
@else
@if ($level === 'error')
# @lang('Whoops!')
@else
# @lang('こんにちは。')
@endif
@endif

{{-- Intro Lines --}}
@foreach ($introLines as $line)
{{ $line }}

@endforeach

{{-- Action Button --}}
@isset($actionText)
<?php
    switch ($level) {
        case 'success':
        case 'error':
            $color = $level;
            break;
        default:
            $color = 'primary';
    }
?>
@component('mail::button', ['url' => $actionUrl, 'color' => $color])
{{ $actionText }}
@endcomponent
@endisset

{{-- Outro Lines --}}
@foreach ($outroLines as $line)
{{ $line }}

@endforeach

{{-- Salutation --}}
@if (! empty($salutation))
{{ $salutation }}
@else
{{ config('app.name') }}
@lang('より')
@endif

{{-- Subcopy --}}
@isset($actionText)
@slot('subcopy')
@lang(
    "もし、\":actionText\"ボタンがうまく機能しない場合、\n以下のURLをコピーしてください。\n".
    ': [:actionURL](:actionURL)',
    [
        'actionText' => $actionText,
        'actionURL' => $actionUrl,
    ]
)
@endslot
@endisset
@endcomponent
```

以上で一通り日本語になっていると思います。
いつか書き直します。