【WordPress】posts_searchフィルターフックで検索フォームの検索対象拡張方法

Wordpressロゴ システム開発
この記事は約3分で読めます。

WordPressの検索は、デフォルトの検索対象が件名と本文のみです。

検索対象を拡張できるプラグインもあるにはあるのですが、更新されていないものが多く、実際に入れたらエラーが出ることがしばしばだったので自力実装してみました。

今回、タグ名・カテゴリ名・カスタムフィールドも検索対象に加えたいことがありましたので、そのやり方をご紹介します。

実際に書いたコード

function.phpなどに以下のコードを追加すれば検索対象が増えます。

add_filter('posts_search',function($search, $wp_query) {
	global $wpdb;
	//検索ページ以外だったら終了
	if (!$wp_query->is_search)
		return $search;

	if (!isset($wp_query->query_vars))
		return $search;

	$search_words = explode(' ', isset($wp_query->query_vars['s']) ? $wp_query->query_vars['s'] : '');
	if ( count($search_words) > 0 ) {
		$search = '';
		foreach ( $search_words as $word ) {
			if ( !empty($word) ) {
				$search_word = $wpdb->escape("%{$word}%");
				$search .= " AND (
						{$wpdb->posts}.post_title LIKE '{$search_word}'
						OR {$wpdb->posts}.post_content LIKE '{$search_word}'
						OR EXISTS (
							SELECT r.object_id
							FROM {$wpdb->term_relationships} AS r
							INNER JOIN {$wpdb->term_taxonomy} AS tt ON r.term_taxonomy_id = tt.term_taxonomy_id
							INNER JOIN {$wpdb->terms} AS t ON tt.term_id = t.term_id
							WHERE r.object_id = {$wpdb->posts}.ID AND 
							(t.name LIKE '{$search_word}'
						OR t.slug LIKE '{$search_word}'
						OR tt.description LIKE '{$search_word}')
						)
						OR EXISTS (
							SELECT p.post_id
							FROM {$wpdb->postmeta} AS p
							WHERE p.post_id = {$wpdb->posts}.ID AND p.meta_value LIKE '{$search_word}'
						)
				) ";
			}
		}
	}
	return $search;
}, 10, 2);

コードの解説

まず、検索を拡張するには、add_filterの’posts_search’を使います。

管理画面の検索にも及んでしまうため、「$wp_query->is_search」以外では、処理しないようにします。

「$search」のクエリにterm(カテゴリー・タグ)やpostmetaの条件を追加すれば拡張ができます。

OR検索については、検索語を分割すればできますが、SQL文を加工する所が結構大変なので効果があるかどうか判断してから実装した方が良いです。

この記事を書いた人
サイト運営者
RYU
RYU

静岡の情シス顧問|情シス出身→大手システム会社→独立|
企業のITコスト・契約・情シス体制を整理|
システム会社の見積確認、社内対応と外部依頼の整理|
Salesforce上流・見積評価にも対応|
現場に寄り添い、ITで会社を強くする。

RYUをフォローする
システム開発
スポンサーリンク