php > framework > symfony > plugin

jpMailPlugin

概要

 このプラグインで日本語環境では一般的なJIS(iso-2022-jp)でのメール送信が簡単に行えます。

仕様

symfonyでは日本語でメールを送信することができますが、標準のsfMailクラスで日本語メール(iso-2022-jp)を送信しようとすると、毎回エンコーディングの変換処理を意識しなければなりません。そこで、標準のsfMailと同じ手順でエンコーディング処理まで行ってくれるsfMailクラスの拡張クラスであるjpMailを利用します。

  1. jpMailクラス
    1. iso-2022-jpへ変換
    2. 変換元の文字コードはmb_internal_encodingの値
    3. ヘッダ(subject, from, toなど)をmb_encode_mimeheader関数で変換
    4. ヘッダから\x00の除去
    5. ボディをmb_convert_encoding関数で変換

また、symfonyは標準でテンプレートのビューをメールの本文として利用できるsendEmailメソッドがコントローラに用意されています。しかし、このメソッドはsfMailを強制的に利用するため、そのままでは本文部分がどうしてもiso-2022-jpに指定できません。そこで、jpMailを利用するようにしたjpMailViewクラスを用意しています。

  1. jpMailViewクラス
    1. mailer.ymlにて設定が行える
    2. jpMailクラスを使用する(iso-2022-jpで送信する)

更新履歴

  • Ver 0.1.0
    • symfony 1.2以降で動作するVer.0.1系を作成
  • Ver 0.0.3
    • サブジェクトが長い場合に¥nが付与されるバグ(asial 笹亀さん)
  • Ver 0.0.2
    • 代替テキストテンプレート(setAltBody)の文字コード変換に対応 (H.Maruiさん)
  • Ver 0.0.1
    • 初版リリース

インストール

プロジェクトルートディレクトリでsymfonyコマンドでプラグインをインストールします。 お使いのsymfonyのバージョンで使い分けてください。

  • symfony1.0系
 $ symfony plugin-install http://develop.ddo.jp/symfony/jpMailPlugin-0.0.3.tgz
  • symfony1.1以降
 $ symfony plugin:install http://develop.ddo.jp/symfony/jpMailPlugin-0.1.0.tgz

また、symfony1.2以降ではPHPMailerがバンドルされていませんので、PHPMailerからダウンロードし、<アプリケーション>/lib/venderなどのautoloadされる領域に配置してください。

  • symfony1.0系で古いバージョンからのアップグレードは以下のコマンドで行ってください
 $ symfony plugin-upgrade http://develop.ddo.jp/symfony/jpMailPlugin-0.0.3.tgz

インストール後はプラグインが読み込まれるように、キャッシュをクリアします。

 $ symfony cc

利用方法

jpMailクラス

 以下のようにアクションで簡単に日本語メール送信が行えます。

  • <プロジェクトルート>/apps/<アプリケーション名>/actions/actions.class.php
   function executeSimpleSend()
  {
    mb_internal_encoding("UTF-8"); # UTF-8の場合
    // class initialization
    $mail = new jpMail();
 
    // definition of the required parameters
    $mail->setSender('webmaster_sender@example.com'); # Return-Path:
    $mail->setFrom('webmaster_from@example.com', 'ナナシさん'); # From:
    $mail->addReplyTo('webmaster_copy@example.com');  # Reply-to:
 
    $mail->addAddress('toaddress@example.com'); # To:
    $mail->setSubject(" メール送信テスト");
    $mail->setBody("メール本文です");
    $mail->send();
    
  }
PHPMailerのバージョンによる違い

PHPMailerのバージョンが5.0以上の場合、'$mail→prepare()'を呼び出すとアクセス権のエラーが発生します。ソースを見る限りはsend()処理時にprepareで行っている処理は行われているので、$mail→prepare()を利用する必要はありません。

テンプレートをメール本文として使用

 テンプレートをメール本文として指定するためには、アクション内でgetPresentationForメソッドを使用します。このときに第3引数にjpMailを指定することで日本語(iso-2022-jp)メールで送信が行えるようになります。

 ただし、第3引数が有効になるのはsymfony1.0系までで1.1系以降では有効になりません。  そのため、1.0系と1.1系以降のそれぞれで説明します。

symfony 1.0系
# 使用したいテンプレートを呼び出すためのモジュールとアクションを指定します
$this->getPresentationFor('モジュール', 'アクション', 'jpMail');

 以下は、mailモジュールのindexアクションが呼び出されたときに、mailモジュールのsimpleSendアクションのテンプレートがメール送信に使用される場合の例です。

  • <プロジェクトルート>/apps/mail/actions/actions.class.php
class mailActions extends sfActions
{
  /**
   * ブラウザから呼ばれるアクション
   */
  public function executeIndex(){
    # メソッドの戻り値には送信したメールのヘッダ、本文をあわせた文字列です
    $raw_email = $this->getPresentationFor('mail','simpleSend','jpMail');
    return sfView::SUCCESS;
  }
  /**
   * メール処理専用のアクション(内部からのみ利用されることを想定)
   */
  public function executeSimpleSend()
  {
    mb_internal_encoding("UTF-8"); # UTF-8の場合
    // class initialization
    $mail = new jpMail();
 
    // definition of the required parameters
    $mail->setSender('webmaster_sender@example.com'); # Return-Path:
    $mail->setFrom('webmaster_from@example.com', 'ナナシさん'); # From:
    $mail->addReplyTo('webmaster_copy@example.com');  # Reply-to:
 
    $mail->addAddress('toaddress@example.com'); # To:
    $mail->setSubject(" メール送信テスト");
 
    $this->mail = $mail;
  }

そして、テンプレートを用意します。

  • <プロジェクトルート>/apps/mail/templates/simpleSendSuccess.class.php
これはメール本文です。パーシャル、コンポーネントも利用できます。
レイアウトは使用されません。
symfony 1.1系以降
# 使用したいテンプレートを呼び出すためのモジュールとアクションを指定します
$this->getController()->getPresentationFor('モジュール', 'アクション');

 以下は、mailモジュールのindexアクションが呼び出されたときに、mailモジュールのsimpleSendアクションのテンプレートがメール送信に使用される場合の例です。

  • <プロジェクトルート>/apps/sendmail/actions/actions.class.php
class sendmailActions extends sfActions
{
  /**
   * ブラウザから呼ばれるアクション
   */
  public function executeIndex(){
    # メソッドの戻り値には送信したメールのヘッダ、本文をあわせた文字列です
    $raw_email = $this->getController()->getPresentationFor('mail','simpleSend');
    return sfView::SUCCESS;
  }
}
  • <プロジェクトルート>/apps/mail/actions/actions.class.php
class mailActions extends sfActions
{
  /**
   * メール処理専用のアクション(内部からのみ利用されることを想定)
   */
  public function executeSimpleSend()
  {
    mb_internal_encoding("UTF-8"); # UTF-8の場合
    // class initialization
    $mail = new jpMail();
 
    // definition of the required parameters
    $mail->setSender('webmaster_sender@example.com'); # Return-Path:
    $mail->setFrom('webmaster_from@example.com', 'ナナシさん'); # From:
    $mail->addReplyTo('webmaster_copy@example.com');  # Reply-to:
 
    $mail->addAddress('toaddress@example.com'); # To:
    $mail->setSubject(" メール送信テスト");
 
    $this->mail = $mail;
  }

そして、テンプレートを用意します。

  • <プロジェクトルート>/apps/mail/templates/simpleSendSuccess.class.php
これはメール本文です。パーシャル、コンポーネントも利用できます。
レイアウトは使用されません。

そして、jpMailViewクラスがmailモジュールで利用されるようにmodule.ymlを用意します。

  • modules/mail/config/module.yaml
all:
  is_internal: on
  view_class: jpMail

また、getPresentationForを使用した場合はmailer.ymlでメール送信に関する設定を行うことができます。以下は標準の設定内容です。

  • <プロジェクトルート>/apps/mail/config/mailer.yml
default:
  deliver:           on
  mailer:            smtp
  domain:            localhost.localdomain
  hostname:          localhost
  port:              25
  username:          ''
  password:          ''

  wordwrap:          0

  .headers:
    priority:        3
    content_type:    text/plain
    charset:         iso-2022-jp
    encoding:        7bit

参照:jpMailPluginをsymfony1.1.5に対応してみた(暫定)

外部リンク

tips

上記例のままであれば、ブラウザから直接executeSimpleSendアクションを呼ばれた場合に、メール送信は行われなくても、画面にメール本文が表示されてしまうでしょう。このための対策として次の方法があります。

module.ymlでis_internal: on

symfonyはモジュール単位でブラウザから直接呼ばれないように設定することができます。 たとえば、myMailモジュールを別途作成し上記のsimpleSendアクションを移動させ、

  • <プロジェクトルート>/apps/myMail/config/module.yml
all:
  is_internal: on

とすれば、ブラウザからmyEmailモジュールは呼び出すことができなくなります。

flash変数を使用した制御

わざわざモジュールに切り出すのもなぁ。。という場合で、セッションが利用できるのであればflash変数で制御するのが簡単です。

たとえば、上記例であれば以下のようにします。

  • <プロジェクトルート>/apps/mail/actions/actions.class.php
class mailActions extends sfActions
{
  /**
   * ブラウザから呼ばれるアクション
   */
  public function executeIndex(){
    $this->setFlash('is_call_simpleSend', true);
    $raw_email = $this->getPresentationFor('mail','simpleSend','jpMail');
    ... 以下同じ ...
  }
  /**
   * メール処理専用のアクション(内部からのみ利用されることを想定)
   */
  public function executeSimpleSend()
  {
    $this->forward404Unless($this->getFlash('is_call_simpleSend', false));
    $this->setFlash('is_call_simpleSend', false);
    ... 以下同じ ...
  }

getPresentationForを呼び出す直前に、flash変数に呼び出し宣言のフラグ(is_call_simpleSend)を有効にしておきます。そして、呼び出されたsimpleSendアクションではフラグが有効かどうかを判断し、無効であれば404モジュールへフォワードします。 そして、有効だった場合は2度目の呼び出しが処理されないように、宣言を無効にします。

php/framework/symfony/plugin/jpmailplugin.txt · 最終更新: 2009/06/29 02:49 by brtriver
chimeric.de = chi`s home Creative Commons License Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0