Laravel5.5 LTS 日本語ドキュメント

このリポジトリはPHP Webアプリフレームワークである、LaravelのLTSバージョンである5.5の公式英文ドキュメントを日本語へ翻訳しています。

This project is maintained by okinaka

メール

イントロダクション

Laravelは人気の高いSwiftMailerライブラリーのクリーンでシンプルなAPIを提供しています。SMTP、Mailgun、SparkPost、Amazon SES、PHPのmail機能、sendmailドライバーを提供しており、選択したローカルやクラウドベースのサービスを使い、素早くメール送信が開始できるようにしています。

ドライバの動作要件

MailgunとSparkPostなどAPIベースドライバはシンプルでSMTPサーバよりも高速です。可能であれば、こうしたドライバを使用しましょう。APIドライバはすべて、Guzzle HTTPライブラリを必要としますので、Composerパッケージマネージャでインストールしてください。

composer require guzzlehttp/guzzle

Mailgunドライバ

Mailgunドライバを使用する場合、最初にGuzzleをインストールしてください。それからconfig/mail.php設定ファイル中のdriverオプションをmailgunに設定してください。次にconfig/services.php設定ファイルが以下のオプションを含んでいるか確認してください。

'mailgun' => [
    'domain' => 'your-mailgun-domain',
    'secret' => 'your-mailgun-key',
],

SparkPostドライバ

SparkPostドライバを使用するには、最初にGuzzleをインストールし、次にconfig/mail.php設定ファイル中のdriverオプションをsparkpostに設定してください。config/services.php設定ファイルに以下のオプションが含まれているか確認してください。

'sparkpost' => [
    'secret' => 'your-sparkpost-key',
],

SESドライバ

Amazon SESドライバを使う場合、Amazon AWS SDK for PHPをインストールしてください。composer.jsonファイルのrequireセクションに以下の行を追加し、composer updateコマンドを実行します。

"aws/aws-sdk-php": "~3.0"

次にconfig/mail.php設定ファイルのdriverオプションをsesに設定します。それからconfig/services.php設定ファイルが以下の内容になっているか確認してください。

'ses' => [
    'key' => 'your-ses-key',
    'secret' => 'your-ses-secret',
    'region' => 'ses-region',  // e.g. us-east-1
],

Mailable概論

Laravelではアプリケーションが送信する、各種メールタイプを”mailable”クラスとして表します。これらのクラスは、app/Mailディレクトリに保存します。アプリケーションにこのディレクトリが存在していなくても、心配ありません。make:mailコマンドを使用して、最初にmailableクラスを生成する時に、作成されます。

php artisan make:mail OrderShipped

Mailableプログラミング

全mailableクラスの設定は、buildメソッド中で行います。このメソッド中でメールのプレゼンテーションとデリバリーを設定する、fromsubjectviewattachなど様々なメソッドを呼び出します。

Senderの設定

fromメソッドの使用

最初に、メールの送信者の設定を見てみましょう。言い換えれば、”from”により、メールを送信する人を指定します。送信者の設定には2つの方法があります。最初にmailableクラスのbuildメソッドの中で、fromメソッドを使う方法です。

/**
 * メッセージの生成
 *
 * @return $this
 */
public function build()
{
    return $this->from('example@example.com')
                ->view('emails.orders.shipped');
}

グローバルfromアドレスの使用

もし、アプリケーションで同じ”from”アドレスを全メールで使用するのであれば、生成する全mailableクラスでfromメソッドを呼び出すのは面倒です。代わりに、グローバルな”from”アドレスをconfig/mail.php設定ファイルで指定しましょう。このアドレスは、mailableクラスの中で、”from”アドレスが指定されなかった場合に使用されます。

'from' => ['address' => 'example@example.com', 'name' => 'App Name'],

ビューの設定

mailableクラスのbuildメソッドの中で、メールの中身をレンダーする時に使用するテンプレートをviewメソッドにより指定できます。各メールでは内容をレンダーするのにBlade テンプレートを通常使用しますので、メールのHTMLを構築する時にBladeテンプレートエンジンのパワーと利便性をフルに利用できます。

/**
 * メッセージの生成
 *
 * @return $this
 */
public function build()
{
    return $this->view('emails.orders.shipped');
}

{tip} メール用テンプレートをすべて設置する、resources/views/emailsディレクトリを作成することができます。しかし、resources/viewsディレクトリの中であれば、好きな場所へ自由に設置できます。

平文テキストメール

平文テキスト版のメールを定義したいときは、textメソッドを使います。viewメソッドと同様に、textメソッドは、メールの内容をレンダーするために使用する、テンプレート名を引数に取ります。メッセージのHTML版と平文テキスト版の両方を定義することも可能です。

/**
 * メッセージの生成
 *
 * @return $this
 */
public function build()
{
    return $this->view('emails.orders.shipped')
                ->text('emails.orders.shipped_plain');
}

ビューデータ

publicプロパティ使用

通常、メールのHTMLをレンダーする時には、ビューへ使用するデータを渡します。ビューでデータを使用できるようにするには、2つの方法があります。まず、mailableクラスで定義したpublicプロパティは、ビューで自動的に利用できます。そのため、たとえばmailableクラスのコンストラクタへデータを渡し、そのデータをクラス上のプロパティとして定義できます。

<?php

namespace App\Mail;

use App\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class OrderShipped extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * 注文インスタンス
     *
     * @var Order
     */
    public $order;

    /**
     * 新しいメッセージインスタンスの生成
     *
     * @return void
     */
    public function __construct(Order $order)
    {
        $this->order = $order;
    }

    /**
     * メッセージの生成
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped');
    }
}

データをpublicプロパティにセットしたら、自動的にビューで使用できるようになり、Bladeテンプレート中で、他のデータと同様にアクセスできます。

<div>
    Price: 
</div>

withメソッド使用

メールのデータフォーマットをテンプレートへ渡す前にカスタマイズしたい場合は、withメソッドを使いデータをビューへ渡すことができます。通常、この場合もデータをmailableクラスのコンストラクタで渡すことになるでしょう。しかし、自動的にテンプレートで使用可能にならないように、protectedprivateプロパティへデータをセットしてください。それから、テンプレートで使用したいデータの配列を引数として、withメソッドを呼び出してください。

<?php

namespace App\Mail;

use App\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class OrderShipped extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * 注文インスタンス
     *
     * @var Order
     */
    protected $order;

    /**
     * 新しいメッセージインスタンスの生成
     *
     * @return void
     */
    public function __construct(Order $order)
    {
        $this->order = $order;
    }

    /**
     * メッセージの生成
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped')
                    ->with([
                        'orderName' => $this->order->name,
                        'orderPrice' => $this->order->price,
                    ]);
    }
}

withメソッドへ渡したデータは、ビューで自動的に使用可能になり、Bladeテンプレートの他のデータと同様にアクセスできます。

<div>
    Price: 
</div>

添付

メールへ添付するには、attachメソッドをmailableクラスのbuildメソッド中で呼び出します。attachメソッドは最初の引数に、ファイルのフルパスを取ります。

    /**
     * メッセージの生成
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped')
                    ->attach('/path/to/file');
    }

ファイルをメッセージ添付する場合、attachメソッドの第2引数として配列を渡し、表示名やMIMEタイプを指定することもできます。

    /**
     * メッセージの生成
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped')
                    ->attach('/path/to/file', [
                        'as' => 'name.pdf',
                        'mime' => 'application/pdf',
                    ]);
    }

Rawデータ添付

attachDataメソッドは添付内容のバイト文字列をそのまま添付する場合に使用します。たとえば、メモリ中でPDFを生成し、それをディスクに書き出さずに、メールへ添付したい場合にこのメソッドを使用できます。attachDataメソッドはrawデータバイトを最初の引数に取り、ファイル名を第2引数に、オプションの配列を第3引数に取ります。

    /**
     * メッセージの生成
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped')
                    ->attachData($this->pdf, 'name.pdf', [
                        'mime' => 'application/pdf',
                    ]);
    }

インライン添付

インライン画像をメールに埋め込むのは、通常手間がかかります。しかし、Laravelは画像をメールに付け、最適なCIDを得る便利な方法を提供しています。インラインイメージを埋め込むには、メールビューの中で$message変数のembedメソッドを使ってください。Laravelでは全メールテンプレートで、$message変数が使用できるようになっていますので、この変数を渡すことについては心配する必要はありません。

<body>
    ここに画像:

    <img src="">
</body>

{note} Markdownメッセージでは、$message変数は使用できません。

添付Rawデータの埋め込み

メールテンプレートへ埋め込むrawデータ文字列を既に用意してある場合は、$message変数のembedDataメソッドを使ってください。

<body>
    ここにrawデータからの画像:

    <img src="">
</body>

SwiftMailerメッセージのカスタマイズ

MailableベースクラスのwithSwiftMessageクラスにより、メッセージ送信前にSwiftMailerメッセージインスタンスを直接呼び出すコールバクを登録できます。これにより配信する前に、メッセージを送信する機会を得られます。

    /**
     * メッセージの生成
     *
     * @return $this
     */
    public function build()
    {
        $this->view('emails.orders.shipped');

        $this->withSwiftMessage(function ($message) {
            $message->getHeaders()
                    ->addTextHeader('Custom-Header', 'HeaderValue');
        });
    }

Markdown Mailable

Markdown mailableメッセージにより、事前に構築したテンプレートとメール通知のコンポーネントの利点をMailable中で利用できます。メッセージをMarkdownで記述すると、Laravelは美しいレスポンシブHTMLテンプレートをレンダーすると同時に、自動的に平文テキスト版も生成します。

Markdown Mailableの生成

対応するMarkdownテンプレートを指定し、Mailableを生成するには、make:mail Artisanコマンドを--markdownオプション付きで使用します。

php artisan make:mail OrderShipped --markdown=emails.orders.shipped

次に、buildメソッド内で、Mailableを設定します。viewメソッドの代わりに、markdownメソッドを呼び出します。markdownメソッドはMarkdownテンプレートの名前とテンプレートで使用するデータの配列を引数に取ります。

/**
 * メッセージの生成
 *
 * @return $this
 */
public function build()
{
    return $this->from('example@example.com')
                ->markdown('emails.orders.shipped');
}

Markdown Messageの記述

Markdown MailableではBladeコンポーネントとMarkdown記法が利用でき、メールメッセージを簡単に構築できると同時に、Laravelが用意しているコンポーネントも活用できます。

@component('mail::message')
# 発送のお知らせ

商品が発送されました!

@component('mail::button', ['url' => $url])
注文の確認
@endcomponent

ありがとうございました。<br>
 様
@endcomponent

{tip} Markdownメールを書く場合は、過剰なインデントを付けないでください。Markdownは段付をコードブロックとしてパースします。

Buttonコンポーネント

ボタンコンポーネントは中央寄せのボタンリンクをレンダーします。このコンポーネントは引数として、urlとオプションのcolorを受け取ります。サポートしている色はbluegreenredです。メッセージに好きなだけのボタンコンポーネントを追加できます。

@component('mail::button', ['url' => $url, 'color' => 'green'])
注文の確認
@endcomponent

Panelコンポーネント

パネルコンポーネントは、メッセージの他の部分とは少し異なった背景色のパネルの中に、指定されたテキストブロックをレンダーします。これにより、指定するテキストに注目を集められます。

@component('mail::panel')
ここはパネルの内容です。
@endcomponent

Tableコンポーネント

テーブルコンポーネントは、MarkdownテーブルをHTMLテーブルへ変換します。このコンポーネントはMarkdownテーブルを内容として受け入れます。デフォルトのMarkdownテーブルの記法を使った、文字寄せをサポートしています。

@component('mail::table')
| Laravel       | テーブル      | 例       |
| ------------- |:-------------:| --------:|
| Col 2 is      | 中央寄せ      | $10      |
| Col 3 is      | 右寄せ        | $20      |
@endcomponent

コンポーネントのカスタマイズ

自身のアプリケーション向きにカスタマイズできるように、Markdownメールコンポーネントは全てエクスポートできます。コンポーネントをエクスポートするには、vendor:publish Artisanコマンドを使い、laravel-mailアセットを公開します。

php artisan vendor:publish --tag=laravel-mail

このコマンドにより、resources/views/vendor/mailディレクトリ下にMarkdownメールコンポーネントが公開されます。mailディレクトリ下に、htmlmarkdownディレクトリがあります。各ディレクトリは名前が示す形式で、利用できるコンポーネント全てのレスポンシブなプレゼンテーションを持っています。これらのコンポーネントはお好きなように自由にカスタマイズしてください。

CSSのカスタマイズ

コンポーネントをエクスポートすると、resources/views/vendor/mail/html/themesディレクトリに、default.cssファイルが用意されます。このファイル中のCSSをカスタマイズすれば、Markdownメールメッセージ変換後のHTML形式の中に、インラインCSSとして自動的に取り込まれます。

{tip} Markdownコンポーネント全体の新しいテーマを作成したい場合は、html/themesの中に新しいCSSファイルを記述し、mail設定ファイルのthemeオプションを変更するだけです。

ブラウザでのMailableプレビュー

mailableのテンプレートをデザインしているとき、Bladeテンプレートのようにブラウザでレンダし、簡単にレビューできると便利です。そのため、Laravelでは、ルートのクロージャやコントローラから直接mailableを返すことができます。mailableが返されるとレンダされ、ブラウザに表示されますので、実際のメールアドレスへ送る必要はなく、素早くレビューできます。

Route::get('/mailable', function () {
    $invoice = App\Invoice::find(1);

    return new App\Mail\InvoicePaid($invoice);
});

メール送信

メッセージを送信するには、Mailファサードtoメソッドを使います。toメソッドはメールアドレス、ユーザーインスタンス、もしくはユーザーのコレクションを引数に取ります。一つのオブジェクト、もしくはオブジェクトのコレクションを渡すと、メーラは自動的にそれらのemailnameプロパティを使用します。そのため、オブジェクトで、その属性を確実に使用可能にしてください。送信先を指定し終えたら、mailableクラスのインスタンスをsendメソッドへ渡してください。

<?php

namespace App\Http\Controllers;

use App\Order;
use App\Mail\OrderShipped;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Http\Controllers\Controller;

class OrderController extends Controller
{
    /**
     * 注文の配送
     *
     * @param  Request  $request
     * @param  int  $orderId
     * @return Response
     */
    public function ship(Request $request, $orderId)
    {
        $order = Order::findOrFail($orderId);

        // 配送処理…

        Mail::to($request->user())->send(new OrderShipped($order));
    }
}

もちろん、メール送信時に”to”で受取人を指定するだけに限りません。”to”、”cc”、”bcc”による受取人をすべて一つのメソッドチェーンで呼び出せます。

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->send(new OrderShipped($order));

キュー使用メール

メールメッセージのキューイング

メールメッセージを送ることにより、アプリケーションのレスポンス時間が極端に長くなり得るため、多くの開発者はメールメッセージをバックグランドで送信するためにキューイングすることを選びます。Laravelの統一されたキューAPIを使うことで、簡単に実現できます。メールメッセージをキューへ送るには、Mailファサードへ、受取人の指定の後に、queueメソッドを使います。

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->queue(new OrderShipped($order));

このメソッドはバックグラウンドでメールを送信するため、自動的にジョブをキューに投入する面倒を見ます。もちろん、この機能を使用する前にキューの設定を行う必要があります。

遅延メッセージキュー

メッセージを投入するキューを指定したい場合、laterOnメソッドを使用します。最初の引数に、laterメソッドは、メッセージを送信する時間を示すDateTimeインスタンスを受け取ります。

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

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->later($when, new OrderShipped($order));

特定のキューに投入

make:mailコマンドにより生成されたmailableクラスにはすべて、Illuminate\Bus\Queueableトレイトが使用されています。接続とキュー名を指定する、onQueueonConnectionメソッドをすべてのmailableクラスインスタンスで呼び出せます。

$message = (new OrderShipped($order))
                ->onConnection('sqs')
                ->onQueue('emails');

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->queue($message);

デフォルトとしてキュー投入

いつもMailableクラスをキューへ投入したければ、クラスへShouldQueue契約を実装してください。それで、メール送信時にsendメソッドを呼びだせば、そのMailableクラスは契約が実装されていますので、いつもキューイングされます。

use Illuminate\Contracts\Queue\ShouldQueue;

class OrderShipped extends Mailable implements ShouldQueue
{
    //
}

メールとローカル開発

メールを送信するアプリケーションを開発している間は、実際のメールアドレスにメールを送信したくはありません。Laravelはメールメッセージを実際に送信することをローカルでの開発期間の間、「無効」にする様々な方法を用意しています。

Logドライバ

メールを送信する代わりに、logメールドライバで、すべてのメールメッセージを確認のためにログファイルへ書き込こめます。アプリケーションの設定に関する詳細は、設定のドキュメントを確認してください。

全メールの送信先指定

Laravelが提供するもう一つの解決策は、フレームワークが送信する全メールの共通受け取り先を設定する方法です。この方法を使うと送信メッセージに指定した実際のアドレスの代わりに、アプリケーションが送る全メールを特定のアドレスに送信します。この方法を使用する場合、config/mail.php設定ファイルでtoオプションを指定します。

'to' => [
    'address' => 'example@example.com',
    'name' => 'Example'
],

Mailtrap

最後の方法はMailtrapのようなサービスを使い、smtpドライバで本当のメールクライアントにより内容を確認できる「ダミー」のメールボックスへメールメッセージを送る方法です。このアプローチの利点は最終的なメールをMailtrapのメッセージビュアーで実際に確認できることです。

イベント

Laravelはメールメッセージ送信の過程で、イベントを2つ発行します。MessageSendingイベントは、メッセージが送信される前に発行され、一方のMessageSentイベントは、メッセージを送った後に発行されます。2つのイベントは、キューした時点でなく、メールが送信された時に発行されることを覚えておいてください。これらに対するイベントリスナは、EventServiceProviderで定義できます。

/**
 * アプリケーションへマッピングするイベントリスナ
 *
 * @var array
 */
protected $listen = [
    'Illuminate\Mail\Events\MessageSending' => [
        'App\Listeners\LogSendingMessage',
    ],
    'Illuminate\Mail\Events\MessageSent' => [
        'App\Listeners\LogSentMessage',
    ],
];