Hi,
i was faced to the problem, that I added some items to cart as anonymous user, whereas my personal cart (cart_id = uid) was empty. After login, the items have been shifted to my personal cart by uc_cart_login_update(). But in this scenario there is no cart-content rebuild caused by a faulty condition. So I had problems with uc_cart_get_contents() called afterwards during page call.
Cart rebuild and any consolidation actions for items only are relevant, if there was a shift of any cart item to my personal cart. Otherwise, there is no need to do anything.
I added a patch for this against 6.x-2.4. (Tested successfully with version 6.x-2.2)
| Comment | File | Size | Author |
|---|---|---|---|
| #13 | 958264-uc_cart_login_update.patch | 1.7 KB | longwave |
| #9 | uc_cart_login_update-958264-9.patch | 813 bytes | TS79 |
| #5 | uc_cart_login_update_V2.patch | 895 bytes | TS79 |
| uc_cart_login_update.patch | 1.04 KB | TS79 |
Comments
Comment #1
TS79 commentedwhy is nobody interested in fixing an obvious bug with a no-brainer patch?
Comment #2
longwaveShouldn't this patch be checking db_affected_rows() instead of the result of db_query()?
Comment #3
TS79 commentedyes, you are right. i did not recognise any failure with db_query(), since the action "content-rebuild", which has been performed always, does not effect anything negative.
but really should be db_affected_rows()
do you require a new patch or can you change this while committing?
Comment #4
longwaveI have no commit access to this project; I suspect the maintainers will want a fully working patch they can apply immediately.
Comment #5
TS79 commentedvoila, the corrected patch; but any hope, that this gets committed within the next weeks does not exist ;)
Comment #6
tr commentedKicking the bot to get it to test the patch.
Comment #7
tr commentedComment #9
TS79 commentednext try
Comment #10
longwaveI am still slightly confused as to what this actually fixes. Can you demonstrate the issue in core alone, or does it require custom code?
Comment #11
TS79 commentedif you are confused, then please answer first the question for yourself, why this if-clause exists in source code after "merging two carts".
if you have this answer, you can read my issue description again and apply the given scenario (empty cart of logged user; filled cart of anonymous user).
after all there should be confusion anymore.
with the bugfix, the $items object holds the merged cart at end of function in the given scenario. without the bugfix, the $items object does not hold the merged cart.
Comment #12
longwaveBut $items isn't returned so what difference does this make? The point of that code is to merge identical items, but if the logged in user has an empty cart, there is nothing to merge.
Comment #13
longwaveI am still confused by the original uc_cart_login_update() and why it does things the way it does. The attached patch/code below makes it much simpler and it still seems to work, please review.
Comment #14
TS79 commentedthe 'rebuild' parameter of uc_cart_get_contents() is the key. if you do not rebuild the cart with the "new merged items", any call of uc_cart_get_contents() afterwards(!!!) without the 'rebuild' parameter fails. the "old static cashed cart items" (not the merged ones) are returned there. these calls of uc_cart_get_contents() can be implemented in any other function during page load (e.g. rules/actions, which are triggered afterwards).
Comment #15
longwaveuc_cart_add_item()callsuc_cart_get_contents($cart_id, 'rebuild')so the suggested improvement in #13 should handle this. Can you try that patch and see if it helps for your case? As I still don't know how to demonstrate this as an actual bug, I need someone else to test things for me.Comment #16
TS79 commentedexcept the rebuild issue, there is another item consolidation in current implementation: quantities of the same order product are added via uc_cart_get_contents(). in your patch, item consolidation happens within uc_cart_add_item() and leads to call of 'hook_update_cart_item'. this call is not in current implementation at login-time and i think this is correct. the call of 'hook_update_cart_item' was already triggered before, when anonymous user added the item to cart.
Comment #17
longwaveIn the original code doesn't hook_update_cart_item get called as well? Seems that uc_cart_add_item() is called for every item in both the anonymous and authenticated carts, which should trigger this hook when consolidating identical items?
Comment #18
TS79 commentedno, hook_update_cart_item is not called, since cart for logged user is deleted before the merged items are added again to the cart of the logged user:
Comment #19
longwaveBut won't hook_update_cart_item() still be triggered in both cases only if both carts have an identical item (with the same nid and data), which is the point of consolidating the items?
Comment #20
longwaveAn example, let's assume attributes etc are disabled so $data is empty. Anonymous cart has nids 1 and 2. Authenticated cart has nids 2 and 3.
The original code:
- merges the carts so the authenticated cart contains items with nids 1, 2, 2 and 3.
- deletes all items
- calls uc_cart_add_item for each item, adding nid 1, nid 2, nid 2 again (triggering hook_update_cart_item) and nid 3
The simplified code:
- calls uc_cart_add_item for each item in the anonymous cart, adding nid 1 (no trigger, as it's not in the authenticated cart) and nid 2 (triggering hook_update_cart_item, as it's already in the authenticated cart)
Comment #21
TS79 commentedhm, no, there is a consolidation of items for the same nid in uc_cart_get_contents()
The original code:
- nid 1 and 2 are "shifted" to authenticated cart
- now there are in DB: nid 1, nid 2, nid 2 and nid 3 (all qty 1)
- all items of the authenticated cart are loaded and consolidated via uc_cart_get_contents():
.... nid 1 (qty 1), nid 2 (qty 2), nid 3 (qty 1)... this is the new merged cart
- deletes all items in DB
- calls uc_cart_add_item for each item, adding nid 1, nid 2 (with qty 2) and nid 3 to DB
... no call of hook_update_cart_item
Comment #22
longwaveuc_cart_get_contents() doesn't perform consolidation:
There was code in there that *tried* to do this before, but it never worked because it compared the existing unserialized data items to the serialized version.
Comment #23
longwaveI think calling hook_update_cart_item() is actually the right thing to do here, it is not a proper hook (only invoked on the module that owns the product), and perhaps a product type module would want to know when an anonymous cart and authenticated cart with the same items were being merged.
uc_product_update_cart_item() will be the function called in 99% of cases and this is necessary to update the quantity field in the db anyway!
Comment #24
TS79 commented... jup, I am on an old UC version (2.3). upgrading and testing anything is not possible for me at the moment. but if this old code is eliminated, your patch might work.
Comment #25
longwaveCommitted #13 to both branches.