Really Simple CSV Importer を使って Advanced Custom Fields で作ったフィールドを登録する

Pocket

システム部の鈴木です。
WordPressで多くの投稿を一気にインポートしたい場合、皆様はどうされてますでしょうか?

そんなときに便利なのが、CSVファイルから一気に投稿をインポートできる
Really Simple CSV Importer

ですが、今回は Advanced Custom Fields を使って作成した画像などのメディアアップロードのカスタムフィールドに登録したい場合にどうするか、ちょっと調べてみました

今回やりたい事は以下の通りです

  • 画像ファイルは予めサーバのuploadディレクトリに配置しておく
  • CSVには画像のファイル名を記載するセルを作っておく
  • 一気に流し込む

まず色々調べましたが、Really Simple CSV Importerの標準の機能では
アイキャッチ画像の登録には対応しているものの、
それ以外のメディアオブジェクトを登録するような方法は無いようです。

しかしここに書かれているようにReally Simple CSV Importerにはいくつかのフックが備わっています

みたところ、これが使えそうです。

really_simple_csv_importer_save_meta

投稿を保存する前に投稿のメタデータ(カスタムフィールドのデータ)を操作することが出来るフックです。
予め投稿が保存されていれば、あとは画像データを wp_insert_attachment() で保存しておいて
その投稿IDをpost_metaに格納すれば、投稿に紐づくメディアオブジェクトが登録できるのでは・・・
と画策しましたが、これは上手くいきませんでした。

その理由は、プラグイン本体の308行目あたりからをみると一目瞭然です。

<br />
				/**<br />
				 * Filter post data.<br />
				 *<br />
				 * @param array $post (required)<br />
				 * @param bool $is_update<br />
				 */<br />
				$post = apply_filters( &#8216;really_simple_csv_importer_save_post&#8217;, $post, $is_update );<br />
				/**<br />
				 * Filter meta data.<br />
				 *<br />
				 * @param array $meta (required)<br />
				 * @param array $post<br />
				 * @param bool $is_update<br />
				 */<br />
				$meta = apply_filters( &#8216;really_simple_csv_importer_save_meta&#8217;, $meta, $post, $is_update);<br />
				/**<br />
				 * Filter taxonomy data.<br />
				 *<br />
				 * @param array $tax (required)<br />
				 * @param array $post<br />
				 * @param bool $is_update<br />
				 */<br />
				$tax = apply_filters( &#8216;really_simple_csv_importer_save_tax&#8217;, $tax, $post, $is_update );</p>
<p>				/**<br />
				 * Option for dry run<br />
				 *<br />
				 * @param bool false<br />
				 */<br />
				$dry_run = apply_filters( &#8216;really_simple_csv_importer_dry_run&#8217;, false );</p>
<p>				if (!$error-&gt;get_error_codes() &amp;&amp; $dry_run == false) {</p>
<p>					/**<br />
					 * Get Alternative Importer Class name.<br />
					 *<br />
					 * @param string Class name to override Importer class. Default to null (do not override).<br />
					 */<br />
					$class = apply_filters( &#8216;really_simple_csv_importer_class&#8217;, null );</p>
<p>					// save post data<br />
					if ($class &amp;&amp; class_exists($class,false)) {<br />
						$importer = new $class;<br />
						$result = $importer-&gt;save_post($post,$meta,$tax,$post_thumbnail,$is_update);<br />
					} else {<br />
						$result = $this-&gt;save_post($post,$meta,$tax,$post_thumbnail,$is_update);<br />
					}<br />

apply_filters() でフックが登録されている後で save_post() されてますね
つまり、really_simple_csv_importer_save_meta フックでデータを操作するタイミングでは
まだ投稿は保存されていません

そしてまだ投稿IDが無いので wp_insert_attachment() は使えません。

 

フックを追加する

そこで、先ほどのコードの直後、つまり投稿が保存された後に以下のようなフックを追加する事にしました

$meta = apply_filters(‘really_simple_csv_importer_save_meta_with_postid’, $meta, $post, $is_update, $result);

ここでフックを追加してあげれば投稿IDが確定しているので wp_insert_attachment() も使えます。
functions.php ではこのフックを使ってこんな感じにしてみました。

 

<br />
function add_chokubai_meta($meta, $post, $is_update, $postId)<br />
{<br />
    if (isset($meta[&#8216;img_file&#8217;]) &amp;&amp; ! empty($meta[&#8216;img_file&#8217;])) {<br />
        $upload = wp_upload_dir();<br />
        $file = $upload[&#8216;path&#8217;] . &#8216;/&#8217; . $meta[&#8216;img_file&#8217;];<br />
        if (file_exists($file) ) {<br />
            $mime_type = &#8221;;<br />
            $wp_filetype = wp_check_filetype(basename($meta[&#8216;img_file&#8217;]), null);</p>
<p>            if (isset($wp_filetype[&#8216;type&#8217;]) &amp;&amp; $wp_filetype[&#8216;type&#8217;]) $mime_type = $wp_filetype[&#8216;type&#8217;];<br />
            unset($wp_filetype);<br />
            $post = get_post($postId);</p>
<p>            $title = isset($title) ? $title : preg_replace(&#8216;/\.[^.]+$/&#8217;, &#8221;, basename($meta[&#8216;img_file&#8217;]));<br />
            $content = isset($content) ? $content : $title;<br />
            $excerpt = isset($excerpt) ? $excerpt : $content;<br />
            $attachment = array(<br />
                &#8216;post_mime_type&#8217; =&gt; $mime_type ,<br />
                &#8216;post_parent&#8217;    =&gt; $postId ,<br />
                &#8216;post_author&#8217;    =&gt; $post-&gt;post_author ,<br />
                &#8216;post_title&#8217;     =&gt; $title,<br />
                &#8216;post_content&#8217;   =&gt; $content ,<br />
                &#8216;post_excerpt&#8217;   =&gt; $excerpt ,<br />
                &#8216;post_status&#8217;    =&gt; &#8216;inherit&#8217;,<br />
                &#8216;menu_order&#8217;     =&gt; 0,<br />
            );</p>
<p>            if (isset($post-&gt;post_name) &amp;&amp; ! empty($post-&gt;post_name)) $attachment[&#8216;post_name&#8217;] = $post-&gt;post_name;<br />
            $attachment_id = wp_insert_attachment($attachment, $file, $postId);<br />
            unset($attachment);</p>
<p>            if (! is_wp_error($attachment_id)) {<br />
                add_post_meta($postId, &#8216;chokubai_img&#8217;, $attachment_id);<br />
            }<br />
        }<br />
    }<br />
}</p>
<p>add_filter(&#8216;really_simple_csv_importer_save_meta_with_postid&#8217;, &#8216;add_chokubai_meta&#8217;, 10, 4);<br />

ちょっと雑ですが、とりあえず画像のオブジェクトを作って投稿への紐付ができました
※ちなみに$meta[‘img_file’] のキーは、保存するカスタムフィールド名を指定します