Advanced Custom Fieldsを使用した環境にCSVから投稿をインポートする方法(Really Simple CSV ImporterのACF対応)
みなさんごきげんよう。kではない方のyamashitaです。
あっという間に夏が来た感じがしますね。年のせいなのか季節の移り変わりに体がついていかないです。
さて、今日はWordPressのプラグイン、Really Simple CSV ImporterのACF(Advanced custom Field)対応の方法をご紹介します。
Really Simple CSV Importerとは
WordPressにCSV形式で投稿をインポートできるプラグインです。
フォーマットは以下のような形になります。
post_id,post_name,post_author,post_date,post_type,post_status,post_title,post_content,meta_key,meta_key2,meta_key3
// 二行目からは各キー名に沿った値を,区切りで記入
投稿に必要な項目のキーとその後に必要なメタキーを並べるといった形です。 acfを使わなければこれだけで問題なく使えます。
早速対応方法
以下をfunctions.phpに書いてインポートの度に呼び出されるようにします。
Really Simple CSV Importerのアクションフックを使用して、保存前のメタデータをACF用に整理します。
引数は三つ指定していますが、今回は一つ目の$metaのみ使用しています。
拡張する際には他の二つも使うかもしれないので参考までに記載しています。
<?php
function really_simple_csv_importer_save_meta_acf($meta, $post, $isUpdate)
{
global $wpdb;
// acf-fieldを取得するためのクエリ
$sqlNormal = "SELECT post_name
FROM wp_posts
WHERE post_type = 'acf-field' AND post_excerpt = '%s' LIMIT 1";
$metaResult = [];
// 各値をacfで登録した場合と同じになるようにメタデータに追加
foreach ($meta as $key => $value) {
/*
* acfのフィールドは"acf_"を先頭に付ける。
* acf以外はそのまま何もしない。
*/
if (strpos($key, "acf_") === false) {
$metaResult[$key] = $value;
continue;
}
// acf_の文字列を取り除く
$acfKey = preg_replace('/^acf_(.*)/', '$1', $key);
$metaResult[$acfKey] = $value;
// 繰り返しフィールド対応
$keyStr = $acfKey;
preg_match('/^(.*)_[0-9]{1,}_(.*)/', $acfKey, $keyMatches);
if (isset($keyMatches[2])) {
$keyStr = $keyMatches[2];
}
// フィールドキー対応
$prepared = $wpdb->prepare($sqlNormal, esc_sql($keyStr));
$fieldKey = $wpdb->get_col($prepared);
// アンダーバー+キー名にフィールドキーの値を当てる
$metaResult["_" . $acfKey] = $fieldKey[0];
}
return $metaResult;
}
add_filter('really_simple_csv_importer_save_meta', 'really_simple_csv_importer_save_meta_acf', 10, 3);
このプラグインはCustom Field Suiteは"cfs_"、Smart Custom Fieldsは"scf_"という接頭辞を付けるみたいです。
しかしACFは対応していないようなので"acf_"の接頭辞を付けるとACFのメタキーとして取り込むようにしました。
この対応をしないとget_field()などでデータの取得、出力ができなくなります。
しかし、ACFのフィールドもget_post_meta()などで取得するとかであれば必要ありません。その場合ACFも必要なさそうですが。
ざっくり解説
まずはACFのメタデータの保存方法についてです。
通常の投稿のメタデータはwp_postmetaテーブルに一行のレコードで保存されていますが、ACFはwp_postsに一行、wp_postmetaに二行のレコードで保存されています。
内容としてはwp_postsには投稿タイプacf_fieldとしてそのフィールドの形式を、wp_postmetaでは通常のメタデータと同じくキーと値を投稿に結びつけるレコードと、上記のフィールド形式のレコードを参照しているレコードの二行が保存されています。
この二行目がReally Simple CSV Importerでは保存できていないのでそれの対応を主にしているのが今回の記事の内容です。
"acf_"の接頭辞がついていれば該当するフィールドとして扱います。
繰り返しフィールドでなければそのまま接頭辞だけ取り除きます。
そしてそれとは別にクエリでwp_postsから参照する値を取得してメタデータに返します。
これで解決。get_field()やthe_field()などACF特有の関数を使えるようになります。
まとめ
色々なプロジェクトで手動では厳しい数の投稿をインポートすることが多々あるので、なるべく汎用性があるように考えてみました。
Really Simple CSV Importerは最近更新が止まっているので少々最新版のWordPressへの対応が心配ですが、早々形式が変わるような部分でもないので、代替プラグインも探しつつ使っていければいいなと思ってます。
ACFはWordPressを触り始めてから使い続けてるので今回少し内部の仕組みがわかってよかったかなと思います。
最近はプラグイン同士の相性に悩まされることも多いのでまた何かあったら書きたいなと思います。