WordPressのカスタムフィールドの値を数えて、CSVに保存。読み込んで件数を表示する。

WordPressで作った自転車データベース「うさぎサイクル」は、カスタムフィールドで色や年式、ブレーキ種別などを登録して検索できるようにしています。

赤い自転車が何台登録されているか、ディスクブレーキが何台あるかなど、検索前に登録件数を表示できるようにしたいと思います。

やること

  1. カスタムフィールドに登録されている件数を調べて、CSVに保存する。
  2. カウントは1日1回、cronで実行する。
  3. 登録された件数を読み込んで、件数を表示する。

完成イメージ。検索条件の横に件数を表示する。

件数カウント、保存部分

管理外から、WordPressにアクセスするおまじない

require_once(dirname( __FILE__ ).'/wp-load.php');
require_once(dirname( __FILE__ ).'wp-admin/includes/file.php');

上記のうち、wp-load.phpとfile.phpはWordPressの管理外のファイルで、WordPressを操作するときのおまじないです。

画像を扱うときは、wp-admin/includes/image.php、wp-admin/includes/media.phpも読み込みます。

カスタムフィールドを配列に読み込む

$material = array(
  'Carbon' => 'material',
  'Aluminum' => 'material',
  'Iron' => 'material',
  'Titanium' => 'material'
);
$color = array(
  'Red' => 'color',
  'Blue' => 'color',
  'Green' => 'color',
  'Yellow' => 'color',
  'Purple' => 'color',
  'Orange' => 'color',
  'Brown' => 'color',
  'Black' => 'color',
  'Grey' => 'color',
  'White' => 'color',
  'Colorful' => 'color',
  'Order' => 'color'
);
$year = array(
  '2022' => 'year',
  '2021' => 'year'
);

$count_array = array_merge($material,$color);
$count_array = $count_array + $year;

keyに値があり、valueにカスタムフィールド名がある構造が気持ち良くないのですが、まあ良しとしましょう。

$yearのkeyである2022は、連想配列の文字列として扱っているつもりですが、array_mergeで結合すると、数値の添え字扱いになってしまうようです。そのため、$count_array[2022]は$count_array[0]、$count_array[2021]は$count_array[1]になってしまいました。

そのため、$yearだけ + で結合しました。

配列で件数をカウントする

foreach($count_array as $key => $value){
  $args = array(
    'post_status' => 'publish',
    'post_type' => '{カスタム投稿名}',
    'posts_per_page' => -1,
    'meta_key' => $value,
    'meta_value' => $key,
    'meta_compare' => 'LIKE',
    );

	$the_query = new WP_Query( $args );
	$count = $the_query->post_count;
	$content .= $key.','.$value.','.$count."\n";
}

$count_arrayをforeachで回しながら、WP_Queryで件数をカウントします。カウントした値は、カスタムフィールドの値、カスタムフィールド名と合わせて、$contentに格納していきます。1行に3列(カスタムフィールドの値、カスタムフィールド名、件数)が並ぶCSVにします。

カスタムフィールドの比較演算子、’meta_compare’ => ‘LIKE’としているのは、色のカスタムフィールドをACFでチェックボックスで選択しているためです。

ACFでチェックボックスを設定し、値を保存すると、1つのカスタムフィールドの中に複数の値を保存します。そのため、’meta_compare’ => ‘=’にしてしまうと、チェックボックスのカスタムフィールドをカウントできません。

その他のカスタムフィールドは、’meta_compare’ => ‘=’の方がいいです。気になる場合は、meta_keyによって、meta_compareを書き換えるif文を追加すると良いと思います。

CSVとして保存

$file_counter = fopen("{保存するファイル名}.csv", "w");
@fwrite($file_counter, $content);
fclose($file_counter);

カウントした値をCSVに保存します。ファイルは常に上書きするので、fopenのmodeはwです。

これで、カウント部分は終了です。

サーバー側でcronを設定し、毎日22時に件数をカウントして、CSVに保存していきます。

下記のようなCSVファイルが作成されます。

Carbon,material,274
Aluminum,material,174
Iron,material,12
Titanium,material,3
Red,color,118
Blue,color,137
Green,color,142
Yellow,color,35
Purple,color,30
Orange,color,39
Brown,color,45
Black,color,202
Grey,color,128
White,color,66
Colorful,color,26
Order,color,39
2022,year,418
2021,year,103

件数読み込み、表示部分

$file_counter = fopen('{CSVファイル名}.csv', 'r');
while($count = fgetcsv($file_counter)){
  $array_count[] = [$count[0],$count[1],$count[2]];
}

CSVファイルを読み込みます。読み取りだけなので、fopenのmodeはrです。

CSVファイルは、1行3列(カスタムフィールドの値、カスタムフィールド名、件数)の値があるため、多次元配列として読み込みます。多次元配列は配列の中に配列を入れることで、複数の値を配列化しておくことです。

2列目のカスタムフィールド名は使わないので、普通の配列として読み込んでもいいのですが、CSVファイルが3列あるのですべて取り込んでおくために多次元配列にします。

foreach($color as $key => $value){
  $counter_key = array_search( $key, array_column( $array_count,0 ));
    echo '.$key.'('.$array_count[$counter_key][2].')
'; }

$colorに色の選択肢(Red、Blue…etc)配列が入っているとします。これをforeachで展開します。

$array_countは、1列目にカスタムフィールドの値、2列目がカスタムフィールド名、3列目がカウントした件数です。

array_column( $array_count,0 )で、0列(1列目にカスタムフィールドの値)を対象にします。array_search( $key,で検索します。

Red(118)
Blue(137)
Green(142)
Yellow(35)
以下、省略。

多分、もっと良い方法があると思いますが、こんな方法でWordPressのカスタムフィールドの件数を数えて、表示できます。