WordPressで 特定の投稿タイプの場合に”次の記事” をカスタムフィールドで絞り込む方法

結構特殊なのかもしれませんが、特定の投稿タイプの場合に、”次の記事”をタクソノミーではなく、カスタムフィールドで絞り込みたいという状況になりましたので、調べた結果のメモ
(ほんとはカテゴリかタグなんでしょうが…)

  1. get_next_post()のコードを読んでみると
  2. get_next_post()は単にget_adjacent_post()のラッパでしたので、get_adjacent_post()を確認
  3. get_adjacent_post()を読んでみると、フィルタとして get_{$adjacent}post_join と get{$adjacent}_post_where が使える感じ

ということで、特定の投稿タイプの場合にフィルタを設定してみることに。フィルタ自体はfunctions.phpにこんな感じで追加

function ex_next_post_join($join, $in_same_cat, $excluded_categories) {
    global $post, $wpdb;
    $post_type = get_post_type($post);
    if ($post_type == 'content') {
        // 投稿タイプ "content" の場合だけ、wp_postmetaをJOIN
        return $wpdb->prepare("LEFT JOIN wp_postmeta ON (p.ID = wp_postmeta.post_id) ");
    }
    return $join;  // その他はそのままreturn
    
}
function ex_next_post_where($where, $in_same_term, $excluded_terms) {
    global $post, $wpdb;
    $post_type = get_post_type($post);
    $key_id = get_post_meta($post->ID, 'key_id');
    if ($post_type == 'content') {
        // 投稿タイプ "content" の場合で、カスタムフィールドkey_idに値が設定されている場合のみ、条件を追加
        if (!empty($key_id[0])) {
            return $wpdb->prepare("$where AND meta_key = %s AND meta_value = %s", 'key_id', $key_id[0]);
        }
    }
    return $where; // その他はそのままreturn
}
add_filter('get_next_post_where', 'ex_next_post_where', 10, 3);
add_filter('get_next_post_join', 'ex_next_post_join', 10, 3);

結果、無事絞り込んでの次の記事が取得できました。