お問合せフォームを置くことで、ユーザーからの要望やバグ報告などを受け取りやすくなります。今回はお問合せフォームに入力すると任意のメールアドレスにメールが送られるような設定にしようと思います。
ルーティング
まずはルーティングを作成します。このように書きます。
web.php
説明Route::get('/contact', 'ContactController@index')->name('index');
//確認ページ
Route::post('/contact/confirm', 'ContactController@confirm')->name('confirm');
//送信完了ページ
Route::post('/contact/thanks', 'ContactController@send')->name('send');
フォーム画面表示、確認ページ、送信完了ページへのルーティングをそれぞれ作成します。
コントローラー
次にコントローラーを作成します。
まずはコマンド入力してコントローラーファイルを生成しましょう。
php artisan make:controller ContactController
コントローラーファイルができたらメソッドを追記していきます。
ContactController.php
説明<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\ContactFormRequest;
use App\Mail\ContactSendmail;
class ContactController extends Controller
{
public function index()
{
return view('contact.index');
}
public function confirm(ContactFormRequest $request)
{
$contact = $request->all();
return view('contact.confirm',compact('contact'));
}
public function send(ContactFormRequest $request)
{
$contact = $request->all();
\Mail::to('your_address@example.com')->send(new ContactSendmail($contact));
$request->session()->regenerateToken();
return view('contact.thanks');
}
}
indexでは単に viewファイルを返しています。
confirmはPOST通信で送られてきたデータを受け取ってviewに渡すという処理を行なっています。
sendは同じくPOST通信で送られたデータを受け取り、生成したMailableクラスを使って、メール送信処理を行なっています。
FormRequest
まずはPOSTで値を受け取るためにFormRequestを作成します。
php artisan make:request ContactFormRequest
生成されたファイルにこのように追記します。
ContactFormRequest.php
説明<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ContactFormRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'email' => 'required|email',
'contact' => 'required'
];
}
}
これで、バリデーションを分離して値を受け取ることができるようになりました。
view
ここからはviewファイルを作って行きます。
お問合せフォームと内容確認画面を作りましょう。
resources/views/contact/index.blade.php
説明@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-12">
<div class="card">
<div class="card-header">お問い合わせ</div>
<div class="card-body">
<form method="POST" action="{{ route('confirm') }}">
@csrf
<div class="form-group row">
<label for="email" class="col-md-3 col-form-label text-md-right">メールアドレス</label>
<div class="col-md-9">
<input id="email" type="text" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" autofocus>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="contact" class="col-md-3 col-form-label text-md-right">お問い合わせ内容</label>
<div class="col-md-9">
<textarea id="contact" class="form-control @error('contact') is-invalid @enderror" name="contact" cols="30" rows="10"></textarea>
@error('contact')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-9 offset-md-3">
<button type="submit" class="btn btn-primary">
お問い合わせ内容の確認へ
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
細かいところは適当で大丈夫です。
とにかくフォームタグでPOST通信をすることができればOKです。
次に確認画面です。
resources/views/contact/confirm.blade.php
説明@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-12">
<div class="card">
<div class="card-header">お問い合わせ内容確認</div>
<div class="card-body">
<form method="POST" action="{{ route('send') }}">
@csrf
<input type="hidden" name="email" value="{{ $contact['email'] }}">
<input type="hidden" name="contact" value="{{ $contact['contact'] }}">
<div class="row">
<label for="email" class="col-md-3 text-md-right">メールアドレス:</label>
<div class="col-md-9">
{{ $contact['email'] }}
</div>
</div>
<div class="row">
<label for="contact" class="col-md-3 text-md-right">お問い合わせ内容:</label>
<div class="col-md-9">
{{ $contact['contact'] }}
</div>
</div>
</div>
<div class="form-group row">
<div class="offset-md-1 col-md-3">
<a href="{{ route('index') }}" class="btn btn-info"><戻る</a>
</div>
<div class="col-md-2 offset-md-6">
<button type="submit" class="btn btn-primary">
送信>
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
POSTで受け取った値を表示すると同時に、hiddenで隠しデータとしてさらにPOST通信を行います。
メールの本文にあたるviewも作成しておきましょう。
resources/views/contact/mail.blade.php
説明お問い合わせメールを受け付けました。<br>
<br>
◆メールアドレス<br>
{!! $email !!}<br>
<br>
◆カテゴリー<br>
{!! $category !!}<br>
<br>
◆お問い合わせ内容<br>
{!! nl2br($contact) !!}
Mailableクラスの作成
次に、Mailableクラスを作成します。
php artisan make:mail ContactSendmail
作られたファイルにはこのように記述します。
app/Mail/ContactSendmail.php
説明<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class ContactSendmail extends Mailable
{
use Queueable, SerializesModels;
private $email;
private $contact;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct($contact)
{
$this->email = $contact['email'];
$this->contact = $contact['contact'];
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this
->from($this->email)
->subject('自動送信メール')
->view('contact.mail')
->with([
'email' => $this->email,
'contact' => $this->contact,
]);
}
}
これで送信処理は完成です。
送信完了ページ
送信後のviewファイルも簡単に作っておきましょう。
thanks.blade.php
説明@extends('layouts.app')
@section('content')
<div class="conrainer">
<div class="card">
<div class="card-body">
送信しました。
</div>
</div>
</div>
@endsection
終わりに
以上でお問合せフォームは完成です。
オリジナルアプリ作成の際にはぜひ作ってみましょう!