參考 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',
        ];
    }
}

測試

最後修改日期: 2020 年 11 月 18 日