Ok, so this is a little hard to explain, as I've only just found this in a live site, and not had chance to reproduce in a test environment, but here goes.....
When Google re-builds the sessions to calculate shipping costs, it doesn't recreate the session variable correctly, and this leads to incorrect shipping costs being shown in certain circumstances.
For some reason, the code assigns the $_SESSION['cart'] to an independant variable, $cart, and then uses this to perform all class functions. This is wrong for starters, as all shipping modules use the SESSION variable, rather than a local variable to calculate weights etc. So, firstly, this $cart variable should be changed to use the $_SESSION['cart'] variable instead.
Secondly, when products are returned from Google to check the shipping costs, they are unserialised, and put into the $order->products array. This is fine for the actual shipping modules and their calculations, however, the function zen_get_shipping_enabled() uses the SESSION['cart']->contents to check if the order is free shipping. As the SESSION variable has been badly re-created, and no products exist, it therefore believes that the order should be shipped for free.
So, my fix, which needs to be fully tested is as follows:
in googlecheckout/responsehandler.php
Line 704 or there abouts, you will find $order->products = $products.
After this line, paste:
Code:
foreach($products as $product) {
if (!isset($_SESSION['cart']->contents[$product['id']])) {
if (isset($product['attributes'])) {
$attributes = array();
foreach($product['attributes'] as $attribute) {
if (strstr('chk_', $attribute['option_id'])) {
$option = explode('chk_', $attribute['option_id']);
$attributes[$attribute['option_id']] = array($attribute['value_id'] => $attribute['value_id']);
}elseif ($attribute['value_id'] == PRODUCTS_OPTIONS_VALUES_TEXT_ID) {
$attributes[TEXT_PREFIX.$attribute['option_id']] = $attribute['value'];
} else {
$attributes[$attribute['option_id']] = $attribute['value_id'];
}
}
$_SESSION['cart']->add_cart($product['id'], $product['qty'], $attributes);
} else {
$_SESSION['cart']->add_cart($product['id'], $product['qty']);
}
}
}
$total_weight = $_SESSION['cart']->show_weight();
$total_count = $_SESSION['cart']->count_contents();
You'll see that the next two lines have been replaced with the last two lines above, which use the SESSION variable, rather than the $cart variable.
Like I said, this fixes a HUGE issue with two of our stores, and I'm not sure that it is the best fix. I think maybe the SESSION['cart'] variable should have the products allocated before the $order variable is defined, and the $order will then auto-populate when the class is initiated, but I haven't tested this as yet.
If you have any questions, or comments regarding this code, PLEASE, let's keep it in the thread, rather than through PM!
Absolute
Bookmarks