Although there already exists the Product Maximum (http://www.ubercart.org/contrib/2155) and Product Minimum (http://www.ubercart.org/contrib/274) for checkout modules which allow you to specify a minimum and maxinum number (quantity) of each product to checkout, there was no way I could find to do this same task on a global spectrum.
In other words, I needed to be able to restrict checkouts to only 1 product at a time (this is due to the special/complicated nature of order fulfillment with these products). Maybe someone else wants to restrict orders to 5 or 10 different items, or maybe someone requires that at least 5 different items be purchased per order due to shipping costs or some such thing.
At any rate, the following patch to uc_cart.module provides some settings (admin/store/settings/cart) that allow you to do just that. The defaults are set to 0, which equate to no minimum, and unlimited for minimum and maximum # of items respectively.
In combination with the aforementioned modules, I think this gives you pretty ultimate control and flexibility over item quantity requirements and restrictions.
The code I modified came from the beta 5 release listed on drupal. The modifications I made can be identified by looking between the commented and tags (Craftyspace is the web dev company I work for).
I'm including the changed code in this post for easy browsing reference.
In function uc_cart_settings_overview() added to the $items array of $sections:
//<craftyspace+>
t('Minimum number of cart items allowed during checkout is !min.',
array('!min' => variable_get('uc_minimum_item_count', 0) ? variable_get('uc_minimum_item_count', 0) : 'unlimited')),
t('Maximum number of cart items allowed during checkout is !max.',
array('!max' => variable_get('uc_maximum_item_count', 0) ? variable_get('uc_maximum_item_count', 0) : 'unlimited')),
//</craftyspace+>In function uc_cart_settings_form():
//<craftyspace+>
$form['general']['uc_minimum_item_count'] = array(
'#type' => 'textfield',
'#title' => t('Minimum number of cart items'),
'#description' => t('Optionally specify the minimum number of cart items required to proceed to checkout. Use 0 for no minimum'),
'#default_value' => variable_get('uc_minimum_item_count', 0),
'#size' => 16,
);
$form['general']['uc_maximum_item_count'] = array(
'#type' => 'textfield',
'#title' => t('Maximum number of cart items'),
'#description' => t('Optionally specify the maximum number of cart items allowed before proceeding to checkout. Use 0 for no limit.'),
'#default_value' => variable_get('uc_maximum_item_count', 0),
'#size' => 16,
);
//</craftyspace+>And finally,
In function uc_cart_checkout():
function uc_cart_checkout() {
global $user;
$items = uc_cart_get_contents();
if (count($items) == 0 || !variable_get('uc_checkout_enabled', TRUE)) {
drupal_goto('cart');
}
//<craftyspace+>
$iMinItems = variable_get('uc_minimum_item_count', 0);
$iMaxItems = variable_get('uc_maximum_item_count', 0);
if(count($items) < $iMinItems) {
drupal_set_message('You must purchase at least '.format_plural($iMinItems,'1 item', '@count different items').' to complete your checkout.');
drupal_goto('cart');
}
if(count($items) > $iMaxItems && $iMaxItems) {
drupal_set_message('You can not purchase more than '.format_plural($iMaxItems,'1 item', '@count different items'). ' at a time.');
drupal_goto('cart');
}
//</craftyspace+>
....I hope this proves useful.
-Justin
| Attachment | Size |
|---|---|
| uc_cart.txt | 78.93 KB |

Problem implementing
Hello Justin,
I need to limit the number of items in the cart as well and found your patch. I have added your changes to ubercart-5.x-1.0-rc2 and I am able to set the cart setting but having more items than the maximum value does not trigger the error message and a return to the cart. Any tips on how to debug your modifications would a great help.
Thanks for the patch,
Patrick
Re: Problem implementing
Just took a quick peak, and I believe the trouble is that doing a count() on the $items array will turn up how many unique products are on the order, but it doesn't take into account their quantity. You'll actually need to loop through the array and add up the quantities to restrict checkout properly.
Also, this could be made into a module fairly simply... you need to get your code to run when the checkout page is loaded (since people can link there directly), so you'd want to make this into a checkout pane with a weight of -10. For an example, you can check out the WonderPay contrib.
Re: Re: Problem implementing
That's exactly the point: There are already modules built that let you set minimum and maximums quantities for each product individually (see the links in my original post), but nothing I could find previously handles the min/max number of unique products in the cart.
What I needed was to have a store that allowed the customer to purchase 1 quantity of 1 product and nothing more. With the product min/max modules, I could restrict the quantity of each product, but then the customer could still order 1 of product a, 1 of product b, etc. This patch in combination with the product max module allowed me to set it up so that the customer can only get 1 of product a, OR 1 of product b. I hope that's clear.
I'll look into turning it into a module, although I thought having this in the cart settings / cart module was a appropriate place.
Re: Problem implementing
Patrick, my guess is that what you're looking for this module:
Product Maximum (http://www.ubercart.org/contrib/2155)
Or it may be that like me you actually need to use both in conjunction with each other to get the results you're looking for.
Read my above post for additional clarification on what this patch actually does.
Re: Re: Re: Problem implementing
Aye, I think I understood the concept of the module, but if you just do a count($items), it's going to say 1 even if someone orders 10 of a single product. This is because for unique products, it's stored in a single line in that array w/ a qty field. Do a print_r() on $items to see the structure.
Re: Re: Problem implementing
What I want to do is set a limit on the total number of items in the cart. It does not matter if all of the items are the same product or different products as long as the total number of items is not greater than the limit. It seems the solution is somewhere between your code and the Product Maximum module with a little Wonderpay thrown in the mix. I am not very knowledgeable with php and building modules at the moment so creating my own module will be difficult but I do know C and can read the code so I will try to hack through it.
Thanks for all the help,
Patrick
Quote:I think I understood
I'm sorry Ryan, but I'm afraid I don't believe you understand the concept. Forgive me if I've been unclear, but I'd like to try to iterate this one more time.
I am 100% aware that count($items) is going to say 1 even if someone orders 10 of a single product. It will say 2 if someone orders 10 of one product, and 20 of another. That is the point. I am counting the number of different types of items in the cart.
I'm afraid that you won't be able to do exactly that with either of these modules or the combination of them.
I believe what you are after (and what Ryan thought my code was intended to do) is something that iterates through all the different items in the cart and adds up their quantities. This calculated value is then what's compared to the maximum number allowed as specified in the settings.
In retrospect, this approach would probably make a lot more sense for the reuse of others. I approached it a bit sideways, looking for the quickest and simplest way to solve my own issue, which didn't require that I know anything about the quantities of items. Counting $items was the quickest way I found to solve it, although I see now how counterintuitive my approach could seem.
When I have the opportunity I'll rewrite the code so that it is a module rather than a patch, and have it function in the more intuitive manner as mentioned above.