14時の間食

CakePHPの記事を中心にWeb制作について

CakePHP2のCakeEmailでメールフォームを作る

CakePHP

CakePHP2.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();
?>

これで完成です。

カテゴリー

最近の記事

Author

  • ささきち-このブログを書いてる人
    s3make@ささきち
    多摩川沿いに住むフリーのWebデザイナーです。近所のイオンによく行きます。