WordPress側は、イーティーネットさんの「ネットショップ管理プラグイン」で構築されています。楽天市場への出店にあたって、商品名や価格などの商品情報はCSV形式でエクスポートして一括登録することができますが、商品画像について楽天側の仕様上の制約があり、単純にアップロードして終了、というわけにはいきませんでした。
楽天側の画像の制約
楽天市場の商品画像(動画)を管理する「R-Cabinet」というサービスには下記のような制約があります。プランによって許容値は変わるようですが、今回は「エンパワーメントプラン」という下位プラン。
- 最大容量:500MB
- 1フォルダあたりの最大点数:500点
- 新規に作成できるフォルダ数:50個
- ファイル名の最大文字数:20文字(拡張子のぞく)
- ファイル名はすべて半角小文字(例:IMG…ではなくimg…)
- 画像サイズ:縦横最大1200ピクセル
WordPressに制約なく蓄積された画像たち
一方、移行元のWordPressのECサイトの商品画像については下記のとおり。
- 掲載中の商品数:約1800商品
- 掲載中の全商品の全画像は約18GB(サイズバリエーションも含む)
- 1商品あたりの最大画像点数:13点
- アップロードされた日時に基づき、年月ごとのフォルダに格納
- 1フォルダあたりの最大点数は9000点ほど
- ファイル名の文字数は長短さまざま
- ファイル名は大文字/小文字など混在
フォルダ分割、ファイル名短縮など調整が必要
移行元のWordPressサイトから、画像フォルダを丸ごとダウンロードして「ガバッ」と一括アップロードできたら楽だったのですが、上記のような制約があるため、そして今後の運用のことも踏まえ、次のような下準備をすることにしました。
- 現在販売中で在庫がある商品(約270点)のみ楽天側に登録
- 縦または横1000ピクセルの画像のみ抽出
- ファイル名が「0」から始まる画像は年月ごとのフォルダに格納(例:2016/04/)
- ファイル名が「0」以外から始まる画像は「年月_2」というフォルダに格納(例:2016/04_2/)
- ファイル名は20文字に収まるようトリミング
- ファイル名はすべて半角小文字になるよう修正
以上の調整をすることでR-Cabinetの上記制約をクリアできるはず。
フォルダを分割するのは、販売中の商品の画像に絞ってもなおフォルダあたり900点ほどある月もあり「1フォルダあたり500点」という制約にひっかかってしまうため。
画像ファイルの抽出
方針が決まったら必要な商品画像の抽出をするわけですが、膨大な画像数から手作業で選別するのはさすがに現実的ではないのでプログラムでどうにかしたい。。
…ということで、結果、下記のようなコードをCSVエクスポート機能の中に割り込むかたちで書きました。2つのことを行っています。
- 楽天用の画像フォルダ構成をサーバ上に用意して商品画像ファイルをそこへ複製
- CSVファイルに画像URLを楽天形式で出力するための準備
// …前段で、商品情報が取得されループ展開中 // $data['post_id'] に記事IDが格納ずみ $images = ''; // 商品に添付された画像をすべて取得 $attachments = get_posts( 'post_type=attachment&numberposts=-1&orderby=menu_order&order=ASC&post_parent=' . $data['post_id'] ); if ( $attachments ) { $img_src = array(); foreach ( $attachments as $attachment ) { // 1000pxサイズのファイルを抽出 $image[0]に画像URLが格納 $image = wp_get_attachment_image_src( $attachment->ID, array( 1000, 1000 ) ); $filename = basename( $image[0] ); // ファイル名のみ抽出 $filename = strtolower( $filename ); // ファイル名を小文字に $filename_length = strlen( $filename ); // ファイル名の文字数取得 $filename_raw = substr( $filename, 0, -3 ); // 拡張子を除去した文字列 $filename_raw_length = strlen( $filename_raw ); // 拡張子を除去した文字列の文字数 // ファイル名が20文字を超えるものはトリミング if ( 20 < $filename_raw_length ) { $filename = substr( $filename_raw, 0, 20 ) . '.jpg'; } // 画像ファイルが保存されている年月フォルダをパスとして抽出 // 例)http://example.jp/wp-content/uploads/…この間…/example.jpg $img_path = substr( $image[0], 37 ); $img_path = substr( $img_path, 0, -$filename_length ); // ファイル名が「0」以外から始まるものは、格納先フォルダを「年月_2」に if ( 0 !== strpos( $filename, '0' ) ) { $img_path = substr( $img_path, 0, -1 ) . '_2/'; } // 指定の格納先フォルダがなければ作成(今回は実行中のプラグインフォルダ内に作成) if ( !file_exists( dirname( __FILE__ ) . '/rakuten/' . $img_path ) ) { mkdir( dirname( __FILE__ ) . '/rakuten/' . $img_path, 0777, true ); } // 抽出された画像を、作成されたフォルダ内に複製 copy( $image[0], dirname( __FILE__ ) . '/rakuten/' . $img_path . $filename ); // CSV出力用 楽天R-Cabinetの形式に沿ったURLを生成 $img_src[] = 'http://image.rakuten.co.jp/example/cabinet/04716618/' . $img_path . $filename; } // CSV出力用 1商品あたり複数画像がある場合は半角スペースでつなぐ $images = implode( ' ', $img_src ); } // CSV出力用 生成された楽天R-Cabinet上の画像URLを配列に格納 $data['product_image'] = !empty( $images ) ? $images : ''; // 以後、CSVファイル生成プロセスが続く…
ファイル名が「0」から始まるかどうかでフォルダを分けたのは、最初はローカルにダウンロード済みの画像ファイルを手作業で分けるつもりで、目視でわかりやすいから。でもプログラム上でフォルダも分けることにしたし、今思えば画像の投稿日時を元に月の前半後半で分けたほうが感覚的にも自然だったかもしれません。
get_postsで抽出した商品画像はファイル名の文字数など加工したのちmkdir関数でフォルダ(ディレクトリ)を構成し、そのフォルダ内にcopy関数で複製(一度限りのことなので、実行中のプラグインフォルダ内に生成…)。あとはFTP等で丸ごと落としてR-Cabinetに同じフォルダ構成を用意してファイルをアップロードすればOKです。
楽天R-Cabinetへアップロード
R-Cabinetへのアップロード作業は、楽天公式の画像管理用デスクトップアプリ「Ribrary」を使います(楽天RMSにログインしないとダウンロードできません)。
画像データは「R-Cabinet」に、CSVファイルは「一括登録サーバ」にドラッグ&ドロップで簡単にアップロードできるので、客側で日常的にアップロード作業してもらうにも便利です。
他にCodaなどのFTPクライアントも使用できますが、アップロードのみ可能。アップした画像やフォルダを触ることはできません(見えない)。サブフォルダに分ける必要がある場合はあらかじめローカルでフォルダを構成した上で丸ごとアップロードすると、既存のフォルダにマージされるようです。
さて、画像のアップロードができたら商品情報をCSV形式で一括登録します。それは次回の記事にて。