はじめに
ユーザー招待機能の詳細設計と実装(5) ユーザー登録フォームと登録処理 について投稿します。
Web業界実務未経験での転職活動用にポートフォリオとしてはじめて作成したWebアプリ開発のオリジナルの機能として 家族ユーザー招待機能 を実装したときのものです。
※ 作成したポートフォリオは、絵本を読み聞かせしたことの記録・管理を、家族と共有できるWebアプリケーションです(作成期間は、2021年2月末〜7月)
投稿内容(全5回)
本連載は以下の順番で投稿します。
- 招待ユーザー機能の概要と基本設計
-
招待ユーザー機能の詳細設計と実装
- (1) 招待メール送信フォーム
- (2) マイグレーションファイルからのテーブル作成
- (3) 招待メール送信処理
- (4) 招待メールのテンプレート
- (5) ユーザー登録フォームと登録処理
今回は、ユーザー招待機能の詳細設計と実装(5) ユーザー登録フォームと登録処理 についてです。
目次
以下、本記事の目次です。
使用技術、サービスなど
- PHP 7.4.13
- Laravel 6.20.20
- MySQL 8.0.23
- MailHog(開発者向けのメールテストツール、開発環境)
1. ルーティングの確認
ルーティングの追加は、以下のステップで完了しています。
2. 「家族招待用の登録フォーム表示」処理の追加
app/Http/Controllers/Auth ディレクトリの RegisterController.php に showInvitedUserRegistrationForm
メソッドを追加します。
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use App\User;
use App\Family;
use App\Child;
use App\Invite; // 追加
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Laravel\Socialite\Facades\Socialite;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
class RegisterController extends Controller
{
// 省略
// 「家族招待用の登録フォーム画面表示」処理の追加
public function showInvitedUserRegistrationForm(string $token)
{
$invite = Invite::where('token', $token)->first();
if (!isset($invite)) {
abort(401);
}
return view('auth.invite_register', [
'token' => $invite->token,
'family_id' => $invite->family_id,
'email' => $invite->email,
]);
}
// 省略
}
-
use App\Invite;
を追加して、トークンを管理している Invite モデルからデータを取得できるようにしておきます。 - トークンが Invite モデルにない場合は、 401 エラーを返すようにしました。
3. 家族招待用の登録フォームの作成
家族招待用の登録フォームの blade を作成します。以下の画面の作成です。
@extends('app')
@section('title', '招待ユーザー登録-よんで-')
@section('content')
@include('auth.nav')
<div class="bg-paper py-4">
<div class="container" style="max-width: 540px">
<h3 class="text-center">
よんで の新規登録(家族招待用)
</h3>
<h4 class="text-center">
<b>ようこそ、 よんで へ。</b>
</h4>
<div class="card my-4 shadow-sm">
<div class="card-body">
@include('error_card_list')
<form method="POST" action="{{ route('register.invited') }}">
@csrf
<input type="hidden" name="token" value="{{ $token }}">
<input type="hidden" name="family_id" value="{{ $family_id }}">
<input type="hidden" name="email" value="{{ $email }}">
<p class="x-small">
(<span class="text-danger">*</span>は必須項目です)
</p>
<div class="form-group">
<label for="email">メールアドレス</label>
<input class="form-control" type="text" id="email" name="email" value="{{ $email }}" disabled
required>
</div>
<div class="form-group">
<label for="nickname">ユーザーネーム</label><span class="text-danger">*</span>
<input class="form-control" type="text" id="nickname" name="nickname" placeholder="ユーザーネームを入力"
required value="{{ old('nickname') }}">
<p class="text-muted small ml-1">50文字以内</p>
</div>
<div class="form-group">
<label for="password">パスワード</label><span class="text-danger">*</span>
<input class="form-control" type="password" placeholder="パスワードを作成" id="password" name="password"
required>
<p class="text-muted small ml-1">半角英数・記号:8文字以上</p>
</div>
<div class="form-group">
<label for="password_confirmation">パスワード(確認)</label><span class="text-danger">*</span>
<input class="form-control" type="password" placeholder="パスワードを確認" id="password_confirmation"
name="password_confirmation" required>
</div>
<label for="agree" class="small" role="button">
<span class="d-flex flex-wrap">
<span>
<input type="checkbox" id="agree" required>
<a href="{{ route('privacy') }}" class="text-teal1 ml-2" target="_blank"
title="プライバシーポリシーをブラウザの別画面で開く">プライバシーポリシー</a>
<span>を確認し、</span>
</span>
<span>同意</span>
<span>
<span>
<span>しました。</span><span class="text-danger">*</span>
</span>
</span>
</label>
<button type="submit" class="btn btn-block bg-pink text-decoration-none text-white mt-4">
<b>登録</b>
</button>
</form>
</div>
</div>
</div>
</div>
@include('footer')
@endsection
4. 「家族ユーザー登録」処理の追加
app/Http/Controllers/Auth ディレクトリの RegisterController.php に registerInvitedUser
メソッドを追加します。
<?php
// 省略
class RegisterController extends Controller
{
// 省略
// 「家族招待用のユーザー登録」処理
public function registerInvitedUser(Request $request)
{
if (!$invite = Invite::where('token', $request->token)->first()) {
abort(401);
}
$request->validate([
'nickname' => ['required', 'string', 'max:50'],
'email' => ['required', 'string', 'email', 'max:255', Rule::unique('users', 'email')->whereNull('deleted_at'),],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
$checkUniqueName = true;
while ($checkUniqueName) {
$userName = Str::random(16);
$checkUniqueName = User::where('name', $userName)->exists();
}
$user = User::create([
'name' => $userName,
'nickname' => $request->nickname,
'email' => $request->email,
'email_verified_at' => now(),
'password' => Hash::make($request->password),
'family_id' => $request->family_id,
]);
$this->guard()->login($user, true);
$invite->delete();
return $this->registered($request, $user)
?: redirect($this->redirectPath());
}
// 省略
}
- 一連の流れを通して、招待する側と同一の
family_id
にしてユーザー登録することで、登録後、家族ユーザーとして本棚を共有できるようにしています。 -
$invite->delete();
で招待用トークンは削除して、使えないようにしています。
5. 家族招待用の登録フォームの確認
前回ブラウザで確認した MailHog の受信ボックスに届いているメールのリンクをクリックすると、フォームが表示されるようになっていることを確認します。
入力して登録ボタンを押すと、招待する側と同一の family_id
で登録されました。
登録後のプロフィール設定画面、家族設定画面は、以下の通りです。
phpMyAdmin での users テーブルのデータの確認画面です。
最後の行の id 5 が追加されたデータです。
おわりに
実装したオリジナルの機能の一つである「家族ユーザー招待」機能についてはこれで完結です。
記事にまとめる目的は、類似の機能を作る方への参考にしていただきたいため、自身の学習の振り返りのため、としていましたが、記事にする過程で、1年ほど触っていない Laravel の実装について、思い出すことができたので良い復習の機会になりました。
また、類似の機能を作る方への参考になると嬉しいです。
ありがとうございました。