September 21, 2008

symfony1.1でswiftを使ってみた。

最近の開発は、ずっとsymfonyなので心中するしかないかなー、なんて思っていたりします。しかし、実際に使っていると、フレームワークではカバーしきれないコードを、ゴリゴリと、かっこ悪い方法で実装してしまったりして、嫌悪感いっぱいになってしまうことがあります。

その一つがメール周りです。symfony1.1からsfMailを使わない方向になりました(まぁ、使おうと思えば使えるけど)。そこで、代替とされているのが、Swift Mailerですね。直接SMTPが叩くので、速いだとか負荷が減るだとか、ほげほげだということで、swiftが採用されているようですが、個人的な感想を言えば、私はsfMailerで十分間に合っていたと思います。。。

とも言っていられないので、ちょっとswiftを使ってみました。でも、
How to send emails in symfony 1.1The symfony Cookbook How to send an emailを読んでもなんかしっくり来ないんですよね。理由は、これらのハウツーには、メールの本文をコントローラに書く方法しか提供していないからだと思います。確か前のsfMailerではViewテンプレートにメールの本文が書けたのですが、それってswiftでどうやったらいいのかなー、なんて思って調べてやってみました。まぁ、Jonathan Wageさんのアイデアなんだけどね。

というわけで、彼のアイデアをまとめると次のような感じか。
メールを使うアクションクラスをすべてsfSwiftMailerActionsの子クラスとする。
実際に呼び出す際には、親クラスの実装メソッドsendMailにモジュール名とアクション名を渡して、そのテンプレートに本文を書く。

  1. <?php
  2. class sfSwiftMailerActions extends sfActions
  3. {
  4.   public function preExecute()
  5.   {
  6.     $mailVars = sfSwiftMailerVars::getInstance()->getAll();
  7.  
  8.     foreach ($mailVars as $key => $value)
  9.     {
  10.       $this->$key = $value;
  11.     }
  12.   }
  13.  
  14.   public function sendEmail($module, $action)
  15.   {
  16.     sfConfig::set('symfony.view.' . $module . '_' . $action . '_layout', false);
  17.     $body = sfContext::getInstance()->getController()->getPresentationFor($module, $action);
  18.  
  19.     $mailVars = sfSwiftMailerVars::getInstance();
  20.  
  21.     $message = $mailVars->has('message')
  22.       ? $mailVars->get('message')
  23.       : new Swift_Message(null, null, 'text/html');
  24.     $swift = $mailVars->has('swift')
  25.       ? $mailVars->get('swift')
  26.       : new Swift(new Swift_Connection_Sendmail(Swift_Connection_Sendmail::AUTO_DETECT));
  27.  
  28.     $message->setSubject($mailVars->get('subject'));
  29.     $message->setBody($body);
  30.  
  31.     $swift->send($message, $mailVars->get('recipients'), $mailVars->get('from'));
  32.     $swift->disconnect();
  33.  
  34.     $mailVars->clear();
  35.   }
  36.  
  37.   public function __set($key, $value)
  38.   {
  39.     sfSwiftMailerVars::getInstance()->set($key, $value);
  40.  
  41.     return parent::__set($key, $value);
  42.   }
  43.  
  44. }
  45.  
  46. class sfSwiftMailerVars extends sfParameterHolder
  47. {
  48.   static $instance = null;
  49.  
  50.   public static function getInstance()
  51.   {
  52.     if (!self::$instance)
  53.     {
  54.       self::$instance = new sfSwiftMailerVars();
  55.     }
  56.  
  57.     return self::$instance;
  58.   }
  59.  
  60. }

ふむ。なるほど。テンプレートの内容を取るだけななら

  1. $body = sfContext::getInstance()->getController()->getPresentationFor($module, $action);

でできてしまうのですね。

私が手元で実装したものでは、もう少し劣化させて、上記とは違って、SwiftクラスやSwift_Messageクラスは直書きでやってしまっています。まぁ、デフォルトの挙動なんていらないと思うので。というわけで、このソースはテストはしていません。ほぼ同じものを手元で書いて、その動作は確認しているので、だいたいのロジックはこれでいいようです。

あとは、実際のアクションクラスにこんな感じで書けばいいのですね。

  1. class hogeActions extends sfSwiftMailerActions
  2. {
  3.   public function executeEdit($request)
  4.   {    $swift->send($message, $mailVars->get('recipients'), $mailVars->get('from'));
  5.     $this->recipients = 'example@ganchiku.com';
  6.     $this->from = 'example@ganchiku.com';
  7.     $this->subject = 'hello world';
  8.     $this->sendEmail('hoge', 'confirm');
  9.   }
  10.  
  11.   public function executeConfirm($request)
  12.   {
  13.   }
  14. }

で、あとは、confirmSuccess.phpに本文を適当に書けばいいのですね。ふーむ。確かに、すっきりはしますが、結構面倒ですね。。。もっといい方法があったら教えてください。

今日は、どうぞ、よろしくお願いします。
私は外国人ですが、PHPで、6年以上の経験を持って、あなたのブログから、Symfony1.1の情報を見ました。
現在、私も、1.1バージョンを使っていますが、いろいろな問題を出ました。(仕方ないが、Symfony1.1の不熟の表現だと思います。)
ですから、あなたと交流したいです。もし、いいなら、私のMSNを追加してください。
また、現在では、1つの問題があります。
私はSymfonyのCURDを使ってから、新規時に、「SQL syntax」(Sql文分析エラーを出た。)、調査しでも、まだ、あります。
それは、どの様な問題ですが、分からないので、説明してもらっていいですか?
MSNで、連絡ことを楽しみね。(下記はエラーメッセージですが、参照してくださいね。)
Unable to execute INSERT statement. [wrapped: Could not execute update [Native Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘DESC) VALUES (0,’2007-03-03 02:03:00′,’fadsfasfas’,'fasfasf’,'fadsfasfas’,'fadsf’ at line 1] [User Info: INSERT INTO tb_dayreport (USERID,DATE,MAILTO,CCTO,TITLE,FILE,KONNSYUU,SENNSYUU,KINOU,KYOU,ASHITA,HORYOUU,DESC) VALUES (0,’2007-03-03 02:03:00′,’fadsfasfas’,'fasfasf’,'fadsfasfas’,'fadsfasfas’,'fadsfasfas’,'fadsfasfas’,'fadsfasfas’,'fadsfasfas’,'fadsfasfas’,'fadsfasfas’,'fadsfasfas’)]]

Comment by stven — November 5, 2008

ふーむ。phpで、6年以上って、私よりも長いかもね。
CRUDは実はやったことがないので、なんとも言えないのですが、DESCという単語が予約語で使えないとか、そんなオチじゃないですか?

しかし、スキーマがないとなんとも言えないですね。

Comment by shin — November 8, 2008

Leave a comment

Bloglines feedburner