1) {
$result[] = array(
'success' => FALSE,
'message' => t('Sorry, you can only add one of those at a time.'),
);
}
return $result;
}
/**
* Add 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_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_add_to_cart_data($form_values) {
$node = node_load($form_values['nid']);
return array('module' => 'uc_product', 'shippable' => $node->shippable);
}
/**
* Calculate tax line items for an order.
*
* @param $order
* An order object or an order id.
* @return
* An array of tax line item objects keyed by a module-specific id.
*/
function hook_calculate_tax($order) {
global $user;
if (is_numeric($order)) {
$order = uc_order_load($order);
$account = user_load(array('uid' => $order->uid));
}
elseif ((int)$order->uid) {
$account = user_load(array('uid' => intval($order->uid)));
}
else {
$account = $user;
}
if (!is_object($order)) {
return array();
}
if (empty($order->delivery_postal_code)) {
$order->delivery_postal_code = $order->billing_postal_code;
}
if (empty($order->delivery_zone)) {
$order->delivery_zone = $order->billing_zone;
}
if (empty($order->delivery_country)) {
$order->delivery_country = $order->billing_country;
}
$order->taxes = array();
if (isset($order->order_status)) {
$state = uc_order_status_data($order->order_status, 'state');
$use_same_rates = in_array($state, array('payment_received', 'completed'));
}
else {
$use_same_rates = FALSE;
}
$arguments = array(
'order' => array(
'#entity' => 'uc_order',
'#title' => t('Order'),
'#data' => $order,
),
'tax' => array(
'#entity' => 'tax',
'#title' => t('Tax rule'),
// #data => each $tax in the following foreach() loop;
),
'account' => array(
'#entity' => 'user',
'#title' => t('User'),
'#data' => $account,
),
);
$predicates = ca_load_trigger_predicates('calculate_taxes');
foreach (uc_taxes_rate_load() as $tax) {
if ($use_same_rates) {
foreach ((array)$order->line_items as $old_line) {
if ($old_line['type'] == 'tax' && $old_line['data']['tax_id'] == $tax->id) {
$tax->rate = $old_line['data']['tax_rate'];
break;
}
}
}
$arguments['tax']['#data'] = $tax;
if (ca_evaluate_conditions($predicates['uc_taxes_'. $tax->id], $arguments)) {
$line_item = uc_taxes_action_apply_tax($order, $tax);
if ($line_item) {
$order->taxes[$line_item->id] = $line_item;
}
}
}
return $order->taxes;
}
/**
* Control 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.
*
* @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: checkbox
* - #value: If selected, removes the $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_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(
'#value' => node_access('view', $node) ? l($item->title, 'node/'. $node->nid) : check_plain($item->title),
);
$context = array(
'revision' => 'altered',
'type' => 'cart_item',
'subject' => array(
'cart_item' => $item,
'node' => $node,
),
);
$price_info = array(
'price' => $item->price,
'qty' => $item->qty,
);
$element['#total'] = uc_price($price_info, $context);
$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('#value' => $description);
}
return $element;
}
/**
* Add extra data about an item in the cart.
*
* Products that are added to a customer's cart are referred as items until the
* sale is completed. Just think of a grocery store having a bunch of products
* on the shelves but putting a sign over the express lane saying "15 Items or
* Less." hook_cart_item() is in charge of acting on items at various times like
* when they are being added to a cart, saved, loaded, and checked out.
*
* Here's the rationale for this hook: Products may change on a live site during
* a price increase or change to attribute adjustments. If a user has previously
* added an item to their cart, when they go to checkout or view their cart
* screen we want the latest pricing and model numbers to show. So, the essential
* product information is stored in the cart, but when the items in a cart are
* loaded, modules are given a chance to adjust the data against the latest settings.
*
* @param $op
* The action that is occurring. Possible values:
* - "load" - Passed for each item when a cart is being loaded in the function
* uc_cart_get_contents(). This gives modules the chance to tweak information
* for items when the cart is being loaded prior to being view or added to
* an order. No return value is expected.
* - "can_ship" - Passed when a cart is being scanned for items that are not
* shippable items. Übercart will bypass cart and checkout operations
* specifically related to tangible products if nothing in the cart is
* shippable. hook_cart_item functions that check for this op are expected
* to return TRUE or FALSE based on whether a product is shippable or not.
* @return
* No return value for load.
* TRUE or FALSE for can_ship.
*/
function hook_cart_item($op, &$item) {
switch ($op) {
case 'load':
$term = array_shift(taxonomy_node_get_terms_by_vocabulary($item->nid, variable_get('uc_manufacturer_vid', 0)));
$arg1->manufacturer = $term->name;
break;
}
}
/**
* Register 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_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 with the following
* keys:
* - "id"
* - type: string
* - value: The internal ID of the pane, using a-z, 0-9, and - or _.
* - "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: string
* - value: The body of the pane when 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_cart_pane($items) {
$panes[] = array(
'id' => 'cart_form',
'title' => t('Default cart form'),
'enabled' => TRUE,
'weight' => 0,
'body' => !is_null($items) ? drupal_get_form('uc_cart_view_form', $items) : '',
);
return $panes;
}
/**
* Alter cart pane definitions.
*
* @param $panes
* The array of pane information in the format defined in hook_cart_pane(), passed
* by reference.
*
* @param $items
* The array of item information.
*/
function hook_cart_pane_alter(&$panes, $items) {
foreach ($panes as &$pane) {
if ($pane['id'] == 'cart') {
$pane['body'] = drupal_get_form('my_custom_pane_form_builder', $items);
}
}
}
/**
* Register 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_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 using the following keys:
* - "id"
* - type: string
* - value: The internal ID of the checkout pane, using a-z, 0-9, and - or _.
* - "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. View
* @link http://www.ubercart.org/docs/developer/245/checkout this page @endlink
* for more documentation and examples of checkout pane callbacks.
* - "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.
*/
function hook_checkout_pane() {
$panes[] = array(
'id' => 'cart',
'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;
}
/**
* Alter checkout pane definitions.
*
* @param $panes
* Array with the panes information as defined in hook_checkout_pane(), passed
* by reference.
*/
function hook_checkout_pane_alter(&$panes) {
foreach ($panes as &$pane) {
if ($pane['id'] == 'cart') {
$pane['callback'] = 'my_custom_module_callback';
}
}
}
/**
* Give clearance to a user to download a file.
*
* By default the uc_file module can implement 3 restrictions on downloads: by
* number of IP addresses downloaded from, by number of downloads, and by a set
* expiration date. Developers wishing to add further restrictions can do so by
* implementing this hook. After the 3 aforementioned restrictions are checked,
* the uc_file module will check for implementations of this hook.
*
* @param $user
* The drupal user object that has requested the download
* @param $file_download
* The file download object as defined as a row from the uc_file_users table
* that grants the user the download
* @return
* TRUE or FALSE depending on whether the user is to be permitted download of
* the requested files. When a implementation returns FALSE it should set an
* error message in Drupal using drupal_set_message() to inform customers of
* what is going on.
*/
function hook_download_authorize($user, $file_download) {
if (!$user->status) {
drupal_set_message(t("This account has been banned and can't download files anymore. "),'error');
return FALSE;
}
else {
return TRUE;
}
}
/**
* Perform actions on file products.
*
* The uc_file module comes with a file manager (found at Administer » Store
* administration » Products » View file downloads) that provides some basic
* functionality: deletion of multiple files and directories, and upload of single
* files (those looking to upload multiple files should just directly upload them
* to their file download directory then visit the file manager which automatically
* updates new files found in its directory). Developers that need to create more
* advanced actions with this file manager can do so by using this hook.
*
* @param $op
* The operation being taken by the hook, possible ops defined below.
* - 'info': Called before the uc_file module builds its list of possible file
* actions. This op is used to define new actions that will be placed in
* the file action select box.
* - 'insert': Called after uc_file discovers a new file in the file download
* directory.
* - 'form': When any defined file action is selected and submitted to the form
* this function is called to render the next form. Because this is called
* whenever a module-defined file action is selected, the variable
* $args['action'] can be used to define a new form or append to an existing
* form.
* - 'upload': After a file has been uploaded, via the file manager's built in
* file upload function, and moved to the file download directory this op
* can perform any remaining operations it needs to perform on the file
* before its placed into the uc_files table.
* - 'upload_validate': This op is called to validate the uploaded file that
* was uploaded via the file manager's built in file upload function. At
* this point, the file has been uploaded to PHP's temporary directory.
* Files passing this upload validate function will be moved into the file
* downloads directory.
* - 'validate': This op is called to validate the file action form.
* - 'submit': This op is called to submit the file action form.
* @param $args
* A keyed array of values that varies depending on the op being performed,
* possible values defined below.
* - 'info': None
* - 'insert':
* - 'file_object': The file object of the newly discovered file
* - 'form':
* - 'action': The file action being performed as defined by the key in the
* array sent by hook_file_action($op = 'info')
* - 'file_ids' - The file ids (as defined in the uc_files table) of the
* selected files to perform the action on
* - 'upload':
* - 'file_object': The file object of the file moved into file downloads
* directory
* - 'form_id': The form_id variable of the form_submit function
* - 'form_values': The form_values variable of the form_submit function
* - 'upload_validate':
* - 'file_object': The file object of the file that has been uploaded into
* PHP's temporary upload directory
* - 'form_id': The form_id variable of the form_validate function
* - 'form_values': The form_values variable of the form_validate function
* - 'validate':
* - 'form_id': The form_id variable of the form_validate function
* - 'form_values': The form_values variable of the form_validate function
* - 'submit':
* - 'form_id': The form_id variable of the form_submit function
* - 'form_values': The form_values variable of the form_submit function
* @return
* The return value of hook depends on the op being performed, possible return
* values defined below.
* - 'info': The associative array of possible actions to perform. The keys are
* unique strings that defines the actions to perform. The values are the
* text to be displayed in the file action select box.
* - 'insert': None
* - 'form': This op should return an array of drupal form elements as defined
* by the drupal form API.
* - 'upload': None
* - 'upload_validate': None
* - 'validate': None
* - 'submit': None
*/
function hook_file_action($op, $args) {
switch ($op) {
case 'info':
return array('uc_image_watermark_add_mark' => 'Add Watermark');
case 'insert':
//automatically adds watermarks to any new files that are uploaded to the file download directory
_add_watermark($args['file_object']->filepath);
break;
case 'form':
if ($args['action'] == 'uc_image_watermark_add_mark') {
$form['watermark_text'] = array(
'#type' => 'textfield',
'#title' => t('Watermark Text'),
);
$form['submit_watermark'] = array(
'#type' => 'submit',
'#value' => t('Add Watermark'),
);
}
return $form;
case 'upload':
_add_watermark($args['file_object']->filepath);
break;
case 'upload_validate':
//Given a file path, function checks if file is valid JPEG
if(!_check_image($args['file_object']->filepath)) {
form_set_error('upload',t('Uploaded file is not a valid JPEG'));
}
break;
case 'validate':
if ($args['form_values']['action'] == 'uc_image_watermark_add_mark') {
if (empty($args['form_values']['watermark_text'])) {
form_set_error('watermar_text',t('Must fill in text'));
}
}
break;
case 'submit':
if ($args['form_values']['action'] == 'uc_image_watermark_add_mark') {
foreach ($args['form_values']['file_ids'] as $file_id) {
$filename = db_result(db_query("SELECT filename FROM {uc_files} WHERE fid = %d",$file_id));
//Function adds watermark to image
_add_watermark($filename);
}
}
break;
}
}
/**
* Make changes to a file before it is downloaded by the customer.
*
* Stores, either for customization, copy protection or other reasons, might want
* to send customized downloads to customers. This hook will allow this to happen.
* Before a file is opened to be transfered to a customer, this hook will be called
* to make any altercations to the file that will be used to transfer the download
* to the customer. This, in effect, will allow a developer to create a new,
* personalized, file that will get transfered to a customer.
*
* @param $file_user
* The file_user object (i.e. an object containing a row from the uc_file_users
* table) that corresponds with the user download being accessed.
* @param $ip
* The IP address from which the customer is downloading the file
* @param $fid
* The file id of the file being transfered
* @param $file
* The file path of the file to be transfered
* @return
* The path of the new file to transfer to customer.
*/
function hook_file_transfer_alter($file_user, $ip, $fid, $file) {
$file_data = file_get_contents($file)." [insert personalized data]"; //for large files this might be too memory intensive
$new_file = tempnam(file_directory_temp(),'tmp');
file_put_contents($new_file,$file_data);
return $new_file;
}
/**
* Used to define line items that are attached to orders.
*
* A line item is a representation of charges, fees, and totals for an order.
* Default line items include the subtotal and total line items, the tax line
* item, and the shipping line item. There is also a generic line item that store
* admins can use to add extra fees and discounts to manually created orders.
* Module developers will use this hook to define new types of line items for
* their stores. An example use would be for a module that allows customers to
* use coupons and wants to represent an entered coupon as a line item.
*
* Once a line item has been defined in hook_line_item, Übercart will begin
* interacting with it in various parts of the code. One of the primary ways this
* is done is through the callback function you specify for the line item.
*
* @return
* Your hook should return an array of associative arrays. Each item in the
* array represents a single line item and should use the following keys:
* - "id"
* - type: string
* - value: The internal ID of the line item.
* - "title"
* - type: string
* - value: The title of the line item shown to the user in various interfaces.
* Use t().
* - "callback"
* - type: string
* - value: Name of the line item's callback function, called for various
* operations.
* - "weight"
* - type: integer
* - value: Display order of the line item in lists; "lighter" items are
* displayed first.
* - "stored"
* - type: boolean
* - value: Whether or not the line item will be stored in the database.
* Should be TRUE for any line item that is modifiable from the order
* edit screen.
* - "add_list"
* - type: boolean
* - value: Whether or not a line item should be included in the "Add a Line
* Item" select box on the order edit screen.
* - "calculated"
* - type: boolean
* - value: Whether or not the value of this line item should be added to the
* order total. (Ex: would be TRUE for a shipping charge line item but
* FALSE for the subtotal line item since the product prices are already
* taken into account.)
* - "display_only"
* - type: boolean
* - value: Whether or not this line item is simply a display of information
* but not calculated anywhere. (Ex: the total line item uses display to
* simply show the total of the order at the bottom of the list of line
* items.)
*/
function hook_line_item() {
$items[] = array(
'id' => 'generic',
'title' => t('Empty Line'),
'weight' => 2,
'default' => FALSE,
'stored' => TRUE,
'add_list' => TRUE,
'calculated' => TRUE,
'callback' => 'uc_line_item_generic',
);
return $items;
}
/**
* Alter a line item on an order when the order is loaded.
*
* @param &$item
* The line item array.
* @param $order
* The order object containing the line item.
*/
function hook_line_item_alter(&$item, $order) {
$account = user_load($order->uid);
ca_pull_trigger('calculate_line_item_discounts', $item, $account);
}
/**
* Alter the line item definitions declared in hook_line_item().
*
* @param &$items
* The combined return value of hook_line_item().
*/
function hook_line_item_data_alter(&$items) {
foreach ($items as &$item) {
// Tax amounts are added in to other line items, so the actual tax line
// items should not be added to the order total.
if ($item['id'] == 'tax') {
$item['calculated'] = FALSE;
}
// Taxes are included already, so the subtotal without taxes doesn't
// make sense.
elseif ($item['id'] == 'tax_subtotal') {
$item['callback'] = NULL;
}
}
}
/**
* Perform actions on orders.
*
* An order in Übercart represents a single transaction. Orders are created
* during the checkout process where they sit in the database with a status of In
* Checkout. When a customer completes checkout, the order's status gets updated
* to show that the sale has gone through. Once an order is created, and even
* during its creation, it may be acted on by any module to connect extra
* information to an order. Every time an action occurs to an order, hook_order()
* gets invoked to let your modules know what's happening and make stuff happen.
*
* @param $op
* The action being performed.
* @param &$arg1
* This is the order object or a reference to it as noted below.
* @param $arg2
* This is variable and is based on the value of $op:
* - new: Called when an order is created. $arg1 is a reference to the new
* order object, so modules may add to or modify the order at creation.
* - save: When an order object is being saved, the hook gets invoked with this
* op to let other modules do any necessary saving. $arg1 is a reference to
* the order object.
* - load: Called when an order is loaded after the order and product data has
* been loaded from the database. Passes $arg1 as the reference to the
* order object, so modules may add to or modify the order object when it's
* loaded.
* - submit: When a sale is being completed and the customer has clicked the
* Submit order button from the checkout screen, the hook is invoked with
* this op. This gives modules a chance to determine whether or not the
* order should be allowed. An example use of this is the credit module
* attempting to process payments when an order is submitted and returning
* a failure message if the payment failed.
*
* To prevent an order from passing through, you must return an array
* resembling the following one with the failure message:
* @code
* return array(array('pass' => FALSE, 'message' => t('We were unable to process your credit card.')));
* @endcode
* - can_update: Called before an order's status is changed to make sure the
* order can be updated. $arg1 is the order object with the old order
* status ID ($arg1->order_status), and $arg2 is simply the new order
* status ID. Return FALSE to stop the update for some reason.
* - update: Called when an order's status is changed. $arg1 is the order
* object with the old order status ID ($arg1->order_status), and $arg2 is
* the new order status ID.
* - can_delete: Called before an order is deleted to verify that the order may
* be deleted. Returning FALSE will prevent a delete from happening. (For
* example, the payment module returns FALSE by default when an order has
* already received payments.)
* - delete: Called when an order is deleted and before the rest of the order
* information is removed from the database. Passes $arg1 as the order
* object to let your module clean up it's tables.
* - total: Called when the total for an order is being calculated after the
* total of the products has been added. Passes $arg1 as the order object.
* Expects in return a value (positive or negative) by which to modify the
* order total.
*/
function hook_order($op, &$arg1, $arg2) {
switch ($op) {
case 'save':
// Do something to save payment info!
break;
}
}
/**
* Add links to local tasks for orders on the admin's list of orders.
*
* @param $order
* An order object.
* @return
* An array of specialized link arrays. Each link has the following keys:
* - "name": The title of page being linked.
* - "url": The link path. Do not use url(), but do use the $order's order_id.
* - "icon": HTML of an image.
* - "title": Title attribute text (mouseover tool-tip).
*/
function hook_order_actions($order) {
$actions = array();
$module_path = base_path() . drupal_get_path('module', 'uc_shipping');
if (user_access('fulfill orders')) {
$result = db_query("SELECT nid FROM {uc_order_products} WHERE order_id = %d AND data LIKE '%%s:9:\"shippable\";s:1:\"1\";%%'", $order->order_id);
if (db_num_rows($result)) {
$title = t('Package order !order_id products.', array('!order_id' => $order->order_id));
$actions[] = array(
'name' => t('Package'),
'url' => 'admin/store/orders/'. $order->order_id .'/packages',
'icon' => '',
'title' => $title,
);
$result = db_query("SELECT package_id FROM {uc_packages} WHERE order_id = %d", $order->order_id);
if (db_num_rows($result)) {
$title = t('Ship order !order_id packages.', array('!order_id' => $order->order_id));
$actions[] = array(
'name' => t('Ship'),
'url' => 'admin/store/orders/'. $order->order_id .'/shipments',
'icon' => '
',
'title' => $title,
);
}
}
}
return $actions;
}
/**
* Register callbacks for an order pane.
*
* This hook is used to add panes to the order viewing and administration screens.
* The default panes include areas to display and edit addresses, products,
* comments, etc. Developers should use this hook when they need to display or
* modify any custom data pertaining to an order. For example, a store that uses
* a custom checkout pane to find out a customer's desired delivery date would
* then create a corresponding order pane to show the data on the order screens.
*
* hook_order_pane() works by defining new order panes and providing a little bit
* of information about them. View the return value section below for information
* about what parts of an order pane are defined by the hook.
*
* The real meat of an order pane is its callback function (which is specified in
* the hook). The callback function handles what gets displayed on which screen
* and what data can be manipulated. That is all somewhat out of the scope of
* this API page, so you'll have to click here to read more about what a callback
* function should contain.
*/
function hook_order_pane() {
$panes[] = array(
'id' => 'payment',
'callback' => 'uc_order_pane_payment',
'title' => t('Payment'),
'desc' => t('Specify and collect payment for an order.'),
'class' => 'pos-left',
'weight' => 4,
'show' => array('view', 'edit', 'customer'),
);
return $panes;
}
/**
* Allows modules to alter ordered products when they're loaded with an order.
*
* @param &$product
* The product object as found in the $order object.
* @param $order
* The order object to which the product belongs.
* @return
* Nothing should be returned. Hook implementations should receive the
* $product object by reference and alter it directly.
*/
function hook_order_product_alter(&$product, $order) {
drupal_set_message('hook_order_product_alter(&$product, $order):');
drupal_set_message('&$product:
'. print_r($product, TRUE) .''); drupal_set_message('$order:
'. print_r($order, TRUE) .''); } /** * Register static order states. * * Order states are module-defined categories for order statuses. Each state * will have a default status that is used when modules need to move orders to * new state, but don't know which status to use. * * @return * An array of order state definitions. Each definition is an array with the * following keys: * - id: The machine-readable name of the order state. * - title: The human-readable, translated name. * - weight: The list position of the state. * - scope: Either "specific" or "general". */ function hook_order_state() { $states[] = array( 'id' => 'canceled', 'title' => t('Canceled'), 'weight' => -20, 'scope' => 'specific', ); $states[] = array( 'id' => 'in_checkout', 'title' => t('In checkout'), 'weight' => -10, 'scope' => 'specific', ); $states[] = array( 'id' => 'post_checkout', 'title' => t('Post checkout'), 'weight' => 0, 'scope' => 'general', ); $states[] = array( 'id' => 'completed', 'title' => t('Completed'), 'weight' => 20, 'scope' => 'general', ); return $states; } /** * Register payment gateway callbacks. * * @see @link http://www.ubercart.org/docs/api/hook_payment_gateway @endlink * * @return * Returns an array of payment gateways, which are arrays with the following keys: * - "id" * - type: string * - value: The internal ID of the payment gateway, using a-z, 0-9, and - or * _. * - "title" * - type: string * - value: The name of the payment gateway displayed to the user. Use t(). * - "description" * - type: string * - value: A short description of the payment gateway. * - "settings" * - type: string * - value: The name of a function that returns an array of settings form * elements for the gateway. */ function hook_payment_gateway() { $gateways[] = array( 'id' => 'test_gateway', 'title' => t('Test Gateway'), 'description' => t('Process credit card payments through the Test Gateway.'), 'credit' => 'test_gateway_charge', ); return $gateways; } /** * Register callbacks for payment methods. * * Payment methods are different ways to collect payment. By default, Übercart * comes with support for check, credit card, and generic payments. Payment * methods show up at checkout or on the order administration screens, and they * collect different sorts of information from the user that is used to process * or track the payment. * * @return * An array of payment methods. */ function hook_payment_method() { $methods[] = array( 'id' => 'check', 'name' => t('Check'), 'title' => t('Check or Money Order'), 'desc' => t('Pay by mailing a check or money order.'), 'callback' => 'uc_payment_method_check', 'weight' => 1, 'checkout' => TRUE, ); return $methods; } /** * Perform actions on product classes. * * @param $type * The node type of the product class. * @param $op * The action being performed on the product class: * - "insert": A new node type is created, or an existing node type is being * converted into a product type. * - "update": A product class has been updated. * - "delete": A product class has been deleted. Modules that have attached * additional information to the node type because it is a product type * should delete this information. */ function hook_product_class($type, $op) { switch ($op) { case 'delete': db_query("DELETE FROM {uc_class_attributes} WHERE pcid = '%s'", $type); db_query("DELETE FROM {uc_class_attribute_options} WHERE pcid = '%s'", $type); break; } } /** * Return a structured array representing the given product's description. * * Modules that add data to cart items when they are selected should display it * with this hook. The return values from each implementation will be * sent through to hook_product_description_alter() implementations and then * all descriptions are rendered using drupal_render(). * * @param $product * Product. Usually one of the values of the array returned by * uc_cart_get_contents(). * @return * A structured array that can be fed into drupal_render(). */ function hook_product_description($product) { $description = array( 'attributes' => array( '#product' => array( '#type' => 'value', '#value' => $product, ), '#theme' => 'uc_product_attributes', '#weight' => 1, ), ); $desc =& $description['attributes']; // Cart version of the product has numeric attribute => option values so we // need to retrieve the right ones $weight = 0; if (empty($product->order_id)) { foreach (_uc_cart_product_get_options($product) as $option) { if (!isset($desc[$option['aid']])) { $desc[$option['aid']]['#attribute_name'] = $option['attribute']; $desc[$option['aid']]['#options'] = array($option['name']); } else { $desc[$option['aid']]['#options'][] = $option['name']; } $desc[$option['aid']]['#weight'] = $weight++; } } else { foreach ((array)$product->data['attributes'] as $attribute => $option) { $desc[] = array( '#attribute_name' => $attribute, '#options' => $option, '#weight' => $weight++, ); } } return $description; } /** * Alters the given product description. * * @param $description * Description array reference. * @param $product * The product being described. */ function hook_product_description_alter(&$description, $product) { $description['attributes']['#weight'] = 2; } /** * List node types which should be considered products. * * Trusts the duck philosophy of object identification: if it walks like a duck, * quacks like a duck, and has feathers like a duck, it's probably a duck. * Products are nodes with prices, SKUs, and everything else Übercart expects * them to have. * * @return * Array of node type ids. */ function hook_product_types() { return array('product_kit'); } /** * Handle additional data for shipments. * * @param $op * The action being taken on the shipment. One of the following values: * - "load": The shipment and its packages are loaded from the database. * - "save": Changes to the shipment have been written. * - "delete": The shipment has been deleted and the packages are available * for reshipment. * @param &$shipment * The shipment object. * @return * Only given when $op is "load". An array of extra data to be added to the * shipment object. */ function hook_shipment($op, &$shipment) { switch ($op) { case 'save': $google_order_number = uc_google_checkout_get_google_number($shipment->order_id); if ($google_order_number && $shipment->is_new) { $xml_data = ''; foreach ($shipment->packages as $package) { if ($package->tracking_number) { $tracking_number = $package->tracking_number; } else if ($shipment->tracking_number) { $tracking_number = $shipment->tracking_number; } if ($tracking_number) { foreach ($package->products as $product) { $xml_data .= '