php > framework > symfony > plugin
このプラグインは日本語(iso-2022-jp)による簡単なメール送信をライブラリに依存せず共通のインターフェースで送信するためのプラグインです。
㈱くじらシステムさんが公開されているライブラリのおかげでSwiftMailer4にも対応することができました。ありがとうございました。
PHPMailer, Swift Mailer, Qdmailが読み込まれてさえすれば以下の共通のインターフェースで日本語(iso-2022-jp)によるメール送信を行います。 引数で与えた日本語文字列はプラグインによって内部エンコーディングからJISに変換されます。
$mailer = jpSimpleMail::create('SwiftMailer'); // このサンプルではSwift Mailerを利用しています。 $mailer->setSubject('メール送信テストです'); $mailer->setSender('from@example.com'); $mailer->addTo(sprintf('%s <%s>', '宛先 太郎', 'to@example.com')); $mailer->setFrom(sprintf('%s <%s>', '管理者', 'from@example.com')); $mailer->setBody('本文です'); $rs = $mailer->send();
また、smtpでの会話には対応していません。 既に公開してあるjpMailPluginとは全くの別モノになります。
以下のライブラリにてテストを行っています。
| ライブラリ名 | バージョン |
|---|---|
| PHPMailer | v2.3 |
| Swift Mailer | 3.3.3, 4.0.6 |
| Qdmailに用意されているsfQdmail | 1.2.6b |
※Qdmailを利用される場合は環境によって、Strictエラー、Noticeのエラーが発生する場合があります。
svnをインストールしている環境であれば下記のようにしてopenpear.orgからチェックアウトします。
$ svn checkout http://svn.openpear.org/jpSimpleMailPlugin/tags/1.0.0 ./plugins/jpSimpleMailPlugin
openpear.orgにて公開させていただいています。そのため、openpear.orgをadd-channelする必要があります。
$ ./symfony plugin:add-channel openpear.org $ ./symfony plugin:install --force-license --release=1.0.0 openpear.org/jpSimpleMailPlugin
plugin:listで表示されていれば無事インストールが完了です。
openpear.orgチャンネルを追加する必要がありますが、symfony1.0ではsymfonyコマンド経由では追加できません。 そこで、手動で以下のファイルを追加することでチャンネルを追加しておきます。
a:6:{s:7:"attribs";a:4:{s:7:"version";s:3:"1.0";s:5:"xmlns";s:31:"http://pear.php.net/channel-1.0";s:9:"xmlns:xsi";s:41:"http://www.w3.org/2001/XMLSchema-instance";s:18:"xsi:schemaLocation";s:71:"http://pear.php.net/channel-1.0 http://pear.php.net/dtd/channel-1.0.xsd";}s:4:"name";s:12:"openpear.org";s:14:"suggestedalias";s:8:"openpear";s:7:"summary";s:30:"channel server of openpear.org";s:7:"servers";a:1:{s:7:"primary";a:1:{s:4:"rest";a:1:{s:7:"baseurl";a:2:{i:0;a:2:{s:7:"attribs";a:1:{s:4:"type";s:7:"REST1.0";}s:8:"_content";s:29:"http://openpear.org/rest.php/";}i:1;a:2:{s:7:"attribs";a:1:{s:4:"type";s:7:"REST1.1";}s:8:"_content";s:29:"http://openpear.org/rest.php/";}}}}}s:13:"_lastmodified";a:2:{s:4:"ETag";s:22:""87cb102-253-5856a200"";s:13:"Last-Modified";s:29:"Fri, 31 Oct 2008 07:14:16 GMT";}}
openpear.org
そして、openpear.orgを指定してプラグインをインストールします。
$ ./symfony plugin-install openpear.org/jpSimpleMailPlugin-1.0.0
plugin-listで表示されていれば完了です。
ただし、このチャンネル追加の方法が力技のため正しいかどうかはちょっと怪しいです。
$ ./symfony plugin:uninstall openpear/jpSimpleMailPlugin $ ./symfony cc
まず、PHPMailer, Swift Mailer, Qdmailのどれかをダウンロードし、autoloadに登録するかincludeしておきます。 symfony1.3以降ではSwiftMailer4がバンドルされているのでSwift Mailerをダウンロードする必要はありません。 ただし、iso-2022-jpでエンコードするためにkzl_Jp_Swift_Mime_Headers_UnstructuredHeaderクラスが必要になりますが、 kuzillaさんのご協力により本プラグインにライブラリを同梱していますので最低限の動作のために別途インストールが必要なライブラリはありません。 また、kuzillaさんのサイトで日本語対応のWeb用デバッグツールバーなどが用意されたプラグインが紹介されていますので是非チェックしてみてください。 symfony1.4の「SwiftMailer」を日本語対応(iso-2022-jp)してみた あとは、jpMail::createメソッドの引数にメーラーを指定し、以下のように呼び出します。
(例)PHPMailerで送信するサンプル
$mailer = jpSimpleMail::create('PHPMailer'); $mailer->setSubject('メール送信テストです'); $mailer->setSender('from@example.com'); $mailer->addTo(sprintf('%s <%s>', '宛先 太郎', 'to@example.com')); $mailer->setFrom(sprintf('%s <%s>', '管理者', 'from@example.com')); $mailer->setBody('本文です'); $rs = $mailer->send();
createメソッドで渡す事ができる名前は以下の3つです。 `PHPMailer`, `SwiftMailer`, `Qdmail`, `SwiftMailer4` symfony1.3以降ではSwiftMailer4を利用することになるはずです。
メールが文字化けする場合はアプリケーションの内部文字コードが何に指定しているかを確認してください。(mb_internal_encoding) 標準ではjpSimpleMailPluginでは内部エンコーディングがutf-8として処理します。 内部エンコーディングがutf-8以外の場合は config/app.ymlの以下の項目でエンコーディングを指定してください。
all:
jpSimpleMail:
encoding: utf-8
symfony1.0まではsfMailというクラスが用意されており、このクラスを利用することでアクションの結果をメールの本文(body)に適用することができました。しかしsymfony1.1以降はこのクラスは廃止されてしまいましたが、もっと簡単に動的に本文を作成するための方法が用意されました。
それはコンポーネント(またはパーシャル)の処理結果を変数で受け取る事ができるようになったのです。
例えば、以下のようなgetComponentメソッドを使います。
public function executeIndex(sfWebRequest $request) { $mailer = jpSimpleMail::create('SwiftMailer'); $mailer->setSubject('メール送信テストです'); $mailer->setSender('master@example.com'); $mailer->addTo(sprintf('%s <%s>', 'シンフォニー 太郎', 'symfony@example.com')); $mailer->setFrom(sprintf('%s <%s>', '管理者', 'master@example.com')); // getComponentでsendmailモジュールのcreateMailBodyコンポーネントに値(name)を渡しつつ処理結果をsetBodyする $mailer->setBody($this->getComponent('sendmail', 'createMailBody', array('name' => 'なまえ'))); $rs = $mailer->send();
<?php class sendmailComponents extends sfComponents { public function executeCreateMailBody($request) { // ここで本文を作成するのに必要なロジックをコーディングする $this->url = "http://www.example.com/"; } }
テンプレートではアサインした$nameと$urlを利用可能
<?php echo $name ?> ------------------ テストです。 どうでしょうか? <?php echo $url ?> -----
上記サンプルのような利用方法ではなく、HTMLメールや添付メールなど各ライブラリを直接操作したい場合は直接各ライブラリを呼び出して利用します。 その場合は以下のように直接ライブラリのインスタンスを取得することができます。
// getterでインスタンスを取得 $Mailer = $mailer->getMailer(); // または直接mailerプロパティを参照 $Mailer = $mailer->mailer;
Zend_Mailなどのその他のメール送信ライブラリにも対応させることも簡単です。 jpSimpleMailPlugin/lib/mailer/jpXXX.class.phpという名前でjpMailerクラスを基に実装すれば良いだけです。
SwiftMailer4は送信結果として0が返ってきたときは「送信しなかった」か「送信に失敗した」かのどちらかになります。 また、ccやbccに宛先を指定した場合はその数を返します。
symfonyのdev環境の標準ではメールを送信しない設定になっています。(delivery_strategy: none) 送信に失敗したかどうかをプラグイン内では判断しませんので、戻り値をチェックする処理をアプリケーション側で制御を記述してください。
もし、SwiftMailer4が例外を投げた場合は、jpSendMailExceptionを投げるようになっています。 なので以下のようにtry,catchが利用できます。
try { $mailer = jpSimpleMail::create('SwiftMailer4'); .... $result = $mailer->send(); } catch (jpSendMailException $e) { // エラーの場合の処理 } if (!$result) { // 「送信しなかった」か「送信に失敗した」場合の処理 .... }
各々のメールライブラリで例外が投げられた場合は、jpSendMailExceptionを投げるようになっています。 なので以下のようにtry,catchが利用できます。
try { $mailer = jpSimpleMail::create('Qdmail'); .... $mailer->send(); } catch (jpSendMailException $e) { // エラーの場合の処理 }
また、jpSendMailExceptionはsfExceptionを継承しているだけです。
単体テスト(メソッドレベルのテスト)と機能テスト(実際にメールを送信してみるテスト)も附属のtestディレクトリのファイルを参考にすると簡単に作成できると思います。 また、テストを実行する場合は $_SERVER['SYMFONY']に使用しているsymfonyのライブラリのパスを設定しなければなりません。そして、テスト送信先のアドレスを$_SERVER['SF_TEST_TO_ADDRESS']に設定しなければなりません。 bashの場合は以下のように環境変数をセットしておきます。
テストを実行する前にexportで変数をSYMFONYをセットしておく
$ export SYMFONY=/path-to-symfony/lib $ export SF_TEST_TO_ADDRESS=to@example.com
全てのテストを実行するためにはprove.phpを叩きます。
$ php /path-to-plugin/test/bin/prove.php
単体テストではエンコーディングが正しく行われているかではなく、メソッドがエラーなく実装されているかどうかをテストしています。テストとしては不十分かもしれません。。
このライブラリはテストするためにsymfonyを活用していますが、ライブラリ自体は最後のメール送信時(sendメソッド)で失敗したときに投げる例外sfExceptionのみsymfonyに依存しています。
なので、フレームワークとは関係なくても各ファイルを読み込みさえできれば移植も簡単(なはず)。