參考 Laravel 官方文件 (我是使用 6.x LTS),建立一個簡單的手動寄信功能,其餘詳細用法請參考 Laravel 官方文件。
Laravel 的寄信功能是使用 Symfony SwiftMailer 及 Guzzle HTTP Library,讓我們可以選擇 SMTP、Mailgun、Postmark、Amazon SES 和 sendmail 來寄信。基本上安裝 Laravel 時已經將這兩個套件包含在內,不需要額外安裝。
composer require guzzlehttp/guzzle
修改 .env 加入 mail 的基本設定
這邊我是使用 smtp 的方式,透過 mailtrap.io 的信箱當作測試。需要使用別種方式,請參考 Laravel 官方文件。
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=admin@mail.com
MAIL_FROM_NAME="${APP_NAME}"
建立 Mailable
這邊的用途主要就是集中管理所有的寄信功能 (全部放置於 App\Mail 目錄下),若網站有很多種寄信用途 (例如: 寄送發票、寄送通知…等等),可以用此種方法來集中管理,這樣就不需要一直重複在Controller 中 撰寫又臭又長的程式碼。
php artisan make:mail AdminSendMail
修改 App\Mail\AdminSendMail.php
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class AdminSendMail extends Mailable
{
use Queueable, SerializesModels;
public $details;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct($details)
{
$this->details = $details;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->subject($this->details['subject']) //主旨
->view('admin.mails.contents.adminsendmailbody'); //使用blade
// ->from($this->details['from'], $this->details['name']) //From
// ->text('emails.orders.shipped_plain') //純文字
// ->with([ //附帶變數
// 'Name' => $this->details->name,
// 'Text' => $this->details->text,
// ])
// ->attach('/path/to/file') //附帶檔案
// ->attach('/path/to/file', [ //附帶指定格式檔案
// 'as' => 'name.pdf',
// 'mime' => 'application/pdf',
// ])
// ->attachFromStorage('/path/to/file') //從Storage附帶檔案
// ->attachFromStorage('/path/to/file', 'name.pdf', [
// 'mime' => 'application/pdf'
// ])
// ->attachFromStorageDisk('s3', '/path/to/file') //從AWS S3, Storage附帶檔案
// ->attachData($this->pdf, 'name.pdf', [
// 'mime' => 'application/pdf',
// ])
}
}
新增 blade
adminsendmailbody.blade.php (信件內容) 這個主要是用來傳遞信件內容的資料,裡面用到 $details->title 就是寄信表單的標題,$details->content 就是寄信表單的內容,由於有使用到 CKeditor 來做內容,所以必須改用 {!! !!} 此種方式來將資料放入。
<h3>{{ $details->title }}</h3>
<div>
{!! $details->content !!}
</div>
adminsendmailform.blade.php (寄信用表單)
<form id="myform" action="{{ route('admin.sendmail') }}" method="POST" role="form">
@csrf
<div class="card-body">
<div class="form-group">
<label for="exampleInputEmail1">To</label>
<input type="email" class="form-control {{ $errors->has('email') ? ' is-invalid' : '' }}" id="email" name="email" value="" placeholder="輸入Email">
@if ($errors->has('email'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
</div>
<div class="form-group">
<label for="exampleInputEmail1">主旨</label>
<input type="text" class="form-control {{ $errors->has('subject') ? ' is-invalid' : '' }}" id="subject" name="subject" value="" placeholder="輸入主旨">
@if ($errors->has('subject'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('subject') }}</strong>
</span>
@endif
</div>
<div class="form-group">
<label for="exampleInputEmail1">標題</label>
<input type="text" class="form-control {{ $errors->has('title') ? ' is-invalid' : '' }}" id="title" name="title" value="" placeholder="輸入標題">
@if ($errors->has('title'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('title') }}</strong>
</span>
@endif
</div>
<div class="form-group">
<label>內容</label>
<textarea class="form-control {{ $errors->has('content') ? ' is-invalid' : '' }} " rows="3" id="content" name="content" placeholder="Enter ..."></textarea>
@if ($errors->has('content'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('content') }}</strong>
</span>
@endif
</div>
</div>
<div class="card-footer text-center">
<button type="submit" class="btn btn-primary">發送</button>
</div>
</form>
新增路由,修改 route\web.php
//後台管理員寄信功能
Route::get('mails/sendmail','Admin\MailsController@adminSendMailForm');
Route::post('mails/sendmail','Admin\MailsController@sendmail')->name('sendmail');
建立 MailsController
php artisan make:controller Admin\MailsController
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use View;
use Redirect;
use File;
use Carbon\Carbon;
use Mail;
use Session;
use App\Http\Requests\Admin\AdminSendMailRequest;
use App\Mail\AdminSendMail;
class MailsController extends Controller
{
public function __construct(){
$this->middleware('auth:admin');
}
/**
* Display the Mail Form.
*
* @return \Illuminate\Http\Response
*/
public function adminSendMailForm()
{
return view('admin.mails.adminsendmailform');
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function sendmail(AdminSendMailRequest $request)
{
// dd($request);
try{
Mail::to($request->email)
// ->cc($moreUsers)
// ->bcc($evenMoreUsers)
->send(new AdminSendMail($request));
}
catch(Exception $e){
$message = "信件寄出失敗";
Session::put('error',$message);
}
$message = "信件已寄出給 $request->email";
Session::put('success',$message);
return view('admin.mails.adminsendmailform');
}
}
建立驗證,AdminSendMailRequest
php artisan make:request Admin\AdminSendMailRequest
<?php
namespace App\Http\Requests\Admin;
use Illuminate\Foundation\Http\FormRequest;
use Auth;
class AdminSendMailRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
//必須登入才可以使用這個Request
public function authorize()
{
return Auth::check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
//欄位規則
public function rules()
{
return [
'email'=>'required|email',
'subject'=>'required|string|max:100',
'title'=>'required|string|max:100',
'content'=>'required|string|max:1000',
];
}
}
測試