1) {
$result[] = array(
'success' => FALSE,
'message' => t('Sorry, you can only add one of those at a time.'),
);
}
return $result;
}
/**
* Adds extra information to a cart item's "data" array.
*
* This is effectively the submit handler of any alterations to the Add to Cart
* form. It provides a standard way to store the extra information so that it
* can be used by hook_uc_add_to_cart().
*
* @param $form_values
* The values submitted to the Add to Cart form.
*
* @return
* An array of data to be merged into the item added to the cart.
*/
function hook_uc_add_to_cart_data($form_values) {
$node = node_load($form_values['nid']);
return array('module' => 'uc_product', 'shippable' => $node->shippable);
}
/**
* Controls the display of an item in the cart.
*
* Product type modules allow the creation of nodes that can be added to the
* cart. The cart determines how they are displayed through this hook. This is
* especially important for product kits, because it may be displayed as a
* single unit in the cart even though it is represented as several items.
*
* This hook is only called for the module that owns the cart item in
* question, as set in $item->module.
*
* @param $item
* The item in the cart to display.
*
* @return
* A form array containing the following elements:
* - "nid"
* - #type: value
* - #value: The node id of the $item.
* - "module"
* - #type: value
* - #value: The module implementing this hook and the node represented by
* $item.
* - "remove"
* - #type: submit
* - #value: t('Remove'); when clicked, will remove $item from the cart.
* - "description"
* - #type: markup
* - #value: Themed markup (usually an unordered list) displaying extra
* information.
* - "title"
* - #type: markup
* - #value: The displayed title of the $item.
* - "#total"
* - type: float
* - value: Numeric price of $item. Notice the '#' signifying that this is
* not a form element but just a value stored in the form array.
* - "data"
* - #type: hidden
* - #value: The serialized $item->data.
* - "qty"
* - #type: textfield
* - #value: The quantity of $item in the cart. When "Update cart" is
* clicked, the customer's input is saved to the cart.
*/
function hook_uc_cart_display($item) {
$node = node_load($item->nid);
$element = array();
$element['nid'] = array('#type' => 'value', '#value' => $node->nid);
$element['module'] = array('#type' => 'value', '#value' => 'uc_product');
$element['remove'] = array('#type' => 'checkbox');
$element['title'] = array(
'#markup' => node_access('view', $node) ? l($item->title, 'node/' . $node->nid) : check_plain($item->title),
);
$element['#total'] = $item->price * $item->qty;
$element['data'] = array('#type' => 'hidden', '#value' => serialize($item->data));
$element['qty'] = array(
'#type' => 'textfield',
'#default_value' => $item->qty,
'#size' => 5,
'#maxlength' => 6,
);
if ($description = uc_product_get_description($item)) {
$element['description'] = array('#markup' => $description);
}
return $element;
}
/**
* Act on a cart item before it is about to be created or updated.
*
* @param $entity
* The cart item entity object.
*/
function hook_uc_cart_item_presave($entity) {
$entity->changed = REQUEST_TIME;
}
/**
* Act on cart item entities when inserted.
*
* @param $entity
* The cart item entity object.
*/
function hook_uc_cart_item_insert($entity) {
drupal_set_message(t('An item was added to your cart'));
}
/**
* Act on cart item entities when updated.
*
* @param $entity
* The cart item entity object.
*/
function hook_uc_cart_item_update($entity) {
drupal_set_message(t('An item was updated in your cart'));
}
/**
* Act on cart item entities when deleted.
*
* @param $entity
* The cart item entity object.
*/
function hook_uc_cart_item_delete($entity) {
drupal_set_message(t('An item was deleted from your cart'));
}
/**
* Registers callbacks for a cart pane.
*
* The default cart view page displays a table of the cart contents and a few
* simple form features to manage the cart contents. For a module to add
* information to this page, it must use hook_uc_cart_pane() to define extra
* panes that may be ordered to appear above or below the default information.
*
* @param $items
* The current contents of the shopping cart.
*
* @return
* The function is expected to return an array of pane arrays, keyed by the
* internal ID of the pane, each with the following members:
* - "title"
* - type: string
* - value: The name of the cart pane displayed to the user. Use t().
* - "enabled"
* - type: boolean
* - value: Whether the pane is enabled by default or not.
* (Defaults to TRUE.)
* - "weight"
* - type: integer
* - value: The weight of the pane to determine its display order.
* (Defaults to 0.)
* - "body"
* - type: array
* - value: The body of the pane to be rendered on the cart view screen.
*
* The body gets printed to the screen if it is on the cart view page. For the
* settings page, the body field is ignored. You may want your function to
* check for a NULL argument before processing any queries or foreach() loops.
*/
function hook_uc_cart_pane($items) {
$body = array();
if (!is_null($items)) {
$body = drupal_get_form('uc_cart_view_form', $items) + array(
'#prefix' => '
',
'#suffix' => '
',
);
}
$panes['cart_form'] = array(
'title' => t('Default cart form'),
'enabled' => TRUE,
'weight' => 0,
'body' => $body,
);
return $panes;
}
/**
* Alters cart pane definitions.
*
* @param $panes
* The array of pane information in the format defined in hook_uc_cart_pane(),
* passed by reference.
* @param $items
* The array of item information.
*/
function hook_uc_cart_pane_alter(&$panes, $items) {
$panes['cart_form']['body'] = drupal_get_form('my_custom_pane_form_builder', $items);
}
/**
* Takes action when checkout is completed.
*
* @param $order
* The resulting order object from the completed checkout.
* @param $account
* The customer that completed checkout, either the current user, or the
* account created for an anonymous customer.
*/
function hook_uc_checkout_complete($order, $account) {
// Get previous records of customer purchases.
$nids = array();
$result = db_query("SELECT uid, nid, qty FROM {uc_customer_purchases} WHERE uid = :uid", array(':uid' => $account->uid));
foreach ($result as $record) {
$nids[$record->nid] = $record->qty;
}
// Update records with new data.
$record = array('uid' => $account->uid);
foreach ($order->products as $product) {
$record['nid'] = $product->nid;
if (isset($nids[$product->nid])) {
$record['qty'] = $nids[$product->nid] + $product->qty;
db_write_record($record, 'uc_customer_purchases', array('uid', 'nid'));
}
else {
$record['qty'] = $product->qty;
db_write_record($record, 'uc_customer_purchases');
}
}
}
/**
* Takes action immediately before bringing up the checkout page.
*
* Use drupal_goto() in the hook implementation to abort checkout and
* enforce restrictions on the order.
*
* @param $order
* The order object to check out.
*/
function hook_uc_cart_checkout_start($order) {
$account = user_load($order->uid);
if (is_array($account->roles) && in_array('administrator', $account->roles)) {
drupal_set_message(t('Administrators may not purchase products.', 'error'));
drupal_goto('cart');
}
}
/**
* Registers callbacks for a checkout pane.
*
* The checkout screen for Ubercart is a compilation of enabled checkout panes.
* A checkout pane can be used to display order information, collect data from
* the customer, or interact with other panes. Panes are defined in enabled
* modules with hook_uc_checkout_pane() and displayed and processed through
* specified callback functions. Some of the settings for each pane are
* configurable from the checkout settings page with defaults being specified
* in the hooks.
*
* The default panes are defined in uc_cart.module in the function
* uc_cart_checkout_pane(). These include panes to display the contents of the
* shopping cart and to collect essential site user information, a shipping
* address, a payment address, and order comments. Other included modules offer
* panes for shipping and payment purposes as well.
*
* @return
* An array of checkout pane arrays, keyed by the internal ID of the pane,
* each with the following members:
* - title:
* - type: string
* - value: The name of the pane as it appears on the checkout form.
* - desc:
* - type: string
* - value: A short description of the pane for the admin pages.
* - callback:
* - type: string
* - value: The name of the callback function for this pane.
* - weight:
* - type: integer
* - value: Default weight of the pane, defining its order on the checkout
* form.
* - enabled:
* - type: boolean
* - value: Optional. Whether or not the pane is enabled by default.
* Defaults to TRUE.
* - process:
* - type: boolean
* - value: Optional. Whether or not this pane needs to be processed when
* the checkout form is submitted. Defaults to TRUE.
* - collapsible:
* - type: boolean
* - value: Optional. Whether or not this pane is displayed as a collapsible
* fieldset. Defaults to TRUE.
* - shippable:
* - type: boolean
* - value: Optional. If TRUE, the pane is only shown if the cart is
* shippable. Defaults to NULL.
*
* @see http://www.ubercart.org/docs/developer/245/checkout
*/
function hook_uc_checkout_pane() {
$panes['cart'] = array(
'callback' => 'uc_checkout_pane_cart',
'title' => t('Cart contents'),
'desc' => t("Display the contents of a customer's shopping cart."),
'weight' => 1,
'process' => FALSE,
'collapsible' => FALSE,
);
return $panes;
}
/**
* Builds and proceses a pane defined by hook_uc_checkout_pane().
*
* @param $op
* The operation the pane is performing. Possible values are "view",
* "process", "review", and "settings".
* @param $order
* The order being viewed or edited.
* @param $form
* The order's edit form. NULL for non-edit ops.
* @param &$form_state
* The form state array of the edit form. NULL for non-edit ops.
*
* @return
* Varies according to the value of $op:
* - view: An array with two keys, "contents" and an optional "description".
* "contents" is a form array to collect the checkout data for the pane. The
* description provides help text for the pane as a whole.
* - process: A boolean indicating that checkout should continue. During this
* op, $order should be modified with the values in
* $form_state['values']['panes'][PANE_ID].
* - review: An array containing review sections. A review section contains
* "title" and "data" keys which have HTML to be displayed on the checkout
* review page.
* - settings: A settings form which can be used with system_settings_form().
*/
function uc_checkout_pane_callback($op, $order, $form = NULL, &$form_state = NULL) {
// uc_checkout_pane_comments()
switch ($op) {
case 'view':
$description = t('Use this area for special instructions or questions regarding your order.');
if (!empty($order->order_id)) {
$default = db_query("SELECT message FROM {uc_order_comments} WHERE order_id = :id", array(':id' => $order->order_id))->fetchField();
}
else {
$default = NULL;
}
$contents['comments'] = array(
'#type' => 'textarea',
'#title' => t('Order comments'),
'#default_value' => $default,
);
return array('description' => $description, 'contents' => $contents);
case 'process':
if ($form_state['values']['panes']['comments']['comments']) {
db_delete('uc_order_comments')
->condition('order_id', $order->order_id)
->execute();
uc_order_comment_save($order->order_id, 0, $form_state['values']['panes']['comments']['comments'], 'order', uc_order_state_default('post_checkout'), TRUE);
}
return TRUE;
case 'review':
$review = NULL;
$result = db_query("SELECT message FROM {uc_order_comments} WHERE order_id = :id", array(':id' => $order->order_id));
if ($comment = $result->fetchObject()) {
$review[] = array('title' => t('Comment'), 'data' => check_plain($comment->message));
}
return $review;
}
}
/**
* Alters checkout pane definitions.
*
* @param $panes
* Array with the panes information as defined in hook_uc_checkout_pane(),
* passed by reference.
*/
function hook_uc_checkout_pane_alter(&$panes) {
$panes['cart']['callback'] = 'my_custom_module_callback';
}
/**
* Handles requests to update a cart item.
*
* @param $nid
* Node id of the cart item.
* @param $data
* Array of extra information about the item.
* @param $qty
* The quantity of this item in the cart.
* @param $cid
* The cart id. Defaults to NULL, which indicates that the current user's cart
* should be retrieved with uc_cart_get_id().
*/
function hook_uc_update_cart_item($nid, $data = array(), $qty, $cid = NULL) {
if (!$nid) return NULL;
$cid = !(is_null($cid) || empty($cid)) ? $cid : uc_cart_get_id();
if ($qty < 1) {
uc_cart_remove_item($nid, $cid, $data);
}
else {
db_update('uc_cart_products')
->fields(array(
'qty' => $qty,
'changed' => REQUEST_TIME,
))
->condition('nid', $nid)
->condition('cart_id', $cid)
->condition('data', serialize($data))
->execute();
}
// Rebuild the items hash
uc_cart_get_contents(NULL, 'rebuild');
if (!strpos(request_uri(), 'cart', -4)) {
drupal_set_message(t('Your item(s) have been updated.'));
}
}
/**
* @} End of "addtogroup hooks".
*/