5.3より新しくなったLaravelのメール機能についてのまとめです。

確認したバージョン

  • PHP 7.0.x
  • Laravel 5.4

Laravelのメール機能は5.3から新しくなっています。

Laravel Mail

Laravel > Mail
http://laravel.com/docs/5.4/mail

Laravelのメール機能をざっくり説明すると次のように役割を分担しています。

  • Bladeテンプレートに本文を書く
  • Mailableクラスで件名や本文を指定する
  • Mailクラスで送信処理を行う

また、Laravel内部ではSwiftMailerを利用しています。
https://github.com/swiftmailer/swiftmailer

ドライバ

メール送信サービスのMailgun、AWSAmazon SESに対応しています。
もちろんsmtpも利用できますよ。

実装してみる

Mailableクラスの追加

In Laravel, each type of email sent by your application is represented as a “mailable” class.

Laravelではメールの種類/内容をMailableと呼称するクラスに定義します。

artisan(アルチザン)コマンドからクラスを生成します。

$ php artisan make:mail Greet

コマンド実行後、App\Mail\Mail.phpが生成されます。
生成直後のクラスです。

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;

class Greet extends Mailable
{
    use Queueable, SerializesModels;

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

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('view.name');
    }
}

viewでBladeテンプレートを指定します。
テンプレートについては後述します。

Mailableの編集

build()でメール本文や件名の指定を行います。

Mailableはコンストラクタを経由して各種データを受け取るのがお作法のようです。
実装例を示します。

class OrderShipped extends Mailable
{
    use Queueable, SerializesModels;

    protected $options;
    protected $content;
    protected $attach;

    public function __construct($options, $content, $attach)
    {
        $this->options = $options;
        $this->content = $content;
        $this->attach  = $attach;
    }
    public function build()
    {
        return $this
            ->from($options['from'], $options['from_name'])
            ->subject($options['subject'])
            ->attachData($this->attach['binary'], $this->attach['file_name']);
            ->view('emails.greet')
            ->with([
                'content' => $content,
            ]);
    }
}

添付ファイルが複数の場合など、次のように書くこともできます。
メソッドチェーンではなくてもOK。

public function build()
{
    foreach ($this->attaches as $attach) {
        $this->attachData($attach['binary'], $attach['file_name']);      
    }
    :

先のLaravel5.4ドキュメントにはあまりオプションが見受けられませんが、5.1ではオプションの一覧が掲載されていました。
https://laravel.com/docs/5.1/mail#sending-mail

上記より引用します。
これだけあれば事足りるでしょう。

$message->from($address, $name = null);
$message->sender($address, $name = null);
$message->to($address, $name = null);
$message->cc($address, $name = null);
$message->bcc($address, $name = null);
$message->replyTo($address, $name = null);
$message->subject($subject);
$message->priority($level);
$message->attach($pathToFile, array $options = []);

// Attach a file from a raw $data string...
$message->attachData($data, $name, array $options = []);

// Get the underlying SwiftMailer message instance...
$message->getSwiftMessage();

なお、Laravelのバージョンは変わっても、この辺りはSwiftMailerなので、同様に利用できるようですね。

テンプレート

テンプレートは単なるLaravelのBladeテンプレートファイルです。
変数の私方が異なるくらいで、コントローラーからviewを呼び出す場合とほとんど同じ感覚で使うことができます。

Atuwebからのご挨拶です。

{{ $content['hoge'] }}
{{ $content['fuga'] }}

@if@foreachも利用できます。


ファイル格納場所はresources/views以下です。
Laravelのドキュメントにならって[resources/views/emails]にまとめておくと良さそうです。

テンプレートの生成

5.4より、artisanコマンド実行時にテンプレートを生成できるようになりました。

次のいずれかのようにコマンドを実行します。

$ php artisan make:mail Greet -m emails.greet
$ php artisan make:mail Greet --markdown=emails.greet

--markdownの示す通り、5.4からはHTMLメールのテンプレートにmarkdownが書けるようになっています。

上記オプション付加した場合、Mailable.build()にmarkdown()がセットされています。

public function build()
{
    return $this->markdown('emails.greet');
}

私は、テンプレートを別途用意するのが面倒なため、サクッとコマンドで用意して上記を書き換えています。

プレーンテキスト/HTMLメール/マークダウン

Mailableクラスで指定したBladeテンプレートをどう処理するかは、呼び出すメソッドで指定します。

プレーンテキスト

プレーンテキストのメールとする場合、text()を呼び出します。
これが、意外とわかりませんでした。

public function build()
{
    return $this->text('emails.greet');
}

テンプレートの開業がそのままメール本文に反映されます。

HTMLメール

view()はテンプレートをHTMLメールとして扱います。

public function build()
{
    return $this->view('emails.greet');
}

Markdown

markdown()は、テンプレート中のmarkdownを解釈してくれるHTMLメールを生成します。

public function build()
{
    return $this->markdown('emails.greet');
}

メール送信

\Mail::to($addresses)
    ->send(new \App\Mail\Greet($options, $content, $attach));

メールはキューに入れたり遅延させることもできますね。

キューに入れるにはsend()のかわりにqueue()を呼び出します。

\Mail::to($addresses)
    ->queue(new \App\Mail\Greet($options, $content, $attach));

遅延送信を行う場合はlater()にCarbonオブジェクトとMailableオブジェクトを与えます。

$when = \Carbon\Carbon::now()->addMinutes(10);

\Mail::to($addresses)
    ->later($when, new \App\Mail\Greet($options, $content, $attach));

わかりやすいですね。

おわりに

かつてはメールヘッダを手動で書くなど、細々と面倒だったメール送信も非常に簡単に処理できますね。
便利です。

この記事はtomita@atuwebがお届けしました。

楽しい開発ライフをお過ごしください。



Laravel: Up and Running: a Framework for Building Modern Php Apps

スポンサーリンク
ad_336
ad_336
  • このエントリーをはてなブックマークに追加
  • Evernoteに保存Evernoteに保存
コメントの入力は終了しました。