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デザイナーです。近所のイオンによく行きます。