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". */