How can an order be valid without $_SESSION['shipping'] being set?
I've noted zc156 since I'm chasing an issue on a site with zc156c installed, but the question is still valid for zc157+.
Notice that the zc157c version of the order.php class (lines 312 thru 326):
Code:
$shipping_module_code = '';
// A shipping-module's 'code', if present in the session, **must** contain a '_' character, separating
// the shipping module's name from the selected method, e.g. 'module_method'. That '_' cannot be the first
// character of the 'code' value.
//
// If that's not the case, issue a PHP Notice and reset the shipping to its unselected state.
//
if (isset($_SESSION['shipping'])) {
if (!empty($_SESSION['shipping']['id']) && strpos((string)$_SESSION['shipping']['id'], '_')) {
$shipping_module_code = $_SESSION['shipping']['id'];
} else {
trigger_error('Malformed value for session-based shipping module; customer will need to re-select: ' . json_encode($_SESSION['shipping']), E_USER_NOTICE);
unset($_SESSION['shipping']);
}
}
... defaults that shipping_module_code to a blank string if the session's shipping information isn't set, which ultimately leads to a 0-value shipping being applied. Can anyone identify a scenario where a valid order doesn't have a shipping selection registered in $_SESSION['shipping']?
Re: How can an order be valid without $_SESSION['shipping'] being set?
It shouldn't happen.
I don't know why it's happening. I know I've dug around a bit and came up with nothing. I think it's related to specific modules.
The trigger_error call was added so that the invalid situation would log itself and take the shopper back through shipping selection before completing the order.
Re: How can an order be valid without $_SESSION['shipping'] being set?
Yes, but that trigger_error is only going to be hit if the $_SESSION['shipping'] is set!
Re: How can an order be valid without $_SESSION['shipping'] being set?
Not hijacking, just wondering if this is part of the reason for this log file. Using only Store Pickup and USPS.
Code:
PHP Notice: Malformed value for session-based shipping module; customer will need to re-select: false in /includes/classes/order.php on line 323
Re: How can an order be valid without $_SESSION['shipping'] being set?
Quote:
Originally Posted by
dbltoe
Not hijacking, just wondering if this is part of the reason for this log file. Using only Store Pickup and USPS.
Code:
[17-Apr-2021 10:41:12 US/Central] PHP Notice: Malformed value for session-based shipping module; customer will need to re-select: false in /includes/classes/order.php on line 323
It's more a question of why (and where) the 'malformed' value was set in the first place! What version of Zen Cart and what payment methods are involved?
Re: How can an order be valid without $_SESSION['shipping'] being set?
1.5.7c with PayPal, Square and Cash on Pickup
Re: How can an order be valid without $_SESSION['shipping'] being set?
If you scan the site's file-set for storefront occurrences of $_SESSION['shipping'] = false ... where's that being set?
Re: How can an order be valid without $_SESSION['shipping'] being set?
Re: How can an order be valid without $_SESSION['shipping'] being set?
not finding anything. Probably not searching correctly.
Re: How can an order be valid without $_SESSION['shipping'] being set?
Quote:
Originally Posted by
lat9
If you scan the site's file-set for storefront occurrences of $_SESSION['shipping'] = false ... where's that being set?
Quote:
Originally Posted by
dbltoe
not finding anything. Probably not searching correctly.
i can not speak to whether dbltoe searched correctly... i can surmise he probably did. i have done some searching in various file sets and have not found the requested code.
i did determine that the result of json_encode could be false if the data being encoded is not UTF-8. there are other possibilities as well...
perhaps there is a need to call json_last_error() to find out what the error was if the return is false?
not sure if this helps with the OP....
Re: How can an order be valid without $_SESSION['shipping'] being set?
I tried the search @lat9 suggested and also came up with nothing.
Re: How can an order be valid without $_SESSION['shipping'] being set?
I can't see where the json_encode bit has anything to do with this.
Re: How can an order be valid without $_SESSION['shipping'] being set?
Quote:
Originally Posted by
DrByte
I can't see where the json_encode bit has anything to do with this.
dbltoe stated he was getting an error log that says:
Notice: Malformed value for session-based shipping module; customer will need to re-select: false in /includes/classes/order.php on line 323
which is coming from this line of code:
PHP Code:
trigger_error('Malformed value for session-based shipping module; customer will need to re-select: ' . json_encode($_SESSION['shipping']), E_USER_NOTICE);
lat9 asked to search for a particular section of code, which 3 of us could not find.
if the json_encode of $_SESSION['shipping'] returns false, that would explain why people are seeing false in their logs.
as i previously stated, i am not sure if this helps with the OP, but there was a request to look for some code, which a number of us did, and that request was based on what was seen in the log, and i am now only providing a reason as to how false got into the log without $_SESSION['shipping'] being set to false.
hope that's clear.
Re: How can an order be valid without $_SESSION['shipping'] being set?
As indicated here: https://www.zen-cart.com/showthread....71#post1377371
If the "cheapest" method in the shipping class has the potential to return false even if all else is "correctly" setup. That is a point where $_SESSION['shipping'] can be set to false without 'false' being hardcoded to "suit" said search...
Ways this could "physically" happen:
$this->modules is not an array (note though there are other checks and operations in normal processing at least in includes/modules/pages/checkout_shipping/header_php.php to not attempt to get the result of the cheapest function unless "basically" this condition has already been met.
So, next chance?
Basically there are no $rates calculated, this involves using the default value of $cheapest which is false at that point and the internal loop never gets processed to change the value of $cheapest to one of the rates.
Last chance within this method: an observer of NOTIFY_SHIPPING_MODULE_CALCULATE_CHEAPEST has set $cheapest to false.
So what does it take in a default install to get to the cheapest method calculation?
$_SESSION['shipping'] isn't set, $_SESSION['shipping']['id'] is not set, or $_SESSION['shipping']['id'] is falsey. Then if any of those are true, if there is at least one shipping module...
How is it that specifically no rates get set? A few different ways: $quotes['methods'] is empty (not set, an array of zero elements, a pair of quotes, the value 0, false, etc...). If there are methods with quotes but the cost is not set as in: $quotes['methods'][$i]['cost'] is not set.
Then... Doing a search for points where $_SESSION['shipping'] is set, assuming that consistent code formatting is used to then search on '$_SESSION['shipping'] = ', there are very few cases at all where it is set to anything let alone a non-array. Basically as already stated in a default install there are two places where this could occur: paying with paypal or standard checkout when stepping through the header file.
That said, there is also the assignment of $shipping_modules->cheapest to $shipping in includes/modules/shipping_estimator.php though I don't know yet what impact that would have if it is set to false at that point. And that was just found by searching on 'cheapest('. I didn't try with a space before the parentheses. Nor have I sought for any weird situations like use of a variable assigned to 'cheapest' and using it as a function...
Re: How can an order be valid without $_SESSION['shipping'] being set?
entirely possible that cheapest could return false as well.... probably a more likely culprit...
Re: How can an order be valid without $_SESSION['shipping'] being set?
I'll note that we (myself included) have somewhat drifted from the original post's query. In the condition I'm investigating, $_SESSION['shipping'] is not set.
From what I've seen so far trolling through the PayPal and raw-access logs, the customer started out with OPC's guest-checkout, went to pay via PayPal Express Checkout and received the dreaded PayPal 10486 (the transaction couldn't be completed). About 5 minutes later, the customer apparently resolved their payment issue and returned to the store (no longer in guest checkout).
The paypalwpp payment method created an account for the customer and merrily created the order ... with no shipping. The 'shipping' order-total for the order shows a shipping_method of '' (empty string) and a value of 0.
Re: How can an order be valid without $_SESSION['shipping'] being set?
Alternatively and to wrap back around to the original question/information (started before prompted in a previous message), it looks like it could be possible that a purchase could be made with $_SESSION['shipping'] not being set if during ec_step2 the cart is determined/identified as possibly being changed, because the order is not present (does not appear to be in the path of being set until after this "change in contents") the section of code mentioned is "processed" and then with the store *not* setup to select the cheapest shipping method, then a purchase appears to be able to complete through paypal without $_SESSION['shipping'] being set. Additionally, because $_SESSION['shipping'] was unset when the cart "discrepancy" was identified, this path of processing would result in reaching the code snippet in the OP but bypassing it because $_SESSION['shipping'] is not set. So the last conditions that cause(d) unsetting are from includes/modules/paypalwpp.php at/around Line 1875:
Code:
(isset($response['SHIPPINGCALCULATIONMODE']) && $response['SHIPPINGCALCULATIONMODE'] != 'Callback') && (!(isset($_SESSION['paypal_ec_markflow']) && $_SESSION['paypal_ec_markflow'] == 1))
There doesn't appear to be anything at this point that ensures correction to the shipping session value in this situation.
Re: How can an order be valid without $_SESSION['shipping'] being set?
Quote:
Originally Posted by
mc12345678
Alternatively and to wrap back around to the original question/information (started before prompted in a previous message), it looks like it could be possible that a purchase could be made with $_SESSION['shipping'] not being set if during ec_step2 the cart is determined/identified as possibly being changed, because the order is not present (does not appear to be in the path of being set until after this "change in contents") the section of code mentioned is "processed" and then with the store *not* setup to select the cheapest shipping method, then a purchase appears to be able to complete through paypal without $_SESSION['shipping'] being set. Additionally, because $_SESSION['shipping'] was unset when the cart "discrepancy" was identified, this path of processing would result in reaching the code snippet in the OP but bypassing it because $_SESSION['shipping'] is not set. So the last conditions that cause(d) unsetting are from includes/modules/paypalwpp.php at/around Line 1875:
Code:
(isset($response['SHIPPINGCALCULATIONMODE']) && $response['SHIPPINGCALCULATIONMODE'] != 'Callback') && (!(isset($_SESSION['paypal_ec_markflow']) && $_SESSION['paypal_ec_markflow'] == 1))
There doesn't appear to be anything at this point that ensures correction to the shipping session value in this situation.
Noting that the SHIPPINGCALCULATIONMODE element of the response was not set.