Really Simple CSV ImporterでACFの繰り返しフィールドへ追加していきたい
受付中
回答 1
投稿
- 評価
- クリップ 0
- VIEW 1,940
前提・実現したいこと
4つのグループがあり、1つのグループに150名程が所属しています。
このメンバーをReally Simple CSV ImporterでACFの繰り返しフィールドへ上書きではなく「追加」していきたい。
csvの形式はそのままでプラグインをカスタマイズしていく形で実現したいです。
作成したCSV
1 | post_type | name | link | post_status | post_id |
---|---|---|---|---|---|
2 | page | name01 | http://link01.co.jp/ | publish | 31 |
3 | page | name02 | http://link02.co.jp/ | publish | 31 |
ざっくりこんな感じで1つのグループで1つのcsvを作成し、インポートを試みています。
発生している問題・エラーメッセージ
下記2サイトを参考にReally Simple CSV ImporterにACFの繰り返しフィールドをカスタマイズを行いましたが
これだと上書きになってしまい追加ができません。(name02さんのデータしか入らない。)
http://notnil-creative.com/blog/archives/2497
https://qiita.com/pappikko/items/4fbda1bc772ec01674b5
↓インポート完了画面
Array
(
[name] => name01
[link] => http://link01.co.jp/
)
Array
(
[field_5cb40c0a50e82] => Array
(
[0] => Array
(
[name] => name01
[link] => http://link01.co.jp/
)
)
)
"" の処理が完了しました。
Array
(
[name] => name02
[link] => http://link02.co.jp/
)
Array
(
[field_5cb40c0a50e82] => Array
(
[0] => Array
(
[name] => name02
[link] => http://link02.co.jp/
)
)
)
"" の処理が完了しました。
書いたコード
/* Plugin Name: custom_field_importer */
function rsci_meta_filter( $meta, $post, $is_update ) {
echo '<pre>';
print_r($meta);
echo '</pre>';
$meta_array = array();
$repeater_array = array();
$i = 0;
foreach ($meta as $key => $value) {
// カスタムフィールド名が "textfield" だった時
if ($key == 'textfield') {
// ACF用のフィールドキーに変換
$meta_array['field_52528d5b8ad30'] = $value;
// カスタムフィールド名が "select" だった時
} elseif ($key == 'select') {
// カンマで分割して配列として登録
$meta_array['field_52528dc88ad31'] = preg_split("/,+/", $value);
// 繰り返しフィールド用のデータを配列に入れていく処理
} elseif ($key == 'name') {
$repeater_array[$i]['name'] = $value;
} elseif ($key == 'link') {
$repeater_array[$i]['link'] = $value;
$i++;
// ACF以外のメタデータはそのまま通す
} else {
$meta_array[$key] = $value;
}
}
// 繰り返しフィールドの配列を戻す
$meta_array['field_5cb40c0a50e82'] = $repeater_array;
echo '<pre>';
print_r($meta_array);
echo '</pre>';
return $meta_array;
}
add_filter( 'really_simple_csv_importer_save_meta', 'rsci_meta_filter', 10, 3 );
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+2
Really Simple CSV Importer のデフォルトの動作は、同じ投稿IDのデータは、1 行にまとまってる前提なので、同じ投稿 ID のデータが複数行ある場合は、最後のデータで上書きされます。
同じ投稿IDのデータが、1ファイルに複数入っている構造のCSVファイルをインポートする場合は、保存済みのデータを読み込んで加工する等の工夫が必要です。
たとえば...
同じ投稿IDに追加されるデータが、ファイルに複数行含まれるのであれば、以下のような処理をする必要があります。
- $post に投稿オプジェクトが渡されてくるので、$post->ID を参照して、現在投稿IDのカスタムフィールドデータを読み込む。
- 読み込んだカスタムフィールドデータを元にして、現在のデータを追加・置換する。
- 更新したデータを返す。
という処理を行う必要があります。
(2019.04.25 12:45追記)
昼の合間にざっと書いてみたのですが、ちょっとテストできるタイミングが遅くなりそうなので、未テストですが、記載しておきます。
やっつけ感満載...ですが、こんな感じだとどうでしょうか。
$meta の中身がリピーターフィールドの項目だけなら、foreach せずに そのまま add_row('member', $meta, $post_id);
でも良いかもしれません。
function rsci_meta_filter186134 ( $meta, $post, $is_update ) {
echo '<pre>';
print_r($meta);
echo '</pre>';
$post_id = $post['ID'];
$repeater_array = array();
foreach ($meta as $key => $value) {
if ($key == 'name') {
$repeater_array['name'] = $value;
} elseif ($key == 'link') {
$repeater_array['link'] = $value;
}
}
$i = add_row('member', $repeater_array, $post_id);
echo '<pre> row = '. $i ."\n";
print_r($repeater_array);
echo '</pre>';
return;
}
add_filter( 'really_simple_csv_importer_save_meta', 'rsci_meta_filter186134', 10, 3 );
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.33%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2019/04/24 13:44
→ $i++;しているのに配列の番号が変わっていないので、おかしいなと思っていたのですがそういうことだったんですね。
>1.$post に投稿オプジェクトが渡されてくるので、$post->ID を参照して、現在投稿IDのカスタムフィールドデータを読み込む。
>2.読み込んだカスタムフィールドデータを元にして、現在のデータを追加・置換する。
>3.更新したデータを返す。
こちらどこでどういうコード加えればいいでしょうか。
お手数ですがご教授いただけるとありがたいです。
2019/04/24 14:23 編集
$i は呼び出し毎にリセットされるので増えないですね。
どの様なコードと言われてもいろいろ情報不足なので、直接的な回答は難しいです。
大まかなプログラムの流れとしては、
最初の方で、変数を空の状態で初期化している部分を 初期化するのではなく、
```
$meta_array = get_post_meta( $post->ID );
$repeaters = $meta_array['繰り返しフィールド名'];
$repeater_array = array();
```
のような感じで、配列 $meta_array と $repeater_array に現在のカスタムフィールドのデータを保存する。
繰り返しフィールド1件が、CSV の1行にかかれているようなので、1件分を保存するために空の配列を用意。
$meta を処理するループ内で、各項目を処理する際に 同じキー名の $meta_array や repeater_array の内容と比べて、変更があるなら、内容を追加や変更する。(詳細が不明なのでこの部分が書けません)
繰り返しフィールドの部分は、
```
// 繰り返しフィールド用のデータを配列に入れていく処理
} elseif ($key == 'name') {
$repeater_array['name'] = $value;
} elseif ($key == 'link') {
$repeater_array['link'] = $value;
// ACF以外のメタデータはそのまま通す
} else {
```
のような感じで、 $repeater_array に 1件分の繰り返しフィールドデータを作成して、 ループで1件(CSV1行)分の処理が終わったら、
```
$repeaters[] = $repeater_array;
```
のように既存データの繰り返しフィールド配列の最後に追加して、
```
$meta_array['繰り返しフィールド名'] = $repeaters;
```
のように $repeaters の変更内容を $meta_array['繰り返しフィールド名'] に上書き。
最後に 作成したカスタムフィールドの配列を ` return $meta_array; ` で変更した内容を返す。
という感じでしょうか。
書いてみたら、$repeaters は、なくても処理できなくはないのか...
2019/04/24 17:06
やはり上書きになってしまいました。
かつ、nameなどは
「["a:1:{i:0;s:243:\"a:1:{i:0;s:224:\"a:1:{i:0;s:205:\"a:1:{i:0;s:186:\"a:1:{i:0;s:167:\"a:1:{i:0;s:148:\"a:1:{i:0;s:129:\"a:1:{i:0;s:110:\"a:1:{i:0;s:92:\"a:1:{i:0;s:74:\"a:1:{i:0;s:56:\"4\u30d1\u30c1 CR\u30d5\u30a3\u30fc\u30d0\u30fc\u30de\u30af\u30ed\u30b9\u30d5\u30ed\u30f3\u30c6\u30a3\u30a23\";}\";}\";}\";}\";}\";}\";}\";}\";}\";}\";}"]」
のような形になりました。
```
<?php
/* Plugin Name: custom_field_importer */
function rsci_meta_filter( $meta, $post, $is_update ) {
echo '<pre>';
print_r($meta);
echo '</pre>';
$meta_array = get_post_meta('31');
$repeaters = $meta_array['member'];
$repeater_array = array();
$i = 0;
foreach ($meta as $key => $value) {
if ($key == 'name') {
$repeater_array['name'] = $value;
} elseif ($key == 'link') {
$repeater_array['link'] = $value;
}
}
$repeaters[] = $repeater_array;
$meta_array['member'] = $repeaters;
echo '<pre>';
print_r($meta_array);
echo '</pre>';
return $meta_array;
}
add_filter( 'really_simple_csv_importer_save_meta', 'rsci_meta_filter', 10, 3 );
```
繰り返しフィールド自体は
固定ページ「グループ名」の中へ設置しています。
繰り返しフィールド名[member]のサブフィィールドに名前[name] と サイト[link]がある感じです。
2019/04/24 19:08
ACF の繰り返しフィールドのデータの構造を調べないと難しそうです。
2019/04/25 11:34
2019/04/25 12:25 編集
このような構造だと 今までに提示した方法だと全然だめですね。
ACF のドキュメントを読んでみるとリピーターフィールドの行を追加する関数はあるので、単純に追加でいいのであれば、HOOK の中で、直接 add_row() ( https://www.advancedcustomfields.com/resources/add_row/ ) の Examples のように、リピーターフィールドの配列を作って、 add_row() を呼び出すほうが簡単かもしれません。
思いつきなので、ちょっと 環境を構築して、試してから回答を修正したいと思います。
2019/04/25 12:48
2019/04/26 15:40
ありがとうございます。ちょっとテストしてみます。
取り急ぎお礼までに。