質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

1回答

2687閲覧

Really Simple CSV ImporterでACFの繰り返しフィールドへ追加していきたい

d_jomko

総合スコア14

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2019/04/24 03:26

前提・実現したいこと

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/ ) ) ) "" の処理が完了しました。

書いたコード

php

1/* Plugin Name: custom_field_importer */ 2function rsci_meta_filter( $meta, $post, $is_update ) { 3 echo '<pre>'; 4 print_r($meta); 5 echo '</pre>'; 6 7 $meta_array = array(); 8 9 $repeater_array = array(); 10 11 $i = 0; 12 13 14 foreach ($meta as $key => $value) { 15 // カスタムフィールド名が "textfield" だった時 16 if ($key == 'textfield') { 17 // ACF用のフィールドキーに変換 18 $meta_array['field_52528d5b8ad30'] = $value; 19 20 21 22 // カスタムフィールド名が "select" だった時 23 } elseif ($key == 'select') { 24 // カンマで分割して配列として登録 25 $meta_array['field_52528dc88ad31'] = preg_split("/,+/", $value); 26 27 28 29 // 繰り返しフィールド用のデータを配列に入れていく処理 30 } elseif ($key == 'name') { 31 $repeater_array[$i]['name'] = $value; 32 33 } elseif ($key == 'link') { 34 $repeater_array[$i]['link'] = $value; 35 36 $i++; 37 38 // ACF以外のメタデータはそのまま通す 39 } else { 40 $meta_array[$key] = $value; 41 } 42 43 } 44 45 46 47// 繰り返しフィールドの配列を戻す 48 $meta_array['field_5cb40c0a50e82'] = $repeater_array; 49 echo '<pre>'; 50 print_r($meta_array); 51 echo '</pre>'; 52 return $meta_array; 53 54 55 56} 57 58 59add_filter( 'really_simple_csv_importer_save_meta', 'rsci_meta_filter', 10, 3 );

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

Really Simple CSV Importer のデフォルトの動作は、同じ投稿IDのデータは、1 行にまとまってる前提なので、同じ投稿 ID のデータが複数行ある場合は、最後のデータで上書きされます。

同じ投稿IDのデータが、1ファイルに複数入っている構造のCSVファイルをインポートする場合は、保存済みのデータを読み込んで加工する等の工夫が必要です。

たとえば...

同じ投稿IDに追加されるデータが、ファイルに複数行含まれるのであれば、以下のような処理をする必要があります。

  1. $post に投稿オプジェクトが渡されてくるので、$post->ID を参照して、現在投稿IDのカスタムフィールドデータを読み込む。
  2. 読み込んだカスタムフィールドデータを元にして、現在のデータを追加・置換する。
  3. 更新したデータを返す。

という処理を行う必要があります。


(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 );

投稿2019/04/24 04:32

編集2019/04/25 03:47
CHERRY

総合スコア25171

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

d_jomko

2019/04/24 04:44

> 同じ投稿IDのデータは、1 行にまとまってる前提なので、同じ投稿 ID のデータが複数行ある場合は、最後のデータで上書きされます。 → $i++;しているのに配列の番号が変わっていないので、おかしいなと思っていたのですがそういうことだったんですね。 >1.$post に投稿オプジェクトが渡されてくるので、$post->ID を参照して、現在投稿IDのカスタムフィールドデータを読み込む。 >2.読み込んだカスタムフィールドデータを元にして、現在のデータを追加・置換する。 >3.更新したデータを返す。 こちらどこでどういうコード加えればいいでしょうか。 お手数ですがご教授いただけるとありがたいです。
CHERRY

2019/04/24 05:28 編集

CSVファイルの1行毎に HOOK が呼び出されて処理されるので、1回に処理されるデータは1行分です。 $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 は、なくても処理できなくはないのか...
d_jomko

2019/04/24 08: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]がある感じです。
CHERRY

2019/04/24 10:08

あ、シリアライズされているのでアンシリアライズも必要か。 ACF の繰り返しフィールドのデータの構造を調べないと難しそうです。
d_jomko

2019/04/25 02:34

別の方法考えてみます。ありがとうございました。
CHERRY

2019/04/25 03:25 編集

ACF のリピーターフィールドをデータ構造を確認してみると number_0_name や number_5_name のような構造でデータをもっていますね。 このような構造だと 今までに提示した方法だと全然だめですね。 ACF のドキュメントを読んでみるとリピーターフィールドの行を追加する関数はあるので、単純に追加でいいのであれば、HOOK の中で、直接 add_row() ( https://www.advancedcustomfields.com/resources/add_row/ ) の Examples のように、リピーターフィールドの配列を作って、 add_row() を呼び出すほうが簡単かもしれません。 思いつきなので、ちょっと 環境を構築して、試してから回答を修正したいと思います。
CHERRY

2019/04/25 03:48

未テストですが思いついたコードを回答欄に記載しておきました。
d_jomko

2019/04/26 06:40

ご返信遅くなりました。 ありがとうございます。ちょっとテストしてみます。 取り急ぎお礼までに。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問