WordPressで外部データベースの複合検索機能を作る方法を紹介します。DBとの通信は、Ajaxを使って実装します。
デモサイトはこちら。
今回は、WordPressで外部のデータベースに接続するで用意したデータベースを使います。
検索フォームを作る
ユーザー名、商品名、個数の入力フィールドを用意します。
通信時にリファラーをチェックするために、wp_referer_field関数を実行しておきます。
<?php wp_referer_field(); ?>
<label for="name">名前</label>
<input type="text" id="name" name="name" />
<label for="product">商品名</label>
<input type="text" id="product" name="product" />
<label for="quantity">個数</label>
<input type="number" id="quantity" name="quantity" />
<button type="button" id="js-submit">検索</button>
JavaScriptを読み込む
Ajaxを使うために、JavaScriptを読み込みます。
nonceを発行してJavaScriptに渡しておきましょう。
function my_enqueue_scripts() {
if ( is_page('external-db-search-demo') ) {
wp_enqueue_script(
'my-external-db-search',
get_theme_file_uri() . '/my_inc/js/external_db_search.js',
array('jquery'),
'1.0.0',
true
);
$localize = [
'ajax_url' => admin_url('admin-ajax.php'),
'action' => 'external_db_search',
'check_nonce' => wp_create_nonce('ajax-nonce-external-db-search')
];
wp_localize_script('my-external-db-search', 'localize', $localize);
}
}
add_action('wp_enqueue_scripts', 'my_enqueue_scripts');
Ajaxのリクエスト処理を追加する
フォーム送信時の処理を追加します。通信が成功したら、HTMLを挿入します。
jQuery(function($) {
$('#js-submit').on('click', function() {
$('#js-results').remove(); // 既に検索結果があれば削除する
const http_referer = $('input[name="_wp_http_referer"]').val();
// 入力内容を取得
const name = $('input[name="name"]').val();
const product = $('input[name="product"]').val();
const quantity = $('input[name="quantity"]').val();
$.ajax({
type: "GET",
url: localize.ajax_url,
dataType: 'html',
data: {
action: localize.action,
check_nonce: localize.check_nonce,
_wp_http_referer: http_referer,
name,
product,
quantity
}
}).done(function(data) {
$('#js-submit').after('<div id="js-results">' + data + '</div>'); // レスポンスを挿入する
}).fail(function() {
console.log('ERROR');
});
});
});
Ajaxのレスポンス処理を追加する
まず、正しいリクエストかどうかをチェックします。
function my_external_db_search() {
$error = TRUE;
do {
// nonceチェック
if ( !check_ajax_referer('ajax-nonce-external-db-search', 'check_nonce', false) ) break;
// リファラーチェック
$referer = wp_get_referer();
if ( strpos($referer, 'external-db-search-demo') === FALSE ) break;
/* 中略 */
$error = FALSE;
} while ( FALSE );
/* 中略 */
}
add_action('wp_ajax_external_db_search', 'my_external_db_search');
add_action('wp_ajax_nopriv_external_db_search', 'my_external_db_search');
続いて、wpdbクラスのインスタンスを生成して、SQLを組み立てます。
function my_external_db_search() {
$error = TRUE;
do {
/* 中略 */
$mydb = new wpdb(
'dbuser', // ユーザー名
'dbpassword', // パスワード
'dbname', // データベース名
'dbhost' // ホスト名
);
$sql = '
SELECT
orders.id AS id,
users.name AS user_name,
products.name AS product_name,
orders.quantity AS quantity,
orders.price AS price,
orders.date AS date
FROM
orders
LEFT JOIN
users ON orders.user_id = users.id
LEFT JOIN
products ON orders.product_id = products.id';
/* 中略 */
$error = FALSE;
} while ( FALSE );
/* 中略 */
}
add_action('wp_ajax_external_db_search', 'my_external_db_search');
add_action('wp_ajax_nopriv_external_db_search', 'my_external_db_search');
検索フォームの入力内容があれば、WHERE句を追加します。
ユーザー名と商品名はあいまい検索、個数は完全一致検索で組み立てます。
function my_external_db_search() {
$error = TRUE;
do {
/* 中略 */
$wheres = array();
if ( !empty($_GET['name']) ) {
$wheres[] = array(
'key' => 'users.name',
'value' => $_GET['name'],
'compare' => 'LIKE',
);
}
if ( !empty($_GET['product']) ) {
$wheres[] = array(
'key' => 'products.name',
'value' => $_GET['product'],
'compare' => 'LIKE',
);
}
if ( !empty($_GET['quantity']) ) {
$wheres[] = array(
'key' => 'orders.quantity',
'value' => $_GET['quantity'],
'compare' => '=',
);
}
if ( $wheres ) {
$args = array();
$i = 1;
foreach ( $wheres as $where ) {
if ( $i === 1 ) {
$sql .= "\nWHERE";
} else {
$sql .= "\nAND";
}
switch ( $where['compare'] ) {
case '=' :
$sql .= "\n{$where['key']} = %s";
break;
case 'LIKE' :
$sql .= "\n{$where['key']} LIKE '%%%s%%'";
break;
default :
break;
}
$args[] = $where['value'];
$i++;
}
}
$sql .= '
ORDER BY
orders.date ASC
';
/* 中略 */
$error = FALSE;
} while ( FALSE );
/* 中略 */
}
add_action('wp_ajax_external_db_search', 'my_external_db_search');
add_action('wp_ajax_nopriv_external_db_search', 'my_external_db_search');
WHERE句があればサニタイズして、SQLを実行します。
結果に応じてHTMLを組み立てて、実装完了です。
function my_external_db_search() {
$error = TRUE;
do {
/* 中略 */
// SQLを実行
if ( $wheres ) {
$results = $mydb->get_results($mydb->prepare($sql, $args));
} else {
$results = $mydb->get_results($sql);
}
$error = FALSE;
} while ( FALSE );
if ( $error ) {
$html = '<p>ERROR</p>';
} elseif ( !$results ) {
$html = '<p>一致するデータはありません。</p>';
} else {
$html = '<table><tr><th>ID</th><th>名前</th><th>商品名</th><th>個数</th><th>単価</th><th>価格</th><th>注文日</th></tr>';
foreach ( $results as $result ) {
$html .= '<tr>';
$html .= '<td>' . $result->id . '</td>';
$html .= '<td>' . $result->user_name . '</td>';
$html .= '<td>' . $result->product_name . '</td>';
$html .= '<td>' . $result->quantity . '</td>';
$html .= '<td>' . $result->price . '</td>';
$html .= '<td>' . $result->quantity * $result->price . '</td>';
$html .= '<td>' . $result->date . '</td>';
$html .= '</tr>';
}
$html .= '</table>';
}
echo $html;
die();
}
add_action('wp_ajax_external_db_search', 'my_external_db_search');
add_action('wp_ajax_nopriv_external_db_search', 'my_external_db_search');
コメント