Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Perhaps this is by design, or I missed a setting, but if an item becomes unpublished while in a users cart, they're still able to purchase it. I wanted these items to be removed from the cart, so here's a patch. I guess something similar should also be added to the cart/checkout page if users are able to get there without viewing cart/.
Comment | File | Size | Author |
---|---|---|---|
#49 | 955810-49.patch | 2.7 KB | TR |
| |||
#48 | 955810-48.patch | 2.6 KB | TR |
| |||
#46 | 955810-43.patch | 2.68 KB | TR |
#43 | ubercart-remove_unpublished_cart_items-955810-43.patch | 2.68 KB | tinker |
#30 | 955810-remove-unpublished-cart-items-30.patch | 1.83 KB | longwave |
Comments
Comment #1
TR CreditAttribution: TR commentedNot by design, but probably just because no one ever considered that case. Needs review now.
Comment #2
longwaveuc_cart_get_contents() or a hook_cart_item implementation may be a better place to do this, as then the items will be removed on the next page load after they are unpublished, rather than waiting for the user to hit the cart page.
Comment #3
DamienMcKennaAnother use case that needs covering: you should not be able to even add an item to the cart if it is unpublished. Right now if you have a cached version of a page that lists a recently unpublished product, you can click the Add To Cart button and it'll be added, allowing you to buy a product that the store owner had "pulled off the shelf", so to speak.
Regarding the patch, at the very least the following line needs to be improved to match the coding standards:
Comment #4
DamienMcKennaThis is a bit more important than originally reported.
Comment #5
longwaveMarked #1366326: Unpublished products can be checked out as duplicate
Comment #6
longwaveSimple patch for 7.x. But would any existing sites be relying on the current behaviour? Should we introduce a permission or setting to control this feature?
Comment #7
DamienMcKennaI don't think that's the best option - it should block the item from being added, not delete the record after-the-fact.
Comment #8
longwave#6 handles the case of the item being added to the cart while being published then becoming unpublished before reaching checkout - and cart items can live for days, weeks or even months. The caching case you describe in #3 arguably covers a much shorter timespan, and is technically covered by this patch, but I agree we should perform this check at add to cart time as well.
I've also realised it should probably use node_access() instead of checking $node->status.
Comment #9
DamienMcKenna@longwave: Good point on the "cart never ends" thing, there are probably other checks that ought to be done with that in mind, e.g. whether the item is in stock, etc. There probably also should be a drupal_set_message to inform the visitor as to what has happened.
Comment #10
rickmanelius CreditAttribution: rickmanelius commentedI can confirm that a modified version of #6 works for D6. Changing
db_query("DELETE FROM {uc_cart_products} WHERE cart_item_id = :id", array(':id' => $item->cart_item_id));
to
db_query("DELETE FROM {uc_cart_products} WHERE cart_item_id = %d", $item->cart_item_id);
This is perfect, as a client of mine just had two orders go through for products that don't exist! If this could be applied for the D6 branch as well, that would be awesome. I can submit in patch form if necessary.
Comment #11
rickmanelius CreditAttribution: rickmanelius commentedSorry, I didn't check the comments in #8 and #9 before I posted. That said, patch #6 does work for D7 (just tested) for the simple use case I needed.
Comment #12
rickmanelius CreditAttribution: rickmanelius commentedPatch #6 still works great for the general use case. Can we get that committed and then move towards a more thorough solution?
Comment #13
Island Usurper CreditAttribution: Island Usurper commentedSeems to have been fixed by #1351104: Need to clear line items as well as products for cart orders. Trying to checkout with an unpublished item in the cart shows "Some of the products in this order are no longer available." It'd be nice to indicate which products are the problem, since they are still in the cart, preventing it from going through.
May be worth porting this to Ubercart 2.x, as #10 says.
Comment #15
topdillon CreditAttribution: topdillon commentedIn D6 I added this code at line 1460 just before return $item; but nothing changed. An unpublished item remained in the cart. Did I do that right?
Comment #16
rickmanelius CreditAttribution: rickmanelius commentedSomething must have switched in the 7.x-3.0 release as the patch in #6 no longer applies... and I can confirm that it's still possible to add items to the cart.
Comment #17
rickmanelius CreditAttribution: rickmanelius commentedComment #18
rickmanelius CreditAttribution: rickmanelius commentedI spoke too soon... that seems to only happen if you're logged in as admin, which confused me. But when I use cart links, etc as a regular authenticated or anonymous user, it does prevent it from being added to the cart.
So I guess I leave this open as to whether or not this should happen for admins? If yes, then this is definitely a 'closed' ticket... but maybe a warning should appear that you have unpublished nodes in your cart and normal users wouldn't get that?
Comment #19
longwaveThis issue is about unpublishing items that are already in the cart, not adding unpublished items in the first place, which I believe has always worked how you describe; if a user has access to the node, they can add it to their cart.
Comment #20
rickmanelius CreditAttribution: rickmanelius commentedOk cool... then closing for now.
Comment #21
jasonabc CreditAttribution: jasonabc commentedThis is also happening in Ubercart 2 (just got a complaint from a client about it today). Anyone got a patch for Ubercart 2.x??
Comment #22
topdillon CreditAttribution: topdillon commentedI'm not a coder, but I can follow code a bit. I have to get this working on my D6 site. For some reason, !$product->status evaluates to FALSE. I have a product that I published, added to cart, unpublished, view cart and it's still there. Am I close to getting it right?
Comment #23
longwaveComment #24
yakbuttertea CreditAttribution: yakbuttertea commentedI'm using UC 7.x-3.2 and if a product is unpublished by admin it stays in the shopping cart and customers can't go to checkout. I tried to insert the patch in #6 to uc_cart/uc_cart.module but can't find where to add it.
Comment #25
longwave#24 describes the same thing as #13, perhaps we should improve this to automatically remove those items rather than stop the user reaching checkout.
Comment #26
Dan Z CreditAttribution: Dan Z commentedIdeally, removing unpublished items from the cart would be an option. There is an edge use case selling unique items. You want to automatically unpublish the item as soon as it goes into someone's cart so that nobody else can try to buy it. You wouldn't want to remove the item from the cart in this case.
Of course, that's adding UI and code complexity for a feature only a few people would use, so it's a judgement call as to whether to do this. Maybe add a Rule action to remove an item from a cart/order, and a have a (default) reaction rule to trigger it when a product is unpublished. The edge case people can re-configure the rule.
Comment #27
ascii122 CreditAttribution: ascii122 commentedI ran into this problem recently. I tried a few things with trying to remove items automatically but as a quick kludge (it just gives a warning and tells the user which product is not available any more). I put into uc_cart.module at line 1054
Just after
foreach ($items[$cid] as $item) {
So it looks like this
Comment #28
longwaveBetter attempt at an implementation on this, with a test. The code now reacts to a node update, whenever a node is unpublished any matching cart items are also deleted.
Reviews and tests welcome; not sure this is the best approach, especially for existing sites that rely on the existing behaviour.
Comment #29
DamienMcKenna@longwave: I think it would be better to not handle this in hook_node_update, but to instead check via the visitor's page load, that way the visitor could be informed of the change rather than things seeming to randomly disappear.
Comment #30
longwaveSo here's a different approach, but doing this in uc_cart_get_contents() feels wrong. I am also wary of affecting custom implementations that may rely on unpublished items, so I wonder if implementing this through Rules would be better; there doesn't seem to be a useful event to do this on, though.
Comment #31
longwaveOops, this doesn't permanently remove the item from the cart.
Comment #32
DamienMcKenna@longwave: It also tries to load $node->title if $node is empty ;-)
Comment #33
longwaveuc_cart_node_delete() should catch that case already, but I guess we really should treat deleted nodes and unpublished nodes in the same way.
@Damien: any thoughts about using Rules for this instead of hard coding it somewhere?
Comment #34
DamienMcKennaI think it'd be more cumbersome to use Rules.
Comment #35
yakbuttertea CreditAttribution: yakbuttertea commented#28 works great!
Comment #36
zooter626 CreditAttribution: zooter626 commented#28 worked great for me as well, thanks!
Comment #37
SilviuChingaru CreditAttribution: SilviuChingaru commentedI think we should never delete unpublished products form carts because if we republish the product again we still want our customer to have that product in the cart!!!
Better approach, I think, is the one to not display the item and maybe still keep unpublished products in customer cart even after checkout to remind somehow the customer that the product is again available.
We should delete a product from customer cart when the product node is deleted only because than it means that the product it doesn't exists anymore.
Comment #38
longwave@fiftyz: I don't think it's good to surprise the user - what if you republish the cart item just before the user gets to checkout, the item will suddenly appear back in their cart and they may pay for it without realising. Also, what if the user completes checkout while the item is still unpublished, and then you publish it - should it appear in their cart then? Simply deleting the item as soon as it becomes unpublished seems much simpler.
Comment #39
SilviuChingaru CreditAttribution: SilviuChingaru commented@longwave: Yes, that could be an issue so maybe you are right.
Comment #40
garbo CreditAttribution: garbo commentedI think the best experience for the user would be that unpublished/deleted nodes are removed from the cart (not hidden! see #38) on cart load (either block, page or on checkout) and that the user sees a message that the product is no longer available.
To make the experience even better an extra module could hook into that and present a contact form where the user can submit it's email address so they can be notified if the product or something similar is available again.
I used a modified version of the patch at #6 in the function
cart_get_item($item)
.Comment #41
yakbuttertea CreditAttribution: yakbuttertea commented@ Garbo: Where do you install your code? in uc_cart.module? there is no function called uc_cart_get_item.
Thanks
Comment #42
garbo CreditAttribution: garbo commented@yakbuttertea
in function uc_cart_get_item() in /uc_cart/uc_cart.module
Comment #43
tinker CreditAttribution: tinker commentedThis is a rework of patch from #30 fixing issues from #31 & #32. It modifies uc_cart_get_contents() and checks for products that are in cart that have been deleted or unpublished. Deleted products should already removed by uc_cart_node_delete() but the extra check here added so little code that I thought I should include it. I agree that unpublished products should not remain in cart as mentioned in #38 so this patch removes them and shows a warning message.
if the product is deleted then warning is "A product is no longer available..." otherwise if unpublished it shows "[product->title] is no longer available...". Test is also included
@longwave, You mentioned a concern about "affecting custom implementations that may rely on unpublished items". Why would anyone want unpublished products in the cart?
Comment #44
longwaveThanks for working on this!
I think my original concern was that there could be an existing site out there using View Unpublished or similar to allow certain users access to unpublished nodes/products for whatever reason, and this might stop them doing that. But because your patch uses node_access() instead of explicitly checking $node->status then there are no problems here.
Overall I think this looks good, though there is a minor security concern. It's generally considered bad practice to leak information does the user should not have access to - in this case, the unpublished node title. The thinking behind this is that the site admin may have retitled the node as well as unpublishing it, and the admin would not expect any users to have access to the new title - but it might get inadvertently exposed here. As removal is likely to be a rare case anyway I wonder if is better to just show a single, generic message if any items were removed from the cart by this code?
(This, I suppose, is an argument for using Rules instead for this feature, because the admin could customise the message if they wished, including exposing the title where available!)
Comment #45
tinker CreditAttribution: tinker commented@longwave, Thanks for the response. As to your security concern about leaking information: I tested current operation, without the patch, and found that the user sees the unpublished node title when they view their cart. So either the leaks already exists or it's not considered a leak. Either way this patch does not expose any data that the customer did not already have access to. I think it's valuable for the customer to see what product was removed rather than just seeing a generic message that something was removed.
Comment #46
TR CreditAttribution: TR commentedUploading patch #43 again for the new testbot - no changes.
Comment #48
TR CreditAttribution: TR commentedStill the same patch from #43, but re-rolled against the current Ubercart 7.x-3.x HEAD.
Comment #49
TR CreditAttribution: TR commentedAnd again, same patch as #48 but with a few coding standards fixes that were identified by the test.
Comment #51
TR CreditAttribution: TR commented