[1.3.2] Baskets loosing Options and Values + Fix
Posted: Mon Aug 17, 2009 8:37 am
Bug
/admin/view/template/catalog/product_form.tpl
About Line 248
Find
Replace with
About Line 276
Find
Replace with
/admin/model/catalog/product.php
Find the Function editProduct and replace the whole function with the one below.
Only a small part of the function has changed but it was easier to post the whole thing rather than specify each line.
Hope this helps people out.
Best Wishes
Alex
- Thousands of your customers are loosing the product options and product option values that they have in their shopping cart, so when they return to the store and their baskets are reloaded, the products are still there, but all options have been lost.
- Customers with accounts that have products in their cart. (the customer doesn't need to be logged on as carts are saved when the customer logs out)( but they can be logged on and the issue still occurrs)
- Guests who have products in their cart who are online and shopping at the time.
- YOU the store owner as I believe that continuing through checkout will produce no errors about the lost Options and therefore you will either send out the incorrect product because of lack of options or you wont be able to send out the product if you realise the options are missing and you wont know what exactly your customer ordered.
- 1: Log on as a customer to your store.
- 2: Add a product, with product options to your cart.
- 3: Log Out (Your cart is then saved in your account, if you log back in, your cart should reload and the options are still there. but in this scenario you need to be logged out to continue the next steps, as I beleive knowing that customers saved carts are being destroyed is an important point)
- 4: Log into your Admin section.
- 5: Go to Catalog > Products and click edit on the product that you have just added to your cart.
- 6: Click Save (nothing needs to be changed, but things can be changed it makes no difference)
- All customers and guests online at the time of clicking "save" have lost all product options for this product if it was in their basket at the time of clicking. Logging in as the customer again you will see that the product you previously added to the cart is reloaded but the options have been lost.
- When Save is clicked on the edit product all saved options and option values for this product are deleted and then recreated according to the submitted form. Therefore the product option id and product option value id numbers change on every click of Save, so the product option id and product option value id numbers that are saved in a customers cart dont correspond to the new id numbers.
- I think i have it sorted with very few changes. I have tested it in 1.3.2 only and with only one language (English) so would be interested to know if it works with multi-language. It should do though.
- I added two lines in the tpl file and rewrote maybe 20 lines in the editProduct function, and thats it.
/admin/view/template/catalog/product_form.tpl
About Line 248
Find
Code: Select all
<td valign="top"><?php echo $entry_sort_order; ?><br />
<input type="text" name="product_option[<?php echo $option_row; ?>][sort_order]" value="<?php echo $product_option['sort_order']; ?>" size="5" /></td>
<td align="right"><a onclick="removeOption('<?php echo $option_row; ?>');" class="remove"><?php echo $button_remove; ?></a></td>
Code: Select all
<td valign="top"><?php echo $entry_sort_order; ?><br />
<input type="text" name="product_option[<?php echo $option_row; ?>][sort_order]" value="<?php echo $product_option['sort_order']; ?>" size="5" />
<input type="hidden" name="product_option[<?php echo $option_row; ?>][product_option_id]" value="<?php echo $product_option['product_option_id']; ?>" /></td>
<td align="right"><a onclick="removeOption('<?php echo $option_row; ?>');" class="remove"><?php echo $button_remove; ?></a></td>
Find
Code: Select all
<td><?php echo $entry_sort_order; ?><br />
<input type="text" name="product_option[<?php echo $option_row; ?>][product_option_value][<?php echo $option_value_row; ?>][sort_order]" value="<?php echo $product_option_value['sort_order']; ?>" size="5" /></td>
<td align="right"><a onclick="removeOptionValue('<?php echo $option_value_row; ?>');" class="remove"><?php echo $button_remove; ?></a></td>
Code: Select all
<td><?php echo $entry_sort_order; ?><br />
<input type="text" name="product_option[<?php echo $option_row; ?>][product_option_value][<?php echo $option_value_row; ?>][sort_order]" value="<?php echo $product_option_value['sort_order']; ?>" size="5" />
<input type="hidden" name="product_option[<?php echo $option_row; ?>][product_option_value][<?php echo $option_value_row; ?>][product_option_value_id]" value="<?php echo $product_option_value['product_option_value_id']; ?>" /></td>
<td align="right"><a onclick="removeOptionValue('<?php echo $option_value_row; ?>');" class="remove"><?php echo $button_remove; ?></a></td>
/admin/model/catalog/product.php
Find the Function editProduct and replace the whole function with the one below.
Code: Select all
public function editProduct($product_id, $data) {
$dont_delete_product_option = array();
$dont_delete_product_option_value = array();
$this->db->query("UPDATE " . DB_PREFIX . "product SET model = '" . $this->db->escape($data['model']) . "', quantity = '" . (int)$data['quantity'] . "', stock_status_id = '" . (int)$data['stock_status_id'] . "', date_available = '" . $this->db->escape($data['date_available']) . "', manufacturer_id = '" . (int)$data['manufacturer_id'] . "', shipping = '" . (int)$data['shipping'] . "', price = '" . (float)$data['price'] . "', sort_order = '" . (int)$data['sort_order'] . "', weight = '" . (float)$data['weight'] . "', weight_class_id = '" . (int)$data['weight_class_id'] . "', length = '" . (float)$data['length'] . "', width = '" . (float)$data['width'] . "', height = '" . (float)$data['height'] . "', measurement_class_id = '" . (int)$data['measurement_class_id'] . "', status = '" . (int)$data['status'] . "', tax_class_id = '" . (int)$data['tax_class_id'] . "', date_modified = NOW() WHERE product_id = '" . (int)$product_id . "'");
if (isset($data['image'])) {
$this->db->query("UPDATE " . DB_PREFIX . "product SET image = '" . $this->db->escape($data['image']) . "' WHERE product_id = '" . (int)$product_id . "'");
}
$this->db->query("DELETE FROM " . DB_PREFIX . "product_description WHERE product_id = '" . (int)$product_id . "'");
foreach ($data['product_description'] as $language_id => $value) {
$this->db->query("INSERT INTO " . DB_PREFIX . "product_description SET product_id = '" . (int)$product_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "', meta_description = '" . $this->db->escape($value['meta_description']) . "', description = '" . $this->db->escape($value['description']) . "'");
}
if (isset($data['product_option'])) {
foreach ($data['product_option'] as $product_option) {
$product_option_id = '';
if(array_key_exists('product_option_id', $product_option)){
$this->db->query("UPDATE " . DB_PREFIX . "product_option SET sort_order = '" . (int)$product_option['sort_order'] . "' WHERE product_option_id = '" . (int)$product_option['product_option_id'] . "'");
$product_option_id = (int)$product_option['product_option_id'];
foreach ($product_option['language'] as $language_id => $language) {
$this->db->query("UPDATE " . DB_PREFIX . "product_option_description SET name = '" . $this->db->escape($language['name']) . "' WHERE product_option_id = '" . $product_option_id . "' AND language_id = '". (int)$language_id ."'");
}
}else{
$this->db->query("INSERT INTO " . DB_PREFIX . "product_option SET product_id = '" . (int)$product_id . "', sort_order = '" . (int)$product_option['sort_order'] . "'");
$product_option_id = $this->db->getLastId();
foreach ($product_option['language'] as $language_id => $language) {
$this->db->query("INSERT INTO " . DB_PREFIX . "product_option_description SET product_option_id = '" . (int)$product_option_id . "', language_id = '" . (int)$language_id . "', product_id = '" . (int)$product_id . "', name = '" . $this->db->escape($language['name']) . "'");
}
}
$dont_delete_product_option[] = $product_option_id;
if (isset($product_option['product_option_value'])) {
foreach ($product_option['product_option_value'] as $product_option_value) {
$product_option_value_id = '';
if(array_key_exists('product_option_value_id', $product_option_value)){
$this->db->query("UPDATE " . DB_PREFIX . "product_option_value SET price = '" . (float)$product_option_value['price'] . "', prefix = '" . $this->db->escape($product_option_value['prefix']) . "', sort_order = '" . (int)$product_option_value['sort_order'] . "' WHERE product_option_value_id = '" . (int)$product_option_value['product_option_value_id'] . "'");
$product_option_value_id = (int)$product_option_value['product_option_value_id'];
foreach ($product_option_value['language'] as $language_id => $language) {
$this->db->query("UPDATE " . DB_PREFIX . "product_option_value_description SET name = '" . $this->db->escape($language['name']) . "' WHERE product_option_value_id = '" . (int)$product_option_value_id . "' AND language_id = '" . (int)$language_id . "'");
}
}else{
$this->db->query("INSERT INTO " . DB_PREFIX . "product_option_value SET product_option_id = '" . (int)$product_option_id . "', product_id = '" . (int)$product_id . "', price = '" . (float)$product_option_value['price'] . "', prefix = '" . $this->db->escape($product_option_value['prefix']) . "', sort_order = '" . (int)$product_option_value['sort_order'] . "'");
$product_option_value_id = $this->db->getLastId();
foreach ($product_option_value['language'] as $language_id => $language) {
$this->db->query("INSERT INTO " . DB_PREFIX . "product_option_value_description SET product_option_value_id = '" . (int)$product_option_value_id . "', language_id = '" . (int)$language_id . "', product_id = '" . (int)$product_id . "', name = '" . $this->db->escape($language['name']) . "'");
}
}
$dont_delete_product_option_value[] = $product_option_value_id;
}
}
}
}
// Delete Product Option that were not submitted for update
$where_clause = array("WHERE product_id = '" . (int)$product_id . "'");
foreach($dont_delete_product_option as $value){
$where_clause[] .= "product_option_id != '". $value . "'";
}
$where_sql = implode(" AND ", $where_clause);
$this->db->query("DELETE FROM " . DB_PREFIX . "product_option ". $where_sql);
$this->db->query("DELETE FROM " . DB_PREFIX . "product_option_description ". $where_sql);
// Delete Product Option Values that were not submitted for update
$where_clause2 = array("WHERE product_id = '" . (int)$product_id . "'");
foreach($dont_delete_product_option_value as $value){
$where_clause2[] .= "product_option_value_id != '". $value . "'";
}
$where_sql2 = implode(" AND ", $where_clause2);
$this->db->query("DELETE FROM " . DB_PREFIX . "product_option_value ". $where_sql2);
$this->db->query("DELETE FROM " . DB_PREFIX . "product_option_value_description ". $where_sql2);
$this->db->query("DELETE FROM " . DB_PREFIX . "product_discount WHERE product_id = '" . (int)$product_id . "'");
if (isset($data['product_discount'])) {
foreach ($data['product_discount'] as $value) {
$this->db->query("INSERT INTO " . DB_PREFIX . "product_discount SET product_id = '" . (int)$product_id . "', customer_group_id = '" . (int)$value['customer_group_id'] . "', quantity = '" . (int)$value['quantity'] . "', priority = '" . (int)$value['priority'] . "', price = '" . (float)$value['price'] . "', date_start = '" . $this->db->escape($value['date_start']) . "', date_end = '" . $this->db->escape($value['date_end']) . "'");
}
}
$this->db->query("DELETE FROM " . DB_PREFIX . "product_special WHERE product_id = '" . (int)$product_id . "'");
if (isset($data['product_special'])) {
foreach ($data['product_special'] as $value) {
$this->db->query("INSERT INTO " . DB_PREFIX . "product_special SET product_id = '" . (int)$product_id . "', customer_group_id = '" . (int)$value['customer_group_id'] . "', priority = '" . (int)$value['priority'] . "', price = '" . (float)$value['price'] . "', date_start = '" . $this->db->escape($value['date_start']) . "', date_end = '" . $this->db->escape($value['date_end']) . "'");
}
}
$this->db->query("DELETE FROM " . DB_PREFIX . "product_image WHERE product_id = '" . (int)$product_id . "'");
if (isset($data['product_image'])) {
foreach ($data['product_image'] as $image) {
$this->db->query("INSERT INTO " . DB_PREFIX . "product_image SET product_id = '" . (int)$product_id . "', image = '" . $this->db->escape($image) . "'");
}
}
$this->db->query("DELETE FROM " . DB_PREFIX . "product_to_download WHERE product_id = '" . (int)$product_id . "'");
if (isset($data['product_download'])) {
foreach ($data['product_download'] as $download_id) {
$this->db->query("INSERT INTO " . DB_PREFIX . "product_to_download SET product_id = '" . (int)$product_id . "', download_id = '" . (int)$download_id . "'");
}
}
$this->db->query("DELETE FROM " . DB_PREFIX . "product_to_category WHERE product_id = '" . (int)$product_id . "'");
if (isset($data['product_category'])) {
foreach ($data['product_category'] as $category_id) {
$this->db->query("INSERT INTO " . DB_PREFIX . "product_to_category SET product_id = '" . (int)$product_id . "', category_id = '" . (int)$category_id . "'");
}
}
$this->db->query("DELETE FROM " . DB_PREFIX . "product_related WHERE product_id = '" . (int)$product_id . "'");
if (isset($data['product_related'])) {
foreach ($data['product_related'] as $related_id) {
$this->db->query("INSERT INTO " . DB_PREFIX . "product_related SET product_id = '" . (int)$product_id . "', related_id = '" . (int)$related_id . "'");
}
}
$this->db->query("DELETE FROM " . DB_PREFIX . "url_alias WHERE query = 'product_id=" . (int)$product_id. "'");
if ($data['keyword']) {
$this->db->query("INSERT INTO " . DB_PREFIX . "url_alias SET query = 'product_id=" . (int)$product_id . "', keyword = '" . $this->db->escape($data['keyword']) . "'");
}
$this->cache->delete('product');
}
Hope this helps people out.
Best Wishes
Alex