Blog スタッフブログ

PHP システム開発

[WordPress]プラグイン制作_管理画面での自作テーブルのデータの追加・編集・削除

システム開発担当のTFです。

※WordPress6.2対応

前回まで

  [WordPress]プラグイン制作_DBテーブルの更新

  [WordPress]プラグイン制作_管理画面で自作テーブルのデータの一覧表示

やり方

  • 管理画面の一覧までは前回までを参照
  • リダイレクトのタイミングに注意しながら、追加・編集・削除の処理を作成する
  • DB操作は$wpdbを用い追加はinsert、 編集はupdate、削除はdeleteを利用する

※注意

前回から追加・編集・削除の為、関数やviewを変更しています

※リダイレクトに関して

sample_action内でリダイレクトを行ってしまうと、すでに他の描画が始まっているため、リダイレクトが行えない。
その為、initにフックをかけ、そちらで処理を行っている(initは、各種描画の前に処理が動く為)
initで行う場合は、sampleのページ外でも処理が通ってしまうため、ページ判定が必要

参考

  wpdbクラスのprepare関数でSQLインジェクション対策をしよう!
  WordPressの日付・時刻の取得【unixtimeとローカル時刻の取得】
  WordPressでRedirectしたい場合の処理について備忘録

サンプル

<?php
/*
Plugin Name: SamplePlugin
Description: サンプルプラグイン
Version: 1.0
Author: MIX
Licence: GPL v2
Licence URI: https://www.gnu.org/licenses/gpl-2.0.html
*/

// DBは省略(前回まで参照)

// ディレクトリとURLの定義
define( 'SAMPLE_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'SAMPLE_PLUGIN_URL', plugin_dir_url( __FILE__ ) );

// 管理画面判定
if( is_admin() ){
	// 管理画面にメニュー追加
	add_action('admin_menu', 'add_admin_menu');
	
	// リソース周りは省略(前回まで参照)
	
	// 通常のタイミングでは、リダイレクトの書き込みがエラーになる為、init時に処理を行う
	add_action('init', 'sample_init_action');
}

// 管理画面にメニュー追加
function add_admin_menu()
{
	// add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position );
	add_menu_page(
		'サンプルページ',		// ページタイトル(title)
		'サンプル',				// メニュータイトル
		'manage_options',		// メニュー表示するユーザーの権限
		'sample',				// メニューのスラッグ
		'sample_action',		// メニュー表示時に使われる関数
		'dashicons-feedback'	// メニューのテキスト左のアイコン
								// メニューを表示する位置 ( デフォルトは一番下 )
	);
}

// ページ分け
function sample_action()
{
	$action = $_GET['action'];
		
	switch($action){
		case 'create':
			sample_create();
			break;
		case 'edit':
			sample_edit();
			break;
		default:
			sample_index();
			break;
	}
}

// ページ分け(initで行う)
function sample_init_action()
{
	// ページ判定
	$page = ( isset($_GET['page']) ) ? $_GET['page'] : "";
	if( $page != "sample" ) return;
	
	$action = (isset($_GET['action'])) ? $_GET['action'] : "";
	
	// 通常のタイミングでは、リダイレクトの書き込みがエラーになる為、init時に処理を行う
	switch($action){
		case 'store':
			sample_store();
			break;
		case 'update':
			sample_update();
			break;
		case 'destroy':
			sample_destroy();
			break;
	}
}

// 一覧ページの表示
function sample_index()
{
	// データの一覧取得
	$datas = getSampleDatas();

	// viewファイルを読み込み表示する
	include( SAMPLE_PLUGIN_DIR .  "/views/admin/index.php");
}

// 自作テーブルデータの一覧取得
function getSampleDatas()
{
	global $wpdb;

	$table_name = $wpdb->prefix . "sample";
	
	$params = [];
	
	$sql = "SELECT * FROM $table_name ;";
	
	// 安全な置き換え
	$query = $wpdb->prepare( $sql, $params );
	
	// 配列で返す
	return $wpdb->get_results( $query, ARRAY_A );
}

// 新規作成ページの表示
function sample_create()
{
	// viewファイルを読み込み表示する
	include( SAMPLE_PLUGIN_DIR .  "/views/admin/create.php");
}

// 新規登録
function sample_store()
{
	global $wpdb;
	
	// バリデーション
	if( !sample_validate() ){
		// postも引き継がれる
		header('Location: '. getBaseUrl().'&action=create&error_flg=true', true, 307);
		return;
	}
	
	$table_name = $wpdb->prefix . "sample";
	
	// 保存
	$datas = array(
		  'title' => $_POST['title'],
		  'created_at' => date_i18n('Y-m-d H:i:s'),// date_i18nでローカルタイムで保存( date関数の場合、unixtimeになる )
		  'updated_at' => date_i18n('Y-m-d H:i:s')
		);

	$wpdb->insert(
		$table_name,
		$datas
	);
	
	// header書き込みは、通常タイミングではエラーとなる為、init時で行う
	header('Location: '. getBaseUrl().'&success=store');
	
}

// 編集ページの表示
function sample_edit()
{
	global $wpdb;
	
	$table_name = $wpdb->prefix . "sample";

	// idからデータ取得
	$query = $wpdb->prepare( "SELECT * FROM ".$table_name." WHERE id = %d ; ", $_GET['id'] );
	
	$data = $wpdb->get_row( $query, ARRAY_A );

	// viewファイルを読み込み表示する
	include( SAMPLE_PLUGIN_DIR .  "/views/admin/edit.php");
}

// 更新
function sample_update()
{
	global $wpdb;
	
	// バリデーション
	if( !sample_validate() ){
		// postも引き継がれる
		header('Location: '. getBaseUrl().'&action=edit&id='.$_GET['id'].'&error_flg=true', true, 307);
		return;
	}
	
	$table_name = $wpdb->prefix . "sample";
	
	// 保存
	$datas = array(
		  'title' => $_POST['title'],
		  'updated_at' => date_i18n('Y-m-d H:i:s')
		);

	$wpdb->update( 
		$table_name,
		$datas, 
		['id' => $_GET['id'] ], 
	);
	
	// header書き込みは、通常タイミングではエラーとなる為、init時で行う
	header('Location: '. getBaseUrl().'&success=update');
	
}

// 削除
function sample_destroy()
{
	global $wpdb;
	
	$table_name = $wpdb->prefix . "sample";

	// 削除
	$wpdb->delete( 
		$table_name,
		['id' => $_GET['id'] ], 
	);
	
	// header書き込みは、通常タイミングではエラーとなる為、init時で行う
	header('Location: '. getBaseUrl().'&success=destroy');
	
}

// バリデーション
function sample_validate()
{
	if( empty($_POST['title']) ){
		return false;
	}
	
	return true;
}


// ベースのURLを返す
function getBaseUrl() {
	return (is_ssl() ? 'https' : 'http') . '://' . $_SERVER["HTTP_HOST"] . $_SERVER['SCRIPT_NAME'] . '?page=sample';
}
<div class="wrap">
	<h1>サンプル一覧</h1>1
	
	<?php if( !empty($_GET['success']) ): ?>
		<?php if($_GET['success'] == 'store'): ?>
			<div>新規追加しました</div>
		<?php endif; ?>
		<?php if($_GET['success'] == 'update'): ?>
			<div>編集しました</div>
		<?php endif; ?>
		<?php if($_GET['success'] == 'destroy'): ?>
			<div>削除しました</div>
		<?php endif; ?>
	<?php endif; ?>
	
	<a href="<?= getBaseUrl() ?>&action=create">新規追加</a>
	
	<table class="table_list">
		<tr>
			<th>日時</th>
			<th>タイトル</th>
			<th></th>
		</tr>
		
		<?php foreach($datas AS $data): ?>
		<tr>
			<td><?= $data['created_at'] ?></td>
			<td><?= $data['title'] ?></td>
			<td>
				<a href="<?= getBaseUrl() ?>&action=edit&id=<?= $data['id'] ?>">編集</a>
				<a href="<?= getBaseUrl() ?>&action=destroy&id=<?= $data['id'] ?>">削除</a>
			</td>
		</tr>
		<?php endforeach; ?>
	</table>
</div>
<div class="wrap">
	<h1>サンプル新規作成</h1>
	
	<a href="<?= getBaseUrl() ?>">戻る</a>
	
	<?php if( !empty($_GET['error_flg']) ): ?>
		<div>エラーがあります</div>
	<?php endif; ?>
	
	<form method="POST" action="<?= getBaseUrl() ?>&action=store">
		<tablie>
			<tr>
				<th>タイトル</th>
				<td><input type="text" name="title" value="<?= $_POST['title'] ?>"></td>
			</tr>
		</talbe>
		
		<input type="submit" value="登録">
		
	</form>
	
</div>
<div class="wrap">
	<h1>サンプル編集</h1>
	
	<a href="#" onclick="window.history.back(); return false;">戻る</a>
	
	<?php if( !empty($_GET['error_flg']) ): ?>
		<div>エラーがあります</div>
	<?php endif; ?>
	
	<form method="POST" action="<?= getBaseUrl() ?>&action=update&id=<?= $data['id'] ?>">
		<tablie>
			<tr>
				<th>タイトル</th>
				<td><input type="text" name="title" value="<?= isset($_POST['title']) ? $_POST['title'] : $data['title'] ?>"></td>
			</tr>
		</talbe>
		
		<input type="submit" value="更新">
		
	</form>
	
</div>