CakePHP2のCakeEmailでメールフォームを作る
CakePHPCakePHP2.1でメールフォームを作ったので、同じコードを2度書かないためにメモ。
データベースにテーブルを作成
まず、テーブルを作ります。テーブル名はcontacts。主要なフィールドは件名・名前・メールアドレス・本文のみ。至ってシンプル。
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
CREATE TABLE IF NOT EXISTS `contacts` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`subject` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`from` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`body` text COLLATE utf8_unicode_ci NOT NULL,
`created` int(11) NOT NULL,
`modified` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
モデルをBakeしてちょこちょこ変更
次に今作ったテーブルのモデル、つまりContactモデルをBakeします。
焼きあがったモデルを開いてバリデーションのメッセージを日本語に修正。こんな感じになりました。
<?php
//app/Model/Contact.php
App::uses('AppModel', 'Model');
/**
* Contact Model
*
*/
class Contact extends AppModel {
/**
* Display field
*
* @var string
*/
public $displayField = 'subject';
/**
* Validation rules
*
* @var array
*/
public $validate = array(
'subject' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => '入力必須です',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'maxlength' => array(
'rule' => array('maxlength', 128),
'message' => '最大文字数を超えています',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'name' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => '入力必須です',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'maxlength' => array(
'rule' => array('maxlength', 128),
'message' => '最大文字数を超えています',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'from' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => '入力必須です',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'maxlength' => array(
'rule' => array('maxlength', 128),
'message' => '最大文字数を超えています',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'email' => array(
'rule' => array('email'),
'message' => 'メールアドレスの形式が正しくありません',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'body' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => '入力必須です',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'maxlength' => array(
'rule' => array('maxlength', 50000),
'message' => '最大文字数を超えています',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
);
}
コントローラーとビューは焼いたまま放置
今回はContactsController.phpではなく、PagesController内にメールフォーム用のアクションを記述していくことにしたので、
ContactsController.phpと各種ビュー(add/edit/index/view)は使用しません。
でも、とりあえずBakeしておいたので、認証(Auth)を適用してバックエンド画面として使用しようと思います。
使用するコンポーネントとモデルを追加
さて、ではPagesControllerに、先ほど作成したContactモデルとこの後作成するContactMailコンポーネントを読み込んでおきます。
もちろんメールフォームを設置したいアクションをPagesController以外に記述する場合はそのコントローラーで構いません。
そもそも何でPagesControllerなんよって話ですしおすし。
app/Controller/PagesController.php
public $uses = array('Contact');
public $components = array('ContactMail');
アクションを追加
メールフォームを設置したいページのコントローラーにアクションを追加します。くどいようですがここではPagesControllerに追加します。
処理の流れは、『メールフォームがPOSTされる→データベースに内容を保存→すぐさま保存したレコードを取り出し内容をメール送信→リダイレクト』といった感じ。
//app/Controller/PagesController.php
public function contact() {
if ($this->request->is('post')) {
$this->Contact->create();
if ($this->Contact->save($this->request->data)) {
$contact = $this->Contact->findByid($this->Contact->getLastInsertID());
$this->ContactMail->send(
'お問い合わせを送信しました', //件名
'contact', //テンプレートファイル名
$contact, //渡すデータ
$contact['Contact']['from'], //メールアドレス
$contact['Contact']['name'] . '様' //名前
);
$this->Session->setFlash('お問い合わせを送信しました');
$this->redirect('/');
} else {
$this->Session->setFlash('送信内容にエラーがあります。エラーメッセージに従って内容を修正してください。');
}
}
$this->set('title_for_layout', 'お問い合わせ');
}
メール送信用のコンポーネントを作ります。
とその前に、app/Config/の中に『email.php.default』ってファイルがあるので.defaultを取っ払ってemail.phpにしてください。これ大事です。忘れがちです。
では、続いてapp/Controller/Component/内にContactMailComponent.phpを作成して次のようなコンポーネントを作ります。
オレンジの部分は送信元メールアドレスと送信者名です。黄色い部分はメールサーバの設定です。
ここではGmailから送信する設定で書いています。お使いのメールサーバに合わせて設定してください。
<?php
//app/Controller/Component/ContactMailComponent.php
App::uses('CakeEmail', 'Network/Email');
class ContactMailComponent extends Component {
// SMTP設定
public $from_mail = '●●●●@gmail.com'; //送信元メールアドレス
public $from_name = null; //送信者名 nullでも可
public $config = array (
'host' => 'ssl://smtp.gmail.com',
'port' => 465,
'username' => '●●●●@gmail.com',
'password' => 'XXXXXXXX',
'transport' => 'Smtp'
);
function send($subject, $template, $data, $to_mail, $to_name = null) {
// 送受信者設定
if( is_null($to_name) ) {
$to_name = $to_mail;
}
if( is_null($this->from_name) ) {
$this->from_name = $this->from_mail;
}
// 送信処理
$email = new CakeEmail($this->config);
$email
->template($template, 'layout')
->viewVars(array('data' => $data))
->emailFormat('text')
->to(array($to_mail => $to_name))
->from(array($this->from_mail => $this->from_name))
->bcc(array($this->from_mail => $this->from_name))
->subject($subject)
->send();
}
}
?>
メールのレイアウトを作ります
レイアウトにはメールによくある署名なんかを入れておくと便利です。
app/View/Layouts/Emails/text/に『layout.ctp』を作ってこんな感じにしておきました。phpタグの部分が本文に置き換わります。
<!--app/View/Layouts/Emails/text/layout.ctp-->
<?php echo $content_for_layout;?>
*********************************************
14時の間食
URL:http://14-00.com/
メールのテンプレートを作ります
疲れてきたんで1時間くらいニコ動観ました。気を取り直してテンプレートを作ります。
app/View/Emails/text/内に『contact.ctp』を作ってこうです。phpタグの部分がモデルから取得した各種データに置き換わります。
<!--app/View/Emails/text/contact.ctp-->
<?php echo $data['Contact']['name']; ?>様
この度はお問い合わせいただき、ありがとうございます。
送信内容は次の通りです。
当方にて内容を確認次第、返信させていただきます。
*********************************************
■ お問い合わせ内容:
*********************************************
――――――――――――――――――――――
件名:<?php echo $data['Contact']['subject']; ?>
――――――――――――――――――――――
<?php echo $data['Contact']['body']; ?>
――――――――――――――――――――――
「当方」って普段言いますか?私は日常生活で一度も言ったことないですね。
いよいよビューです!メールフォームを作ります
やっとメールフォームを作ります。別に順番なんてどうでもいいんですが、ようやくですね。
app/View/Pages/にcontact.ctpを作って次のように記述します。
手前味噌ですがautoConfirm.jsを使って確認画面も出るようにします。このために用意したようなjQueryプラグインなんで。
もちろん、使わない場合は上3行を削って下さい。
使う場合はautoConfirm.jsをダウンロード&解凍して各種ファイルをapp/webroot/jsディレクトリに配置してください。
<!--app/View/Pages/contact.ctp-->
<?php echo $this->Html->script('jquery-1.7.2.min'); ?>
<?php echo $this->Html->script('jquery.ba-hashchange.min'); ?>
<?php echo $this->Html->script('autoConfirm'); ?>
<?php
echo $this->Form->create('Page', array('action' => 'contact', 'type' => 'post', 'class' => 'autoConfirm'));
echo $this->Form->input('Contact.subject', array('label' => 'タイトル'));
echo $this->Form->input('Contact.name', array('label' => 'お名前'));
echo $this->Form->input('Contact.from', array('label' => 'メールアドレス'));
echo $this->Form->input('Contact.body', array('label' => '本文'));
echo $this->Form->button('戻る', array('type' => 'button', 'class' => 'autoConfirmBack'));
echo $this->Form->submit('送信', array('div' => false));
echo $this->Form->end();
?>
これで完成です。