WordPress の検索対象にカスタムフィールドを追加する

WordPressの検索機能は記事のタイトルと本文が対象になっている。
WordPress にカスタムフィールドを追加したので、カスタムフィールドの内容も検索対象にしたいので、方法を調べてみた。

functions.php に以下を追加した。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
add_filter( 'posts_join', function ($join){
global $wpdb;
$join ="INNER JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)";
return $join;
}, 10 ,2);

add_filter('posts_search',function($org_search, $query) {
global $wpdb;
$q = $query->query_vars;

if (! $q || ! isset($q['search_terms_count']) || $q['search_terms_count'] === 0) {
return $org_search;
}

$search = $org_search . ' OR (';
foreach ((array)$q['search_terms'] as $term) {
if ($term !== reset($q['search_terms'])) {
$search .= ' OR ';
}
$search .= "({$wpdb->postmeta}.meta_value LIKE '%{$term}%' AND {$wpdb->postmeta}.meta_key = 'additional_data'";
}
$search .= ')';

return $search;
}, 10, 2);

1つめの add_filter( ‘post_join’ ) は、検索時に wp_posts と wp_postmeta を JOIN するように指定している。

2つめの add_filter( ‘posts_search’ ) が、今回のメインで検索対象を実際に指定している。
検索文字が複数あることを想定して foreach で WHERE 句に条件を追加している。wp_postmeta と JOIN しているので、wp_postmeta に保存された meta_key でカスタムフィールドの種別を指定し meta_values の値で検索できる。