CakePHP2系を使うなら、あなたはQdmailに頼っても良いし頼らなくても良い

この記事はだいぶ前に書かれたものなので情報が古いかもしれません
相も変わらずCakePHPでのお話です。恐縮です。



CakePHPが2系になったなら

メールの送信機能を実装する際、Qdmailを使って送信するって場合は結構あると思います。僕もそうです。CakePHPで開発してて、メールの送信機能をつけろって言われたら、ほぼQdmailを使います。

ところがこのQdmail。CakePHPのバージョンが1.2とか1.3の頃は問題なく使えていたんですが、2.0で使おうとすると、何かエラーが出て上手く使えないみたいです。

このあかつきのお宿はCakePHPの2系で動いてるんですが、簡単なお問い合わせ機能でもつけてみようと思って、いつも通りQdmailを使おうと思ったら、使えませんでした。

で、これまたいつものように調べてみました。

Qdmailを2系で使う場合、ちょびっとファイルの中身をいじくらないといけないみたい。若干めんどい。

まあでも修正の量はそこまですごいボリュームでもないし、使えないままじゃ仕方ないから、いっちょやったるか〜と闘志を燃え上がらせようと思ったんですが……。



2系の場合は、わざわざコンポーネントでQdmailを読み込んだりしなくても、すでにメールを送信するための機能が組み込まれているみたいなんですな。

CakeEmail.phpとかいうファイルがコアライブラリの中にあって、それ使うと、Qdmailと似たような感じで、メールの送信処理を実装することができます。

こりゃあもう使うっきゃないでしょーってことで、さっそく使ってみました。



email.phpの設定

まずは初期設定から。

database.phpとかcore.phpとかが置いてある「Config」というフォルダを見ると、「email.php.default」っていうのがあると思います。

ない場合? いや、そんなはずはねえ。Cakeさんを信じろ。もしかしたら何かの弾みで消しちゃっただけかもしれないから、もっかいCakePHPの本家サイトに行って、本体を落として来ると良いんじゃないかしら。

本家はここだ!

そのemail.php.defaultの.defaultを消して、ふつーのphpファイルにしたら、中身を見てみましょう。「EmailConfig」っていうクラスの中に、何やら設定っぽい変数が定義されていますね。

class EmailConfig {

  public $default = array(
    'transport' => 'Mail',
    'from' => 'you@localhost',
    'charset' => 'utf-8',
    'headerCharset' => 'utf-8',
  );

〜 中略 〜

ようはこれがメール送信の際の初期設定みたいです。あとでコントローラー側でもいろいろと設定は変えられるから、別にこれはこのままでも良いのかもしれないですが、一応、少しいじってみることにします。僕も初めて触るんで。

class EmailConfig {

  public $default = array(
    'transport' => 'Mail',
    'from' => 'you@localhost',
    'charset' => 'utf-8',
    'headerCharset' => 'utf-8',
  );

  //オリジナルの設定
  public $sample = array(
    'transport' => 'Mail', //よく分かんない
    'from' => 'anonymous@norm-nois.com', //送信者のアドレス
    'to' => 'akatsuki@norm-nois.com', //送信先のアドレス
    'layout' => 'contact', //Viewのレイアウトファイル名
    'template' => 'mail_body', //Viewのテンプレートファイル名
    'subject' => 'お問い合わせ', //メールの件名
  );

fromとかtoは分かると思います。layoutとtemplateは、メールの本文に使うテンプレートファイルのファイル名ですね。後でもうちょい出て来ます。

メールサーバーのポートだのホストだのっていう設定もかなり細かくできるようなんですが、今回は省略ってことで、上の設定だけやってみました。

たぶん、自分でサーバーを構築して、メールサーバーが外部にあるような設計になっている場合は、ホストの設定とかもしないといけないのかもしれない。あかつきのお宿はレンタルサーバーで動いてるから、その辺は無視で。



送信するだけならたった二行で良い

ここでは、ContactController.phpというファイル作って、メールの送信をすることにしましょう。

App::uses('AppController', 'Controller');
App::uses('CakeEmail', 'Network/Email');
class ContactController extends AppController {
  $public = 'Contact';

  function index() {

  }
}

「App::uses」で「CakeEmail」というファイルを読み込む必要があります。これやっとかないと後でクラスのインスタンスを生成できない。

んで、index()の中身は凡そこんな感じ。

function index() {
  $email = new CakeEmail('sample');
  $email->send();
}

さっきemail.phpで設定した内容をそのまま使うのであれば、これだけでメールの送信はできます。らくしょーっすね。ハラショー。

newしてるとき、引数に「sample」って入れてるのは、email.phpで「$sample」という変数を作ったからです。これが「$contact」だったら「new CakeEmail(‘contact’)」になるし、「$doublecheeseburger」だったら「new CakeEmail(‘doublecheeseburger’)」になる。そういや、もう半年くらい行ってないなぁ、マック。

何か、ハンバーガーのことを思い浮かべながらコードを書いてると、かっこ( )が段々とハンバーガーのパンに見えて……こないな、別に。



あ、ごめんなさい。話が脱線しちゃいましたね。

ちなみに、こういう書き方をしても設定できる。やってることは同じ。

$email = new CakeEmail();
$email->config('sample');
$email->send();



応用編

通常、お問い合わせフォームを作った場合って、送信者の情報とかは毎回違いますから、デフォルトの設定そのままってことはないと思います。

例えば、ビューの中身がこんな感じの、簡易なお問い合わせフォームがあるとしましょうか。

echo $form->create($this->name, array('action' => $this->action));
echo $form->text('name');
echo $form->text('email');
echo $form->textarea('comment');
echo $form->end();

submitボタンを省略しちゃいましたが、まあこんなフォームがあって、送信ボタンが押されたとします。

すると、コントローラー側では、こんなような処理が行なわれることになると思います。

if($this->request->data[$this->name]) {
  $data = $this->request->data[$this->name];
  $email = new CakeEmail('sample');
  $email->from($data['email'], $data['name']);
  $email->viewVars($data);
  $email->template('mail_body', 'contact');
  $email->send();
}

さっきより少し記述が増えましたが、順番に行きましょう。

「$email->from()」は、まあそのまま、送信者の情報ですね。第一引数にメールアドレス、第二引数に名前をセットしています。

「$email->veiwVars()」は、ビュー側に渡す変数をセットしています。コントローラーでよく使う「$this->set()」と似たようなもんです。「$this->set()」で渡せればそれでも良いんだろうけど、僕がやったら上手くビューに変数が渡りませんでした。だからこっちを使います。

「$email->template()」は、メールの本文に使うテンプレートファイルです。第一引数がテンプレートファイル、第二引数がレイアウトファイルです。

他にも「$email->to()」で送信先を設定したり、「$email->attachments()」で添付ファイルの設定をしたり、いろいろできるみたいです。



テンプレートファイルって?

Qdmailを使ってた人ならイメージつかみやすいと思うんですが、CakeEmailでもメールの本文にビューのテンプレートファイルを使うことができます。

通常、ウェブ上にページを表示する際、CakePHPではレイアウトとテンプレートの二つのファイルを使って表示するじゃないですか。例えばさっきのお問い合わせフォームの場合だと、「View」の下にある以下の二つのファイルが読み込まれてます。

・Layouts/default.ctp
・Contact/index.ctp

メールの本文もこれと一緒です。

レイアウトファイルは「Layouts/Emails/text」というフォルダの下、テンプレートファイルは「Emails/text」の下に、それぞれctpファイルを作ります。htmlメールを作成して送信するなら、それぞれ「Layouts/Emails/html」「Emails/html」の下に作ることになりますかね。今回は普通のテキストメールで話を進めます。

今回の例だと、レイアウトファイル名が「contact」、テンプレートファイル名が「mail_body」なので、こんなファイルを作成することになります。

・Layouts/Emails/text/contact.ctp
・Eamils/text/mail_body.ctp

コントローラーで「$email->template()」を使わない場合、テンプレートの指定をしない場合は、email.phpに書いてある設定が適用されます。



ビューを使わない場合

メール本文に署名の定型文とかがなくて、送信内容だけをそのままメール本文に載せるような場合は、別にビューファイルをわざわざ読み込む必要もないですよね。

そういうときは、こんな風に書けばオッケー。

if($this->request->data[$this->name]) {
  $data = $this->request->data[$this->name];
  $email = new CakeEmail('sample');
  $email->from($data['email'], $data['name']);
  $email->template('null', 'null');
  $email->send($data['comment']);
}

「$email->template()」でnullを指定してしまうわけですね。

もちろんこれも、email.phpでnullにしておけば、コントローラーの方は省略できます。

//email.php
public $sample = array(
  'transport' => 'Mail',
  'from' => 'anonymous@norm-nois.com',
  'to' => 'akatsuki@norm-nois.com',
  'layout' => null,
  'template' => null,
  'subject' => 'お問い合わせ',
);

//ContactController.php
if($this->request->data[$this->name]) {
  $data = $this->request->data[$this->name];
  $email = new CakeEmail('sample');
  $email->from($data['email'], $data['name']);
  $email->send($data['comment']);
}






……ってな感じで、このあかつきのお宿にもお問い合わせフォームを作ってみました。

ものもうす?

どうせお問い合わせなんか来ないだろうと思って、あまり目立たない感じになってるけど、ページの右上にある「ものもうす?」ってとこにマウスカーソルを合わせると、お問い合わせフォームが出て来ます。

ものもうせ

これはCakeEmail.phpを使っております。

まあ、気が向いたら何か送ってみてちょ。



Qdmailを2系でも使えるように頑張って直しても良いんですけど、せっかくこういうのがデフォルトで備わってるわけですし、使ってみるのも良いんじゃないでしょうか。
 もしかしたら何か関連しているかも? 
 みんなからのコメント 
2013年11月29日 10:25:11
What are they afraid
2013年11月29日 12:43:45
まっち~(管理人)
>tomsさん
Nothing in particular.