WordPress

最終更新日:
公開日:

ワークショップ

オリジナルのWordPressプラグインを作る(12)

お問い合わせの編集ページを作成する

お問い合わせ管理プラグインにお問い合わせのデータを編集する機能を実装していきます。

この記事のポイント

  • 編集ページのビューファイルを作成する
  • データの取得ではプリペアドステートメントを使って安全にSQLを実行する

目次

お問い合わせを編集できるようにする

前回の「お問い合わせのデータをデータベースから取得する」ではプラグインのトップページに、データベースから取得したデータを一覧に表示する機能を実装してきました。

前回作成したコード:GitHub

今回は一覧に表示されているお問い合わせの中から「編集」リンクを押したら、お問い合わせ内容の編集ページを表示するようにしていきます。

編集ページを作成する

まずは編集ページのビューを作成します。
その後、編集ページで編集するお問い合わせデータを取得する新しいメソッドをCm_Dbクラスに作成しましょう。

編集ページのビューファイルを作成する

トップページでviewsフォルダindex.phpを作成したときのように、編集ページにもビューファイルを作成します。
viewsフォルダedit.phpを作成してコードエディタで開き、ファイル内に以下のコードを書いてください。

views/edit.php

<p class="link_back"><a href="<?php echo Cm::getBaseUrl(); ?>">戻る</a></p>

<div class="form_area">

<form method="post" action="<?php echo Cm::getBaseUrl(); ?>">
<dl class="form_list">
	<dt>お名前</dt>
	<dd><input type="text" name="name" value=""></dd>
	<dt>メールアドレス</dt>
	<dd><input type="email" name="email" value=""></dd>
	<dt>メールアドレス</dt>
	<dd><textarea name="content"></textarea></dd>
</dl>
<input type="hidden" name="id" value="">
<input type="hidden" name="edit_token" value="">
<input type="submit" name="btn_register" value="更新">
</form>

</div>

form要素action属性CmクラスgetBaseUrlメソッドを指定します。
非表示(type="hidden")のinput要素idカラムの値が入る「name="id"」と、セッショントークンが入る「name="edit_token"」の2つを用意します。
この後、これらのinput要素にもvalue属性に値を設定していきます。

続いて、作成した編集ページを表示できるようにcontactManager.phpにコードを追加していきます。
前回、トップページの一覧を作成したときに編集リンクを設置しましたが、そこへGETパラメータで「cm=edit」を出力しました。
GETパラメータのcmの値で表示するビューを切り替えるように設定します。

contactManager.php

<?php
/*
Plugin Name: Contact Manager
Description: お問い合わせを管理するためのプラグイン
Version: 0.1
Author: GRAYCODE
Author URI: https://gray-code.com
Licence: GPL v2 or later
Licence URI: https://www.gnu.org/licenses/gpl-2.0.html
*/

define( 'CM_VERSION', '0.1.1' );
define( 'CM_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );

require_once( CM_PLUGIN_DIR . 'class.cm.php' );
require_once( CM_PLUGIN_DIR . 'class.cm-db.php' );

function cm_option_page_html() {

$page_title = 'お問い合わせ管理';
$view = 'index';

if( !empty($_GET['cm']) ) {

	switch( $_GET['cm'] ) {
		
		case 'edit':
			$page_title = 'お問い合わせ管理 編集';
			$view = 'edit';
			break;

		case 'delete':
			$page_title = 'お問い合わせ管理 削除';
			$view = 'delete';
			break;

		default:
			$page_title = 'お問い合わせ管理';
			$view = 'index';
	}

}

?>

<div class="wrap">
	<h1><?php echo $page_title; ?></h1>
	<?php Cm::view($view); ?>
</div>

----- 省略 -----

if文empty関数を使って$_GET[‘cm’]に値があるか確認をしてから、switch文で表示するページのタイトルと読み込むビューファイルを変数に設定します。
$_GET[‘cm’]editなら編集ページ、deleteのときは削除ページを表示し、それ以外の値はトップページを表示します。

もし$_GET[‘cm’]に値がないときは$page_title$viewの値はif文の前で設定した値から変更がないため、そのままトップページが表示されます。

編集するデータを取得するメソッドを作成する

続いて、編集するデータを1件だけ取得するメソッドをCm_Dbクラスに追加していきます。

お問い合わせのデータを検索するメソッドを作成する

これから作成するお問い合わせのデータを検索するメソッドは、contactテーブルからAUTO_INCREMENT属性の付いた主キー(PRIMARY KEY)であるidカラムとパラメータに指定した値が一致するデータをSQLで検索します。

Cm_Dbクラスclass.cm-db.phpを開いて、以下のgetDataFromIdメソッドを追加してください。

class.cm-db.php

<?php

class Cm_Db {

	public static function getDataFromId($id) {

		global $wpdb;
		$res = null;

		$res = $wpdb->get_row( $wpdb->prepare("SELECT * FROM contact WHERE id = %d", $id), ARRAY_A);

		return $res;
	}


	public static function getAllData() {

		global $wpdb;
		$res = null;

		$res = $wpdb->get_results( "SELECT * FROM contact ORDER BY id DESC", ARRAY_A);

		return $res;
	}

}

getDataFromIdメソッド$idで受け取った値を使ってSQLを実行し、contactテーブルidカラムと一致するデータを1件だけ取得します。
テーブル内の全件のデータを取得するときはwpdbクラスget_resultsメソッドを使いましたが、今回は取得するデータが1件のみなのでget_rowメソッドを使います。

get_rowメソッドでもget_resultsメソッドと同様に戻り値の形式を第2パラメータで指定することができます。
戻り値の形式は統一する方が扱いやすいため、ここでも連想配列であるARRAY_Aを指定します

また、get_rowメソッドを実行する前に、安全にSQLを実行するためにprepareメソッドによるプリペアドステートメントを使います。
SQLのWHERE句idカラムと比較する値を数値のプレースホルダー「%d」にし、prepareメソッドの第2パラメータにプレースホルダーにセットする値を指定します。

GETパラメータの値をメソッドに渡す

データを検索するgetDataFromIdメソッドができたところで、続いてこちらのメソッドに検索するidカラムの値をパラメータで渡せるようにしていきます。

トップページの一覧には各データごとに編集リンクを設置していますが、そのURLに「id=n」を出力するように設定したことを覚えているでしょうか。
nにはデータごとのidカラムの値が入ります)

この設定により、編集リンクのURLにはGETパラメータでidの値が含まれるようになっています。
そのため、GETパラメータのidgetDataFromIdメソッドに渡すことで、編集ページに表示するデータを検索することができます。

編集ページのedit.phpを開いて、以下のコードを追加してください。

views/edit.php

<?php

$data = null;

if( !empty($_GET['id']) ) {

	$data = Cm_Db::getDataFromId($_GET['id']);

}

?>

<p class="link_back"><a href="<?php echo Cm::getBaseUrl(); ?>">戻る</a></p>

<div class="form_area">

----- 省略 -----

if文でGETパラメータのidがあるか確認し、値がある場合はgetDataFromIdメソッドに渡してデータ検索を実行します。
検索結果は$dataで受け取ります。

編集ページに取得したお問い合わせデータを表示する

getDataFromIdメソッドで取得したお問い合わせのデータを編集ページに表示していきます。
編集ページのビューファイルedit.phpを開いて、以下のコードを入力してください。

views/edit.php

<?php

$data = null;

if( !empty($_GET['id']) ) {

	$data = Cm_Db::getDataFromId($_GET['id']);

}

?>

<p class="link_back"><a href="<?php echo Cm::getBaseUrl(); ?>">戻る</a></p>

<div class="form_area">

<form method="post" action="<?php echo Cm::getBaseUrl(); ?>">
<dl class="form_list">
	<dt>お名前</dt>
	<dd><input type="text" name="name" value="<?php if( !empty($data['name']) ){ echo htmlspecialchars( $data['name'], ENT_QUOTES); } ?>"></dd>
	<dt>メールアドレス</dt>
	<dd><input type="email" name="email" value="<?php if( !empty($data['email']) ){ echo htmlspecialchars( $data['email'], ENT_QUOTES); } ?>"></dd>
	<dt>お問い合わせ内容</dt>
	<dd><textarea name="content"><?php if( !empty($data['content']) ){ echo htmlspecialchars( $data['content'], ENT_QUOTES); } ?></textarea></dd>
</dl>
<input type="hidden" name="id" value="<?php echo htmlspecialchars( $data['id'], ENT_QUOTES); ?>">
<input type="hidden" name="edit_token" value="">
<input type="submit" name="btn_register" value="更新">
</form>

</div>

お名前、メールアドレス、お問い合わせ内容のフォームに取得したデータをhtmlspecialchars関数で記号エスケープしてから出力します。
非表示のname="id"input要素にもidカラムの値を出力します。
この値は後ほど更新ボタンを押したときに、更新するデータを特定するときに使います。

続いて、お問い合わせのデータを取得できなかったときの表示も設定しておきましょう。
edit.phpに以下のコードを追加してください。

views/edit.php

<?php

----- 省略 -----

<p class="link_back"><a href="<?php echo Cm::getBaseUrl(); ?>">戻る</a></p>

<div class="form_area">

<?php if( !empty($data) ): ?>

<form method="post" action="<?php echo Cm::getBaseUrl(); ?>">
<dl class="form_list">
	<dt>お名前</dt>
	<dd><input type="text" name="name" value="<?php if( !empty($data['name']) ){ echo htmlspecialchars( $data['name'], ENT_QUOTES); } ?>"></dd>
	<dt>メールアドレス</dt>
	<dd><input type="email" name="email" value="<?php if( !empty($data['email']) ){ echo htmlspecialchars( $data['email'], ENT_QUOTES); } ?>"></dd>
	<dt>お問い合わせ内容</dt>
	<dd><textarea name="content"><?php if( !empty($data['content']) ){ echo htmlspecialchars( $data['content'], ENT_QUOTES); } ?></textarea></dd>
</dl>
<input type="hidden" name="id" value="<?php echo htmlspecialchars( $data['id'], ENT_QUOTES); ?>">
<input type="hidden" name="edit_token" value="<?php echo $_SESSION['edit_token']; ?>">
<input type="submit" name="btn_register" value="更新">
</form>

<?php else: ?>

<p>お問い合わせのデータを取得できませんでした。</p>
<p class="link_back"><a href="<?php echo Cm::getBaseUrl(); ?>">戻る</a></p>

<?php endif; ?>

</div>

フォームをif文で囲み、empty関数$dataに値が入っているか確認します。
もしgetDataFromIdメソッドでデータを取得できなかった場合は$dataNULLが入るため、そのときはelse文へ移動して「お問い合わせのデータを取得できませんでした。」と表示されます。

編集ページにセッショントークンを入れる

最後に、編集ページにセッショントークンを入れましょう。
セッショントークンを入れる意味や仕組みはお問い合わせページのときと同様です。
(もしセッショントークンを入れる意味を改めて確認したい場合は」をご覧ください。)

セッショントークンを生成するコードはedit.phpに追加しますが、その前にセッションを開始するコードをcontactManager.phpに追加しましょう。
contactManager.phpを開いて、以下のコードを追加してください。

contactManager.php

<?php
/*
Plugin Name: Contact Manager
Description: お問い合わせを管理するためのプラグイン
Version: 0.1
Author: GRAYCODE
Author URI: https://gray-code.com
Licence: GPL v2 or later
Licence URI: https://www.gnu.org/licenses/gpl-2.0.html
*/

define( 'CM_VERSION', '0.1.1' );
define( 'CM_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );

require_once( CM_PLUGIN_DIR . 'class.cm.php' );
require_once( CM_PLUGIN_DIR . 'class.cm-db.php' );

if( session_status() !== PHP_SESSION_ACTIVE ) {
	session_start();
}

function cm_option_page_html() {

$page_title = 'お問い合わせ管理';
$view = 'index';

----- 省略 -----

session_start関数でセッションを開始する前に、session_status関数でセッションがすでに開始されていないか確認します。
ここはお問い合わせページと同じ内容です。

続いて、edit.phpに以下のコードを追加してください。

views/edit.php

<?php

if( !empty($_SESSION['edit_token']) ) {
	unset($_SESSION['edit_token']);
}

$_SESSION['edit_token'] = bin2hex(openssl_random_pseudo_bytes(24));

$data = null;

if( !empty($_GET['id']) ) {

	$data = Cm_Db::getDataFromId($_GET['id']);

}

?>

<p class="link_back"><a href="<?php echo Cm::getBaseUrl(); ?>">戻る</a></p>

<div class="form_area">

<?php if( !empty($data) ): ?>

<form method="post" action="<?php echo Cm::getBaseUrl(); ?>">
<dl class="form_list">
	<dt>お名前</dt>
	<dd><input type="text" name="name" value="<?php if( !empty($data['name']) ){ echo htmlspecialchars( $data['name'], ENT_QUOTES); } ?>"></dd>
	<dt>メールアドレス</dt>
	<dd><input type="email" name="email" value="<?php if( !empty($data['email']) ){ echo htmlspecialchars( $data['email'], ENT_QUOTES); } ?>"></dd>
	<dt>お問い合わせ内容</dt>
	<dd><textarea name="content"><?php if( !empty($data['content']) ){ echo htmlspecialchars( $data['content'], ENT_QUOTES); } ?></textarea></dd>
</dl>
<input type="hidden" name="id" value="<?php echo htmlspecialchars( $data['id'], ENT_QUOTES); ?>">
<input type="hidden" name="edit_token" value="<?php echo $_SESSION['edit_token']; ?>">
<input type="submit" name="btn_register" value="更新">
</form>

<?php else: ?>

<p>お問い合わせのデータを取得できませんでした。</p>
<p class="link_back"><a href="<?php echo Cm::getBaseUrl(); ?>">戻る</a></p>

<?php endif; ?>

</div>

コードの冒頭で$_SESSION[‘edit_token’]にすでにセッショントークンが入っていたら一旦unset関数で削除して空にします。
その後すぐに、openssl_random_pseudo_bytes関数bin2hex関数を使って24文字からなるセッショントークンを生成して$_SESSION[‘edit_token’]にセットしています。
この時点で、編集ページにアクセスする度にセッショントークンは更新される仕組みになります。

続いて、作成したセッショントークンを非表示のname="edit_token"input要素にセットします。
編集ページからフォームを送信したら、このinput要素$_SESSION[‘edit_token’]に入っている値が一致するかを確認することで、編集ページから正しくデータが送信されていることを確認します。

今回は編集ページを表示するところまで進めてきました。
次回は編集ページに入力してから更新ボタンを押した後に、編集した内容がデータベースに保存されるように更新機能を実装していきます。

今回作成したコード:GitHub

前のページへ 一覧に戻る 次のページへ