Thanks to wizonesolutions and a bit of googling, I came up with a very simple solution using a custom module.
I've now moved to Drupal 7. Using a combination of Logintoboggan, Rules, and Entity Fields, I can set up complex conditions for membership using the admin interface rather than code. More importantly, this means my clients will be able to do the same.
Ubercart Rules is fantastically useful, but doesn't have support for adding products to a user's cart out of the box. This was easily fixed with a small custom module which added the action. Below is the code from that module:
<?php
/**
* @file
* This file contains the Rules hooks and functions necessary to enable adding
* products to carts from Rule actions.
*/
/**
* Implements hook_rules_action_info().
*/
function mycustommodule_rules_action_info() {
$actions['mycustommodule_add_product'] = array(
'label' => t('Add a product to the cart'),
'group' => t('MyCustomModule Order'),
'base' => 'mycustommodule_add_product_to_cart',
'parameter' => array(
'product' => array(
'type' => 'text',
'label' => t('Product'),
'restriction' => 'input',
'options list' => 'mycustommodule_product_list_options',
),
'quantity' => array(
'type' => 'text',
'label' => t('Quantity'),
),
),
);
return $actions;
}
/* * ****************************************************************************
* Condition Callbacks and Forms *
* **************************************************************************** */
/**
* Return a list of product nodes, keyed to their nid.
*/
function mycustommodule_product_list_options() {
// Get a list of all products
$query = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->orderBy('title');
$query->join('uc_products', 'p', 'n.vid = p.vid');
$result = $query->execute();
foreach($result as $row) {
$return[$row->nid] = $row->title;
}
return $return;
}
/**
* Add a product to the user's cart, based on the rule.
*
* @param int $product
* nid of the product to add
* @param nid $quantity
* quanity of product to add
*/
function mycustommodule_add_product_to_cart($product, $quantity = 1) {
uc_cart_add_item($product, $quantity);
}
I hope someone finds this useful.