CakePHP3を使用したアプリケーションでメールの本文を取得→画面で編集した上で送信するという流れを作ったときの備忘録です。
メールの本文はEmailクラスのmessage関数から取得できます。ただしsend関数による送信処理を呼び出した後でないとnullが返ってきます。そこで今回はデバッグ用のメール設定を作成し、架空の宛先に架空のメールを送信→本文を取得するという方法を取ってみました。
プログラムについて
以下のような感じとなりました。
'EmailTransport' => [ 'debug' => [ 'className' => 'Cake\Mailer\Transport\DebugTransport', 'host' => 'localhost', 'port' => 25, 'timeout' => 30, 'username' => null, 'password' => null, 'client' => null, 'tls' => null, 'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null), ], ],
/** * メール送信後に取得可能な本文を取得する * @param unknown $template * @param unknown $view_vars * @return string */ public function get_compiled_message($template, $view_vars) { $email = new Email(); $email->setCharset('ISO-2022-JP'); $email->setTransport('debug'); $email->setTo(TEMP_MAIL_ADDR); $email->setTemplate($template); $email->setViewVars($view_vars); $email->send(); $message = $email->message(Email::MESSAGE_TEXT); $message = mb_convert_encoding($message, 'UTF-8', 'ISO-2022-JP'); return $message; }
/** * メール本文を直指定したメール送信処理 * @param unknown $to_addr * @param unknown $from_addr * @param unknown $from_name * @param unknown $subject * @param unknown $mail_msg * @return boolean */ public function sendmail_from_mailbody($to_addr, $from_addr, $from_name, $subject, $mail_msg) { $email = new Email(); $email->setCharset('ISO-2022-JP'); $email->setTransport('default'); $email->setTo($to_addr); $email->setFrom($from_addr, $from_name); $email->setSubject($subject); return $email->send($mail_msg); }
- メール本文のテンプレートは一律でEmail/text以下のファイルを参照しています。
- EmailクラスのsetTransport関数でapp.php内に定義したデバッグ用のトランスポート設定を指定しています。
- 独自に作成したEmailコンポーネント内のget_compiled_message関数にEmail/text以下のテンプレート名とメールに埋め込む変数を指定することで、送信した際のメール本文が取得できるようになっています。
- sendmail_from_mailbody関数ではsend関数にメール本文を指定したメール送信を行っています。
動作確認用のプログラム作成
動作確認用に適当なHogeController.phpを作成しsendアクションでメール送信を行ってみます。
メールのテンプレートも適当に会員情報を出力するものを作成しました。
ちなみに、Windowsの開発環境のためsmtp4devというダミーのSMTPサーバーを立てるツールを起動した状態で確認しています。
<?= h($var['user']['company']) ?> <?= h($var['user']['name']) ?>様 ◆◆ 会員登録完了のご連絡 ◆◆ <?= h($var['current_date']) ?> ********************************************************************** 会員登録完了のご連絡 ********************************************************************** ご登録いただき誠にありがとうございます。 会員登録の手続きが完了致しましたことをご連絡申し上げます。 会員情報は以下のとおりです。 --会員情報--------------------------------- ログインID :<?= h($var['user']['email']) ?> パスワード :<?= h($var['user']['password']) ?> 会員名 :<?= h($var['user']['name']) ?> ご不明な点がございましたら以下のアドレス宛にご連絡をお願い申し上げます。 担当 :ほげ アドレス :example@example.com
<?php namespace App\Controller; use App\Controller\AppController; use Cake\ORM\TableRegistry; /** * Hoge Controller * * @property \App\Model\Table\UsersTable $Users * @property \App\Controller\Component\EMailComponent $EMail */ class HogeController extends AppController { public function initialize() { parent::initialize(); $this->loadComponent('EMail'); $this->Users = TableRegistry::getTableLocator()->get('Users'); } public function send($id = null) { $user = $this->Users->find()->where(['id' => $id])->enableHydration(false)->first(); // メール本文取得 $current_time = new \DateTime(); $current_time->setTimeZone( new \DateTimeZone('Asia/Tokyo')); $mail_msg = $this->EMail->get_compiled_message('sample', [ 'vars' => [ 'user' => $user, 'current_date' => $current_time->format('Y年m月d日'), ], ]); // 取得したメール本文をビューにセットしたりする // ここで直接いじったりもできる // $this->set(compact('mail_msg')); // メール送信 $this->EMail->sendmail_from_mailbody($user['mail'], ADMIN_MAIL, ADMIN_NAME, '件名ほげほげ', $mail_msg); $this->redirect(['action' => 'complete']); } public function complete() { // complete.ctp表示するだけ } }
動作確認する
cake.batからビルトインサーバーを起動して以下のURLで確認
http://localhost:8765/hoge/send/1
smtp4devに送信されたメールが表示されることを確認。