Adding product to basket in Ubercart causes checkout bug

As part of a site I’ve recently been developing using Ubercart, I needed the ability to be able to add an item to the basket via a URL. Getting a URL to trigger an event was trivial, using the following code.

First, you setup the URL pattern to trigger a callback function:

$items['product/%/add'] = array(
	'page callback'		=>'djg_add_product_to_basket',
	'type'			=>MENU_CALLBACK,
	'access arguments'	=>array('access content'),
);

Next, I setup a simple callback function, which would get the Node ID from the URL, and pass it to the uc_cart_add_item function and then redirect the user to the checkout.

function djg_add_product_to_basket() {
	$parts	= explode('/', $_GET['q']);
	$nid	= $parts[1];

	uc_cart_add_item($nid, 1);
	drupal_goto('cart/checkout');
}

I tried this, and it seemed to work, however I later realised that the delivery pane had been removed from the checkout. Several searches later, and all I could find were people with similar problems, but in their case it was because the product they wanted to buy wasn’t shippable.

Some more digging around, and I found that when you add a product pragmatically using uc_cart_add_item, it doesn’t pick up the shippable status from the product node.

The solution is to explicitly set the product as shippable using the third parameter, which is attributes, so the line of code should look like:

uc_cart_add_item($nid, 1, array('shippable'=>true));