この記事の意図
Laravelには便利な認証機能がついてます。
とっても便利なのでおすすめです。
すごく親切なLaravelですが、なぜか日本語化してくれてません。なので日本語化します。
他にもQiitaであるんですが、メール認証とパスワードリセットがセットになってなかったので
セットで書くのが目的です。
前提
- 認証したいのは User
- メール認証が送れるとこまでは自力で
- メール送れる状態( mailtrapとかでもいいすよ)
1. 通知を使う
デフォルトのメール認証やパスワードリセットはメールで来るんですが、実は機能としてはnotificationなるものを使ってます。なので、いまからいじるのはNotificationになります。
2. UserモデルでOverride
- sendEmailVerificationNotification
- sendPasswordResetNotification
という function を追加しています。(useを忘れないように)
理由は、これが実際にメールを送る function だからです。
これは、Authenticatableのtraitで書かれてて(たしか)、メール認証とパスワードリセット時に呼ばれます。ここをオーバーライドして独自の Notification を使うことで日本語化します。
<?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. 日本語化
本丸!日本語化していきます。
説明はしません。
コードをみてください。該当部分だけ載せますね。
<?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('身に覚えがない場合は何もしないでくださいね。怪しいので。');
}
/**
* 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('身に覚えがない場合は何もしないでくださいね。怪しいので。');
}
結果はこちら
微妙に残ります。これはテンプレートに直に書かれてる部分が残ってる影響です。
mailのテンプレートを日本語化
ここにもありますが、notification で使ってるデフォルトのテンプレートをコピーできます。
$ 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.
これでテンプートができたので、日本語化します。
@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
晴れて日本語化
という感じで、少し面倒だったので
個人的な備忘録として残してみました。
では、また
追伸
Githubでのpull requestを載せるので参考までにどうぞ