Skip to content
Caution: You are browsing the legacy symfony 1.x part of this website.

16日目: メーラー

Symfony version
Language
ORM

昨日、リードオンリーのWebサービスをJobeetに追加しました。 アフィリエイトはアカウントを作ることができますが使えるようにする前に管理者によってアクティベイトされる必要があります。 アフィリエイトがトークンを使えるようにするには、まだemailノーテーションを実装する必要があります。 これが今日作業することです。

symfonyフレームワークはPHPの最高のEメールソリューションの1つ: Swift Mailerを搭載しています。 もちろん、ライブラリはデフォルトの機能の上に追加されたクールな機能を伴ってsymfonyに完全に統合されています。

note

symfony 1.3はバージョン4.1のSwift Mailerを使います。

シンプルなEメールを送信する

アフィリエイトのアカウントが確認されアフィリエイトトークンを渡すときにアフィリエイトに通知するためのシンプルなEメールを送信することから始めましょう。

activateアクションを次のコードで置き換えます:

// apps/backend/modules/affiliate/actions/actions.class.php
class affiliateActions extends autoAffiliateActions
{
  public function executeListActivate()
  {
    $affiliate = $this->getRoute()->getObject();
    $affiliate->activate();
 
    // send an email to the affiliate
    $message = $this->getMailer()->compose(
      array('jobeet@example.com' => 'Jobeet Bot'),
      $affiliate->getEmail(),
      'Jobeet affiliate token',
      <<<EOF
Your Jobeet affiliate account has been activated.
 
Your token is {$affiliate->getToken()}.
 
The Jobeet Bot.
EOF
    );
 
    $this->getMailer()->send($message);
 
    $this->redirect('@jobeet_affiliate_affiliate');
  }
 
  // ...
}

note

コードをきちんと動くようにするたために、Eメールアドレスのjobeet@example.comを実際のものに変更します。

symfonyでのEメール管理はメーラーオブジェクトに集約され、getMailer()メソッドでアクションから取得できます。

compose()メソッドは4つの引数を受け取りEメールメッセージオブジェクトを返します:

  • 送信者のEメールアドレス(from);
  • 受信者のEメールアドレス(to);
  • メッセージの件名;
  • メッセージのボディ;

メッセージの送信はメーラーインスタンスでsend()メソッドを呼び出し引数としてメッセージを渡すだけです。 ショートカットとして、composeAndSend()メソッドを使うことでEメールを作成し送信することを一度にできます。

tip

EメールメッセージはSwift_Messageクラスのインスタンスです。 このオブジェクトの詳しい内容や、ファイル添付のような高度な方法を学ぶにはSwift Mailerの公式ドキュメントを参照してください。

コンフィギュレーション

デフォルトでは、send()メソッドは受信者にメッセージを送信するためにローカルのSMTPサーバーを使おうとします。 もちろん、symfonyの多くのコンポーネントと同じように、これは全体に渡って設定可能です。

ファクトリ

以前の日の間に、すでにuserrequestresponse、もしくはroutingのようなsymfonyのコアオブジェクトを話しました。 これらのオブジェクトはsymfonyフレームワークによって自動的に作成され、設定され、管理されます。 これらはつねにsfContextオブジェクトからアクセス可能で、フレームワークのほかのコンポーネントと同じで、 設定ファイルのfactories.ymlを通して設定可能です。 このファイルのコンフィギュレーションは環境によって設定できます。

sfContextがコアファクトリを初期化するとき、これはコンストラクターに渡すためのクラスの名前(class)とパラメーター(param)のためにfactories.ymlファイルを読み込みます:

response:
  class: sfWebResponse
  param:
    send_http_headers: false

上記のスニペットにおいて、レスポンスファクトリを作るために、symfonyはsfWebResponseオブジェクトをインスタンス化しsend_http_headersオプションをパラメーターとして渡します。

sidebar

sfContextクラス

sfContextオブジェクトはリクエスト、レスポンス、ユーザーなどのsymfonyのコアオブジェクトへの参照を持ちます。 sfContextはSingletonのようにふるまうので、任意の場所からsfContext::getInstance()ステートメントを使えばsymfonyの任意のコアオブジェクトにアクセスできます:

$mailer = sfContext::getInstance()->getMailer();

クラスの1つでsfContext::getInstance()を使いたいと思うときは、 これは強結合をもたらすので考え直してください。 必要なオブジェクトを引数として渡すほうがずっとよいです。

sfContextをレジストリとして使いset()メソッドを使い独自のオブジェクトを追加することもできます。 これはオブジェクトを引数としてとりget()メソッドはオブジェクトを名前として読み取るために後で使うことができます:

sfContext::getInstance()->set('job', $job);
$job = sfContext::getInstance()->get('job');

デリバリー戦略

ほかの多くのsymfonyのコアオブジェクトのように、メーラーはファクトリです。 ですので、factories.yml設定ファイルで行われます。 デフォルトのコンフィギュレーションは次の内容を読み込みます:

mailer:
  class: sfMailer
  param:
    logging:           %SF_LOGGING_ENABLED%
    charset:           %SF_CHARSET%
    delivery_strategy: realtime
    transport:
      class: Swift_SmtpTransport
      param:
        host:       localhost
        port:       25
        encryption: ~
        username:   ~
        password:   ~

新しいアプリケーションを作るとき、ローカルのfactories.yml設定ファイルはデフォルトのコンフィギュレーションをenvtest環境用の実用的なデフォルトでオーバーライドします:

test:
  mailer:
    param:
      delivery_strategy: none
 
dev:
  mailer:
    param:
      delivery_strategy: none

delivery_strategy設定はsymfonyにEメールを配信する方法を伝えます。 デフォルトとして、symfonyには4つの異なる戦略があります:

  • realtime: メッセージはリアルタイムでされる。
  • single_address: メッセージは単独のアドレスに送信される。
  • spool: メッセージはキューに保存される。
  • none: メッセージは無視される。

戦略が何であれ、EメールはつねにロギングされWebデバッグツールバーの"メーラー"パネルで利用可能です。

メールトランスポート

メーラーメッセージは実際にはトランスポートによって送信されます。 トランスポートはfactories.yml設定ファイルで設定されデフォルトのコンフィギュレーションはローカルマシンのSMTPサーバーを使います:

transport:
  class: Swift_SmtpTransport
  param:
    host:       localhost
    port:       25
    encryption: ~
    username:   ~
    password:   ~

Swift Mailerには3つの異なるトランスポートクラスが同梱されます:

  • Swift_SmtpTransport: メッセージを送信するのにSMTPサーバーを使う。

  • Swift_SendmailTransport: メッセージを送信するのにsendmailを使う。

  • Swift_MailTransport: メッセージを送信するのにPHPネイティブのmail()関数を使う。

tip

Swift Mailerの公式ドキュメントの"トランスポートの種類"のセクションは組み込みのトランスポートクラスとこれらの異なるパラメーターに関して知る必要のあるすべての内容を説明しています。

Eメールをテストする

symfonyメーラーでEメールを送信する方法を見てきたので、正しく作業をしたことを保証するために機能テストを書いてみましょう。 デフォルトでは、symfonyは機能テストでのメールテストを楽にするmailerテスター(sfMailerTester)を登録します。

バックエンドアプリケーション用のaffiliate機能テストファイルを次のコードに置き換えます:

// test/functional/backend/affiliateActionsTest.php
include(dirname(__FILE__).'/../../bootstrap/functional.php');
 
$browser = new JobeetTestFunctional(new sfBrowser());
$browser->loadData();
 
$browser->
  info('1 - When validating an affiliate, an email must be sent with its token')->
 
  get('/affiliate/new')->
  click('activate', array(), array('position' => 1))->
  with('mailer')->begin()->
    checkHeader('Subject', '/Jobeet affiliate token/')->
    checkBody('/Your token is symfony/')->
  end()
;

以前のコードを動かすためには、昨日のフィクスチャファイル(data/fixtures/030_affiliates.yml)をtest/fixtures/ディレクトリにコピーします。

それぞれの送信EメールはcheckHeader()checkBody()メソッドのヘルプでテストできます。 checkHeader()checkBody()の最初の引数は次のものの1つになります:

  • 完全にマッチするかチェックするための文字列;

  • これに対する値をチェックするための正規表現;

  • 値がマッチしないことをチェックするためのネガティブな正規表現(!で始まる正規表現)。

note

デフォルトでは、チェックは最初のEメール送信で行われます。 いくつかのEメールが送信されたら、withMessage()メソッドでテストしたいものを選ぶことができます。 withMessage()は最初の引数として受信者をとります。 これは複数のEメールが同じ受信者に送信される場合テストしたいEメールを示す2番目の引数もとります。

tip

ほかの組み込みのテスターのように、debug()メソッドを呼び出すことで生のメッセージを見ることができます。

また明日

明日は、Jobeetのサイトに欠けている最後の機能である検索エンジンを実装します。

This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License license.