雨ときどき晴れ

最近は C# や Blazor やってます。Raspberry Pi で Node-RED も活用できるようになりました。

CakePHPでお問い合わせフォームを作ってみた。

CakePHP でお問い合わせフォームを作ってみました。


実行環境

仕様
  • ページ構成は、入力、確認、完了の3ページ。
  • 入力項目は、名前、メールアドレス、本文の3種類。
  • 入力ページでは、入力内容をモデルのバリデーションでチェック。
  • 完了ページにて、問い合わせた人にメールを送信。
  • メール送信ログとして、送信メールにはBccで管理者メールアドレスを設定。
使用するプラグイン

プラグインの設置方法はリンク先をご参照ください。

作成するファイル
  • コントローラー
    • /app/controllers/contacts_controller.php
  • モデル
    • /app/models/contact.php
  • ビュー
    • /app/views/contacts/index.ctp(入力)
    • /app/views/contacts/confirm.ctp(確認)
    • /app/views/contacts/finish.ctp(完了)
    • /app/views/elements/contact_input.ctp(入力部分に使用するエレメント)

ビューの contact_input.ctp は、入力、確認ページで使用します。

ソース

コントローラー
  • ファイル名:/app/contollores/contacts_contoroller.php
    • ページのURLは変更せず、POSTされた値に応じて表示する内容を変更。
    • 完了ページでのページリロードによるメール再送信の防止。
    • メール送信には SMTP 送信を利用。
<?php

class ContactsController extends AppController {
  public $name = 'Contacts';
  public $uses = array('Contact');

  var $helpers = array('Html', 'Form', 'xformjp', 'Cakeplus.Formhidden');
  var $components = array('Qdmail', 'Qdsmtp');

  function index(){
    if (isset($this->params['form']['confirm'])) { //確認ページ
      if (!empty($this->data)){
        $this->Contact->set($this->data);
        if ($this->Contact->validates()) {   //バリデーション問題なし
          $this->Session->write('reload', false);  //リロード対策セッションの登録
          $this->params['xformHelperConfirmFlag'] = true;  //確認画面の表示に切り替える
          $this->render('confirm');
          return;
        }
        $this->render();
        return;
      }
    } else if (isset($this->params['form']['back'])) { //入力ページに戻る
      $this->render();
      return;
    } else if (isset($this->params['form']['finish'])) { //完了ページ
      if (!$this->Session->read('reload')) { //リロードした場合はメール送信しない。
        $name = $this->data['Contact']['name'];  //フォームからデータ取得
        $email = $this->data['Contact']['email'];
	      
        $this->send_mail($email, $name);  //メールを送信
        $this->Session->write('reload', true);  //リロードフラグを立てる
      }
      $this->render('finish');
      return;
    }
  }
  
  //メールを送信します。
  function send_mail($email, $name) {
    $admin_email = 'admin@hoge.jp';  //管理者のメールアドレス
    $admin_name = '管理者';  //管理者の名前
  
    $mail_param = array(            //SMTPの設定
        'host' => 'smtp.hoge.jp',   //ホスト名
        'port' => 587,              //ポート
        'from' => 'admin@hoge.jp',  //Return-path
        'protocol' => 'SMTP_AUTH',  //認証方式
        'user' => 'admin',          //SMTPサーバーのユーザーID
        'pass' => 'password'        //SMTPサーバーの認証パスワード
    );
  
    $this->Qdmail->reset();  //リセット
    $this->Qdmail->allwaysBcc($admin_email);  //常にBcc設定で管理者に送信
	
    $this->Qdmail->smtp(true);	//SMTP設定
    $this->Qdmail->smtpServer($mail_param);
	
    $this->Qdmail->to($email, $name);    //送信先
    $this->Qdmail->subject('お問い合わせを受け付けました');   //件名
    $this->Qdmail->from($admin_email, $admin_name);  //送信元
    $this->Qdmail->text('本文です。');  //本文
    $this->Qdmail->send();  //メールを送信
  }
}
モデル
  • ファイル名:/app/models/contact.php
<?php

class Contact extends AppModel {
  public $name = 'Contact';
  public $actsAs = array('Cakeplus.AddValidationRule');
  
  var $useTable = false;  //データベースのテーブルを使用しない
  
  public $validate = array(
  		'name' => array(  //名前
            'maxLengthJP' => array(
                'rule' => array('maxLengthJP', '50'), //日本語50文字以内
                'allowEmpty' => false,
                'message' => '50文字以内で入力してください'
            ),
            'notEmpty' => array(
                'rule' => 'notEmpty',
                'message' => '名前を入力してください'
            )
        ),
        'email' => array( //メールアドレス
            'email' => array(
                'rule' => array('email', true),  //メールサーバーのホストが存在するか調べる
                'message' => 'メールアドレスを正しく入力してください'
            ),
            'notEmtpy' => array(
                'rule' =>'notEmpty',
                'message' => 'メールアドレスを入力してください'
            )
        ),
        'body' => array(  //お問い合わせ内容
            'maxLengthJP' => array(
                'rule' => array('maxLengthJP', '500'), //日本語500文字以内
                'allowEmpty' => false,
                'message' => '500文字以内で入力してください'
              ),
            'notEmpty' => array(
                'rule' => 'notEmpty',
                'message' => 'お問い合わせ内容を入力してください'
            )
        )
  );
}

?>
ビュー
  • ファイル名:/app/views/contacts/index.ctp
    • 入力ページ。
<h2>お問い合わせ</h2>
<p>名前、メールアドレス、お問い合わせ内容を入力してください。</p>
	
<?php echo $xformjp->create('Contact', array('type' => 'post', 'controller'=>'contact', 'action' => '.')); ?>
<?php echo $this->element('contact_input'); ?>
<?php echo $xformjp->submit('確認', array('name' => 'confirm', 'div' => false)); ?>
<?php echo $xformjp->end(); ?>
  • ファイル名:/app/views/contacts/confirm.ctp
    • 確認ページ。
<h2>お問い合わせ</h2>
<p>下記の入力内容を確認してください。</p>
	
<?php echo $xformjp->create('Contact', array('type' => 'post', 'controller'=>'contact', 'action' => '.')); ?>
<?php echo $formhidden->hiddenVars(); ?>
<?php echo $this->element('contact_input'); ?>
<?php echo $xformjp->submit('戻る', array('name' => 'back', 'div' => false)); ?>
<?php echo $xformjp->submit('送信', array('name' => 'finish', 'div' => false)); ?>
<?php echo $xformjp->end(); ?>
  • ファイル名:/app/views/contacts/finish.ctp
    • 完了ページ。
<h2>お問い合わせ</h2>
<p>お問い合わせを受け付けました</p>
  • ファイル名:/app/views/elements/contact_input.ctp
    • 入力部分に使用するエレメント。
    • コントローラーで設定されるフラグによって、入力と確認用に表示が切り替わる。
<table>
  <tr>
    <th>名前</th>
	<td>
      <?php echo $xformjp->input('name', array('type' => 'text')); ?>
      <?php echo $xformjp->error('name'); ?>
    </td>
  </tr>
  <tr>
    <th>メールアドレス</th>
    <td>
      <?php echo $xformjp->input('email', array('type' => 'text', 'class' => 'text_l')); ?>
      <?php echo $xformjp->error('email'); ?>
    </td>
  </tr>
  <tr>
    <th>お問い合わせ内容</th>
    <td>
      <?php echo $xformjp->textarea('body', array('rows' => '10', 'cols' => '40')); ?>
      <?php echo $xformjp->error('body'); ?>
    </td>
  </tr>
</table>