Laravel9 | お問合せフォームを作成する

Laravel Sail を利用して簡単なお問合せフォームを作成する内容のメモ。

フォーム用プロジェクト作成

form-app という名前でお問合せフォーム用のプロジェクトを作成します。DBなどは利用せずメールの送信確認のみ行う目的でしたので、MailHog のみを with で指定して作成しました。

curl -s "https://laravel.build/form-app?with=mailhog" | bash

タイムゾーン・ロケール変更

/config/app.php を開き timezone と locale の設定を日本に変更します。

# /config/app.php

return [
  // タイムゾーン
  'timezone' => 'Asia/Tokyo',
  // ロケール
  'locale'   => 'ja',
];

コントローラを作成

コントローラ作成

フォーム用のコントローラ FormController を作成します。

sail artisan make:controller FormController

入力・完了ページ用アクション追加

FormControllerに入力・完了ページ用のアクションを追加します。

入力ページ

# /app/Http/Controllers/FormController.php

/**
 * 入力ページ
 */
public function index()
{
  return view('form.index');
}

完了ページ

# /app/Http/Controllers/FormController.php

/**
 * 完了ページ
 */
public function complete()
{
  return view('form.complete');
}

ルーティング設定

/form で入力ページ、/form/complete で完了ページが表示できるようルーティング設定を追加します。

use宣言でFormControllerを追加

# /routes/web.php

use App\Http\Controllers\FormController;

お問合せ用ルーティング

# /routes/web.php

// お問合せフォーム
Route::get('/form', [FormController::class, 'index'])->name('form');
Route::get('/form/complete', [FormController::class, 'complete'])->name('form.complete');

Bladeテンプレートファイル追加

レイアウト用、インデックス用、フォーム入力・完了ページ用のBladeテンプレートファイルを追加します。

/resources/views/layouts/default.blade.php
/resources/views/index.blade.php
/resources/views/form/index.blade.php
/resources/views/form/complete.blade.php

レイアウト用

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>@yield('title', 'フォームAPP')</title>
</head>
<body>

<header>{{-- // header --}}</header>

<main>@yield('content')</main>

<footer>{{-- // footer  --}}</footer>

</body>
</html>

入力ページ用

@extends('layouts.default')
@section('title', 'お問い合わせ')

@section('content')

<section>

{{-- ▼▼ エラーメッセージ --}}
@if($errors->any())
<div>
  <ul>
    @foreach($errors->all() as $error)
    <li>{{ $error }}</li>
    @endforeach
  </ul>
</div>
@endif
{{-- ▲▲ エラーメッセージ --}}

{{-- ▼▼ フォーム --}}
<form action="{{ route('form') }}" method="POST">
  @csrf

  {{-- ▼ 会社名 --}}
  <div>
    <label for="company">会社名(必須)</label>
    <input id="company" type="text" name="company" value="{{ old('company') }}">
    @if($errors->has('company'))
    <p>{{ $errors->first('company') }}</p>
    @endif
  </div>

  {{-- ▼ お名前 --}}
  <div>
    <label for="name">お名前(必須)</label>
    <input id="name" type="text" name="name" value="{{ old('name') }}">
    @if($errors->has('name'))
    <p>{{ $errors->first('name') }}</p>
    @endif
  </div>

  {{-- ▼ フリガナ --}}
  <div>
    <label for=name_kana>フリガナ(必須)</label>
    <input id="name_kana" type="text" name="name_kana" value="{{ old('name_kana') }}">
    @error('name_kana')
    <p>{{ $message }}</p>
    @enderror
  </div>

  {{-- ▼ 電話番号 --}}
  <div>
    <label for="phone">電話番号</label>
    <input id="phone" type="text" name="phone" value="{{ old('phone') }}">
    @error('phone')
    <p>{{ $message }}</p>
    @enderror
  </div>

  {{-- ▼ メールアドレス --}}
  <div>
    <label for="email">メールアドレス(必須)</label>
    <input id="email" type="email" name="email" value="{{ old('email') }}">
    @if($errors->has('email'))
    <p>{{ $errors->first('email') }}</p>
    @endif
  </div>

  {{-- ▼ お問い合わせ内容 --}}
  <div>
    <label for="body">お問い合わせ内容(必須)</label>
    <textarea id="body" type="text" name="body">{{ old('body') }}</textarea>
    @if($errors->has('body'))
    <p>{{ $errors->first('body') }}</p>
    @endif
  </div>

  {{-- ▼ 送信ボタン --}}
  <div>
    <button type="submit">送信</button>
  </div>

</form>
{{-- ▲▲ フォーム --}}

</section>
@endsection

言語パッケージを追加

パッケージをダウンロード

以下のコマンドで、vendor ディレクトリに laravel-lang が追加されます。

sail composer require laravel-lang/lang laravel-lang/publisher --dev 

日本語パッケージ追加

以下のコマンドで、lang ディレクトリに ja を追加します。

sail artisan lang:add ja

パッケージ削除

lang ディレクトリに追加後は不要なので削除しました。(*残しておいても問題なし)

sail composer remove laravel-lang/lang laravel-lang/publisher --dev

バリデーションで利用する属性名を設定

# /lang/ja/validation.php

// 属性名
'attributes' => [
  'company'   => '会社名',
  'name'      => '名前',
  'name_kana' => 'フリガナ',
  'phone'     => '電話番号',
  'email'     => 'メールアドレス',
  'body'      => '本文'
]

フォームリクエスト作成

フォームリクエスト作成

sail artisan make:request ContactFormRequest

authorizeメソッドのfalseをtrueに変更

# /app/Http/Requests/ContactFormRequest.php

public function authorize()
{
  // false から true に変更
  return true;
}

バリデーションルール・属性名・メッセージ設定

バリデーションルール

# /app/Http/Requests/ContactFormRequest.php

/**
  * バリデーションルール
  *
  * @return array<string, mixed>
  */
public function rules()
{
  // 
  $rules = [
    'company'   => ['required', 'string', 'max:30'],
    'name'      => ['required', 'string', 'max:30'],
    'name_kana' => ['required', 'string', 'max:30', 'regex:/^[ァ-ロワンヴー]*$/u'],
    'phone'     => ['nullable', 'regex:/^0(\d-?\d{4}|\d{2}-?\d{3}|\d{3}-?\d{2}|\d{4}-?\d|\d0-?\d{4})-?\d{4}$/'],
    'email'     => ['required', 'email'],
    'body'      => ['required', 'string', 'max:1000'],
  ];

  // 
  return $rules;
}

属性名

# /app/Http/Requests/ContactFormRequest.php

/**
  * 属性名
  * /lang/ja/validation.php で指定した内容を変更する場合に設定
  */
public function attributes()
{
  // 
  return [
    'company'   => '会社・組織名',
    // 'name'      => '氏名',
    // 'name_kana' => 'フリガナ',
    // 'phone'     => '電話番号',
    // 'email'     => 'メールアドレス',
    'body'      => 'お問い合わせ内容'
  ];
}

エラーメッセージ

# /app/Http/Requests/ContactFormRequest.php

/**
  * エラーメッセージ
  */
public function messages()
{
  // 
  return [
    'name.required' => ':attributeは必須項目です。',
    'phone.regex'   => ':attributeが正しくありません。'
  ];
}

Mailableクラスの作成

Mailableクラスの作成

sail artisan make:mail FormAdminMail
sail artisan make:mail FormUserMail

Mailableクラスの設定(管理者宛メール)

use宣言で Mailables\Address を追加

# /app/Mail/FormAdminMail.php

use Illuminate\Mail\Mailables\Address;

__construct() / envelope() / content() メソッド設定

# /app/Mail/FormAdminMail.php

/**
  * Create a new message instance.
  *
  * @return void
  */
public function __construct(public array $form_data)
{
  //
}

/**
  * Get the message envelope.
  *
  * @return \Illuminate\Mail\Mailables\Envelope
  */
public function envelope()
{
  $from    = new Address($this->form_data['email'], $this->form_data['name']);
  $subject = 'お問合せがありました';

  // 
  return new Envelope(
    from: $from,
    subject: $subject,
  );
}

/**
  * Get the message content definition.
  *
  * @return \Illuminate\Mail\Mailables\Content
  */
public function content()
{
  return new Content(
      // view: 'emails.form.admin',
      text: 'emails.form.admin', // プレーンテキストで送信
  );
}

Mailableクラスの設定(ユーザー宛メール)

use宣言で Mailables\Address を追加

# /app/Mail/FormUserMail.php

use Illuminate\Mail\Mailables\Address;

__construct() / envelope() / content() メソッド設定

# /app/Mail/FormUserMail.php

/**
  * Create a new message instance.
  *
  * @return void
  */
public function __construct(public array $form_data)
{
  //
}

/**
  * Get the message envelope.
  *
  * @return \Illuminate\Mail\Mailables\Envelope
  */
public function envelope()
{
    $from    = new Address('admin@example.com', 'フォームAPP');
    $subject = '【フォームAPP】お問合せ有難うございます';

    // 
    return new Envelope(
      from: $from,
      subject: $subject,
    );
}

/**
  * Get the message content definition.
  *
  * @return \Illuminate\Mail\Mailables\Content
  */
public function content()
{
    return new Content(
      // view: 'emails.form.user',
      text: 'emails.form.user', // プレーンテキストで送信
    );
}

メール用テンプレート追加

管理者宛メール

# /resources/views/emails/form/admin.blade.php

{{ $form_data['name'] }} 様より下記の内容のお問い合わせがありました

==============================
お問い合わせ内容
==============================
■会社名:
{{ $form_data['company'] }}
■お名前:
{{ $form_data['name'] }}
■フリガナ:
{{ $form_data['name_kana'] }}
■メールアドレス:
{{ $form_data['email'] }}
■電話番号:
{{ $form_data['phone'] }}
■お問い合わせ内容:
{{ $form_data['body'] }}
------------------------------

ユーザー宛メール

# /resources/views/emails/form/user.blade.php

{{ $form_data['name'] }} 様
この度はお問い合わせいただき有難うございます。

==============================
お問い合わせ内容
==============================
■会社名:
{{ $form_data['company'] }}
■お名前:
{{ $form_data['name'] }}
■フリガナ:
{{ $form_data['name_kana'] }}
■メールアドレス:
{{ $form_data['email'] }}
■電話番号:
{{ $form_data['phone'] }}
■お問い合わせ内容:
{{ $form_data['body'] }}
------------------------------

メール送信処理追加

FormController にメール送信処理を追加します。

メール送信

# /app/Http/Controllers/FormController.php

/**
  * メール送信
  */
public function sendMail(ContactFormRequest $request)
{
  // 
  $form_data = $request->validated();

  // 送信先メールアドレス
  $email_admin = 'admin@example.com';
  $email_user  = $form_data['email'];

  // 管理者宛メール
  Mail::to($email_admin)->send( new FormAdminMail($form_data) );
  // ユーザー宛メール
  Mail::to($email_user)->send( new FormUserMail($form_data) );
  
  // ログ
  // Log::debug($form_data['name']. ' さまよりお問い合わせ');

  // 
  return to_route('form.complete');
}

use宣言で各クラス追加

use Illuminate\Support\Facades\Log; // ログを利用する場合
use Illuminate\Support\Facades\Mail;
use App\Http\Requests\ContactFormRequest;
use App\Mail\FormAdminMail;
use App\Mail\FormUserMail;

送信処理用のルーティング設定

# /routes/web.php

// postされた際に送信処理を実行するようにする
Route::post('/form', [FormController::class, 'sendMail']);

動作環境情報

"macOS Ventura" 13.1
"Docker Desktop" 4.15.0
"Laravel Sail"
"Laravel Framework" 9.43.0

関連記事

コメント

タイトルとURLをコピーしました