CakePHPのShell内部でemailビューをレンダリングしてQdmailでメールを送る

タイトルまま。
我ながらこれは悪手だと思うがとりあえずこの方法で実現は出来ましたので公開。
こんなやり方もあるよ!とかあれば是非twitterなどでツッコミくださいませ。
ちなみにビューはSmartyプラグインを使っていますがこの場合基本ビューはなんでもよく、ヘルパーも普通に使えると思います(多分)_。

環境

PHP5.3.6
CakePHP1.3系
Qdmail1.2.6b

そもそもの問題点

cakeのというか、Qdmailの仕様で、ビューのemailエレメントを使ってメール本文を構築する際に、コントローラーに値をセットして渡す必要がある。
コントローラーからメール送信する場合はそれでよいが、シェルなどから(例えばユーザーに対しての一斉送信などで)メールを送る場合はコントローラーが存在しないため値の受け渡しが出来ないので考えた結果コントローラをでっちあげる事にしたという話。

サンプル

<?php

App::import('Core', 'Controller');
App::import('Component', 'Qdmail');
App::import('Core', 'Router');

class HogeShell extends Shell {

    var $uses = array('User');

    function startup() {

    }

    function main() {

        // qdmail
        $this->Qdmail = new QdmailComponent();
        // テンプレートに入れ込むためのデータ
        $userdata = $this->User->read(null, 100);

        // Qdmailコンポーネントに食わせるためのダミーコントローラーを生成
        App::import("Controller", "App");
        $dummycontroller = new AppController();
        // 値をセット
        $dummycontroller->set("user", $userdata);
        // startupを自分で呼んでダミーコントローラーを渡す
        $this->Qdmail->startup($dummycontroller);

        $this->Qdmail->to($userdata['User']['email']);
        $this->Qdmail->subject('シェルからのメール送信');
        $this->Qdmail->from('test@example.com');
        // emailエレメント使う
        $this->Qdmail->cakeText( null ,'users.notice');
        $this->Qdmail->send();
    }
}

これで生成したAppコントローラーを経由して値の受け渡しが出来、送信時にviews以下のテンプレートを使用することが出来る。
コントローラーはもちろんダミーで無駄な生成コストがかかってるがとりあえずやりたい内容は実現出来た。

そもそもの話というか不満点

emailの送信はコントローラーだけでなく色々なレイヤーで行われるので、コントローラーに依存したくない。画面出力に使わない値をメール送信のためだけのコントローラーにバインドするというのもちょっと気持ち悪い。
(まとめて配列でパラメータを渡すとかでいいと思う)

いずれにせよこれはあまり筋の良い解決法とは思われないので、何か良い方法を考えたい・・。


Tags: , ,

Comments are closed.