読者です 読者をやめる 読者になる 読者になる

Motomichi Works Blog

その日学習したことについて書いている日記です。誰かの役に立ったらそれはそれで嬉しいです。

さくらvpsとcakephp2.6.7で開発日記 その0001 お問い合わせフォームの作成をする

参考にさせて頂いたページ

お問い合わせフォームの全般的なこと

CakeEmailを使った確認画面付きの問い合わせフォーム | CakePHPクッキング

フォームから送信された値のバリデーションについて

vagrantその19-39 cakephp入門をやってみる(バリデーション 簡易設定) - MOTOMICHI WORKS BLOG

コントローラーからのバリデーション

Viewについて

[CakePHP2] バリデーションエラーを任意の位置に表示する | unlinked log

FormHelper

index, confirm, completeそれぞれ別actionに分けたい場合について

Cakephp2 リダイレクトにpost送信お世話になります。$this->re... - Yahoo!知恵袋

メールの自動送信について

CakePHP 2.x - CakeEmailでメール送信(@gmail)

saveについて

データを保存する

どのsubmitボタンがクリックされたか判定する

(CakePHP2.x)フォームでsubmitを分けて処理する | 日々の覚書…日常のことも少しだけ

ランダムな文字列を生成する

ランダムな英数字の文字列を作成 - Qiita

contactsテーブルを作成する

実行したsqlは以下の通り

CREATE TABLE `contacts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `email` varchar(255) NOT NULL,
  `text` varchar(2000) NOT NULL,
  `created` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

AppController.php

記述内容は以下の通り

<?php
/**
 * Application level Controller
 *
 * This file is application-wide controller file. You can put all
 * application-wide controller-related methods here.
 *
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 * @link          http://cakephp.org CakePHP(tm) Project
 * @package       app.Controller
 * @since         CakePHP(tm) v 0.2.9
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
 */

App::uses('Controller', 'Controller');

/**
 * Application Controller
 *
 * Add your application-wide methods in the class below, your controllers
 * will inherit them.
 *
 * @package   app.Controller
 * @link    http://book.cakephp.org/2.0/en/controllers.html#the-app-controller
 */
class AppController extends Controller {
  public $components = array(
    'DebugKit.Toolbar',
    'Session'
  );
}

上記した通り、DebugKit.ToolbarSessionコンポーネントを有効化しています。

ContactsController.phpを作成する

記述内容は以下の通り

<?php
App::uses('AppController', 'Controller');
App::uses('CakeEmail', 'Network/Email');
class ContactsController extends AppController {
  public $uses = array('Contact');


  public function index() {

    //postでアクセスしていない場合または、フォーム送信データが無い場合、Contacts/indexを表示
    if(!$this->request->is('post') || !$this->request->data){
      $this->render('index');
      return;
    }

    //ここから下はpostでアクセスされていて、フォーム送信データがある場合の処理

    //送信された値をContactモデルで使用できるようにset
    //(Model/Contact.phpで送信データのバリデーションを行うために値をset)
    $this->Contact->set($this->request->data);

    //バリデーション実行
    if (!$this->Contact->validates()) {
      //バリデーションチェックに引っかかった場合の処理
      $this->Session->setFlash('入力に不備があります。');
      $this->render('index');
      return;
    }

    //クリックされたボタンがどれだったか判定して、それに応じた処理を実行
    if(isset($this->request->data['index_page__next'])){
      //indexページで「確認」がクリックされたときの処理
      $this->render('confirm');
      return;
    }else if(isset($this->request->data['confirm_page__back'])){
      //confirmページで「戻る」がクリックされたときの処理
      $this->render('index');
      return;
    }else if(isset($this->request->data['confirm_page__next'])){
      //confirmページで「送信」がクリックされたときの処理
      //DBにお問い合わせ内容を保存
      if(!$this->Contact->save($this->request->data)){
        //saveに失敗したときの処理
        $this->Session->setFlash('お問い合わせの送信に失敗しました。恐れ入りますが始めからやり直してください。');
        $this->render('index');
        return;
      }
      //メール自動送信に必要な設定をする
      $cake_email = new CakeEmail('default');//インスタンス生成
      $cake_email->from( array('mw.contacts@hoge.com' => 'Sender'));//送信元を設定
      $cake_email->to($this->request->data['Contact']['email']);//送信相手を設定
      $cake_email->subject('お問い合わせありがとうございます');//件名を設定
      $cake_email->emailFormat('text');//HTMLまたはテキストメールで送信する
      $cake_email->template('contact');//View/Emailsの中のどのctpを使うか選択
      //メール本文で使用する変数を設定
      $cake_email->viewVars(array(
        'name' => $this->request->data['Contact']['name'],
        'text' => $this->request->data['Contact']['text']
      ));
      //メールを送信
      if($cake_email->send()){
        //メール送信成功時の処理
        $this->redirect('complete');
        return;
      }else{
        //メール送信失敗時の処理
        $this->Session->setFlash('お問い合わせの送信に失敗しました。恐れ入りますが始めからやり直してください。');
        $this->render('index');
        return;
      }
    }
  }//end of index action

  public function complete() {
  }//end of complete action
}

Model/Contact.phpを作成する

記述内容は以下の通り

<?php
App::uses('AppModel', 'Model');

class Contact extends AppModel{
  // public $useTable = false;
  public $validate = array(
    'name' => array(
      array(
        'rule' => 'notEmpty',
        'message' => '名前を入力してください。'
      )
    ),
    'email' => array(
      array(
        'rule' => 'notEmpty',
        'message' => '必須項目です。'
      ),
      array(
        'rule' => 'email',
        'message' => 'メールアドレスを入力してください。'
      )
    ),
    'text' => array(
      array(
        'rule' => 'notEmpty',
        'message' => 'お問い合わせ内容を入力してください。'
      )
    )
  );
}

View/Contacts/index.ctpを作成する

記述内容は以下の通り

<h1>お問い合わせ</h1>
<?php echo $this->Form->create('Contact', array('action' => '/')); ?>
  <?php
    //name 
    echo $this->Form->input(
      'name',
      array(
        'errorMessage' => false,
        'div' => false,
        'required' => false
      )
    );
    //バリデーションエラーのときはメッセージを表示
    echo $this->Form->error('name');
  ?>

  <?php
    //email
    echo $this->Form->input(
      'email',
      array(
        'errorMessage' => false,
        'div' => false,
        'required' => false
      )
    );
    //バリデーションエラーのときはメッセージを表示
    echo $this->Form->error('email');
  ?>

  <?php
    //text
    echo $this->Form->textarea(
      'text',
      array('required' => false)
    );
    //バリデーションエラーのときはメッセージを表示
    echo $this->Form->error('text')
  ?>

  <?php
    // submitボタンを描画
    echo $this->Form->submit(
      '確認へ進む',
      array(
        'name' => 'index_page__next'
      )
    );
  ?>
<?php echo $this->Form->end(); ?>

View/Contacts/confirm.ctpを作成する

記述内容は以下の通り

<h1>お問い合わせ内容確認</h1>
<?php echo $this->Form->create('Contact', array('action' => '/')); ?>
  <div>
    <?php
      echo $this->Form->value('name');
      echo $this->Form->hidden('name');
    ?>
  </div>
  <div>
    <?php
      echo $this->Form->value('email');
      echo $this->Form->hidden('email');
    ?>
  </div>
  <div>
    <?php
      echo $this->Form->value('text');
      echo $this->Form->hidden('text');
    ?>
  </div>

  <?php
    // submitボタンを二つ描画
    echo $this->Form->submit(
      '戻る',
      array(
        'name' => 'confirm_page__back'
      )
    );
    echo $this->Form->submit(
      '送信する',
      array(
        'name' => 'confirm_page__next'
      )
    );
  ?>

<?php echo $this->Form->end(); ?>

View/Contacts/complete.ctpを作成する

記述内容は以下の通り

<h1>お問い合わせ完了</h1>

お問い合わせ完了
<br>
お問い合わせありがとうございました。

View/Emails/text/contact.ctp

記述内容は以下の通り

<?php echo($name);?> 様

お問い合わせありがとうございました。

以下の内容でお問い合わせを受付ました。

お問い合わせ内容 : 

<?php echo($text); ?>

app/Config/email.php

email.php.defaultをコピーして、email.phpを作成します。

その記述内容のうち、今回は以下の部分を使用しています。

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

今回学習できたこと

必要なファイル

  • AppController.php
  • ContactsController.php
  • Model/Contact.php
  • View/Contacts/index.ctp
  • View/Contacts/confirm.ctp
  • View/Contacts/complete.ctp
  • View/Emails/text/contact.ctp
  • app/Config/email.php

actionは二つにした

  • index
  • confirm
  • send
  • complete

validationについて

確認ページを挟んでから実際に送信する場合は、コントローラからのバリデーションが必要なので、 コントローラーからのバリデーション が参考になった。

これは今後も頻繁に使いそう。

クリックされたsubmitボタンのvalueも取得できる

ボタンについているname属性をもとに、isset()でどのボタンがクリックされたか判定できる。

redirectとrender

redirectするとユーザーが入力した内容が消えてしまうのでrenderで。

処理成功時は消したいのでredirectで。

createdフィールドとmodifiedフィールド

cakephpでは、createdフィールドとmodifiedフィールドをdatetime型で用意しておくと、saveのときに自動的に値を入れてくれる。

CakeEmail

CakeEmailの使い方について理解がはかどった。

type="text"の要素

以下のようにすることで、

  <?php
    //name 
    echo $this->Form->input(
      'name',
      array(
        'errorMessage' => false,
        'div' => false,
        'required' => false
      )
    );
    //バリデーションエラーのときはメッセージを表示
    echo $this->Form->error('name');
  ?>
  • errorMessageを自分の好きな場所に表示できる
  • input要素を包括するdiv要素を出さないようにする事ができる
  • required属性を付与しないようにできる

type="submit"の要素

以下のようにすることで

  <?php
    // submitボタンを描画
    echo $this->Form->submit(
      '確認へ進む',
      array(
        'name' => 'index_page__next'
      )
    );
  ?>

valueとnameを設定できるので、Controller側で取得できる。

確認ページでの出力

確認ページでは

  • ユーザーに見える部分の出力はecho $this->Form->value('name');
  • type="hidden"の要素はecho $this->Form->hidden('name');

の二つワンセットで今後も頻繁に使いそう。

所感

ただ基礎的な使い方を断片的に学ぶところから、ようやく実際に作る段階に入った。

実際に作ってみると、formヘルパーの使い方、バリデーションの仕方、CakeEmailの使い方、renderとredirectの使い分け、など色々検索して試行錯誤しながらだったし、結構大変だった。

webアプリケーションでよく見られる、入力、確認、完了のフォームでは非常に基礎的な制作を通して、ただ知ってるのではなくて色々理解できた感じ。