CakePHP2 プラグインを駆使して問い合わせフォームを作ってみます♪

本投稿はわたくしオリジナルではなく、次の記事を自分なりに実践した勉強となります。

  • WEB+DB PRESS Vol.65|gihyo.jp … 技術評論社
    特集2 PHPフレームワーク実践活用 ~Symfony2,CakePHP,Silex~
    第3章:CakePHP最新開発スタイル 豊富なプラグインを用いた開発とCakePHP 2.0を体験……市川 快

作るものの簡単な仕様

  • お問い合わせ送信の前に確認画面を表示する。
  • お問い合わせの入力内容は DB に保存する。
  • E -mail は2回入力してもらい、一致しているかどうかのバリデーションチェックを行う。

お問い合わせフォームの実装流れ

  1. インストール、設定
  2. DB スキーマの用意とテーブル作成
  3. bake all で初期コードの自動生成
  4. プラグイン設置
  5. 確認画面の遷移を追加
  6. 確認画面のビューを追加
  7. 保存データのチェック
  8. 完成画面

1.インストール、設定

いきなりですが、省略します。次のページを参照です。

2.DB スキーマの用意とテーブル作成

次のスキーマで MySQL にテーブルを作成しました。

CREATE TABLE posts (
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL,
    text TEXT NOT NULL,
    created DATETIME DEFAULT NULL,
    modified DATETIME DEFAULT NULL
);

3.bake all で初期コードの自動生成

post テーブルの情報から、モデル、コントローラー、ビューを bake all で自動生成します。環境が Windows の XAMPP ですので、コマンドプロンプトからです。

# PHP へのパスを通す
set path=%path%;C:\pleiades\xampp\php
# CakePHP のあるところまで移動
cd C:\pleiades\xampp\htdocs\cake04

# bake all の実行
php app\Console\cake.php bake all

バッチファイルではなく、php で実行しています。cake.php の引数には bake all を指定しました。

Welcome to CakePHP v2.2.1 Console
---------------------------------------------------------------
App : app
Path: C:\pleiades\xampp\htdocs\cake04\app\
---------------------------------------------------------------
Bake All
---------------------------------------------------------------
Possible Models based on your current database:
1. Post
Enter a number from the list above,
type in the name of another model, or 'q' to exit
[q] >

ひとつだけですが、モデルの選択肢が出ますので、左の番号の「1」を入力して Enter し、初期コードが自動生成されました。

4.プラグイン設置

次のプラグインを使用しました。

また、Debug Kit プラグインも入れてデバッグの助けとします。

プラグイン 導入方法

それぞれの GitHub リンクから CakePHP2 用の最新バージョンの zip ファイルをダウンロード、解凍しました。そして解凍したフォルダ名を次のようにリネームしました。これらを app/Plugin に置きました。

  • Transition Component → Transition
  • XformHelper → Xform
  • Cakeplus → Cakeplus
  • Debug Kit → DebugKit

置いただけでは使えません。このプラグインを使う!とか Plugin フォルダに置かれたものは全部使う!とか、宣言しなければなりません。今回は後者のやり方で、次のようにしました。

app/Config/bootstrap.php の末尾に追加。

/**
 * Plugins
 */
 CakePlugin::loadAll();

さて、まだ使えません。以前どこかのページで、CakePHP2 のプラグインを使うのに、Plugin フォルダに置くのは電化製品を家に運んだだけ、bootstrap.php に書くのはコンセントを刺しただけ、スイッチオンして使うには使用したいソースで読み込んでやらなければならない、といったことが書いてありました。

スイッチオン!しましょうか。今回はサンプルということで、app/Controller/AppController.php と app/Model/AppModel.php で読み込んで、これらを継承するすべてのコントローラー、モデルでも使えるようにします。

app/Controller/AppController.php で Transition Component、XformHelper、Debug Kit を読み込みます。

class AppController extends Controller {
	public $components = array(
			'DebugKit.Toolbar',
			'Transition.Transition',
			'Session',
	);

	var $helpers = array('Form', 'Xform.Xform');
}

app/Model/AppModel.php で Cakeplus を読み込みます。

class AppModel extends Model {
	public $actsAs = array('Cakeplus.AddValidationRule');
}

プラグインが読み込めたかどうか、確認です。

Debug Kit からそのページで使用可能なプラグインを確認することができます。 bake all で作成した posts コントローラーの index アクションのページで確認してみます。わたくしの今回の例での URL は http://localhost/cake04/posts となりました。

CakePHP- the rapid development php framework- Posts1.jpg

Debug Kit の Include から、Cakeplus、Debug Kit、Transition Component プラグインの読み込みを確認できました。

CakePHP- the rapid development php framework- Posts2.jpg

続いて、Debug Kit の Variables から、Xform プラグインの読み込みを確認できました。

5.確認画面の遷移を追加

bake all で生成された app/Controller/PostsController.php の add() つまり入力画面アクションを編集し、confirm() 確認画面アクションと finish() 保存アクションを追加します。

app/Controller/PostsController.php

<?php
App::uses('AppController', 'Controller');
/**
 * Posts Controller
 *
 * @property Post $Post
 */
class PostsController extends AppController {

// 親クラスの AppController でプラグイン読み込み済みなのでここでは読み込みません。

/**
 * add アクション
 * 入力フォームページの初期表示、
 * 入力後、送信ボタンでバリデーションチェックと確認画面への遷移を行います。
 *
 * @return void
 */
	public function add() {
		/*
		 * 入力データあればバリデーションチェックを行ないます。
		 * 問題がなければ、入力データをセッションに格納して
		 * confirm アクションに遷移します。
		 */
		$this->Transition->checkData('confirm');
	}

/**
 * confirm アクション
 * 入力内容の確認画面。
 * 送信ボタンで保存処理へ遷移します。
 *
 * @return void
 */
	public function confirm() {
		//確認画面の表示に切り替えます。
		$this->params['xformHelperConfirmFlag'] = true;

		/*
		 * 入力画面からの正しい遷移かどうかをチェックします。
		 * 第1引数:前のアクション、
		 * 第2引数:次のアクション。
		 */
		$this->Transition->automate('add', 'finish');

		/*
		 * 確認画面に表示するデータを渡すために
		 * マージしたセッションデータを post に代入して
		 * Xfrom で使えるようにします。
		 */
		$this->request->data = $this->Transition->mergedData();

		// confirm アクションでも add.ctp の view ファイルを利用します。
		$this->render('add');
	}

/**
 * finish アクション
 * 入力データを保存します。
 *
 * @return void
 */
	public function finish() {
		// 入力画面、確認画面からの正しい遷移かどうかを確認します。
		$this->Transition->checkPrev(array('add', 'confirm'));

		/*
		 * 確認画面を経由すると入力データは post で来ないため、
		 * 保存データはセッションから取得します。
		 */
		$save_data = $this->Transition->mergedData();

		// バリデーションおよび保存
		$this->Post->create();
		if ($this->Post->save($save_data)) {
			// セッションにある入力フォームデータを削除します。
			$this->Transition->clearData();

			$this->Session->setFlash('お問い合わせを保存しました。');
		} else {
			$this->Session->setFlash('お問い合わせは保存できませんでした。');
		}
		$this->redirect(array('action' => 'index'));
	}

// index、view、edit、delete アクションは省略
}

ポイントは、confirm アクションを表示するときのデータの渡し方、finish アクションで保存するデータをとってくる方法となると感じました。Xfrom と Transition でのデータの取り扱い方をきちんと把握しないと大混乱に陥ると思います。

今回の例でわかった、それぞれのプラグインでのデータの取り扱い方法は次のようでしたよ。

  • Xfrom : 確認画面では post のデータを取得してラベルで表示します。したがって、 hidden で data[Post][name] を持ったりはしません。つまり、次のアクションへ post データを渡すことができません。
    そのため、finish アクション実行時に post でデータが送れるように工夫をするか、finish アクション内でセッションからデータをとるようにします。
  • Transition : セッションでデータを管理します。そのため画面にデータを表示したいときはコントローラーのアクション内でセッションからデータを取り出してリクエストに渡すなどの処理が必要となってきます。

6.確認画面のビューを追加

こちらも bake all で自動生成された app/View/Posts/add.ctp を編集します。この add.ctp ビューは、入力画面と、確認画面を兼ねます

app/View/Posts/add.ctp

<div class="posts form">
<?php echo $this->Xform->create('Post'); ?>
	<fieldset>
		<legend><?php echo __('Add Post'); ?></legend>
	<?php
		echo $this->Xform->input('name');
		echo $this->Xform->input('email');
		echo $this->Xform->input('email_confirm');
		echo $this->Xform->input('text');
	?>
	</fieldset>
<?php echo $this->Xform->end('次の画面へ'); ?>
</div>
<div class="actions">
	<h3><?php echo __('Actions'); ?></h3>
	<ul>
		<li><?php echo $this->Html->link(__('List Posts'), array('action' => 'index')); ?></li>
	</ul>
</div>

変更点は多くなく、次の2点です。

  • $this->Form-> を、$this->Xfrom-> に変更して確認画面での表示をできるようにしました。
  • echo $this->Xform->input(‘email_confirm’); つまりメールアドレス確認用のフィールドを追加しました。同じメールアドレスを入力してしてもらって間違いがないかどうかを確認するためです。

7.保存データのチェック

またまた bake all で自動生成された app/Model/Post.php を編集します。バリデーションルールを少し編集します。。

app/Model/Post.php

<?php
App::uses('AppModel', 'Model');
/**
 * Post Model
 *
 */
class Post extends AppModel {

// 親クラスの AppModel でプラグイン読み込み済みなのでここでは読み込みません。

/**
 * Validation rules
 *
 * @var array
 */
	public $validate = array(
		'name' => array(
			'notempty' => array(
				'rule' => array('notempty'),
				'message' => '必ず入力してください。',
			),
		),
		'email' => array(
			'email' => array(
				'rule' => array('email'),
				'message' => 'eメール形式で入力してください。',
			),
			'compare2fields' => array(
				'rule' => array('compare2fields', 'email_confirm'),
				'message' => 'Email Confirm と同じ内容を入力してください。',
			),
		),
		'text' => array(
			'notempty' => array(
				'rule' => array('notempty'),
				'message' => '必ず入力してください。',
			),
		),
	);
}

ポイントです。

  • email フィールドのバリデーションに email_confirm フィールド入力値と値が一致するかどうかのルールを追加しました。ソースの28~31行にあたります。

 8.完成画面

わたくしの環境では、http://localhost/cake04/posts にアクセスすると、次のように入力、確認、完了画面と無事動きました。

CakePHP- the rapid development php framework- Posts_nyuryoku.jpg

↑入力画面

CakePHP- the rapid development php framework- Posts_kakunin.jpg

↑確認画面

CakePHP- the rapid development php framework- Posts_hozon.jpg

↑保存完了

プラグインを導入してみて、導入する方法が初心者向けでなかったりで若干難しかったのと、プラグインの使い方を習得するのにやはり少し難しいのを除けば、大変便利だと感じました。

以上です。

コメントを残す

コメントを残す