コンテンツに移動 ナビゲーションに移動

IT全般に関する雑記や技術ブログ。wordpressやPHP LaravelたまにPython

南の島のSE エンジニアブログ

PHP
  1. HOME
  2. PHP
  3. Laravel 8で会員サイト構築5 会員情報更新機能
2020年9月19日 / 最終更新日 : 2022年8月8日 syun03 PHP

Laravel 8で会員サイト構築5 会員情報更新機能

Laravelのパッケージとして利用できるログイン機能のカスタマイズシリーズも第5弾となりまして、今回は会員情報更新機能を準備します。

会員サイトとしては必須の機能となりますが、更新辺りから少し複雑になってきますのでできるだけ細かく記載していきます。

目次
  • 1. 対応概要
  • 2. 手順
  • 2.1. コントローラ新規作成
  • 2.1.1. use Customer\EditsTrait
  • 2.1.2. index
  • 2.1.3. validator
  • 2.1.4. update
  • 2.2. traitの準備
  • 2.2.1. showEditForm
  • 2.2.2. edit
  • 2.3. リクエストフォーム新規作成
  • 2.4. VIEWの新規作成
  • 2.5. ルート設定
  • 3. ログイン機能連載一覧

対応概要

パッケージとして利用できる会員登録機能の流れに準拠し、会員情報更新機能を構築します。

今回の対応の中では作り込まない機能もありますが、ルールを統一のために呼び出すだけ呼び出されている機能などもありますので、ご了承ください。

手順

今回準備が必要なのは下記です。ちょっと多いですが、個々の対応はそこまで複雑ではありません。

  • コントローラ
  • Trait
  • リクエストフォーム
  • Event
  • View
  • ルートの設定

それではまずはコントローラを作成しましょう。

コントローラ新規作成

ベースは会員登録のコントローラ(RegisterController)をコピペしてきます。

完成形は下記になります。

namespace App\Http\Controllers\Customer;

use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use App\Traits\Customer;
use Illuminate\Validation\Rule;

class EditController extends Controller
{
    use Customer\EditsTrait;

    protected $redirectTo = '/home';

    public function __construct()
    {
        $this->middleware('auth');
    }

    public function index ()
    {
        return $this->showEditForm();
    }

    protected function validator(array $data)
    {
        return Validator::make($data, [
            Rule::unique('users')->ignore(Auth::id())
        ]);
    }

    protected function update(array $data)
    {
        $id = Auth::id();
        $customer = User::find($id);
        $customer->email = $data['email'];
        $customer->zipcode = $data['zipcode'];
        $customer->prefecture = $data['prefecture'];
        $customer->city = $data['city'];
        $customer->address1 = $data['address1'];
        $customer->address2 = $data['address2'];
        $customer->tel = $data['tel'];
        $customer->save();

        return $customer;
    }
}

use Customer\EditsTrait

あとから作成するTraitを呼び出しています。

会員情報変更に関わるビジネスロジックはこちらに集約します。

index

会員情報更新画面を呼び出します。showEditFormはTraitに定義しておりまして、Viewに渡す会員情報の取得などもTraitから渡しています。

validator

こちらが今回のミソです。

会員情報を更新する際に、メールアドレスのバリデーションロジックをそのまま使うと

「メールアドレスがすでに登録されているよ」というエラーに見舞われることになります。

自分の会員情報を更新しようとして、すでに自分の情報として登録済みのメールアドレスが重複チェックとして引っ掛かるわけです。

そこで、重複チェックの対象から「ログインユーザのみ外す」というルールを追加します。

Rule::unique('users')->ignore(Auth::id())

update

Viewからarrayでパラメータを受け取り、updateしています。

更新対象の会員はログイン情報から受け取るようにします。

$id = Auth::id();

View側にhiddenで埋め込んだIDを使うなどしてしまうと、不正にIDが書き換えられた場合に他人の会員情報が更新できてしまいます。必ずフロント側から遠いところで会員特定する必要があります。

traitの準備

こちらもベースはRegisterUsersを利用しますが、このファイルはコアファイルの中に格納されているので、探すのが少し手間取ります。

パスはこちらになります。

src/Illuminate/Foundation/Auth/RegistersUsers.php

完成したソースがこちら

namespace App\Traits\Customer;

use App\Events\Customer\CustomerEditedEvent;
use App\Http\Requests\Customer\CustomerEditRequest;
use App\User;
use Illuminate\Foundation\Auth\RedirectsUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;

trait EditsTrait
{
    use RedirectsUsers;

    public function showEditForm()
    {
        $id = Auth::id();
        $customer = User::find($id);

        return view('customer.edit',[
            'customer' => $customer
        ]);
    }

    public function edit(CustomerEditRequest $request)
    {
        $this->validator($request->all())->validate();

        event(new CustomerEditedEvent($user = $this->update($request->all())));

        $this->guard()->login($user);

        return $this->edited($request, $user)
                        ?: redirect($this->redirectPath());
    }

    protected function guard()
    {
        return Auth::guard();
    }

    protected function edited(request $request, $user)
    {
    }
}

こちらもメソッドの説明をしていきます。

showEditForm

会員情報更新画面を表示させるためのメソッドです。

$id = Auth::id() でログイン中の会員情報を取得しており、Viewにパラメータとして渡しています。

    return view('customer.edit',[
        'customer' => $customer
    ]);

edit

会員情報更新のビジネスロジックを記述しています。

public function edit(CustomerEditRequest $request)

CustomerEditRequestリクエストフォーム(このあと構築)からパラメータを受けとって処理を行います。

$this->validator($request->all())->validate();

コントローラ独自のバリデーションロジックを読み出します。

event(new CustomerEditedEvent($user = $this->update($request->all())));

会員情報変更をイベントとして登録します。(イベントの中身はこのあと構築)

リクエストフォーム新規作成

登録画面の作成のたびに、リクエストフォームも準備します。

こちらも会員登録画面作成時に作成したリクエストフォームをベースにします。

namespace App\Http\Requests\Customer;

use App\ValueObjects\Address1;
use App\ValueObjects\Address2;
use App\ValueObjects\City;
use App\ValueObjects\Email;
use App\ValueObjects\Prefecture;
use App\ValueObjects\Tel;
use App\ValueObjects\Zipcode;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;

class CustomerEditRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        $id = Auth::id();
        return [
            'address1' => Address1::rules(),
            'address2' => Address2::rules(),
            'city' => City::rules(),
            'email' => Email::rules($id),
            'prefecture' => Prefecture::rules(),
            'tel' => Tel::rules(),
            'zipcode' => Zipcode::rules()
        ];
    }

    public function messages()
    {
        return [
            'required' => ':attribute を入力してください。'
        ];
    }


今回、メールアドレスの値オブジェクトはバリデーションルールを修正しています。

    public static function rules($customer_id = 0){
        if($customer_id===0){
            return ['required','string','email','max:255'];
        }else{
            $customer = User::find($customer_id);
            return ['required','string','email','max:255',Rule::unique('users')->ignore($customer->email,'email')];
        }
    }

更新対象として、重複チェックから外す対象がある場合の分岐を追加しています。

VIEWの新規作成

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Customer_Edit') }}</div>

                <div class="card-body">
                    <form method="POST" action="{{ route('customer.update') }}">
                        @csrf

                        <div class="form-group row">
                            <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>

                            <div class="col-md-6">
                                <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ $customer->email }}" required autocomplete="email">

                                @error('email')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>
                        <!-------ここから会員登録追加---------->
                        <div class="form-group row">
                            <label for="zip-code" class="col-md-4 col-form-label text-md-right">{{ __('zip-code') }}</label>

                            <div class="col-md-6">
                                <input id="zip-code" type="number" class="form-control @error('zip-code') is-invalid @enderror" name="zipcode" value="{{ $customer->zipcode }}" required autocomplete="zip-code">

                                @error('zip-code')
                                <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="form-group row">
                            <label for="prefecture" class="col-md-4 col-form-label text-md-right">{{ __('prefecture') }}</label>

                            <div class="col-md-6">
                                <input id="prefecture" type="text" class="form-control @error('prefecture') is-invalid @enderror" name="prefecture" value="{{ $customer->prefecture }}" required autocomplete="prefecture">

                                @error('prefecture')
                                <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="form-group row">
                            <label for="city" class="col-md-4 col-form-label text-md-right">{{ __('city') }}</label>

                            <div class="col-md-6">
                                <input id="city" type="text" class="form-control @error('city') is-invalid @enderror" name="city" value="{{ $customer->city }}" required autocomplete="city">

                                @error('city')
                                <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>
                        <div class="form-group row">
                            <label for="address1" class="col-md-4 col-form-label text-md-right">{{ __('address1') }}</label>

                            <div class="col-md-6">
                                <input id="address1" type="text" class="form-control @error('address1') is-invalid @enderror" name="address1" value="{{ $customer->address1 }}" required autocomplete="address1">

                                @error('address1')
                                <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>
                        <div class="form-group row">
                            <label for="address2" class="col-md-4 col-form-label text-md-right">{{ __('address2') }}</label>

                            <div class="col-md-6">
                                <input id="address2" type="text" class="form-control @error('address2') is-invalid @enderror" name="address2" value="{{ $customer->address2 }}" autocomplete="address2">

                                @error('address2')
                                <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>
                        <div class="form-group row">
                            <label for="tel" class="col-md-4 col-form-label text-md-right">{{ __('tel') }}</label>

                            <div class="col-md-6">
                                <input id="tel" type="tel" class="form-control @error('tel') is-invalid @enderror" name="tel" value="{{ $customer->tel }}" required autocomplete="tel">

                                @error('tel')
                                <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>
                        <!-------ここまで会員登録追加---------->
                        <div class="form-group row mb-0">
                            <div class="col-md-6 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Register') }}
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

ルート設定

追加するのはこの2行です。

Route::get('/customer/edit', 'Customer\EditController@index')->name('customer.edit');
Route::post('/customer/edit', 'Customer\EditController@edit')->name('customer.update');

Laravelログイン機能連載一覧

  • Laravel 8でログイン機能実装1 基本機能
  • Laravel 8でログイン機能実装2 ログインIDの導入 
  • Laravel 8でログイン機能実装3 会員登録時の入力項目追加 
  • Laravel8でログイン機能実装4 ValueObjectとバリデーション
  • Laravel 8でログイン機能実装5 会員情報変更

  • クリックして Twitter で共有 (新しいウィンドウで開きます)
  • Facebook で共有するにはクリックしてください (新しいウィンドウで開きます)

関連記事

LaravelとAmazon Cognitoでログイン実装
Laravelで Amazon Cognito ログイン認証2【会員登録機能】
 2022年9月2日
Laravel8でログイン機能実装4 値オプジェクト
Laravel8 ログイン機能実装4 値オブジェクトを用いたバリデーション
 2020年9月15日
Laravel8でログイン機能実装3
Laravel 8でログイン機能実装3 会員登録項目追加
 2020年8月31日
Laravel8でログイン機能実装2
Laravel 8でログイン機能実装2 ログインID導入
 2020年8月12日
Laravel8でログイン機能実装1
Laravel8でログイン機能実装1 基本機能導入編
 2020年8月7日
カテゴリー
PHP、Laravel
タグ
ログイン

コメントを残す コメントをキャンセル

PHP
Laravel8でログイン機能実装4 値オプジェクト

前の記事

Laravel8 ログイン機能実装4 値オブジェクトを用いたバリデーション
2020年9月15日
wordpress
simple membership 会員登録プラグイン一部表示制限方法

次の記事

simple membership 会員登録プラグイン 一部表示制限方法
2020年10月12日

検索

自己紹介

auther

南の島を愛するエンジニア
他にはない一歩踏み込んだ内容を心がけています。PHP/Phtyonでの開発やwordpressのカスタマイズ。最近はAWS
【IPA資格】
ITストラテジスト/ ITアーキテクト/ 情報セキュリティスペシャリスト

ココナラで活動中 お仕事のご依頼はこちら

【お友達紹介キャンペーン】ここから会員登録で1,000ポイント獲得

ランサーズはこちら お仕事承ります

人気記事

カテゴリー

  • システム構築 (5)
  • AWS (7)
    • コスト最適化 (1)
  • Python (4)
    • Django (4)
  • PHP (19)
    • Laravel (18)
  • wordpress (31)
    • WooCommerce (5)
    • welcart (2)
  • ライフスタイル (1)
    • 副業 (1)
  • セキュリティ (1)
  • 資格 (37)
    • 基本情報技術者試験 (3)
    • プロジェクトマネージャ (7)
    • システムアーキテクト (3)
    • ITストラテジスト (6)
    • 情報処理安全確保支援士 (17)
  • その他 (7)

タグ

AWS (1) cognito (2) laravel-admin (4) SalonBookingSystem (5) simple-membership (3) stripe (5) subscription (1) wp-members (10) ドメイン駆動設計 (1) ログイン (6) 会員サイト (1)

目次

  • 1 対応概要
  • 2 手順
    • 2.1 コントローラ新規作成
      • 2.1.1 use Customer\EditsTrait
      • 2.1.2 index
      • 2.1.3 validator
      • 2.1.4 update
    • 2.2 traitの準備
      • 2.2.1 showEditForm
      • 2.2.2 edit
    • 2.3 リクエストフォーム新規作成
    • 2.4 VIEWの新規作成
    • 2.5 ルート設定
  • 3 Laravelログイン機能連載一覧

当サイトについて

TOP |
プライバシーポリシー |
お問合せ

カテゴリー

  • システム構築
  • AWS
    • コスト最適化
  • Python
    • Django
  • PHP
    • Laravel
  • wordpress
    • WooCommerce
    • welcart
  • ライフスタイル
    • 副業
  • セキュリティ
  • 資格
    • 基本情報技術者試験
    • プロジェクトマネージャ
    • システムアーキテクト
    • ITストラテジスト
    • 情報処理安全確保支援士
  • その他

タグ

  • laravel
  • wp-members
  • 会員サイト
  • ドメイン駆動設計
  • simple-membership
  • stripe
  • SalonBookingSystem
  • laravel-admin
  • subscription
  • AWS
  • ログイン
  • cognito

最近の投稿

ITストラテジスト午後2 令和4年
ITストラテジスト試験 令和4年午後2論述解説
2023年3月19日
【AWS】VPCリソースマップがイケてる【VPC可視化】
2023年3月12日
基本情報技術者試験解説 科目A
【2023新試験】基本情報技術者試験サンプル問題(科目A試験)
2023年2月26日
AWS budgetsで予算管理
【事例で学ぶ】AWS Budgetsを利用した予算設定
2023年2月18日
プロジェクトマネージャ試験令和4年度秋季 午後1問3解答速報
【解答・解説】プロジェクトマネージャ 令和4年度秋季【午後1問3】
2022年10月15日

Copyright © 南の島のSE エンジニアブログ All Rights Reserved.

MENU
  • HOME