こんにちは。もんしょー(@sima199407)です。
という質問があるかと思います。
今回は、Laravel5.6を使ったメール実装の方法についてご紹介でして、その中でもお問い合わせのためのフォームの作り方になります。
最近はWebサイトを作るときにGoogleフォームを使って、コードを貼り付けるだけでかんたんに実装できるようになりましたが、自由度の高い独自のフォームを作ること機会があるかと思います。
では早速見ていきましょう!
開発環境
今回使う環境は以下の通り。
・Laravel5.6
・docker
・Nginx
・MacOS
・mailtrap
MacOSの環境でdockerで仮想環境を作り、Laravelを動かしていきます。
もし環境設定が必要な方は「【シンプル解説】docker-composeを使ってLaravel,nginx,MySQL環境構築する」で解説していますので読んでみてください。
最後のmailtrapというはテスト用のメールサーバーになります。
「本番用のサーバーを使って作業する前にテストしたい!」という人はぜひ使ってみてください。
使い方についてもこのページで説明します。
メール機能の実装方法
メール機能の実装は以下の方法で行います。
マイグレーションファイル作成
ルートを作成
コントローラー
モデル
viewファイル
リクエスト←作る理由は?
mailableクラスを作成
という流れでやっていこうと思います。
完成図
・ 名前
・ メールアドレス
・ 内容
とシンプルな形にします。
マイグレーションファイル作成
まずはDBの型を作っていきます
$ php artisan make:migration create_contacts_table --create=contacts
ファイル名は[create_contacts_table]にしまして、[--create=contacts]でDBのテーブル名をcontactsに指定します。
そして、/database/migrations/に移動して上記で作成したファイルを編集します。
/database/migrations/create_contacts_table
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateContactsTable extends Migration
{
public function up()
{
Schema::create('contacts', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email');
$table->text('body');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('contacts');
}
}
こんな感じです。
[$table->]には必要最低限のデータしか入れてません。
件名や電話番号を入れたいときは、string型などで追記すれば増やすことができます。
~
$table->string(’title’);
$table->string(’tel');
~
ルート作成
ついでにルートも作っておきましょう。
routes/web.php
Route::get('contact', 'ContactController@index');
Route::post('contact/confirm', 'ContactController@confirm');
Route::post('contact/complete', 'ContactController@complete');
確認画面もつけておくので、confirmルートもつけておきましょう!
Controllers作成
まず、型となるファイルをコマンドで作成します。
$ php artisan make:controller ContactController --model=Contact
オプション[--model]をつけることでモデルも一緒に作成します。
こんなふうに聞かれますので、「yes」と入力
$ php artisan make:controller ContactController --model=Contact
A App\Contact model does not exist. Do you want to generate it? (yes/no) [yes]:
> yes
Model created successfully.
Controller created successfully.
そして ContactControllerを以下のように編集します。
とりあえず、indexのみを作成します。
app/Http/Controllers/ContactController.php
class ContactController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
return view('contacts.index');
}
Model作成
先程Controllersを作ったときに一緒に作成したModelファイルも編集します。
ここでは,protected $fillable = []を使って、扱ってもいいデータの名前を入れます。これをホワイトリスト形式といいます。
※fillable→代入可能という意味。
app/Contact.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Contact extends Model
{
protected $fillable = [
'name', 'email', 'body'
];
}
name,email,bodyは必須項目に設定しておきます。
モデルにはファイル名の付け方に条件がありましてそれが
・最初を大文字
・単数形
という条件がありますので気をつけましょう。
View作成
ではフロンド部分にあたるViewを作っていきましょう。
そのときにviewファイルをまとめておきたいので、viewディレクトリ直下にcontactsディレクトリを作成します。
$ cd resources/views
$ mkdir contacts
resources/views/contacts/index.blade.php
<div class="container">
<div class="col-12">
<h2 class="text-center page-title">お問い合わせ</h2>
</div>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
{!! Form::open(['url' => 'contact/confirm','class' => 'form-horizontal']) !!}
<div class="row">
<!-- form1 -->
<div class="col-12 form-group{{ $errors->has('name') ? ' has-error' :''}}">
<div class="offset-md-3 col-sm-5 col-md-4">
{!! Form::label('name', 'お名前(もしくは企業名):', ['class' => 'sizeM control-label']) !!}
</div>
<div class="offset-md-3 col-sm-7 col-md-6">
{!! Form::text('name', null, ['class' => 'form-control']) !!}
</div>
@if ($errors->has('name'))
<span class="help-block">
<strong>{{ $errors->first('name') }}</strong>
</span>
@endif
</div>
<!-- form2 -->
<div class="col-12 form-group{{ $errors->has('email') ? ' has-error' :''}}">
<div class="offset-md-3 col-sm-5 col-md-4">
{!! Form::label('email', 'メールアドレス:', ['class' => 'sizeM control-label']) !!}
</div>
<div class="offset-md-3 col-sm-7 col-md-6">
{!! Form::email('email', null, ['class' => 'form-control']) !!}
</div>
@if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
</div>
<!-- form3 -->
<div class="col-12 form-group{{ $errors->has('body') ? ' has-error' :''}}">
<div class="offset-md-3 col-sm-5 col-md-4">
{!! Form::label('body', '内容:', ['class' => 'sizeM control-label']) !!}
</div>
<div class="offset-md-3 col-sm-7 col-md-6">
{!! Form::textarea('body', null, ['class' => 'form-control']) !!}
</div>
@if ($errors->has('body'))
<span class="help-block"><strong>{{ $errors->first('body') }}</strong>
</span>@endif
</div>
</div>
<div class="col-12 form-group text-center">
{!! Form::submit('確認', ['class' => 'btn-lg btn-primary']) !!}
</div>
{!! Form::close() !!}
</div>
Request作成
次にリクエストの作成です。あまり聞き慣れないかもしれませんが、バリデーションをするためにこのファイルをつかいます。
$ php artisan make:request ContactRequest
app/Http/Requests/ContactRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ContactRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required|max:10',
'email' => 'required|email',
'body' => 'required|max:1000'
];
}
public function attributes() {
return [
'name' => 'お名前',
'email' => 'メールアドレス',
'body' => '内容'
];
}
}
文字数の制限やemail形式なっているかどうかも判断してます。
そしてこのRequestはControllerファイルで使うことができます。
以下のような感じで使いますので、ContactController.phpを編集してます。
app/Http/Controllers/ContactController.php
public function index()
{
return view('contacts.index');
}
public function confirm(ContactRequest $request)
{
$contact = new Contact($request->all());
return view('contacts.confirm');
}
// 保存
public function complete(ContactRequest $request)
{
$input = $request->except('action');
if ($request->action === '戻る') {
return redirect()->action('ContactController@index')->withInput($input);
}
// データを保存
Contact::create($request->all());
// 二重送信防止
$request->session()->regenerateToken();
return view('contacts.complete');
$name = $request->name;
$body = $request->body;
$to = $request->email;
// $bcc = 'bcc@mail.com';
Mail::to($request->email)
// ->bcc('test@bcc.com')
->send(new \App\Mail\Contact($name, $body));
}
使うのはファンクションの一番最初ですね。
function complete(ContactRequest $request)
→function FUNCTIONNAME(Requestファイル名 $request)
こんな感じで、Requestを使っていきます。
ちなみにバリデーションから通過したデータはどうやって受け取る方法は
→[$request->all()]で受け取ることができます。
送信メールでCCやBCCを送る方法は1行追加してあげればOKです
Mail::to($request->email)
->bcc('test@bcc.com')
->send(new \App\Mail\Contact($name, $body));
ここまでで一連の流れを作ることができました。
次に実際にメールを送るテストも行っていきましょう。
メール送信設定
ターミナルでartisanコマンドを叩きましょう。
$ php artisan make:mail Contact
ファイルを編集していきましょう。
app/Mail/Contact.php
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class Contact extends Mailable
{
use Queueable, SerializesModels;
protected $title;
protected $body;
public function __construct($name, $body)
{
$this->title = sprintf('%s様、お問い合わせありがとうございます', $name);
$this->body = $body;
}
public function build()
{
return $this->view('email.to')
->subject($this->title)
->with([
'body' => $this->body,
]);
}
}
メールの本文を作ってみると以下通りにします。
resources/views/email/to.blade.php
<div>この度はお問い合わせありがとうございます。</div>
<div>下記の内容で受付致しました。</div>
<div>【名前】</div>
<div>{{$_POST['name']}}</div>
<div>【お問い合わせ内容】</div>
<div>{{$_POST['body']}}</div>
ここまででLaravel側の設定は終了です。
送信者情報を追加してテスト送信を行う
Laravelでの設定が終わったら、送信するための情報を設定しましょう。
envファイルから追加することができるので確認します。
必要な情報は以下の通り
./env
MAIL_DRIVER=smtp
MAIL_HOST=HOSTNAME
MAIL_PORT=2525
MAIL_USERNAME=USERNAME
MAIL_PASSWORD=PASSWORD
MAIL_FROM_ADDRESS=YOURTEST@YOURTEST.com //送信アドレス
MAIL_FROM_NAME=Example
メールサーバーに書いてある情報を使えばオッケーです。
mailtapを使ってみよう
とりあえずテストするんだったら無料のテストメールサーバー、mailtapが便利です。
開発環境でメール送信するときはこちらを使いましょう。
登録ができたら「SMTP Settings」→「Integrations」を探して、「laravel」を選択するとenvファイルにコピペする内容がでてきます。
それをenvファイルにコピペすればオッケーです。
まとめ
ここまでお疲れさまでした!
これでシンプルなメール送信機能が完成しました。
お役にたてば幸いです。