// 重複確認のためのフィルタを設定
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 で利用可能にする」仕組みの全体像がイメージできるはずです。
ご不明な点やさらに突っ込んだカスタマイズがあれば、遠慮なくお知らせください!