follow us in feedly
PHP

複合検索(絞り込み検索)をPHPとJavaScriptで実装(前編)

複合検索(絞り込み検索)と言いますと「エリアで探す」「間取りで探す」「家賃で探す」などの不動産物件情報サイトが思い浮かびます。もちろんワードプレスでもこうした機能は可能です。基本的な機能だけならPHPだけで可能ですがJavaScriptも併用すればより使いやすい検索機能になります。

2019年3月7日

複合検索(絞り込み検索)の完成イメージ

Indeed(インディード)やGoogle for Jobsのような無料の求人サービスが出てきたことで、自社ホームページ内に求人情報を掲載する企業が増えてきています。特に恒常的に人材不足である飲食業などは、そうしたサービスを活用することで採用コストがある程度下げられると考えられています。

こうした背景もあって、ワードプレスでホームページを作りつつそのなかに求人コンテンツを作成するわけですが(ホームページ全体をワードプレスで作り直すか、既にワードプレスで作ってある場合は求人コンテンツのみを追加)、多店舗展開している企業では求人情報も多くなりますので、ユーザーに対して複合検索(絞り込み検索)の機能を提供しないと、せっかく作った求人コンテンツを活かすことができません。

ただし、ご存じのようにワードプレスには複合検索(絞り込み検索)の機能はデフォルトでは実装されていません。そこでPHPとJavaScriptを使ってこの機能を実装してみます。

ではまず完成形のイメージです。

デスクトップ版の複合検索(絞り込み検索)フォーム

ワードプレスの複合検索(絞り込み検索)フォーム

今回はカスタム投稿とカスタムタクソノミーを利用しています。

「志向で探す」「職種で探す」などは親タームです。そしてそれらに子タームとして「副業OK!」「甲殻類が好き!」などが設定されています。これらタームは管理画面で自由に作成・追加することができ、変更後はこのフォームに自動的に反映されます。

また、検索ボタンの上部に選択した条件で何件ヒットするのかを表示しています。これはAjaxを使っていますので画面を再読込することなく件数が表示されるようになっています。

スマートフォン版の複合検索(絞り込み検索)フォーム(レスポンシブ)

ワードプレスの複合検索(絞り込み検索)フォーム

デスクトップ版の複合検索(絞り込み検索)結果画面

検索結果画面でも複合検索(絞り込み検索)フォームを表示しています。何を選択してこの画面に来たかがわかるようにパラメーターがフォームに反映された状態になっています。結果が気に入らなければ再度このフォームから検索し直すことができます。こうしてストレスなく何度でも検索できるようにすることで、ユーザーが目的のコンテンツにたどり着きやすくなります。

ワードプレスの複合検索(絞り込み検索)フォーム

複合検索フォームのhtmlとPHPの記述

カスタムタクソノミーの設定

今回の実装ではカスタムタクソノミーにjob_taxonomyというスラッグをつけ、タームには副業OK!(side_job)、甲殻類が好き!(love_koukakurui)などを設定しています。タームの構造は図のように親ターム、子タームの階層構造になっています。

ワードプレスの複合検索(絞り込み検索)フォーム

検索フォーム部分のhtml、PHPの記述

<form method="get" action="<?php echo esc_url( home_url() ); ?>/career-list/">

検索フォームのデータ送信先ページ(検索結果を表示するページ)は任意の固定ページになります。ここでは/career-list/でアクセスできる固定ページとしました。

ワードプレスの複合検索(絞り込み検索)フォーム
ワードプレスの複合検索(絞り込み検索)フォーム

検索フォーム1段目(上図デスクトップ版・スマートフォン版)のチェックボックス部分の記述は以下のようになります。

<?php $categories = get_terms( array('taxonomy' => 'job_taxonomy', 'parent' => 9)); ?>
<?php foreach($categories as $category) : ?>
		<label for="<?php echo $category->slug ?>">
			<input type="checkbox" name="term1[]" value="<?php echo $category->slug ?>" id="<?php echo $category->slug ?>">
			<span class="checkbox-text"><?php echo $category->name; ?>(<?php echo $category->count; ?>件)</span>
		</label>
<?php endforeach; ?>

1行目でワードプレスの組み込み関数get_termsを使ってjob_taxonomyに属するタームを全て取得し$categoriesに格納。これをforeachで1つずつ取り出しながら必要な情報を出力していきます。’parent’ => 9を指定することで親タームのIDが9(int型)である子タームのみに限定しています。この場合では「志向で探す」のタームIDが9になっているからです。

また、4行目の以下の記述では複数選択された場合も想定してnameの属性値をterm1[](角括弧付き)としています。

<input type="checkbox" name="term1[]" value="<?php echo $category->slug ?>" id="<?php echo $category->slug ?>">

上記の記述で出力されるhtmlは以下のようになります。

<label for="side_job">
	<input type="checkbox" name="term1[]" value="side_job" id="side_job">
	<span class="checkbox-text">副業OK!(4件)</span>
</label>
<label for="love_koukakurui">
	<input type="checkbox" name="term1[]" value="love_koukakurui" id="love_koukakurui">
	<span class="checkbox-text">甲殻類が好き!(3件)</span>
</label>
<label for="opening_staff">
	<input type="checkbox" name="term1[]" value="opening_staff" id="opening_staff">
	<span class="checkbox-text">オープニングスタッフ(3件)</span>
</label>

送信されるURLパラメーター

前述した通り、この検索フォームの送信先は任意の固定ページになります。この場合では/career-list/でアクセスできる固定ページになりますが、そのページへのアクセスは以下のようなパラメーター付きのURLになります。

/career-list/?term1[]=side_job&term1[]=love_koukakurui&term2[]=hall_staff&term3[]=western_food&term4[]=ginza

上記のなかでterm1[]が2つ入っています。「副業OK!」「甲殻類が好き!」の2つが選択されたためですが、属性値に[](角括弧)をつけておくことで、$_GET[‘term1’]を配列で受け取ることができるようになります。

パラメータを配列で受け取る(検索結果ページ)

パラメーターからWP_Queryの引数を作る

検索フォームから送られたデータを任意の固定ページで受け取ります。今回は/career-list/でアクセスできる固定ページになります。例えば、副業OK!(side_job)と甲殻類が好き!(love_koukakurui)の2つがチェックされて検索された場合は、以下のようなパラメーター付きURLでアクセスされることになります。

/?term1[]=side_job&term1[]=love_koukakurui

このパラメーターから以下のようなオブジェクトを作りWP_Queryの引数として与えてあげれば目的とする検索結果を引き出すことができます。今回の場合はカスタム投稿タイプをcareerとしています。pageについては固定ページでページング機能を有効にするために必要で、『複合検索(絞り込み検索)をPHPとJavaScriptで実装(後編)』でご説明したいと思いますのでここでは割愛します。posts_per_pageは1ページあたりの表示件数です。

$args = array(
	'post_type' => 'career',
	'paged' => $paged,
	'posts_per_page' => 6,
	'tax_query' => array(
			'taxonomy' => 'job_taxonomy',
			'field'    => 'slug',
			'terms'    => array('side_job', 'love_koukakurui')
		)
);

そして肝心のtax_queryの部分ですが、taxonomy、field、termsにそれぞれの値を与えてあげるわけですが、そのための記述が以下のようになります。

$args = array(
	'post_type' => 'career',
	'paged' => $paged,
	'posts_per_page' => 6,
);

if(isset($_GET['term1']) && $_GET['term1'] != '') {
	$args[tax_query][0] = array(
			'taxonomy' => 'job_taxonomy',
			'field'    => 'slug',
			'terms'    => $_GET['term1'],
		);
};

termsに対してパラメーターから受け取った値$_GET[‘term1’]を設定します。今回の場合は$_GET[‘term1’]はarray(‘side_job’, ‘love_koukakurui’)を意味しますので、これで目標としたWP_Queryの引数ができます。

パラメーターの不正文字列を空文字に変換

パラメーターに想定していない文字列が入っていた場合は空文字に変換します。パラメーターにはタームのスラッグ以外は入らないはずです。タームのスラッグは、[英小文字の連続] + [-(ハイフン)と_(アンダーバー)の0回または1回の繰り返し] + [英小文字の連続] + [-(ハイフン)と_(アンダーバー)の0回または1回の繰り返し] + [英小文字の連続]という命名ルールになっていますので正規表現では以下のような記述になります。

※正規表現についてはドットインストールの エディタで学ぶ正規表現入門 (全18回) がたいへんわかりやすくておすすめです。

$count = count($_GET['term1']);
for ($i = 0; $i < $count; $i++) {
	if (!preg_match('/\A[a-z]+-?_?[a-z]+-?_?[a-z]+\z/', $_GET['term1'][$i])) {
			$_GET['term1'] = '';
	}
}

以上で「複合検索(絞り込み検索)をPHPとJavaScriptで実装(前編)」の解説を終わります。

このエントリーをはてなブックマークに追加