【WordPress】クエリを関数化してループを使い回す

ワードプレスのクエリを操作して、投稿の絞り込み検索をするのは通常運転の私ですが。

一つのページの中で、違う条件で投稿を絞り込まなきゃいけなくなりまして。

毎回クエリのパラメータを書くのは無駄だなぁと思い。

クエリを関数化してみることにしました。

発端は入力値のバリデーション

データを入力するフォームをワードプレス上で運用しているんですが。

その入力値を前もって用意したデータと合致するかをする必要があり。

バリデーションをどうするか考えていたのです。

例えば、スケジュールと実績みたいなもので。

実績とスケジュールで変わることが無いものがあると思います。

すごいざっくりですと、日付や曜日は変わりようがありません。

人の名前や会社の名前といったものも、そう簡単には変わらないですよね。

そういったデータが実績として入力された時に、スケジュールに前もって登録されていたデータと違っていれば、エラーを吐き出すように・・・という動作が必要となりました。

ワードプレスの通常のクエリ操作で投稿データを取得すると、該当する投稿データを全件取得することになります。

そうすると、人の名前で投稿データを絞り込んでも、様々な投稿で出てくる可能性があります。

例えば、アルバイトのシフトは週1でも無い限り、2〜3回は時間帯が違っても出てくるわけです。

タイムカードを押した時に、週のデータを参照して出勤かどうかを判定するプログラムの場合、その当日のデータじゃないと、常に出勤が返されることに。

・・・ちょっとざっくりですが、そういう感じでした。

入力フォーム毎にこの条件が変わるため、すべてに対してクエリを実行しないといけなさそうだよねと。

なので、クエリのパラメータの共通部分だけ関数化して。

その関数をバリデーション関数で呼び出し、パラメータを追加すれば良いかなと。

独自関数に配列のパラメータを渡す

まずはベースとなるクエリの関数を作って行きます。

入力された日付を元に投稿データを取得したいので、日付が入力されているカスタムフィールドの値を参照するようにしています。

function base_schedule_query( $add_query_params = array() ){
  //入力日の取得
  $input_date = new DateTimeImmutable( $_POST['入力フォームのname'] );
  //クエリで使用する基本パラメータの返り値
  $query_params = array(
    'post_type' => 'test-post',
    'post_status' => 'publish',
    'posts_per_page' => -1,
    'orderby' => 'ID',
    'no_found_rows' => true,
    'meta_query' => array(
      'relation' => 'AND',
      array(
        //日付のサブフィールドと日報入力日が同じかの確認
        'key' => 'schedule_date',
        'value' => $input_date->format( 'Y/m/d' ),
        'compare' => '=',
      ),
    ),
  );
//続く・・・

独自関数のbase_schedule_query()に、$add_query_paramsという変数を配列で渡すようにします。

で、入力された日付を取得し、’meta_query’で同じ日付が入力されたtest-postの投稿データを取得する。

というクエリのパラメータです。

パラメータは配列でクエリ関数に渡されるので、追加するパラメータも配列にしておきます。

$add_query_paramsが空であれば、このパラメータがクエリの条件となります。

空ではない場合、クエリにパラメータを追加する処理を書いて行きます。

//・・・続き
//追加クエリ$add_query_paramsを結合する
  //外部で$add_query_paramsに追加パラメータを設定すれば絞込み条件になる
  if( !empty( $add_query_params ) ){
    if( !empty( $add_query_params['meta_query'] ) ){
      $query_params['meta_query'] = array_merge( $query_params['meta_query'], $add_query_params['meta_query'] );
    }
  }
//・・・さらに続く

今回条件として追加するものは、カスタムフィールドの値なので。

'meta_query’の部分に追加されるようにしています。

なので、$add_query_paramsに値があるか確認し、念の為’meta_query’も存在するか確認し。

もともとの’meta_query’の配列に、$add_query_paramsの’meta_query’の配列をarray_merge()で結合します。

ここまででreturnしても良かったんですが。

呼び出すたびに、get_posts( base_schedule_query( $add_query_params ) )と書くのも面倒だったので。

get_posts()までを関数にいれることにしました。

  //クエリ実行
  //データ使用のため、get_posts()
  $query = get_posts( $query_params );
  return $query;
}

パラメータを別関数で追加する

パラメータを別関数で追加するのは、$add_query_paramsで追加するパラメータを設定し、独自関数を呼び出すだけです。

function schedule_validation_data(){
  //入力された現場名の取得
  $test_validation_input = $_POST['test-input'];
  //現場名をクエリに追加
  $add_query_params = array(
    'meta_query' => array(
      array(
        'key' => 'schedule-input',
        'value' => $test_validation_input,
        'compare' => '=',
      ),
    ),
  );
  //現場名でのクエリ実行
  $query_result = base_schedule_query( $add_query_params );
  return $query_result;
}

あとはこの関数を呼び出してループを回せば、絞り込んだ投稿データを操作できます。

使い回せる方が楽

このブログで一番読まれている記事でもある、「【WordPress】カスタムフィールドを使って投稿の絞り込み検索を実装する」でもパラメータの追加について書いてますが。

関数を使わないものであれば、「+=」でも追加はできます。

今回はバリデーション自体を関数で行っていたため、関数内に投稿データを渡す方法を考えなければなりませんでした。

基本外部参照はできませんからね。

かといって、クラスを作るほどの規模でもないし・・・。

と考えついたのが、関数化でした。

使い方によっては、投稿タイプの指定や表示数も動的に変える事ができるので。

絞り込み検索を多用するサイトでは、基本部分だけfunctions.phpに書いておいて、追加分だけ個別のPHPファイルに書くようにすれば便利かもなぁと思いました。