プラグインを利用せずに固定ページに登録フォームを自作する
フォームの作成
WordPressの固定ページに登録フォームを作成する方法。セッションによる再送信防止機能やバリデーション機能を追加したフォームの開発。
基本となる固定ページの作成
固定ページにフォームを作成するので、最初にベースとなる固定ページを作成します。
画像のように
フォームのテスト
という固定ページをサンプル的に作りました。
エディタを
ビジュアルからテキスト
に変更することでPHPコードを有効にできると思っていたのですが、やってみたらできませんでした。そのための専用プラグインがあるようですが、今回は
functions.phpとthe_contentフィルターフック
を利用してフォームを自作します。
スラッグの追加
URLのスラッグを利用してthe_contentフィルターフック内でページによる判定処理を行いますので、スラッグ名を追加します。
スラッグ名は
form-test
として設定しました。フィルターフックに関連付けた関数内で以下のようにして条件分岐することが可能になります。
if( is_page( 'form-test' ) ) { }
ページ毎に異なるフォームを作成したり、記事ページにはフォームを表示しないように制御することが出来ます。
テーブルの追加
データベースにフォームから送信されたデータを保存するテーブルを作成します。今回は、メールアドレスを登録するフォームを想定して以下の構造で新規テーブルを作成しました。
CREATE TABLE IF NOT EXISTS `wp_mailmagazine` ( `id` int(11) NOT NULL AUTO_INCREMENT, `email` varchar(512) NOT NULL, `status` int(1) NOT NULL, `date` datetime NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
設定したデータベースはmysqlを利用しました。
セッションを利用した重複送信禁止機能とバリデーション機能を省略した動くフォームをコーディングします。
functions.phpの最後に以下のコードを追加します。
function page_form_sample($content) { if( is_page( 'form-test' ) ) { // POSTリクエストの場合 if( $_POST['post_method'] == 'Y' ) { global $wpdb; $email = $_POST['email']; $status = $_POST['status']; // データベースに登録 $wpdb->insert('wp_mailmagazine', array( 'email' => $email, 'status' => $status, 'date' => current_time('mysql', 1) ), array( '%s', '%d', '%s' ) ); $message = '登録処理が完了しました'; ?> <div class="updated"><p><strong><?php echo $message; ?></strong></p></div> <?php } echo '<div class="wrap">'; echo "<h2>メールアドレスを入力してください</h2>"; ?> <h3>登録</h3> <form name="form1" method="post" action="<?php echo str_replace( '%7E', '~', $_SERVER['REQUEST_URI']); ?>"> <input type="hidden" name="post_method" value="Y"> <input type="hidden" name="status" value="1"> <input type="text" name="email" value=""> <p class="submit"> <input type="submit" name="Submit" value="登録する" /> </p> </form> </div> <?php } else { return $content; } } add_filter('the_content', 'page_form_sample');
functions.phpに上のコードを追加して、固定ページを表示すると下の画像の通り表示されます。
テキストボックスに何か入力してボタンを押すとデータベースにデータが反映されます。
バリデーション機能の実装
ここまでの作業で動くメールフォームを固定ページに作成することができましたが、メールアドレスを登録するフォームなので、メールアドレスの書式に該当しないデータはデータベースに保存する前にエラーを返すようにしてみます。
現状のフォームだとメールアドレスではない、普通の文字列も登録することが出来てしまいますので、バリデーション機能を追加します。
if( is_email($email) ) { // データベース追加処理 $message = '登録処理が完了しました'; } else { $message = '不正なメールアドレスです'; }
メールアドレスのバリデーションは、WordPressの
is_email()
を利用して実装することが出来ます。
バリデーション機能と重複送信禁止機能を実装したフォームのコードは記事の最後に載せます。
フォームの重複送信問題
フォームを送信した後の画面でブラウザの更新ボタンを押すと、firefox場合は下のポップアップが表示されます。
この状態で再送信を押すと同じデータが再度データベースに登録されてしまいます。
この問題は、
Webアプリケーションにおけるフォームの多重送信問題
といわれていて、複数の対処方法があります。今回は、セッションデータを利用して、初回表示と画面遷移後でワンタイムチケットを異なる値にすることで制御してみます。
セッションを使った重複送信の制御
セッションを利用するためにWordPressの
wp-config.php
でセッションを利用可能な状態にします。ファイルの一番上に
session_start();
を追加することでセッションが使えるようになります。
セッションデータの生成とセッションへの格納をするコードは以下の通りです。
$session_key = md5(sha1(uniqid(mt_rand(), true))); $_SESSION['key'] = $session_key;
そして、$session_keyフォームで送信できるようにします。
<input type="hidden" name="ticket" value="<?php echo $session_key; ?>">
$session_keyをフォームのhiddenにセットしてPOSTメソッドで送信し、POSTリクエストを処理する際に、
$_SESSION[‘key’]と$_POST[‘ticket’]が同じか否か
を判定処理します。
if ( $_SESSION['key'] and $_POST['ticket'] and $_SESSION['key'] == $_POST['ticket'] ) { $message = '登録処理が完了しました'; } else { $message = 'メールアドレスは送信済みです'; }
コード全体
重複送信の制御機能とバリデーション機能を含めたコードは以下の通りです。
function page_form_sample($content) { if( is_page( 'form-test' ) ) { if( $_POST['post_method'] == 'Y' ) { global $wpdb; $email = $_POST['email']; $status = $_POST['status']; // セッションキーとチケットが一致しているどうか if ( $_SESSION['key'] and $_POST['ticket'] and $_SESSION['key'] == $_POST['ticket'] ) { // メールのバリデーションチェック if( is_email($email) ) { $wpdb->insert('wp_mailmagazine', array( 'email' => $email, 'status' => $status, 'date' => current_time('mysql', 1) ), array( '%s', '%d', '%s' ) ); $message = '登録処理が完了しました'; } else { $message = '不正なメールアドレスです'; } } else { $message = 'メールアドレスは送信済みです'; } // セッションの破棄 unset($_SESSION['key']); ?> <div class="updated"><p><strong><?php echo $message; ?></strong></p></div> <?php } // ワンタイムチケットの生成とセッションへの保存 $session_key = md5(sha1(uniqid(mt_rand(), true))); $_SESSION['key'] = $session_key; echo '<div class="wrap">'; echo "<h2>メールアドレスを入力してください</h2>"; ?> <h3>登録</h3> <form name="form1" method="post" action="<?php echo str_replace( '%7E', '~', $_SERVER['REQUEST_URI']); ?>"> <input type="hidden" name="post_method" value="Y"> <input type="hidden" name="status" value="1"> <input type="hidden" name="ticket" value="<?php echo $session_key; ?>"> <input type="text" name="email" value=""> <p class="submit"> <input type="submit" name="Submit" value="登録する" /> </p> </form> </div> <?php } else { return $content; } } add_filter('the_content', 'page_form_sample');
まとめ
functions.phpとthe_contentフィルターフックを利用したフォームの開発方法を書いてみた。
- 基本フォームの作成
- データベーステーブルの作成
- 動くフォームの開発
- メールのバリデーション
- 重複送信の制御
固定ページにフォームを作成する方法について書くことで、上のテーマを扱うことが出来た。WordPressを使いこなす上では必須のスキルやノウハウになる。
I comment when I especially enjoy a post on a site or I have something
to valuable to contribute to the conversation. Usually it is triggered by the fire communicated in the article I browsed.
And on this article WordPressで登録フォームを作成 |
Webエンジニアブログ. I was actually excited enough to drop a leave a responsea response :
-) I do have 2 questions for you if it’s allright.
Is it only me or do some of the comments appear like they are
coming from brain dead folks? 😛 And, if you are posting on other social sites, I
would like to keep up with you. Could you make a list every one of your social sites like your linkedin profile, Facebook page or
twitter feed?