I was recently building an e-commerce solution for someone, and came across a rather irritating issue which after many hours of searching for a solution I still couldn't find any information on, and every solution I found didn't do what I needed it to do. The site is Drupal 6.x with Ubercart 2.x installed as the e-commerce shopping platform, these two products have been proven over and over again to be fantastic, but as I have recently found, it takes a little more than just standard contributed modules to make everything seamless.
The Problem
Whilst building this site I noticed that there were two add to cart buttons on the concept design I was given, one labeled 'Add to cart' and the other 'Add to cart and complete'. On it's own this wouldn't really have posed too much of an issue as Ubercart 2.x comes with the 'Cart Links' module which allows the addition of cart based URLs in template files, this would enable me to just add a link to cart/checkout/*product info* and be done with it. Unfortunately this store uses attributes on many products which don't work with the 'Cart Links' module, and the quantity is also exposed to allow customers to add more than 1 to the cart at a time, this was where my issues started as the Ubercart community seemed very unsure on how to get around this, and the mighty Google wasn't much help either. Enter Drupal FAPI and a bit of module tweaking.
The Solution
Many out there will probably shudder at the thought of modifying anything related to such a large module as Ubercart, however I have recently come around to realising that these modules are a platform to build on, some more complete than others, and some needing a lot of moulding to get working the way you want.
To get the behaviour I wanted I needed to modify two of the Ubercart files, namely the "uc_cart.module" and "uc_product.module" files. These modifications make use of Drupal 6's fantastic FAPI (Form API) to allow two submit buttons to be used to trigger a single submit handler function, which in turn contains an if statement which determines which button has been clicked and performs the correct action. Onto the code...
uc_product.module line 1475function uc_cart_add_item($nid, $qty = 1, $data = NULL, $cid = NULL, $msg = TRUE, $check_redirect = TRUE, $rebuild = TRUE, $tocheck = NULL) {
This function was altered to have an extra variable at the end $tocheck which by default is set to NULL which means it will be ignored unless it's set. This will be used by the 'Add to cart and complete' button.
uc_product.module lines 1505 - 1511if ($row['silent'] === TRUE) {
if ($check_redirect) {
if ($tocheck) {
drupal_goto('cart/checkout');
}
if (isset($_GET['destination'])) {
drupal_goto();
This code adds in the $tocheck variable to redirect to cart/checkout within the $check_redirect section.
uc_product.module lines 1554 - 1561if ($check_redirect) {
if ($tocheck) {
drupal_goto('cart/checkout');
}
if (isset($_GET['destination'])) {
drupal_goto();
}
This does pretty much the same thing as the above but not within the silent setting allowing for both situations. That's all the changes needed to the uc_cart module, the system will work perfectly fine still without having the second button as the $tocheck variable is NULL, just like nothing has changed.
The next sections are from the product module, and are a little more involved, but nothing too taxing.
uc_product.module lines 1492 - 1505),
);
$form['submit2'] = array(
'#type' => 'submit',
'#value' => t('Add to bag and checkout'),
'#id' => 'edit-submit2-'. $node->nid,
'#attributes' => array(
'class' => 'node-add-to-cart',
),
);
$form['node'] = array(
'#type' => 'value',
This chunk of code extends the already existing add_to_cart_form FAPI call and adds another submit button called 'submit2'. If you know Drupal FAPI then this will be pretty standard to you, if not I'd suggest having a look at the FAPI documentation at api.drupal.org as it's fantastic and will help you understand this better.
uc_product.module lines 1525 - 1535/**
* @see uc_product_add_to_cart_form()
*/
function uc_product_add_to_cart_form_submit($form, &$form_state) {
if($form_state['clicked_button']['#value'] == $form_state['values']['submit'])
$form_state['redirect'] = uc_cart_add_item($form_state['values']['nid'], $form_state['values']['qty'], module_invoke_all('add_to_cart_data', $form_state['values']), NULL, variable_get('uc_cart_add_item_msg', TRUE));
else if($form_state['clicked_button']['#value'] == $form_state['values']['submit2'])
$form_state['redirect'] = uc_cart_add_item($form_state['values']['nid'], $form_state['values']['qty'], module_invoke_all('add_to_cart_data', $form_state['values']), NULL, variable_get('uc_cart_add_item_msg', TRUE), TRUE, TRUE, TRUE);
}
I've posted the entire function here as I've changed pretty much the entire thing. Instead of being a single $form_state['redirect'] now, we have 2 submit buttons which need to be redirected to different places so I have placed an if statement seeing which button is clicked. The first if checks to see if it was the original submit button, and if it was then the original redirect is carried out, after this I have an else if statement which checks to see if the second button was clicked, if it was then the $tocheck variable added previously is set to TRUE which will run the drupal_goto() function added, redirecting the user to cart/checkout.
With the way this is coded it would be possible to have as many buttons as you liked with just some more small alterations. When I get more time I'll post up a method of doing just that.


