Not sure whether this is a bug or a documentation flaw.
hook_update_cart_item is invoked from uc_cart_add_item() but instead of calling module_invoke_all() this time module_invoke() is called. Consequently, other modules that implement this hook will not be called.

Comments

longwave’s picture

This is apparently by design. When a cart item gets added, if you want to handle it in your module, you should set $item->module.

Compare uc_product_update_cart_item() and uc_product_kit_update_cart_item().

mcpuddin’s picture

Status: Needs review » Reviewed & tested by the community

I'm not one to say if this is by design or not but I feel like a hook is meant to be something used by an external module and hook_update_cart_item is not set up in that way. The patch works for me and resolves this issue.

longwave’s picture

Have you tested this with product kits enabled, or any other module that actually implements this hook? It obviously works if only uc_product is enabled, but I think other modules may cause unintended side effects if this hook is called for items they previously didn't handle.

Island Usurper’s picture

Status: Reviewed & tested by the community » Closed (works as designed)

hook_update_cart_item() is a strange duck. But it does what it was meant to do.

seemas’s picture

patch conflicts with hotel_booking_update_cart_item when no qty(0) is sent to this function so it deletes the item (D6)
by the way - lets call these hooks that are special - moons (escorts,wifes)

seemas’s picture

StatusFileSize
new1.21 KB

this is wrong patch. Please do not mind.
VVVVVVVVVVVVVVVVVVVVVVVVVVVVV

fizk’s picture

Status: Closed (works as designed) » Active

I need this functionality and it looks like I'm not alone. If this patch wasn't accepted, what is the correct hook to implement?

longwave’s picture

Status: Active » Closed (works as designed)

Use hook_add_to_cart_data() to set $item->data['module'] to 'your_module', then you can implement your_module_update_cart_item().

fizk’s picture

Thanks, the problem with this method seems to be that only one module could use this strategy successfully. If two different contrib modules tried to do this, one of them would overwrite the other's change to $item->data['module']. Or am I wrong?

To avoid breaking existing code and other contrib modules, I think we should add a new hook: hook_pre_update_cart_item()

The call would look exactly the same as hook_update_cart_item() and it would be called just before hook_update_cart_item()

module_invoke_all('pre_update_cart_item', $node->nid, $data, min($qty, 999999), $cid);
module_invoke($data['module'], 'update_cart_item', $node->nid, $data, min($qty, 999999), $cid);

and

module_invoke_all('pre_update_cart_item', $item['nid'], unserialize($item['data']), $item['qty']);
module_invoke($item['module'], 'update_cart_item', $item['nid'], unserialize($item['data']), $item['qty']);
fizk’s picture

Version: 6.x-2.4 » 6.x-2.x-dev
Status: Closed (works as designed) » Needs review
StatusFileSize
new994 bytes

Here's a patch.

DanZ’s picture

Title: hook_update_cart_item is not a hook other modules can use » Add a new hook: hook_pre_update_cart_item()
Category: bug » feature
Priority: Major » Normal
longwave’s picture

Status: Needs review » Needs work

What are you actually trying to do here? Can you give a sample implementation of this hook that does something useful?

Moving to needs work, because any new hook will need documentation.

tr’s picture

Version: 6.x-2.x-dev » 7.x-3.x-dev

I really think that new hooks and other new features should go into 7.x-3.x first - 7.x-3.x is where we should be putting our efforts. New features in the current branch encourage people to upgrade, while introducing new features first in the old, soon-to-be-obsolete branch just encourages people to stick with the old code. New features can always be backported to 6.x-2.x, but that should be an afterthought, and only if someone is willing to do the work.

See also #1903564: [policy] Maintenance phase for 6.x-2.x branch.

longwave’s picture

In 7.x I think this should be solved by #1492626: "Cart Items" triggers dont work which will let you use either Entity API hooks or Rules to trigger on cart item updates.

fizk’s picture

Version: 7.x-3.x-dev » 6.x-2.x-dev

Marking as 6.x as per #14.

longwave’s picture

Can you answer my questions in #12? I'm more likely to consider adding this if I can see what it might actually be used for!

fizk’s picture

@longwave, here's a sample implementation:

/**
 * Implements hook_pre_update_cart_item().
 */
function mymodule_pre_update_cart_item($nid, $data = array(), $qty, $cid = NULL) {
    if (!$nid)
        return NULL;

    if ($qty < 1 && ($node = node_load($nid)) && $node->model == 'sku-123') {
        drupal_goto('confirm-page');
    }
}
fizk’s picture

Status: Needs work » Needs review
StatusFileSize
new1.95 KB

Here's a patch that also includes documentation for the new hook. Feel free to change the example code.

Status: Needs review » Needs work

The last submitted patch, 933124-pre-update-cart-item-2.patch, failed testing.

fizk’s picture

Status: Needs work » Needs review
fizk’s picture

tr’s picture

In 7.x I think this should be solved by #1492626: "Cart Items" triggers dont work which will let you use either Entity API hooks or Rules to trigger on cart item updates.

That's great, but then why are we spending any time and effort at all on a dead-end fix for 6.x-2.x? Creating a new hook for an old branch, a hook that will never be added to the current branch or future branches? That doesn't make sense to me. I suggest that anyone who really NEEDS this feature should instead spend the time to upgrade to 7.x-3.x and help out with #1492626: "Cart Items" triggers dont work. That is one specific way we can encourage users to move to the current version of Ubercart and to help improve Ubercart going forward. Continuing to engineer new features specifically for 6.x-2.x, new features which cannot be carried into 7.x-3.x, simply encourages people to stick with 6.x-2.x.

longwave’s picture

    if ($qty < 1 && ($node = node_load($nid)) && $node->model == 'sku-123') {
        drupal_goto('confirm-page');
    }

So basically you want to add a confirmation page if the user tries to remove a specific SKU from the cart? Isn't it just as easy to do this without modifying Ubercart core by using hook_form_alter() on the cart form?

longwave’s picture

Status: Needs review » Closed (won't fix)

This should be achievable with hook_form_alter(), there is already an equivalent hook in 7.x, and we are no longer adding new features to 6.x as per #1903564: [policy] Maintenance phase for 6.x-2.x branch