Drupal 6 Ubercart hook_uc_checkout_complete and content_profile
Share with Others
On a recent Drupal 6 multi-currency Ubercart website I came across the following requirements.
- I needed to save a users preferences to determine whether to display prices with VAT or not
- I needed the user to be able to manage these preferences from within their account settings
- When the user purchased something, either for the first time, or multiple times, I needed their preferences to be updated
In this post I will go over part of my solution to solve these requirements. My implementation is just one of many ways that I thought about building this solution out. Here is what I did.
Drupal 6 content_profile module
I installed the Drupal 6 content_profile module and created a simple preferences content type for storing a users preferences. The main field of note here is a country field (I had other fields in the content type). To ensure that the field contained the correct Ubercart countries and the correct numeric values, I used the following PHP to build out the available options. Note: I broke this out into a function inside a custom module and just called the function inside the available options PHP code section. Most of this code was borrowed directly from the Ubercart module.
$order_by = 'country_name'; $result = db_query("SELECT * FROM {uc_countries} WHERE version > 0 ORDER BY country_name"); $options = array(); while ($country = db_fetch_array($result)) { $options[$country['country_id']] = ($order_by == 'country_name') ? t($country[$order_by]) : $country[$order_by]; } if (count($options) == 0) { $options[] = t('No countries found.'); } natcasesort($options); return $options;
Implementing the hook_uc_checkout_complete Ubercart hook
The next step was to make sure that if a user checked out of the store, that their preferences would either be updated (if they already existed) or created (if this is a new user). This way, when a user logs back into the site, they will see the prices as they originally have specified based on their country. I was originally going to use hook_order, but decided instead that the hook_uc_checkout_complete hook was the much easier solution. Here is an example of my hook_uc_checkout_complete implementation that updates or creates a "preferences" content type based on the orders billing country.
/** * Implements hook_uc_checkout_complete(). */ function MYMODULE_uc_checkout_complete($order, $account) { // Get the nid of the existing preferences node. $sql = "SELECT n.nid FROM {content_type_preferences} ctp INNER JOIN {node} n ON ctp.nid = n.nid WHERE n.uid = %d"; $result = db_fetch_object(db_query($sql, $account->uid)); // Check if the user has a preferences node created. if (isset($result->nid)) { // Load the full node object. $node = node_load($result->nid); // Set the country field. if (isset($country)) { $node->field_country[0]['value'] = $order->billing_country; } // Set other fields if needed. // Save the updated node. $node = node_submit($node); node_save($node); } else { // We need to create a new preferences node. $node = new stdClass(); $node->type = 'preferences'; $node->title = $account->name . 'Preferences'; $node->uid = $account->uid; $node->name = $account->name; $node->comment = 0; $node->promote = 0; // Set the country fields value. if (isset($country)) { $node->field_country[0]['value'] = $order->billing_country; } // Set other fields values if needed. // Create the node. $node = node_submit($node); node_save($node); } }
Additional notes
I also added some settings to the users $_SESSION variable to handle displaying things for anonymous users. I won't go into all that detail here, but it is an important note.
hook_uc_checkout_complete and content_profile conclusion
The above was only a small part of my total solution to get this working but was one of the most important pieces to the puzzle. If you need an example on how the hook_uc_checkout_complete Ubercart hook can be used or how to create a content_profile node programmatically, the above code should be able to help you out.
Any questions or comments? Let me know below.