wordpressのfunction.php メモ

```
// 重複確認のためのフィルタを設定
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. メタクエリ用フィルタの有効化

```php
// 重複確認のためのフィルタを設定
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 );
});
```

1. **`add_action('rest_api_init', …)`**

   * REST API のエンドポイントを登録するタイミング（`rest_api_init`）で、後述のフィルタを追加する準備を行います。
   * つまり「REST API が使われる直前に、この処理を挟む」ということです。

2. **`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()` 関数を登録しています。

3. **`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. メタパラメータを登録する関数

```php
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` など決まったものしかありませんが、ここで新たに以下を追加しています。

1. **`meta_key`**

   * `description`：ドキュメント用の説明文（メタキーを指定するためのパラメータです）。
   * `type`：`string` として扱うことを明言。
   * `sanitize_callback`：`sanitize_key` を使って値をクリーンにします（英数字とアンダースコアだけを許容する）。

2. **`meta_value`**

   * `description`：ドキュメント用の説明文（メタキーに対応する値を指定するためのパラメータ）。
   * `type`：こちらも `string` として定義。
   * `sanitize_callback` は指定していませんが、実際に利用するフィルタ関数内で `sanitize_text_field()` を使うようにしています。

* 最後に `$params` を返すことで、**REST API 側で `meta_key` と `meta_value` の２つのパラメータを受け取れる**ようになります。

---

## 3. `meta_key/meta_value` → `meta_query` への変換

```php
// 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;
}
```

1. **`add_filter('rest_youtube_query', …)`**

   * REST API で `youtube` 投稿タイプを検索するときに使われるクエリ引数（`$args`）をカスタマイズするためのフックです。
   * つまり、最終的に内部で実行される `WP_Query` に渡る `$args` に手を加えられます。

2. **関数内部の処理**

   * `$request` には、URL のクエリパラメータすべてが入っています。
   * ここで「`meta_key` と `meta_value` が両方セットされていれば」、`$args['meta_query'][]` に次の配列を追加します：

     ```php
     [
       'key'   => (サニタイズ済みの meta_key),
       'value' => (サニタイズ済みの meta_value),
     ]
     ```
   * これにより **「メタキーとメタ値がマッチする投稿だけを `WP_Query` で絞り込む」** という仕組みが働きます。

3. **結果として**

   * たとえば `/wp-json/wp/v2/youtube?meta_key=video_id&meta_value=abc123` のようにリクエストすれば、投稿メタ `video_id = abc123` となっている `youtube` 投稿だけが返ります。

---

## 4. すべての投稿ステータスを検索対象にする

```php
// すべてのステータスを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);
```

1. **再び `rest_youtube_query` をフィルタ**

   * 先ほどの `add_meta_query_to_youtube` と同じフックに、追加で無名関数（クロージャ）を登録しています。
   * 順序は「優先度 10, 引数 2」なので、この無名関数はメタクエリ変換のあと、などのタイミングで実行されます。

2. **`error_log("✅ rest_youtube_query: post_statusを上書きします");`**

   * ログ出力して、「このフィルタが動いているか？」「実際に post\_status を書き換えているか？」を確認できるようにしています。

3. **`$args['post_status'] = [ … ]`**

   * デフォルトでは REST API で返される投稿ステータスは `publish`（公開済み）のみです。
   * `draft（下書き）`, `pending（承認待ち）`, `future（予約投稿）`, `private（非公開）`, `trash（ゴミ箱）` などをすべて含めることで、
     **「いかなる投稿ステータスの `youtube` 投稿でも検索対象にする」** という意味になります。

4. **こうしておくことで**

   * 通常は、たとえ `post_status[]=draft` などを渡しても認証ユーザー以外には無視される仕組みがありますが、
   * このフィルタを入れることで **「常にすべてのステータスを検索対象にする」** という強制的なオーバーライドを行っています。
   * その結果、たとえば管理者権限であれば「下書きや非公開の投稿も REST API で取れる」ようになります。

---

## 5. 全体の役割をまとめると

1. **`rest_api_init` でフィルタ登録**
   → `rest_post_collection_params` と `rest_youtube_collection_params` に `meta_key` と `meta_value` を受け取る仕組みを追加
2. **`rest_youtube_query` でメタクエリを実装**
   → `meta_key` と `meta_value` が指定されたら、内部クエリ（`WP_Query`）に `meta_query` を追加してメタ検索を行う
3. **同じ `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
```

といったリクエストを送るだけで、

1. 指定した **カスタムフィールド（メタキーとその値）** をもつ投稿を絞り込み
2. かつ **公開済み／下書き／非公開／ゴミ箱** など全ステータスを対象に検索

が可能になります。

---

## 🛠️ 実践的な利用例

* **YouTube ID をキーにして、すでに同じ動画IDが登録済みか（重複チェック）を行いたい**

  ```http
  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 で利用可能にする」仕組みの全体像がイメージできるはずです。
ご不明な点やさらに突っ込んだカスタマイズがあれば、遠慮なくお知らせください！