こんにちわ。kimonoです
本日は、ネットショップ通販サイト構築のオープンソース「Zen Cart」のバグが発見されましたので、それらを修正させていただきましたので、報告させていただきます。
Zen Cart掲示板にて報告がありましたので、修正しました。
admin/includes/functions/functions_prices.php
1109行目辺り
$string = trim($string); $word_count = substr_count($string, ' '); return (($word_count+1) - $free);
↓
$string = trim($string); $word_count = mb_substr_count($string, ' '); return (($word_count+1) - $free);
1136行目辺り
if (TEXT_SPACES_FREE == '1') { $letters_count = strlen(str_replace(' ', '', $string)); } else { $letters_count = strlen($string); }
↓
if (TEXT_SPACES_FREE == '1') { $letters_count = mb_strlen(str_replace(' ', '', $string)); } else { $letters_count = mb_strlen($string); }
includes/functions/functions_prices.php
1154行目辺り
$string = trim($string); $word_count = substr_count($string, ' '); return (($word_count+1) - $free);
↓
$string = trim($string); $word_count = mb_substr_count($string, ' '); return (($word_count+1) - $free);
1181行目辺り
if (TEXT_SPACES_FREE == '1') { $letters_count = strlen(str_replace(' ', '', $string)); } else { $letters_count = strlen($string); }
↓
if (TEXT_SPACES_FREE == '1') { $letters_count = mb_strlen(str_replace(' ', '', $string)); } else { $letters_count = mb_strlen($string); }
●オプションを設定した商品をカートに入れ、同一product_idの商品でオプションを変えた商品をカートに入れた場合、在庫数以上に注文ができてしまう件
もう一つ。こちらは掲示板に私の方で記載させていただきましたが、上記の図のように、通常の状態のZen Cartであれば、商品単体での在庫管理のため、在庫数が1000と登録していた場合は、1001以上の個数をカートに入れると二番目の画像のように在庫切れになり、購入ができなくなります。
しかし、Zen Cartの機能として、オプションがあり、同一商品で、別々のオプションを選択し、一度の注文で同じ商品のオプション違いを購入しようとした場合は、一つのカート上に同じ商品が並んで表示されます。オプションが違う商品のため。
ただ、この場合、それぞれで在庫確認を行っているため、図のように、片方が900個、片方が500個とカートに入れた場合は、どちらもそれぞれが在庫数をオーバーしていないため、一緒に購入できてしまうといったバグが発見されました。
こちらは、本家の1.5.1の最新版でも修正されていないバグで、このような購入ができるにも関わらず、同時に購入した場合の在庫チェックの処理がなかったため、購入後-400個などの在庫になってしまう現象が発生しておりました。
また、同様に同一商品を同時購入した場合、注文完了後のページに表示される「下記商品についてお知らせメールを希望する」に、同一IDのチェックボックスが複数表示され、チェックを入れて更新しようとすると、エラーになってしまうというバグも発見されました。
こちらも1.5.1の日本語版の最新版では修正済みですが、運営しているサイトでも下記のように修正することで、対応が可能になります。
includes/modules/pages/shopping_cart/header_php.php
の124行目辺り
if (STOCK_CHECK == 'true') { $flagStockCheck = zen_check_stock($products[$i]['id'], $products[$i]['quantity']); if ($flagStockCheck == true) { $flagAnyOutOfStock = true; } }
↓
if (STOCK_CHECK == 'true') { $product_in_cart[zen_get_prid($products[$i]['id'])] += $products[$i]['quantity']; $flagStockCheck = zen_check_stock($products[$i]['id'], $product_in_cart[zen_get_prid($products[$i]['id'])]); if ($flagStockCheck == true) { $flagAnyOutOfStock = true; } }
includes/modules/pages/checkout_confirmation/header_php.php
の107行目辺り
for ($i=0, $n=sizeof($order->products); $i<$n; $i++) { if ($stock_check[$i] = zen_check_stock($order->products[$i]['id'], $order->products[$i]['qty'])) { $flagAnyOutOfStock = true; } }
↓
for ($i=0, $n=sizeof($order->products); $i<$n; $i++) { $product_in_order[zen_get_prid($order->products[$i]['id'])] += $order->products[$i]['qty']; if ($stock_check[$i] = zen_check_stock($order->products[$i]['id'], $product_in_order[zen_get_prid($order->products[$i]['id'])])) { $flagAnyOutOfStock = true; } }
includes/modules/pages/checkout_success/header_php.php
の83行目辺り
while (!$products->EOF) { $notificationsArray[] = array('counter'=>$counter, 'products_id'=>$products->fields['products_id'], 'products_name'=>$products->fields['products_name']); $counter++; $products->MoveNext(); }
↓
while (!$products->EOF) { if(!isset($notify_product[$products->fields['products_id']])){ $notificationsArray[] = array('counter'=>$counter, 'products_id'=>$products->fields['products_id'], 'products_name'=>$products->fields['products_name']); } $notify_product[$products->fields['products_id']]=true; $counter++; $products->MoveNext(); }