This function is not extensible, so other modules don't have a chance to say whether or not a user should be able to access the checkout page for the order they've specified. This problem manifests itself in the function baking in logic to do with the Cart order state even though Checkout does not have a dependency on Cart.
I think what needs to happen at the same time this function is made extensible is order statuses need to get an additional property similar to $order_status->cart that dictates whether or not orders in said status should be able to access the checkout completion page. This would be checked instead of disallowing at the end of the function orders in the Cart and Canceled states from viewing the checkout page... we simply can't know up front what other states this might apply to.
elseif ($checkout_page->page_id == 'complete') {
// Don't allow completion page access for orders in the cart or canceled states.
if (in_array($order_status->state, array('canceled', 'cart'))) {
return FALSE;
}
}
Comments
Comment #1
rszrama commentedWork in progress patch attached... this is tricky.
Comment #2
das-peter commentedSubscribe
Comment #3
alexiswatson commentedBeen working on this for a client while attempting to sort out #1362412: commerce_checkout_access() blocks anonymous checkout. Above patch doesn't seem to apply to the latest dev cleanly, but the approach used in node_access seems to make the most sense here:
This means we'll probably want constants for COMMERCE_CHECKOUT_ACCESS_ALLOW/DENY to distinguish between a hook implementation explicitly allowing/denying access and the absence of a response (in which case the default logic should take hold, with any DENY taking precedence in the event of conflicting implementations).
Time permitting I'll whip up another patch, but does this sound like a reasonable approach?
Comment #4
alexiswatson commentedPatch operates much in the spirit of #1, though unless I'm mistaken it seems like we really want two hooks here: hook_commerce_checkout_access() to extend order-level access and hook_commerce_checkout_page_access() to extend page-level access. Both require implementors to use the same ALLOW/DENY constants. Review and feedback welcome.
Comment #5
tommy kaneko commentedI have made a patch for PayPal WPS using the above patch (comment #4).
See: #1350264: Completion message problem with anonymous users only
Comment #6
bripatand commentedThanks for creating that patch. I needed it desperately for a custom module I developed which allows a user to impersonate another user during the checkout process . Commerce does not allow it by default.
Comment #7
BassistJimmyJam commentedI think #4 is headed in the right direction but I made a few changes and rolled a new patch. The changes include:
commerce_checkout_hook_info()in order to allow lazy loading.commerce_checkout.api.php.Comment #8
alexiswatson commentedThanks for the improvements! I actually used the constants to maintain consistency with hook_node_access and similar mechanisms in core after a bit of research, but I'm not hellbent on keeping them. It's just a matter of what we want to be consistent with.
EDIT: Looking back, do we want to handle IGNORE in a similar way?
Comment #9
BassistJimmyJam commentedIn the current patch, ignore would be handled by returning NULL (or nothing). This is how it is handled in hook_commerce_entity_access() as well as several other access hooks outside of hook_node_access().
Comment #10
alexiswatson commentedAh, I see. So long as we're being consistent. :]
One more for RTBC?
Comment #11
amateescu commentedThe patch from #7 makes a lot of sense to me, let's do this :)
Comment #12
rszrama commentedI'll give it another look, but I think we still need to move the Cart session variable checking into an implementation of this hook in commerce_cart.module. Might need to spin up a child issue to deal with the other aspect of the OP talking about what order statuses should have access to the checkout completion page.
Comment #13
alexbarrett commentedHere's a new patch based on #7 that includes moving the cart session variable checking into commerce_cart.module.
Comment #14
alexiswatson commentedCalls to the same method looking in the same place for only slightly different things smells a bit, but that's not an issue for this patch.
Approach looks sane, though.
Comment #15
alexbarrett commentedThe double call to commerce_cart_order_session_exists() definitely smells a bit to me as well, but it's a far more pleasant smell than the one the session variable checks at the end of commerce_checkout_access() are giving off now. I think removing the double call would require changing the way the commerce_cart_order_session_* functions are implemented, which I agree is not an issue for this patch.
Comment #16
alexiswatson commentedTotally agree, on all counts.
More eyes for RTBC?
Comment #17
torgospizzaI'll see if I can test this soon. On our site it would be preferable to allow anonymous checkout, but prevent users coming through anonymously with PayPal EC from having an access denied, etc.
Comment #18
rlmumfordTested against the latest dev and it all looks good!
Many +1's for getting this committed. We have several sites at the moment that are overriding the whole of 'commerce_checkout_router' just to get around this problem.