8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Laravel】メール認証とパスワードリセットを日本語化

Last updated at Posted at 2019-10-31

この記事の意図

Laravelには便利な認証機能がついてます。
とっても便利なのでおすすめです。

すごく親切なLaravelですが、なぜか日本語化してくれてません。なので日本語化します。
他にもQiitaであるんですが、メール認証とパスワードリセットがセットになってなかったので
セットで書くのが目的です。

前提

  • 認証したいのは User
  • メール認証が送れるとこまでは自力で
  • メール送れる状態( mailtrapとかでもいいすよ)

1. 通知を使う

デフォルトのメール認証やパスワードリセットはメールで来るんですが、実は機能としてはnotificationなるものを使ってます。なので、いまからいじるのはNotificationになります。

2. UserモデルでOverride

  • sendEmailVerificationNotification
  • sendPasswordResetNotification

という function を追加しています。(useを忘れないように)
理由は、これが実際にメールを送る function だからです。
これは、Authenticatableのtraitで書かれてて(たしか)、メール認証とパスワードリセット時に呼ばれます。ここをオーバーライドして独自の Notification を使うことで日本語化します。

User
<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use App\Notifications\VerifyEmail;    // <-- あとで作ります
use App\Notifications\ResetPassword; // <-- あとで作ります

class User extends Authenticatable implements MustVerifyEmail
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    /**
     * ここを追加していますー
     * override
     *
     * @return void
     */
    public function sendEmailVerificationNotification()
    {
        $this->notify(new VerifyEmail);
    }

    /**
     * ここを追加していますー
     * override
     *
     * @return void
     */
    public function sendPasswordResetNotification($token)
    {
        $this->notify(new ResetPassword($token));
    }
}

3. Notificationをコピー

app/Notifications というフォルダをまず作ります。(どこでもいいちゃいいです。)
その配下に以下の2つをコピー

  • vendor/laravel/framework/src/Illuminate/Auth/Notifications/VerifyEmail.php
  • vendor/laravel/framework/src/Illuminate/Auth/Notifications/ResetPassword.php

この2つが実際に送ってるやつらですね。
コピーしたらnamespaceを書き換えるのをお忘れなく。

4. 日本語化

本丸!日本語化していきます。

説明はしません。
コードをみてください。該当部分だけ載せますね。

App\Notifications\VerifyEmail
<?php
    /**
     * Build the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        $verificationUrl = $this->verificationUrl($notifiable);

        if (static::$toMailCallback) {
            return call_user_func(static::$toMailCallback, $notifiable, $verificationUrl);
        }

        return (new MailMessage)
            ->greeting('こんにちは!')
            ->subject('メール認証をお願いします')
            ->line('ボタンを押して認証してね')
            ->action('メールを認証する', $verificationUrl)
            ->line('身に覚えがない場合は何もしないでくださいね。怪しいので。');
    }

App\Notifications\ResetPassword
    /**
     * 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)
            ->greeting('こんにちは!')
            ->subject('パスワードリセット用メールです')
            ->line('これはパスワードリセットの依頼があったのでおくっっています。')
            ->action('パスワードリセット', url(config('app.url').route('password.reset', ['token' => $this->token, 'email' => $notifiable->getEmailForPasswordReset()], false)))
            ->line('このリンクの有効期限は :count 分です。', ['count' => config('auth.passwords.'.config('auth.defaults.passwords').'.expire')])
            ->line('身に覚えがない場合は何もしないでくださいね。怪しいので。');
    }

結果はこちら
微妙に残ります。これはテンプレートに直に書かれてる部分が残ってる影響です。
Screen Shot 2019-10-31 at 13.01.41.png

mailのテンプレートを日本語化

ここにもありますが、notification で使ってるデフォルトのテンプレートをコピーできます。

ternimal
$ php artisan vendor:publish --tag=laravel-notifications
Copied Directory [/vendor/laravel/framework/src/Illuminate/Notifications/resources/views] To [/resources/views/vendor/notifications]
Publishing complete.
Publishing complete.

これでテンプートができたので、日本語化します。

resources/views/vendor/notifications/email.blade.php
@component('mail::message')
{{-- Greeting --}}
@if (! empty($greeting))
# {{ $greeting }}
@else
@if ($level === 'error')
# @lang('Whoops!')
@else
# @lang('Hello!')
@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') }}をよろしくです。
@endif

{{-- Subcopy --}}
@isset($actionText)
@slot('subcopy')
@lang(
    "もし \":actionText\" ボタンが動かない場合は、このURLをブラウザにコピぺしてください\n".
    ': [:actionURL](:actionURL)',
    [
        'actionText' => $actionText,
        'actionURL' => $actionUrl,
    ]
)
@endslot
@endisset
@endcomponent

晴れて日本語化

Screen Shot 2019-10-31 at 13.18.25.png

という感じで、少し面倒だったので
個人的な備忘録として残してみました。
では、また

追伸

Githubでのpull requestを載せるので参考までにどうぞ

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?