symfony1.1でswiftを使ってみた。
最近の開発は、ずっとsymfonyなので心中するしかないかなー、なんて思っていたりします。しかし、実際に使っていると、フレームワークではカバーしきれないコードを、ゴリゴリと、かっこ悪い方法で実装してしまったりして、嫌悪感いっぱいになってしまうことがあります。
その一つがメール周りです。symfony1.1からsfMailを使わない方向になりました(まぁ、使おうと思えば使えるけど)。そこで、代替とされているのが、Swift Mailerですね。直接SMTPが叩くので、速いだとか負荷が減るだとか、ほげほげだということで、swiftが採用されているようですが、個人的な感想を言えば、私はsfMailerで十分間に合っていたと思います。。。
とも言っていられないので、ちょっとswiftを使ってみました。でも、
How to send emails in symfony 1.1やThe symfony Cookbook How to send an emailを読んでもなんかしっくり来ないんですよね。理由は、これらのハウツーには、メールの本文をコントローラに書く方法しか提供していないからだと思います。確か前のsfMailerではViewテンプレートにメールの本文が書けたのですが、それってswiftでどうやったらいいのかなー、なんて思って調べてやってみました。まぁ、Jonathan Wageさんのアイデアなんだけどね。
というわけで、彼のアイデアをまとめると次のような感じか。
メールを使うアクションクラスをすべてsfSwiftMailerActionsの子クラスとする。
実際に呼び出す際には、親クラスの実装メソッドsendMailにモジュール名とアクション名を渡して、そのテンプレートに本文を書く。
getAll();
foreach ($mailVars as $key => $value)
{
$this->$key = $value;
}
}
public function sendEmail($module, $action)
{
sfConfig::set('symfony.view.' . $module . '_' . $action . '_layout', false);
$body = sfContext::getInstance()->getController()->getPresentationFor($module, $action);
$mailVars = sfSwiftMailerVars::getInstance();
$message = $mailVars->has('message')
? $mailVars->get('message')
: new Swift_Message(null, null, 'text/html');
$swift = $mailVars->has('swift')
? $mailVars->get('swift')
: new Swift(new Swift_Connection_Sendmail(Swift_Connection_Sendmail::AUTO_DETECT));
$message->setSubject($mailVars->get('subject'));
$message->setBody($body);
$swift->send($message, $mailVars->get('recipients'), $mailVars->get('from'));
$swift->disconnect();
$mailVars->clear();
}
public function __set($key, $value)
{
sfSwiftMailerVars::getInstance()->set($key, $value);
return parent::__set($key, $value);
}
}
class sfSwiftMailerVars extends sfParameterHolder
{
static $instance = null;
public static function getInstance()
{
if (!self::$instance)
{
self::$instance = new sfSwiftMailerVars();
}
return self::$instance;
}
}
ふむ。なるほど。テンプレートの内容を取るだけななら
$body = sfContext::getInstance()->getController()->getPresentationFor($module, $action);
でできてしまうのですね。
私が手元で実装したものでは、もう少し劣化させて、上記とは違って、SwiftクラスやSwift_Messageクラスは直書きでやってしまっています。まぁ、デフォルトの挙動なんていらないと思うので。というわけで、このソースはテストはしていません。ほぼ同じものを手元で書いて、その動作は確認しているので、だいたいのロジックはこれでいいようです。
あとは、実際のアクションクラスにこんな感じで書けばいいのですね。
class hogeActions extends sfSwiftMailerActions
{
public function executeEdit($request)
{ $swift->send($message, $mailVars->get('recipients'), $mailVars->get('from'));
$this->recipients = 'example@ganchiku.com';
$this->from = 'example@ganchiku.com';
$this->subject = 'hello world';
$this->sendEmail('hoge', 'confirm');
}
public function executeConfirm($request)
{
}
}
で、あとは、confirmSuccess.phpに本文を適当に書けばいいのですね。ふーむ。確かに、すっきりはしますが、結構面倒ですね。。。もっといい方法があったら教えてください。
Shin Ohno 2003-2012