[PHP] EC-CUBEで【※ 既に同じ内容の登録が存在します。】を解決する方法!

※解決方法だけ知りたい方は、下のソースコードのとこだけみてください。

現在、EC-CUBEを使ってショッピングサイトを構築しております。

で、普通に売買するだけのショッピングサイトくらいなら、自分で作ってるし、ノウハウもあるんだけどポイント機能とか、複雑な支払方法、発送方法なんかに対応させようと思ったら、事前に調べることがたくさんあって、とてもじゃないけど、時間的にも厳しいので、オープンソースのものを探していました。

PHPで動く、オープンソースのショッピングサイトというと「osCommerce」とか「Zen Cart」が有名ですよね。
私も最初、この2つを考えていました。

だけど、事前調査の結果、いろいろと不安が出てきて、どうにかならないものかなぁとまた探し始めました。

そこで見つけたのが、EC-CUBEです。

EC-CUBEは、日本製。
EC-CUBEの開発も活発に動いているようだ。
EC-CUBEコミュニティも充実。
EC-CUBEの構築事例やマニュアルもたくさんある。
EC-CUBEのデモサイトを見るとやりたいことが適いそうだ。

だから、EC-CUBEに決めた。

なのにさ。
問題って後からいっぱいでてくるんだもん。

まず、気に入らなかったのがSmarty。
Smartyが騒がれている時も私は見向きもしなかった。
どうして、PHPなのに、オレオレ言語をまた覚えなきゃいけないの?

それから、ディレクトリ構造。
あっちこっちにファイルを作りすぎ。
2,800ファイルも必要ない。
たった6行程度書くためにファイルを分離する必要があるの?

データベースのテーブル数の多さはなに?
全く同じ構造のテーブルが、いまざっと数えただけでも40個ある。
で、その中に入っている行数と言えば数行だけ。
えっ?フィールド数は3つだよ。

PHPの閉じタグもさ。
?>[改行コード] [改行コード] ってなに?

あと、セキュリティ的な事情も絡んでくるから言えないけど、ちょっと不安があるよね。
1箇所でもそういうところを見つけたら、全体を見なくても不安になってくるよ。

それからそれから、<br> と <br/> が混在してる。
いや、それはいいよ。直すの忘れてたんだよね。
でもさ、</br> ってなにさ?

まぁそうはいっても、EC-CUBEって色んなところで使われているんだよね。
EC-CUBEのサイトに書いてあるものだけでも、全国に190もの会社が、【インテグレートパートナー】になって、EC-CUBEを使ったECサイトを制作して売っているんだよね。

色んなweb制作会社のサイトを見ていると、

EC-CUBEを使ったECサイトでなんたらかんたらー
弊社は、あのEC-CUBEをカスタマイズ制作できますよー

って謳っている会社をよく見かけるんだ。

だからさ、だからなのさ、
どうしてなの?
違うんじゃないの?

私は、EC-CUBEがキライだからこんなことを書いているんじゃない。
誰もが安心して、利用できるECに特化したオープンソースに育って欲しいから書いている。

あんなにたくさんのEC-CUBEを利用する制作会社がいるのに、どうしてなの?
純粋にそう思う。

それで、本題。

EC-CUBEで【※ 既に同じ内容の登録が存在します。】を解決する方法!

まず、これがどういう問題で、どうやったら再現するのかを書く。

EC-CUBEで【※ 既に同じ内容の登録が存在します。】を再現する方法!

1.管理画面の「商品管理」→「カテゴリ管理」を開く
2.手動でいくつかカテゴリを作る(階層も作って)
3.CSV形式でダウンロードする。

4.2で作成したカテゴリを全部削除して、1つも登録されてない状態にする。

5.管理画面の「商品管理」→「カテゴリ登録CSV」を開く
6.3で保存したCSVを選択して、登録ボタンを押す。
7.【※ 既に同じ内容の登録が存在します。】となりインポートできない

まずここで問題がある。
手順4で、カテゴリを空っぽにしなければならない。
これは、Googleで検索しているときに、どこかのサイトに書いてあっただけで私は検証していない。

ただ、インポートする場面と言えば、通常、開発環境から本番環境へ移行するときだろう。
または、サーバ負荷のため、高性能なサーバに切り替えるときにも使うだろう。

だから、空っぽの時にでも、正常にインポートできなければそれは問題だ。

EC-CUBEで【※ 既に同じ内容の登録が存在します。】を解決する方法!

いよいよ、いよいよ、お待ちかねの解決する方法です。

ちなみに、eccube-2.4.0です。

原因となるファイルは、1つです。

/data/class/pages/admin/products/LC_Page_Admin_Products_UploadCSVCategory.php

こいつです。こいつ。
こいつが元凶ですので、エディタで開いてください。

元の行数がちょっと曖昧ですが・・・
268行目あたりの下記の場所を見つけてください。

$sqlval['update_date'] = $time;
$sqlval['creator_id'] = $_SESSION['member_id'];

// 更新
if ($update) {
echo "UPDATE ";
$where = "category_id = ?";

↑これを↓次のように、書き加えてください。

$sqlval['update_date'] = $time;
$sqlval['creator_id'] = $_SESSION['member_id'];

// 既に存在するか確認
// ここで $updateをセットし直すため、243,246行目は不要だけど面倒だからそのまま
$update = (0 < $objQuery->count('dtb_category', 'category_id = ' . $sqlval['category_id']));

// 更新
if ($update) {
echo "UPDATE ";
$where = "category_id = ?";

データベースに、同じIDが登録されてたらUPDATE、無ければINSERTとします。
いちいち、データベースに存在確認をするように変更したわけです。

もう一箇所直すところがあります。
行番号は、↑の修正をした後の行番号です。
次の場所を探してください。

$where = "parent_category_id = ? AND category_name = ?";
$arrCat = $objQuery->select("category_id, category_name", "dtb_category", $where, array($parent_category_id, $arrRet['category_name']));
if (empty($arrCat)) {
$arrCat = array(array("category_id" => "", "category_name" => ""));
}
// 編集中のレコード以外に同じ名称が存在する場合
if ($arrCat[0]['category_id'] != $arrRet['category_id'] && $arrCat[0]['category_name'] == $_POST['category_name']) {
$objErr->arrErr['category_name'] = "※ 既に同じ内容の登録が存在します。<br>";
}

↑これを↓次のように、書き加えてください。

$where = "parent_category_id = ? AND category_name = ?";
$arrCat = $objQuery->select("category_id, category_name", "dtb_category", $where, array($parent_category_id, $arrRet['category_name']));
if (empty($arrCat)) {
$arrCat = array(array("category_id" => "", "category_name" => ""));
}
// 編集中のレコード以外に同じ名称が存在する場合
//if ($arrCat[0]['category_id'] != $arrRet['category_id'] && $arrCat[0]['category_name'] == $_POST['category_name']) {
// $objErr->arrErr['category_name'] = "※ 既に同じ内容の登録が存在します。<br>";
//}
$arr_category_name = $arrRet['category_name'];
if (strlen($arr_category_name) == 0){
$objErr->arrErr['category_name'] = "※ カテゴリ名を入力してください。<br />";
// category_idは必須じゃなさそうなので空文字チェックは不要?
} else if ($arrCat[0]['category_id'] != $arrRet['category_id']){
if ($arrCat[0]['category_name'] == $arr_category_name) {
$objErr->arrErr['category_name'] = "※ 既に同じ内容の登録が存在します。<br />";
}
}

以上です。
はい。たったこれだけです。
これだけなんです!!

EC-CUBEコミュニティを眺めると、「2008-7-3 11:39」の時点では既にこの問題が発生していることが分かります。
Googleさんに尋ねてもたくさんでてきます。

なぜなの?
すぐ直ったよ。

もう一度しつこく書くけど、私は、EC-CUBEがキライだから言っているんじゃないんです。
EC-CUBEに期待しているから、こうやって書いているんです。

自分だけ修正を加えて、知らんフリってことも私は選択できます。
でも、EC-CUBEがみんなにとって、簡単で安心でき柔軟性があり拡張可能なECサイト構築オープンソースに育って欲しいから書いているんです。

よろしくお願いします。

あっ、ちなみに、↑のコードは【カテゴリのCSVインポートなので】ということと、【ノークレームノーリターン】でお願いします。まだEC-CUBE全体を把握しきれているわけじゃないので、どこに影響があるかは分かりません。ただ、私の勘は、「別に影響ないだろう」と申しております。