wordpressのサイト内検索にカスタムフィールドを含める

備忘録として。
記事、ページ、カスタム投稿(items)の記事の中から、タイトル、コンテンツ、カテゴリー、タグ、タームと、選んだカスタムフィールドの値でサイト内検索。

//サイト内検索の設定
function filter_search($query)
{
  if ($query->is_search() && $query->is_main_query() && !is_admin()) {

    //検索に含めるもの(記事、ページ、カスタム投稿)
    $post_array = array('post', 'page', 'items');

    //検索に含めたくないもの(例えばお問い合わせの確認、完了画面とか)
    $page_ID_contact_confirm = get_page_by_path('contact/confirm')->ID;
    $page_ID_contact_completion = get_page_by_path('contact/completion')->ID;

    $not_in_array = array($page_ID_contact_confirm,$page_ID_contact_completion);

    $query->set('post_type', $post_array);
    $query->set('post__not_in', $not_in_array);
  }
}
add_filter('pre_get_posts', 'filter_search');


//検索
function custom_search($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 = '%' . esc_sql($word) . '%';
        $search .= " AND (
          {$wpdb->posts}.post_title LIKE '{$search_word}' -- タイトル
          OR {$wpdb->posts}.post_content LIKE '{$search_word}' -- コンテンツ
          OR {$wpdb->posts}.ID IN ( -- タグ、カテゴリー、ターム
             SELECT distinct 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 t.name LIKE '{$search_word}'
             OR t.slug LIKE '{$search_word}'
             OR tt.description LIKE '{$search_word}'
            )
            OR {$wpdb->posts}.ID IN ( -- カスタムフィールド
            SELECT distinct post_id
            FROM {$wpdb->postmeta}
            WHERE {$wpdb->postmeta}.meta_key IN ('カスタムフィールド1','カスタムフィールド2') AND meta_value LIKE '{$search_word}'
            )
         )";
      }
    }
  }
  return $search;
}
add_filter('posts_search', 'custom_search', 10, 2);

全てのカスタムフィールドを検索対象にしたい場合は、
WHERE {$wpdb->postmeta}.meta_key IN ('カスタムフィールド1','カスタムフィールド2') AND meta_value LIKE '{$search_word}'

WHERE meta_value LIKE '{$search_word}'
に変える。

参考サイト

WordPressの検索機能でカスタムフィールドを検索対象にする方法 – Offise Kondo
https://takayakondo.com/post-13762/