前回実装した論理削除の今回は復元処理について書いていきます。こう考えるとユーザーにとっては論理削除の方が優しいですね。
前提
前回の記事の内容を把握している。
やること
確認メールを使ったアカウント復元処理
大まかな流れ
ルーティング記載追加
ビュー記載追加
コントローラー記載追加
確認メール作成
モデル記載追加
って感じの流れで行きます。
ルーティング記載追加
3つのアクションを用意します。
1 Route::get('/user/restore', 'UserController@restore_user')->name('restore_user');
2 Route::post('/user/restore', 'UserController@restore_user_send')->name('restore_user_send');
3 Route::get('/user/restore/{user}', 'UserController@restore_user_confirm')->name('restore_user_confirm');
1, 復元申請ページです。emailを使って実装します。
2, emailが条件に一致した場合は、確認メールを送信する処理です。
3, 確認メールをクリックした時の処理が記載してあります。
退会申請ページへのリンク
ページのどこかに記載しておけば大丈夫ですね。
@if (Route::has('restore_user'))
<a class="btn btn-link" href="{{ route('restore_user') }}">
{{ __('退会処理を取り消したい方') }}
</a>
@endif
ビュー記載追加
申請ページのビューです。
@if(session('say'))
<div class="alert alert-success" role="alert">
{{ session('say') }}
</div>
@endif
<form method="POST" action="{{ route('restore_user_send') }}">
@csrf
<div class="form-group row">
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('以前使用していたE-Mail') }}</label>
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
</div>
<button type="submit" class="btn btn-primary">
{{ __('申請する') }}
</button>
</form>
最小限しか書いていません。上部のセッション部分についてはユーザーが見つからなかった時の表示です。
emailをコントローラーに送信するようにしています。
モデル記載追加
通知ファイルの読み込みです。後から作成する通知クラスをuserから呼び出せるように設定しています。
Userモデル
use \App\Notifications\UserRestore;
......省略
public function sendUserRestoreNotification($user_id)
{
$this->notify(new UserRestore($user_id));
}
引数が渡されているので、呼び出し時に引数がいるということに注意してください。
コントローラー記載追加
こちらもルーティングと同じく3つのアクションから成り立っています。
use Carbon\Carbon;
public function restore_user()
{
return view('users.restore_user');
}
public function restore_user_send(Rrequest $request)
{
1 $check_user = User::withTrashed()->where(['email' => $request->email])->first();
2 if(isset($check_user->deleted_at)) {
$check_user->deleted_at = null;
$check_user->email_verified_at = null;
3 $check_user->save();
4 Auth::logout();
5 $check_user->sendUserRestoreNotification($check_user->id);
return redirect()->route('home')->with('say', '確認メールをお送りしたので、承諾してログインを完了しましょう');
} else {
return redirect()->back()->with('say', '条件に一致するユーザーを取得できませんでした');
}
}
public function restore_user_confirm(User $user)
{
6 if($user->email_verified_at == null) {
$now_time = Carbon::now('Asia/Tokyo');
$user->email_verified_at = $now_time;
7 $user->save();
Auth::login($user);
8 return redirect()->route('my_page', ['user' => $user->id])->with(['user' => $user, 'say' => 'アカウントの復元が完了しました']);
} else {
return redirect()->route('home')->with('say', '何らかの理由で、復元が出来ませんでした。もう一度お試しください');
}
}
確認メール送信まで
1, 送信されたemailと同じユーザーがいるかどうかを、withTrashed()メソッドで論理削除したユーザーも含めて検索を掛けます。
2, 取得したユーザーが論理削除されたユーザーである事を確認します。
3, deleted_atとemail_verified_atカラムを削除して保存します。復元への手順で、確認メールが正しく動くようにです。
4, ログアウトさせます。そのままだとリダイレクトログインしてしまうので、確認メールの意味がなくなってしまいます。
5, 先ほどモデルに設定した確認メール通知用メソッドを発火させます。
確認メールをクリックした後
6, そのユーザーはまだemail認証されていない事を確認します。
7, ユーザーのemail認証カラムを保存してからログインさせます。
8, ユーザー詳細ページにリダイレクトで飛ばす。
確認メール作成
コマンドでファイルを作成し、ファイルに記載を加えていきます。
php artisan make:notification UserRestore
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Lang;
class UserRestore extends Notification
{
use Queueable;
1 public $user_id;
/**
* Create a new notification instance.
*
* @return void
*/
2 public function __construct($user_id)
{
$this->user_id = $user_id;
}
/**
* 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)
{
3 return (new MailMessage)
->subject(Lang::get('ユーザー復元認証メールです'))
->line(Lang::get('下記リンクをクリックして復元認証を完了してください'))
->action(Lang::get('復元認証メール'), url('user/restore',$this->user_id))
->line(Lang::get('この変更に身に覚えがない場合は、無視してください'));
}
。。。。省略
}
1, $user_idをこのファイルで使用出来る事を明示します。
2, 初期値として渡された引数の値を代入します。
3, 実際のメール文の部分です。actionの部分にuser_idを使用してクリックした先のアクションを指定しています。
ここまで出来ればユーザーはマイページに飛んで復元される形になると思います。
まとめ
通知クラスの設定、アクションの定義などが出来ていればある程度出来ると思います。万が一を考えると論理削除の方が良いかもですね。
emailのバリデーションやtestなども追加で実装出来ると良いですね!
最近はVue.jsのテストで苦しんでいますwwただこれ出来るようになったら良いな〜って思いもあるのでやったりますw
今回はそんな感じで!!
以上!