// 重複確認のためのフィルタを設定
add_action( 'rest_api_init', function() {
// 標準投稿タイプにも適用
add_filter( 'rest_post_collection_params', 'enable_meta_query_for_all', 10, 1 );
// カスタム投稿タイプ youtube にも適用
add_filter( 'rest_youtube_collection_params', 'enable_meta_query_for_all', 10, 1 );
});
function enable_meta_query_for_all( $params ) {
$params['meta_key'] = [
'description' => 'フィルタ対象の meta_key',
'type' => 'string',
'sanitize_callback' => 'sanitize_key',
];
$params['meta_value'] = [
'description' => 'フィルタ対象の meta_value',
'type' => 'string',
];
return $params;
}
// meta_key/meta_value を meta_query に変換
add_filter( 'rest_youtube_query', 'add_meta_query_to_youtube', 10, 2 );
function add_meta_query_to_youtube( $args, $request ) {
if ( ! empty( $request['meta_key'] ) && ! empty( $request['meta_value'] ) ) {
$args['meta_query'][] = [
'key' => sanitize_key( $request['meta_key'] ),
'value' => sanitize_text_field( $request['meta_value'] ),
];
}
return $args;
}
// すべてのステータスをAPIで使用できるようにする。
add_filter('rest_youtube_query', function($args, $request) {
error_log("✅ rest_youtube_query: post_statusを上書きします");
$args['post_status'] = ['publish', 'draft', 'pending', 'future', 'private', 'trash'];
return $args;
}, 10, 2);
以下のコードは、WordPress の REST API に対して「メタ(カスタムフィールド)を使ったフィルタ」と「すべての投稿ステータスを検索対象にする」機能を追加する仕組みです。パートごとに順を追って解説します。
1. メタクエリ用フィルタの有効化
// 重複確認のためのフィルタを設定
add_action( 'rest_api_init', function() {
// 標準投稿タイプにも適用
add_filter( 'rest_post_collection_params', 'enable_meta_query_for_all', 10, 1 );
// カスタム投稿タイプ youtube にも適用
add_filter( 'rest_youtube_collection_params', 'enable_meta_query_for_all', 10, 1 );
});
-
add_action('rest_api_init', …)- REST API のエンドポイントを登録するタイミング(
rest_api_init)で、後述のフィルタを追加する準備を行います。 - つまり「REST API が使われる直前に、この処理を挟む」ということです。
- REST API のエンドポイントを登録するタイミング(
-
add_filter('rest_post_collection_params', 'enable_meta_query_for_all', 10, 1)- 標準投稿(
post)に対する REST API(/wp-json/wp/v2/posts)のクエリパラメータを拡張します。 - ここでは「標準投稿にもメタキー/メタ値をパラメータとして渡せるようにする」ため、
enable_meta_query_for_all()関数を登録しています。
- 標準投稿(
-
add_filter('rest_youtube_collection_params', 'enable_meta_query_for_all', 10, 1)- カスタム投稿タイプ
youtube(エンドポイント/wp-json/wp/v2/youtube)にも同じく、メタキー/メタ値を受け取るパラメータを追加します。 -
youtubeという名前の CPT を使っている前提ですので、このフィルタを通すことで REST API 側でmeta_keyとmeta_valueを受け取れるようになります。
- カスタム投稿タイプ
2. メタパラメータを登録する関数
function enable_meta_query_for_all( $params ) {
$params['meta_key'] = [
'description' => 'フィルタ対象の meta_key',
'type' => 'string',
'sanitize_callback' => 'sanitize_key',
];
$params['meta_value'] = [
'description' => 'フィルタ対象の meta_value',
'type' => 'string',
];
return $params;
}
-
引数
$params
REST API が受け付けるクエリパラメータの定義配列です。
たとえば標準ではper_page,page,search,authorなど決まったものしかありませんが、ここで新たに以下を追加しています。
-
meta_key-
description:ドキュメント用の説明文(メタキーを指定するためのパラメータです)。 -
type:stringとして扱うことを明言。 -
sanitize_callback:sanitize_keyを使って値をクリーンにします(英数字とアンダースコアだけを許容する)。
-
-
meta_value-
description:ドキュメント用の説明文(メタキーに対応する値を指定するためのパラメータ)。 -
type:こちらもstringとして定義。 -
sanitize_callbackは指定していませんが、実際に利用するフィルタ関数内でsanitize_text_field()を使うようにしています。
-
- 最後に
$paramsを返すことで、REST API 側でmeta_keyとmeta_valueの2つのパラメータを受け取れるようになります。
3. meta_key/meta_value → meta_query への変換
// meta_key/meta_value を meta_query に変換
add_filter( 'rest_youtube_query', 'add_meta_query_to_youtube', 10, 2 );
function add_meta_query_to_youtube( $args, $request ) {
if ( ! empty( $request['meta_key'] ) && ! empty( $request['meta_value'] ) ) {
$args['meta_query'][] = [
'key' => sanitize_key( $request['meta_key'] ),
'value' => sanitize_text_field( $request['meta_value'] ),
];
}
return $args;
}
-
add_filter('rest_youtube_query', …)- REST API で
youtube投稿タイプを検索するときに使われるクエリ引数($args)をカスタマイズするためのフックです。 - つまり、最終的に内部で実行される
WP_Queryに渡る$argsに手を加えられます。
- REST API で
-
関数内部の処理
-
$requestには、URL のクエリパラメータすべてが入っています。 -
ここで「
meta_keyとmeta_valueが両方セットされていれば」、$args['meta_query'][]に次の配列を追加します:[ 'key' => (サニタイズ済みの meta_key), 'value' => (サニタイズ済みの meta_value), ] -
これにより 「メタキーとメタ値がマッチする投稿だけを
WP_Queryで絞り込む」 という仕組みが働きます。
-
-
結果として
- たとえば
/wp-json/wp/v2/youtube?meta_key=video_id&meta_value=abc123のようにリクエストすれば、投稿メタvideo_id = abc123となっているyoutube投稿だけが返ります。
- たとえば
4. すべての投稿ステータスを検索対象にする
// すべてのステータスをAPIで使用できるようにする。
add_filter('rest_youtube_query', function($args, $request) {
error_log("✅ rest_youtube_query: post_statusを上書きします");
$args['post_status'] = ['publish', 'draft', 'pending', 'future', 'private', 'trash'];
return $args;
}, 10, 2);
-
再び
rest_youtube_queryをフィルタ- 先ほどの
add_meta_query_to_youtubeと同じフックに、追加で無名関数(クロージャ)を登録しています。 - 順序は「優先度 10, 引数 2」なので、この無名関数はメタクエリ変換のあと、などのタイミングで実行されます。
- 先ほどの
-
error_log("✅ rest_youtube_query: post_statusを上書きします");- ログ出力して、「このフィルタが動いているか?」「実際に post_status を書き換えているか?」を確認できるようにしています。
-
$args['post_status'] = [ … ]- デフォルトでは REST API で返される投稿ステータスは
publish(公開済み)のみです。 -
draft(下書き),pending(承認待ち),future(予約投稿),private(非公開),trash(ゴミ箱)などをすべて含めることで、
「いかなる投稿ステータスのyoutube投稿でも検索対象にする」 という意味になります。
- デフォルトでは REST API で返される投稿ステータスは
-
こうしておくことで
- 通常は、たとえ
post_status[]=draftなどを渡しても認証ユーザー以外には無視される仕組みがありますが、 - このフィルタを入れることで 「常にすべてのステータスを検索対象にする」 という強制的なオーバーライドを行っています。
- その結果、たとえば管理者権限であれば「下書きや非公開の投稿も REST API で取れる」ようになります。
- 通常は、たとえ
5. 全体の役割をまとめると
-
rest_api_initでフィルタ登録
→rest_post_collection_paramsとrest_youtube_collection_paramsにmeta_keyとmeta_valueを受け取る仕組みを追加 -
rest_youtube_queryでメタクエリを実装
→meta_keyとmeta_valueが指定されたら、内部クエリ(WP_Query)にmeta_queryを追加してメタ検索を行う -
同じ
rest_youtube_queryで post_status を上書き
→ 検索時にpublish以外のステータスも常に対象にする(未ログインでもフィルタ上書き可能な状態にする)
この構成により、外部のクライアントやバッチ処理から
GET /wp-json/wp/v2/youtube?
meta_key=任意のキー&
meta_value=任意の値&
post_status[]=publish&
post_status[]=draft&
post_status[]=private
といったリクエストを送るだけで、
- 指定した カスタムフィールド(メタキーとその値) をもつ投稿を絞り込み
- かつ 公開済み/下書き/非公開/ゴミ箱 など全ステータスを対象に検索
が可能になります。
🛠️ 実践的な利用例
-
YouTube ID をキーにして、すでに同じ動画IDが登録済みか(重複チェック)を行いたい
GET /wp-json/wp/v2/youtube? meta_key=video_id&meta_value=abc123だけで「
video_id = abc123をメタに持つ投稿があるかどうか」を返す。 -
管理者ユーザーなら、下書きのまま保存してある動画情報も検出したい
メタクエリと合わせて post_status をすべて対象にしているため、
下書きステータス(draft)のものもヒットする。 -
外部で自動化バッチを実行し、すでに登録済みの投稿をスキップしつつ新規登録する
このフィルタがあれば、外部スクリプトから簡単に「この ID は既存か?」をチェックできる。
📝 最後に
-
rest_post_statusesのフィルタ を併用してshow_in_restをすべてのステータスにtrueにすると、さらに厳密に「REST API で全ステータスを認める」仕組みが必要になります。 - ただしここでは
rest_youtube_queryで post_status を直接上書き しているので、最も簡単に全ステータスを検索対象にできる形です。
これで「メタキー/メタ値を使ったフィルタリング」と「すべての投稿ステータスを API で利用可能にする」仕組みの全体像がイメージできるはずです。
ご不明な点やさらに突っ込んだカスタマイズがあれば、遠慮なくお知らせください!