uc_cart_get_contents and drupal_alter

mfer - December 22, 2008 - 13:20
Project:Ubercart
Version:6.x-2.0-beta3
Component:Code
Category:feature request
Priority:normal
Assigned:rszrama
Status:closed
Description

Would it be possible to get a drupal_alter call in the function uc_cart_get_contents. It's nice to be able to add to each item but it would be great to alter what other modules have done or at a point after the entire care has been populated.

The code would look something like:

<?php
/**
* Grab the items in a shopping cart for a user.
*
* If $cid is not passed in, this function uses the uid of the person currently
* accessing this function.
*/
function uc_cart_get_contents($cid = NULL, $action = NULL) {
  static
$items = array();
 
$cid = $cid ? $cid : uc_cart_get_id();

  if (
$action == 'rebuild') {
   
$items = array();
  }

  if (!isset(
$items[$cid])) {
   
$items[$cid] = array();
   
$result = db_query("SELECT c.*, n.title, n.vid FROM {node} n INNER JOIN {uc_cart_products} c ON n.nid = c.nid WHERE c.cart_id = '%s'", $cid);

    while (
$item = db_fetch_object($result)) {
      for (
$i = 0; $i < count($items[$cid]); $i++) {
        if (
$items[$cid][$i]->nid == $item->nid && $items[$cid][$i]->data == $item->data) {
         
$items[$cid][$i]->qty += $item->qty;
          continue
2;
        }
      }
     
$product = node_load($item->nid);
     
$item->cost = $product->cost;
     
$item->price = $product->sell_price;
     
$item->weight = $product->weight;
     
$item->data = unserialize($item->data);
     
$item->module = $item->data['module'];
     
$item->options = array();
     
$item->model = $product->model;

     
// Invoke hook_cart_item() with $op = 'load' in enabled modules.
     
foreach (module_implements('cart_item') as $module) {
       
$func = $module .'_cart_item';
       
$func('load', $item);
      }

     
$items[$cid][] = $item;
    }
   
drupal_alter('cart_item', $items);
  }

  return
$items[$cid];
}
?>

notice the drupal_alter call at the bottom.

This would be great if I want to alter the prices of items in the cart based on the contents of the cart. This is my use case but I'm sure there are many more.

Can we get this change in. If needed I'll roll a patch. It's just a one line change.

#1

mfer - December 22, 2008 - 13:23

Looking at this again I'd actually make the alter call read:

<?php
  drupal_alter
('cart_items', $items);
?>

#2

Island Usurper - December 22, 2008 - 20:12
Status:active» needs review

Here's an interesting idea. I can see how this could make product kits a lot less complicated. Possibly. It may just move the complexity around to a different function. It's definitely worth another look.

My patch makes it call hook_uc_cart_alter(). It's really the entire cart that's being altered and not the individual item. Also, I'm only passing it the actual cart being returned by uc_cart_get_contents(). This keeps each module from modifying the cart more than once, and doesn't allow any kind of cross-contamination through faulty coding.

I'm going to mull it over for a while. I can think of a lot of different applications for this, but I'm not sure they're all going to sit well together.

AttachmentSize
cart_alter.patch 285 bytes

#3

mfer - December 22, 2008 - 20:29

My use case is where I have two products. When one is purchased the other gets a discount if it is there as well. This is a lot simpler with a _alter call. I can imagine a number of other uses..... for example the uc discounts module which has to build a psuedo cart on it's own so it knows what's in the cart before it acts. That could possible be removed if it had the cart there.

#4

rszrama - February 6, 2009 - 21:37
Version:6.x-2.x-dev» 6.x-2.0-beta3
Assigned to:Anonymous» rszrama
Status:needs review» fixed

Lyle's patch in #3 seems good to me... unobtrusive and certainly useful. Maybe one day we'll have better cart support in general, but this is a good small step.

Will document this so people know implementations of this hook must receive the $items argument by reference.

#5

System Message - February 20, 2009 - 21:40
Status:fixed» closed

Automatically closed -- issue fixed for 2 weeks with no activity.

 
 

Drupal is a registered trademark of Dries Buytaert.