CakePHP5入門【CakePHP5応用編⑧】メール送信②

B美
(あとあと必ず役に立つはずだから…)
①CakePHPから直接、外部のメールサーバを利用する方法
②メールの内容について、テンプレートファイルを利用する方法 ③Mailerクラスを継承して新たなクラスを作成し、それを利用する方法 |
の3点ね

A子
別にもう良いじゃん

B美
これは学習の一環として、必ず知識として持っておきたいって項目なの
(しかも、これで最低限だからね)

C菜

B美
ただし、私が横から口を挟むかもしれないけどね

A子

C菜
前回のこのページを参考にするです~


A子
'default' => [
・・・ ], |
の下に「default」とは別の名前で設定を書いて、「new Mailer()」の際の引数として渡せば良いんじゃないかしら?

C菜
'isp' => [
'host' => 'smtp-auth.□.ne.jp', 'port' => 587, 'username' => '□@mx2.□.ne.jp', 'password' => '□', 'className' => 'Smtp', 'tls' => false, ], |
…という感じで、どうでしょうか~?
(□の部分は伏字ですぅ~)


A子
てか、「isp」って何?

C菜
(通称「プロバイダ」ですね~)

A子
で、あとは「PostsController.php」の「add」メソッドの中の以下の箇所を書き換えれば良いかな?
$mailer = new Mailer('default'); |
↓
$mailer = new Mailer('isp'); |


C菜
とりあえずテストしてみるです~

B美
(念のためね)
「MATE端末」を開いて、以下のコマンドを入力してちょうだい
su -[Enter]
systemctl stop exim4[Enter] |
ちなみに、停止は「stop」だけど、起動は「start」、再起動は「restart」ね


A子

C菜

↓


A子
なんで?
「isp」というメールの設定を知らない…ってどういうこと?

B美
てか、公式のページにすら書かれてない…(苦笑)

A子
なぜそれをB美が知ってるのかが謎なんだけど、まぁB美だからと思うしかないか…

C菜

B美
二つ目は「Email」セクションの「default」項目の「transport」の値を「isp」に変更すること
どっちでも良いんだけど、私のお勧めは二つ目かな
(「PostsController.php」を書き換えなくて済むからね)

A子
'Email' => [
'default' => [ 'transport' => 'default', 'from' => 'you@localhost', ], ], |
…って箇所だよね?

C菜
'Email' => [
'default' => [ 'transport' => 'default', 'from' => 'you@localhost', ], 'isp' => [ 'transport' => 'isp', 'from' => 'you@localhost', ], ], |
ということですか~?

B美
それじゃ二つ目の方法についてはA子が答えてね

A子
'Email' => [
'default' => [ 'transport' => 'isp', 'from' => 'you@localhost', ], ], |


B美
あ、二つ目の方法を採用する場合は、さっき書き換えた「PostsController.php」を元に戻しておいてね
$mailer = new Mailer('default'); |


C菜

B美
分かってしまえば簡単なんだけど、なぜか公式ページにも書かれてないのよね(苦笑)

A子
まぁ、良いけど…
(いや、良くはない(笑))

B美
んじゃ、とりあえずはあなたたちでやってみて…

C菜


A子
(とは言っても、ちょっとだけ書き換えてるけど…)
$mailer = new Mailer('default');
$mailer->setEmailFormat('html') ->setFrom([FROM_ADDRESS => FROM_NAME]) ->setTo(TO_ADDRESS) ->viewBuilder() ->setTemplate('welcome') ->setLayout('fancy'); $mailer->deliver(); |
…って感じでどうかな?


C菜
調べてみたら「templates/email/html」には「welcome.php」は存在しないし、「templates/layout/email/html」にも「fancy.php」というファイルは無かったですよ~
(あったのはどちらも「default.php」というファイルでした~)


A子


C菜
ただし、件名と本文が空欄でしたけど~


A子
件名については、さっき「setSubject()」を削っちゃったからね
あと、本文のほうは「templates/email/html」の中にある「default.php」を書き換えれば良いってことじゃないかな?
…ってことで、ちょっと書き換えてから「add.php」というファイル名で保存してみたよ

↓


C菜
$mailer = new Mailer('default');
$mailer->setEmailFormat('html') ->setFrom([FROM_ADDRESS => FROM_NAME]) ->setTo(TO_ADDRESS) ->setSubject(MAIL_SUBJECT) ->viewBuilder() ->setTemplate('add') ->setLayout('default'); $mailer->deliver(); |


A子
お、きちんと届いたみたいだね
(件名と本文も問題なし)


C菜
「投稿番号」や「画像ファイルの有無」を渡せれば便利だと思います~

A子
確かに…
ちょっとググってみよう
・・・
お、「setViewVars」メソッドか、ViewBuilderの「setVar」または「setVars」メソッドでできるみたいだね

B美
$mailer = new Mailer('default');
$mailer->・・・ ->viewBuilder() ->setVars(連想配列); |
…って感じね

C菜
$mailer = new Mailer('default');
$mailer->setEmailFormat('html') ->setFrom([FROM_ADDRESS => FROM_NAME]) ->setTo(TO_ADDRESS) ->setSubject(MAIL_SUBJECT) ->viewBuilder() ->setTemplate('add') ->setLayout('default') ->setVars(['number' => $new_id, 'image' => $img_flag]); $mailer->deliver(); |
で、どうでしょうか~?
あ、「$img_flag」というのは、初期値がfalseで、画像を保存したらtrueを代入する変数です~




A子
…ってことは、テンプレートファイルのほうも変更しないとね


C菜


B美
if ($image) {
echo '有り'; } else { echo '無し'; } |
・画像の有無:<?= $image ? '有り' : '無し' ?> |
これは条件演算子と呼ばれるもので、「条件式 ? 真の場合 : 偽の場合」という形式の演算子なの
(四則演算のように二項ではなく、三つの要素を指定するから三項演算子とも呼ばれているわ)

C菜

A子
(確かに、こっちのほうが分かりやすいかも…)


C菜

B美
実はメール送信においては、これこそが大本命なのよ
(普通は③の方式を採用することが多いってこと)

A子


C菜
簡単にまとめると~
1.「src/Mailer」ディレクトリの中に新しいファイルを作って、そこに「○○Mailer」クラスを記述
2.そのクラスの中にメール送信のメソッドを記述
3.「PostsController.php」の中では以下の形で呼出し
$this->getMailer('○○')->send('××', 引数の配列); |
○○はクラス名の中の「Mailer」の左側で、××はメソッド名です~

A子
とりあえず、やってみよう
namespace App\Mailer;
use Cake\Mailer\Mailer; class PostMailer extends Mailer { public function add($number, $image) { $this->setEmailFormat('html') ->setFrom([FROM_ADDRESS => FROM_NAME]) ->setTo(TO_ADDRESS) ->setSubject(MAIL_SUBJECT) ->viewBuilder() ->setTemplate('add') ->setLayout('default') ->setVars(['number' => $number, 'image' => $image]); } } |
ほとんどは、さっき「PostsController.php」の中に書いたものと同じだね
(微妙に変えてるけど…)

B美
手作業でディレクトリやファイルを作っても良いんだけどさ
こういうときはbakeコマンドを使うと、ひな形を作ってくれるからめっちゃ便利よ
「MATE端末」を開いて
cd html/bbsapp[Enter]
bin/cake bake mailer post[Enter] |
…って打ち込んでね


A子
勝手にディレクトリ(src/Mailer)とファイル(PostMailer.php)が作られたよ
んじゃ、このファイルを開いて、さっきのコードを打ち込んでっと…

↓


C菜
use Cake\Mailer\MailerAwareTrait;
class PostsController extends AppController { use MailerAwareTrait; ・・・ public function add() { ・・・ $this->getMailer('Post')->send('add', [$new_id, $img_flag]); ・・・ |



A子
お、問題なくメールが届いたね

C菜
まさにメール機能の部品化というか、オブジェクト指向って感じです~

A子
そういうことなのかぁ

B美
投稿時だけじゃなく、削除の際なんかにもメール通知するようにしたければ「PostMailer.php」の中に新たなメソッドを追加すればOKってわけ
(メール送信に関するもろもろを一ヶ所に集約できるのは便利だし、見通しも良くなるからね)

C菜

B美
さて、今回はここまでね
次回は本番環境への配置(デプロイ)とテストに関する話をしていきましょう

A子
長かった…(苦笑)