Laravelでコミュニティ招待機能を実装（無制限招待&&本人確認なし）

#要件

###概要
事業者に、ユーザーを招待したい。
考えられるパターン
・ログインユーザー
・未登録ユーザー
・未ログインユーザー

未ログインの場合は、ログイン画面にリダイレクトされ、ログイン後に訪れたページへ飛ぶので
未ログインユーザーは、ログインユーザーの枝葉として考えられる。
⬇
・ログインユーザー(未ログインユーザー)：トークン付きURLを踏むと、参加する。
・未登録ユーザー：ユーザー登録後に再度URLを踏む。もしくは、ユーザー登録時にトークンを入力する。

###機能詳細
・招待コード生成アクション
・招待を受け入れるアクション
・招待コードを指定したメールアドレスに送信するアクション


#招待コード生成アクション

![スクリーンショット 2021-09-11 13.21.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620852/26f34e83-eed0-d69a-ee73-a45440edac43.png)

```Controller.php
    public function create_invitation_url(){
        :
        :
        $company->invitation_token = Str::random(30);
        $company->save();

        return redirect()->back()->with('flash_message', "招待コードおよび招待URLを生成しました。");
    }
```

```blade.php
    :
    :

    <p>招待コード</p>
    <p>{{ $company->invitation_token }}</p>

    <p>招待URL</p>
    @if($company->invitation_token)
        <p>http://127.0.0.1/enterprise/join/{{$company->id}}/{{ $company->invitation_token }}</p>
    @endif

    <a href="{{ route('enterprise.create_invitation_url') }}" class="btn btn-success">作成</a>

    :
    :
```

#招待を受け入れるアクション

Viewは用意していない。

![スクリーンショット 2021-09-11 13.24.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620852/5fe98029-8f40-666a-d93e-eebd5bce3e87.png)
⬇
リダイレクト先の画面でflash_messageを表示させる。
![スクリーンショット 2021-09-11 13.25.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620852/a6576d97-8579-e933-6259-6b65364d49d7.png)

```Controller.php
public function join($id,$token){

    $company = Company::find($id);
    //中間テーブルに所属しているかの確認を取りたいので、途中までクエリをビルドする。
    //$queryは、途中で止めておくことがポイント
    $query = Belong::where('user_id',Auth::id())
                ->where('company_id',$company->id);

    //所属してなければ、参加させる
    if($query->doesntExist()){
        //tokenの期限が切れていないか、または、偽物ではないかの確認をする。
        if( $company->invitation_token == $token){

            $belong = new Belong();
            $belong -> user_id = Auth::id();
            $belong -> company_id = $id ;
            $belong -> member_status = config('membership.status.staff');
            $belong -> save();

            return redirect()->to(route('enterprise.companies.list'))->with('flash_message', "参加しました。");

        }else{
            //tokenが腐っているか、偽物ならば、弾いておく。
            return redirect()->to(route('enterprise.companies.list'))->with('flash_message', "無効な招待です。再度、招待してもらってください。");      
        }

    }else{
        //所属済みならば、弾いておく。
        return redirect()->to(route('enterprise.companies.list'))->with('flash_message', "あなたは既に所属しています。");
    }        
}
```

#招待コードを指定したメールアドレスに送信するアクション

![スクリーンショット 2021-09-11 13.34.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620852/c783064c-8c4f-9a25-406f-8355df0fa9b7.png)
⬇
![スクリーンショット 2021-09-11 13.34.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620852/a947a253-117f-bea8-2555-2e84eb11d5d4.png)


```blade.php
        <form action="/enterprise/add_member" method="post">            
            <label for="exampleFormControlTextarea1">メンバー追加：ユーザーのメールアドレスを入れてください。</label>
                <input class="form-control" name="email" type="text">
                <div class="text-center">
                    <input class="btn btn-primary" type="submit" value="投稿する">
                    <input type="hidden" name="_token" value="{{csrf_token()}}">
                    <input type="hidden" name="company_id" value= "{{$company->id}}" >
                </div>
        </form>
```

```Controller.php
public function add_member(Request $request)
{
    :
    $company = Company::find($companyId);

    // メールにのせる変数を定義。
    $invite_url = "http://127.0.0.1/enterprise/join/$companyId"."/".$company->invitation_token;
    $token = $company->invitation_token;
    $companyName = $company->name;

    // メールを送信する。
    Mail::to($request->email)->send(new InviteMail($invite_url,$token, $companyName));
    return redirect()->back()->with('flash_message', '招待メールを送信しました。');
}
```