Laravel 5.7 メールアドレスの確認を日本語化も含めて実装する

[こちらの内容はブログの方にも記載しています。](https://ksysnote.com/wp-admin/post.php?post=317&action=edit)

<!-- wp:paragraph -->
<p>アプリ開発でメールアドレスが本当に登録してきたユーザー本人のものかを確認するときがあると思います。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Laravel5.7からMustVerifyEmailというの追加になったようで簡単に実装することができましたので簡単にまとめてます。</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>メールアドレス確認の実装</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3>認証の準備</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>まずは認証の準備をします。以下のコマンドで簡単に作成できます。</p>
<!-- /wp:paragraph -->

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

<!-- wp:heading {"level":3} -->
<h3>モデル</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>App\UserモデルにMustVerifyEmailインタフェースを設定します</p>
<!-- /wp:paragraph -->

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

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements MustVerifyEmail
{
    use Notifiable;

    // ...
}</code></pre>
<!-- /wp:code -->

<!-- wp:heading {"level":3} -->
<h3>ルートの設定</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>まずメールアドレス確認をするAuth\VerificationControllerを認証ルートに追加します。</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>Auth::routes(['verify' => true]);</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>これでメールアドレス確認ができるようになったので、ルートを保護します。</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>Route::get('profile', function () {
    // Only verified users may enter...
})->middleware('verified');</code></pre>
<!-- /wp:code -->

<!-- wp:heading -->
<h2>メール送信の設定</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3>mailtrap</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>テスト中に間違ってメールを送ってしまわないように、mailtrapを利用して実際にはメールを送信して内容が確認できるようにします。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>無料でも十分利用できますので、以下のサイトから登録してください</p>
<!-- /wp:paragraph -->

<!-- wp:embed {"url":"https://mailtrap.io/"} -->
<figure class="wp-block-embed"><div class="wp-block-embed__wrapper">
https://mailtrap.io/
</div></figure>
<!-- /wp:embed -->

<!-- wp:heading {"level":3} -->
<h3>.envファイルの設定</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>mailtrapの接続情報を確認して.envファイルに設定します。</p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":319} -->
<figure class="wp-block-image"><img src="https://ksysnote.com/wp-content/uploads/2019/02/image-1024x248.png" alt="" class="wp-image-319"/></figure>
<!-- /wp:image -->

<!-- wp:heading -->
<h2>日本語化</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>ここまででも利用できますが、画面内の文言やメールが英語なので日本語に変更します。</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>ビュー</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><strong>php artisan make:auth</strong> でビューが<strong>resources/views/auth/verify.blade.php</strong>に作成されます。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>こちらの内容を日本語に置き換えて下さい</p>
<!-- /wp:paragraph -->

<!-- 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.Verify.Title') }}&lt;/div>

                &lt;div class="card-body">
                    @if (session('resent'))
                        &lt;div class="alert alert-success" role="alert">
                            {{ __('message.Verify.NewUrl') }}
                        &lt;/div>
                    @endif

                    {{ __('message.Verify.SendActionUrl') }}&lt;br/>
                    @lang('message.Verify.NotEmail', ['url' => route('verification.resend')])
                &lt;/div>
            &lt;/div>
        &lt;/div>
    &lt;/div>
&lt;/div>
@endsection
</code></pre>
<!-- /wp:code -->

<!-- wp:heading {"level":3} -->
<h3>メール本文の変更</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Illuminate/Auth/MustVerifyEmail.phpの中身を確認するとsendEmailVerificationNotificationの中でメールを送っていましたので、カスタマイズしたNotificationを送信するように変更します。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>まずはNotificationを作成します。</p>
<!-- /wp:paragraph -->

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

<!-- wp:paragraph -->
<p>中身はVerifyEmail.phpの中身をそのままコピーして、英語の部分を日本語にします。</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>&lt;?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 VerifyEmailCustom extends Notification
{
    /**
     * The callback that should be used to build the mail message.
     *
     * @var \Closure|null
     */
    public static $toMailCallback;

    /**
     * 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);
        }

        return (new MailMessage)
            ->subject(Lang::getFromJson('message.Mail.Verify.Title'))
            ->line(Lang::getFromJson('message.Mail.Verify.Line'))
            ->action(
                Lang::getFromJson('message.Mail.Verify.Action'),
                $this->verificationUrl($notifiable)
            )
            ->line(Lang::getFromJson('message.Mail.Verify.OutLine'));
    }

    /**
     * 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;
    }
}
</code></pre>
<!-- /wp:code -->

<!-- wp:heading {"level":3} -->
<h3>Userモデル</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>UserモデルでsendEmailVerificationNotificationをオーバーライドして、カスマイズしたNotificationを送信するようにします。</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>    public function sendEmailVerificationNotification()
    {
        $this->notify(new VerifyEmailCustom);
    }</code></pre>
<!-- /wp:code -->

<!-- wp:heading {"level":3} -->
<h3>通知メールの変更</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>このままでも通知メールのレイアウト部分が英語のままなので、そちらも日本語にします。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>以下のコマンドでレイアウトを変更できるようにします。</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>php artisan vendor:publish</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>resources/views/notifications/email.blade.phpファイルができるので、中身を変更します。</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>@component('mail::message')
{{-- Greeting --}}
@if (! empty($greeting))
# {{ $greeting }}
@else
@if ($level === 'error')
# @lang('message.Mail.Whoops')
@else
# @lang('message.Mail.Opning')
@endif
@endif

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

@endforeach

{{-- Action Button --}}
@isset($actionText)
&lt;?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
@lang('message.Mail.Regards')&lt;br>{{ config('app.name') }}
@endif

{{-- Subcopy --}}
@isset($actionText)
@component('mail::subcopy')
@lang(
"message.Mail.NotClick",
[
    'actionText' => $actionText,
    'actionURL' => $actionUrl,
]
)
@endcomponent
@endisset
@endcomponent
</code></pre>
<!-- /wp:code -->

<!-- wp:heading -->
<h2>日本語化ファイル</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>日本語のファイルをresources/lang/ja/message.phpに設定します。</p>
<!-- /wp:paragraph -->

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

return [
    // メールアドレスの確認
    "Verify" => [
        "Title" => "メールアドレスの確認",
        "NewUrl" => "新しく確認用のURLを送信しました。",
        "SendActionUrl" => "送られたメールを確認してURLをクリックして下さい。",
        "NotEmail" => "メールが届いていない場合は、&lt;a href=':url'>こちら&lt;/a>をクリックして下さい。"
    ],

    // メール
    "Mail" => [
        "Opning" => "ご利用ありがとうございます。",
        "Whoops" => "ご迷惑をおかけいたします。",
        "Regards" => "引き続きのご利用をよろしくお願いいたします。",
        "NotClick" =>"「:actionText」がクリックできない場合は以下のURLをブラウザにコピーして下さい。\n[:actionURL](:actionURL)",

        // メールアドレスの確認
        "Verify" => [
            "Title" => "メールアドレスの確認",
            "Line" => "メールアドレスを確認するには、下のボタンをクリックしてください。",
            "Action" => "メールアドレスを確認",
            "OutLine" =>"アカウントを作成しなかった場合、それ以上の操作は必要ありません。"
        ]
    ]
];
</code></pre>
<!-- /wp:code -->

<!-- wp:heading -->
<h2>参考</h2>
<!-- /wp:heading -->

<!-- wp:embed {"url":"https://blog.capilano-fw.com/?p=289#i-7"} -->
<figure class="wp-block-embed"><div class="wp-block-embed__wrapper">
https://blog.capilano-fw.com/?p=289#i-7
</div></figure>
<!-- /wp:embed -->

<!-- wp:embed {"url":"https://blog.capilano-fw.com/?p=1099#i-7"} -->
<figure class="wp-block-embed"><div class="wp-block-embed__wrapper">
https://blog.capilano-fw.com/?p=1099#i-7
</div></figure>
<!-- /wp:embed -->