| 1 |
<?php
|
| 2 |
// $Id:$
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file
|
| 6 |
* These are the hooks that are invoked by the Übercart core.
|
| 7 |
*
|
| 8 |
* Core hooks are typically called in all modules at once using
|
| 9 |
* module_invoke_all().
|
| 10 |
*/
|
| 11 |
|
| 12 |
/**
|
| 13 |
* @addtogroup hooks
|
| 14 |
* @{
|
| 15 |
*/
|
| 16 |
|
| 17 |
/**
|
| 18 |
* Do extra processing when an item is added to the shopping cart.
|
| 19 |
*
|
| 20 |
* Some modules need to be able to hook into the process of adding items to a
|
| 21 |
* cart. For example, an inventory system may need to check stock levels and
|
| 22 |
* prevent an out of stock item from being added to a customer's cart. This hook
|
| 23 |
* lets developers squeeze right in at the end of the process after the product
|
| 24 |
* information is all loaded and the product is about to be added to the cart.
|
| 25 |
* In the event that a product should not be added to the cart, you simply have
|
| 26 |
* to return a failure message described below. This hook may also be used simply
|
| 27 |
* to perform some routine action when products are added to the cart.
|
| 28 |
*
|
| 29 |
* @param $nid
|
| 30 |
* The node ID of the product
|
| 31 |
* @param $qty
|
| 32 |
* The quantity being added
|
| 33 |
* @param $data
|
| 34 |
* The data array, including attributes and model number adjustments
|
| 35 |
* @return
|
| 36 |
* The function can use this data to whatever purpose to see if the item can
|
| 37 |
* be added to the cart or not. The function should return an array containing
|
| 38 |
* the result array. (This is due to the nature of Drupal's module_invoke_all()
|
| 39 |
* function. You must return an array within an array or other module data will
|
| 40 |
* end up getting ignored.) At this moment, there are only three keys:
|
| 41 |
* - "success": TRUE or FALSE for whether the specified quantity of the item
|
| 42 |
* may be added to the cart or not; defaults to TRUE.
|
| 43 |
* - "message": the fail message to display in the event of a failure; if
|
| 44 |
* omitted, Ubercart will display a default fail message.
|
| 45 |
* - "silent": return TRUE to suppress the display of any messages; useful
|
| 46 |
* when a module simply needs to do some other processing during an add to
|
| 47 |
* cart or fail silently.
|
| 48 |
*/
|
| 49 |
function hook_add_to_cart($nid, $qty, $data) {
|
| 50 |
if ($qty > 1) {
|
| 51 |
$result[] = array(
|
| 52 |
'success' => FALSE,
|
| 53 |
'message' => t('Sorry, you can only add one of those at a time.'),
|
| 54 |
);
|
| 55 |
}
|
| 56 |
return $result;
|
| 57 |
}
|
| 58 |
|
| 59 |
/**
|
| 60 |
* Add extra information to a cart item's "data" array.
|
| 61 |
*
|
| 62 |
* This is effectively the submit handler of any alterations to the Add to Cart
|
| 63 |
* form. It provides a standard way to store the extra information so that it
|
| 64 |
* can be used by hook_add_to_cart().
|
| 65 |
*
|
| 66 |
* @param $form_values
|
| 67 |
* The values submitted to the Add to Cart form.
|
| 68 |
* @return
|
| 69 |
* An array of data to be merged into the item added to the cart.
|
| 70 |
*/
|
| 71 |
function hook_add_to_cart_data($form_values) {
|
| 72 |
$node = node_load($form_values['nid']);
|
| 73 |
return array('module' => 'uc_product', 'shippable' => $node->shippable);
|
| 74 |
}
|
| 75 |
|
| 76 |
/**
|
| 77 |
* Control the display of an item in the cart.
|
| 78 |
*
|
| 79 |
* Product type modules allow the creation of nodes that can be added to the
|
| 80 |
* cart. The cart determines how they are displayed through this hook. This is
|
| 81 |
* especially important for product kits, because it may be displayed as a single
|
| 82 |
* unit in the cart even though it is represented as several items.
|
| 83 |
*
|
| 84 |
* @param $item
|
| 85 |
* The item in the cart to display.
|
| 86 |
* @return
|
| 87 |
* A form array containing the following elements:
|
| 88 |
* - "nid"
|
| 89 |
* - #type: value
|
| 90 |
* - #value: The node id of the $item.
|
| 91 |
* - "module"
|
| 92 |
* - #type: value
|
| 93 |
* - #value: The module implementing this hook and the node represented by
|
| 94 |
* $item.
|
| 95 |
* - "remove"
|
| 96 |
* - #type: checkbox
|
| 97 |
* - #value: If selected, removes the $item from the cart.
|
| 98 |
* - "options"
|
| 99 |
* - #type: markup
|
| 100 |
* - #value: Themed markup (usually an unordered list) displaying extra information.
|
| 101 |
* - "title"
|
| 102 |
* - #type: markup
|
| 103 |
* - #value: The displayed title of the $item.
|
| 104 |
* - "#total"
|
| 105 |
* - "type": float
|
| 106 |
* - "value": Numeric price of $item. Notice the '#' signifying that this is
|
| 107 |
* not a form element but just a value stored in the form array.
|
| 108 |
* - "data"
|
| 109 |
* - #type: hidden
|
| 110 |
* - #value: The serialized $item->data.
|
| 111 |
* - "qty"
|
| 112 |
* - #type: textfield
|
| 113 |
* - #value: The quantity of $item in the cart. When "Update cart" is clicked,
|
| 114 |
* the customer's input is saved to the cart.
|
| 115 |
*/
|
| 116 |
function hook_cart_display($item) {
|
| 117 |
$node = node_load($item->nid);
|
| 118 |
$element = array();
|
| 119 |
$element['nid'] = array('#type' => 'value', '#value' => $node->nid);
|
| 120 |
$element['module'] = array('#type' => 'value', '#value' => 'uc_product');
|
| 121 |
$element['remove'] = array('#type' => 'checkbox');
|
| 122 |
$op_names = '';
|
| 123 |
if (module_exists('uc_attribute')){
|
| 124 |
$op_names = "<ul class=\"cart-options\">\n";
|
| 125 |
foreach ($item->options as $option){
|
| 126 |
$op_names .= '<li>'. $option['attribute'] .': '. $option['name'] ."</li>\n";
|
| 127 |
}
|
| 128 |
$op_names .= "</ul>\n";
|
| 129 |
}
|
| 130 |
$element['options'] = array('#value' => $op_names);
|
| 131 |
$element['title'] = array(
|
| 132 |
'#value' => l($node->title, 'node/'. $node->nid),
|
| 133 |
);
|
| 134 |
$element['#total'] = $item->price * $item->qty;
|
| 135 |
$element['data'] = array('#type' => 'hidden', '#value' => serialize($item->data));
|
| 136 |
$element['qty'] = array(
|
| 137 |
'#type' => 'textfield',
|
| 138 |
'#default_value' => $item->qty,
|
| 139 |
'#size' => 3,
|
| 140 |
'#maxlength' => 3
|
| 141 |
);
|
| 142 |
return $element;
|
| 143 |
}
|
| 144 |
|
| 145 |
/**
|
| 146 |
* Add extra data about an item in the cart.
|
| 147 |
*
|
| 148 |
* Products that are added to a customer's cart are referred as items until the
|
| 149 |
* sale is completed. Just think of a grocery store having a bunch of products
|
| 150 |
* on the shelves but putting a sign over the express lane saying "15 Items or
|
| 151 |
* Less." hook_cart_item() is in charge of acting on items at various times like
|
| 152 |
* when they are being added to a cart, saved, loaded, and checked out.
|
| 153 |
*
|
| 154 |
* Here's the rationale for this hook: Products may change on a live site during
|
| 155 |
* a price increase or change to attribute adjustments. If a user has previously
|
| 156 |
* added an item to their cart, when they go to checkout or view their cart
|
| 157 |
* screen we want the latest pricing and model numbers to show. So, the essential
|
| 158 |
* product information is stored in the cart, but when the items in a cart are
|
| 159 |
* loaded, modules are given a chance to adjust the data against the latest settings.
|
| 160 |
*
|
| 161 |
* @param $op
|
| 162 |
* The action that is occurring. Possible values:
|
| 163 |
* - "load" - Passed for each item when a cart is being loaded in the function
|
| 164 |
* uc_cart_get_contents(). This gives modules the chance to tweak information
|
| 165 |
* for items when the cart is being loaded prior to being view or added to
|
| 166 |
* an order. No return value is expected.
|
| 167 |
* - "can_ship" - Passed when a cart is being scanned for items that are not
|
| 168 |
* shippable items. Übercart will bypass cart and checkout operations
|
| 169 |
* specifically related to tangible products if nothing in the cart is
|
| 170 |
* shippable. hook_cart_item functions that check for this op are expected
|
| 171 |
* to return TRUE or FALSE based on whether a product is shippable or not.
|
| 172 |
* @return
|
| 173 |
* No return value for load.
|
| 174 |
* TRUE or FALSE for can_ship.
|
| 175 |
*/
|
| 176 |
function hook_cart_item($op, &$item) {
|
| 177 |
switch ($op) {
|
| 178 |
case 'load':
|
| 179 |
$term = array_shift(taxonomy_node_get_terms_by_vocabulary($item->nid, variable_get('uc_manufacturer_vid', 0)));
|
| 180 |
$arg1->manufacturer = $term->name;
|
| 181 |
break;
|
| 182 |
}
|
| 183 |
}
|
| 184 |
|
| 185 |
/**
|
| 186 |
* Register callbacks for a cart pane.
|
| 187 |
*
|
| 188 |
* The default cart view page displays a table of the cart contents and a few
|
| 189 |
* simple form features to manage the cart contents. For a module to add
|
| 190 |
* information to this page, it must use hook_cart_pane to define extra panes
|
| 191 |
* that may be ordered to appear above or below the default information.
|
| 192 |
*
|
| 193 |
* @param $items
|
| 194 |
* The current contents of the shopping cart.
|
| 195 |
* @return
|
| 196 |
* The function is expected to return an array of pane arrays with the following
|
| 197 |
* keys:
|
| 198 |
* - "id"
|
| 199 |
* - type: string
|
| 200 |
* - value: The internal ID of the pane, using a-z, 0-9, and - or _.
|
| 201 |
* - "title"
|
| 202 |
* - type: string
|
| 203 |
* - value: The name of the cart pane displayed to the user. Use t().
|
| 204 |
* - "enabled"
|
| 205 |
* - type: boolean
|
| 206 |
* - value: Whether the pane is enabled by default or not. (Defaults to TRUE.)
|
| 207 |
* - "weight"
|
| 208 |
* - type: integer
|
| 209 |
* - value: The weight of the pane to determine its display order. (Defaults
|
| 210 |
* to 0.)
|
| 211 |
* - "body"
|
| 212 |
* - type: string
|
| 213 |
* - value: The body of the pane when rendered on the cart view screen.
|
| 214 |
*
|
| 215 |
* The body gets printed to the screen if it is on the cart view page. For the
|
| 216 |
* settings page, the body field is ignored. You may want your function to check
|
| 217 |
* for a NULL argument before processing any queries or foreach() loops.
|
| 218 |
*/
|
| 219 |
function hook_cart_pane($items) {
|
| 220 |
$panes[] = array(
|
| 221 |
'id' => 'cart_form',
|
| 222 |
'title' => t('Default cart form'),
|
| 223 |
'enabled' => TRUE,
|
| 224 |
'weight' => 0,
|
| 225 |
'body' => !is_null($items) ? drupal_get_form('uc_cart_view_form', $items) : '',
|
| 226 |
);
|
| 227 |
|
| 228 |
return $panes;
|
| 229 |
}
|
| 230 |
|
| 231 |
/**
|
| 232 |
* Register callbacks for a checkout pane.
|
| 233 |
*
|
| 234 |
* The checkout screen for Ubercart is a compilation of enabled checkout panes.
|
| 235 |
* A checkout pane can be used to display order information, collect data from
|
| 236 |
* the customer, or interact with other panes. Panes are defined in enabled modules
|
| 237 |
* with hook_checkout_pane() and displayed and processed through specified callback
|
| 238 |
* functions. Some of the settings for each pane are configurable from the checkout
|
| 239 |
* settings page with defaults being specified in the hooks.
|
| 240 |
*
|
| 241 |
* The default panes are defined in uc_cart.module in the function
|
| 242 |
* uc_cart_checkout_pane(). These include panes to display the contents of the
|
| 243 |
* shopping cart and to collect essential site user information, a shipping address,
|
| 244 |
* a payment address, and order comments. Other included modules offer panes for
|
| 245 |
* shipping and payment purposes as well.
|
| 246 |
*
|
| 247 |
* @return
|
| 248 |
* An array of checkout pane arrays using the following keys:
|
| 249 |
* - "id"
|
| 250 |
* - type: string
|
| 251 |
* - value: The internal ID of the checkout pane, using a-z, 0-9, and - or _.
|
| 252 |
* - "title"
|
| 253 |
* - type: string
|
| 254 |
* - value:The name of the pane as it appears on the checkout form.
|
| 255 |
* - "desc"
|
| 256 |
* - type: string
|
| 257 |
* - value: A short description of the pane for the admin pages.
|
| 258 |
* - "callback"
|
| 259 |
* - type: string
|
| 260 |
* - value: The name of the callback function for this pane. View
|
| 261 |
* @link http://www.ubercart.org/docs/developer/245/checkout this page @endlink
|
| 262 |
* for more documentation and examples of checkout pane callbacks.
|
| 263 |
* - "weight"
|
| 264 |
* - type: integer
|
| 265 |
* - value: Default weight of the pane, defining its order on the checkout form.
|
| 266 |
* - "enabled"
|
| 267 |
* - type: boolean
|
| 268 |
* - value: Optional. Whether or not the pane is enabled by default. Defaults
|
| 269 |
* to TRUE.
|
| 270 |
* - "process"
|
| 271 |
* - type: boolean
|
| 272 |
* - value: Optional. Whether or not this pane needs to be processed when the
|
| 273 |
* checkout form is submitted. Defaults to TRUE.
|
| 274 |
* - "collapsible"
|
| 275 |
* - type: boolean
|
| 276 |
* - value: Optional. Whether or not this pane is displayed as a collapsible
|
| 277 |
* fieldset. Defaults to TRUE.
|
| 278 |
*/
|
| 279 |
function hook_checkout_pane() {
|
| 280 |
$panes[] = array(
|
| 281 |
'id' => 'cart',
|
| 282 |
'callback' => 'uc_checkout_pane_cart',
|
| 283 |
'title' => t('Cart Contents'),
|
| 284 |
'desc' => t("Display the contents of a customer's shopping cart."),
|
| 285 |
'weight' => 1,
|
| 286 |
'process' => FALSE,
|
| 287 |
'collapsible' => FALSE,
|
| 288 |
);
|
| 289 |
return $panes;
|
| 290 |
}
|
| 291 |
|
| 292 |
/**
|
| 293 |
* Give clearance to a user to download a file.
|
| 294 |
*
|
| 295 |
* By default the uc_file module can implement 3 restrictions on downloads: by
|
| 296 |
* number of IP addresses downloaded from, by number of downloads, and by a set
|
| 297 |
* expiration date. Developers wishing to add further restrictions can do so by
|
| 298 |
* implementing this hook. After the 3 aforementioned restrictions are checked,
|
| 299 |
* the uc_file module will check for implementations of this hook.
|
| 300 |
*
|
| 301 |
* @param $user
|
| 302 |
* The drupal user object that has requested the download
|
| 303 |
* @param $file_download
|
| 304 |
* The file download object as defined as a row from the uc_file_users table
|
| 305 |
* that grants the user the download
|
| 306 |
* @return
|
| 307 |
* TRUE or FALSE depending on whether the user is to be permitted download of
|
| 308 |
* the requested files. When a implementation returns FALSE it should set an
|
| 309 |
* error message in Drupal using drupal_set_message() to inform customers of
|
| 310 |
* what is going on.
|
| 311 |
*/
|
| 312 |
function hook_download_authorize($user, $file_download) {
|
| 313 |
if (!$user->status) {
|
| 314 |
drupal_set_message(t("This account has been banned and can't download files anymore. "),'error');
|
| 315 |
return FALSE;
|
| 316 |
}
|
| 317 |
else {
|
| 318 |
return TRUE;
|
| 319 |
}
|
| 320 |
}
|
| 321 |
|
| 322 |
/**
|
| 323 |
* Perform actions on file products.
|
| 324 |
*
|
| 325 |
* The uc_file module comes with a file manager (found at Administer » Store
|
| 326 |
* administration » Products » View file downloads) that provides some basic
|
| 327 |
* functionality: deletion of multiple files and directories, and upload of single
|
| 328 |
* files (those looking to upload multiple files should just directly upload them
|
| 329 |
* to their file download directory then visit the file manager which automatically
|
| 330 |
* updates new files found in its directory). Developers that need to create more
|
| 331 |
* advanced actions with this file manager can do so by using this hook.
|
| 332 |
*
|
| 333 |
* @param $op
|
| 334 |
* The operation being taken by the hook, possible ops defined below.
|
| 335 |
* - 'info': Called before the uc_file module builds its list of possible file
|
| 336 |
* actions. This op is used to define new actions that will be placed in
|
| 337 |
* the file action select box.
|
| 338 |
* - 'insert': Called after uc_file discovers a new file in the file download
|
| 339 |
* directory.
|
| 340 |
* - 'form': When any defined file action is selected and submitted to the form
|
| 341 |
* this function is called to render the next form. Because this is called
|
| 342 |
* whenever a module-defined file action is selected, the variable
|
| 343 |
* $args['action'] can be used to define a new form or append to an existing
|
| 344 |
* form.
|
| 345 |
* - 'upload': After a file has been uploaded, via the file manager's built in
|
| 346 |
* file upload function, and moved to the file download directory this op
|
| 347 |
* can perform any remaining operations it needs to perform on the file
|
| 348 |
* before its placed into the uc_files table.
|
| 349 |
* - 'upload_validate': This op is called to validate the uploaded file that
|
| 350 |
* was uploaded via the file manager's built in file upload function. At
|
| 351 |
* this point, the file has been uploaded to PHP's temporary directory.
|
| 352 |
* Files passing this upload validate function will be moved into the file
|
| 353 |
* downloads directory.
|
| 354 |
* - 'validate': This op is called to validate the file action form.
|
| 355 |
* - 'submit': This op is called to submit the file action form.
|
| 356 |
* @param $args
|
| 357 |
* A keyed array of values that varies depending on the op being performed,
|
| 358 |
* possible values defined below.
|
| 359 |
* - 'info': None
|
| 360 |
* - 'insert':
|
| 361 |
* - 'file_object': The file object of the newly discovered file
|
| 362 |
* - 'form':
|
| 363 |
* - 'action': The file action being performed as defined by the key in the
|
| 364 |
* array sent by hook_file_action($op = 'info')
|
| 365 |
* - 'file_ids' - The file ids (as defined in the uc_files table) of the
|
| 366 |
* selected files to perform the action on
|
| 367 |
* - 'upload':
|
| 368 |
* - 'file_object': The file object of the file moved into file downloads
|
| 369 |
* directory
|
| 370 |
* - 'form_id': The form_id variable of the form_submit function
|
| 371 |
* - 'form_values': The form_values variable of the form_submit function
|
| 372 |
* - 'upload_validate':
|
| 373 |
* - 'file_object': The file object of the file that has been uploaded into
|
| 374 |
* PHP's temporary upload directory
|
| 375 |
* - 'form_id': The form_id variable of the form_validate function
|
| 376 |
* - 'form_values': The form_values variable of the form_validate function
|
| 377 |
* - 'validate':
|
| 378 |
* - 'form_id': The form_id variable of the form_validate function
|
| 379 |
* - 'form_values': The form_values variable of the form_validate function
|
| 380 |
* - 'submit':
|
| 381 |
* - 'form_id': The form_id variable of the form_submit function
|
| 382 |
* - 'form_values': The form_values variable of the form_submit function
|
| 383 |
* @return
|
| 384 |
* The return value of hook depends on the op being performed, possible return
|
| 385 |
* values defined below.
|
| 386 |
* - 'info': The associative array of possible actions to perform. The keys are
|
| 387 |
* unique strings that defines the actions to perform. The values are the
|
| 388 |
* text to be displayed in the file action select box.
|
| 389 |
* - 'insert': None
|
| 390 |
* - 'form': This op should return an array of drupal form elements as defined
|
| 391 |
* by the drupal form API.
|
| 392 |
* - 'upload': None
|
| 393 |
* - 'upload_validate': None
|
| 394 |
* - 'validate': None
|
| 395 |
* - 'submit': None
|
| 396 |
*/
|
| 397 |
function hook_file_action($op, $args) {
|
| 398 |
switch ($op) {
|
| 399 |
case 'info':
|
| 400 |
return array('uc_image_watermark_add_mark' => 'Add Watermark');
|
| 401 |
case 'insert':
|
| 402 |
//automatically adds watermarks to any new files that are uploaded to the file download directory
|
| 403 |
_add_watermark($args['file_object']->filepath);
|
| 404 |
break;
|
| 405 |
case 'form':
|
| 406 |
if ($args['action'] == 'uc_image_watermark_add_mark') {
|
| 407 |
$form['watermark_text'] = array(
|
| 408 |
'#type' => 'textfield',
|
| 409 |
'#title' => t('Watermark Text'),
|
| 410 |
);
|
| 411 |
$form['submit_watermark'] = array(
|
| 412 |
'#type' => 'submit',
|
| 413 |
'#value' => t('Add Watermark'),
|
| 414 |
);
|
| 415 |
}
|
| 416 |
return $form;
|
| 417 |
case 'upload':
|
| 418 |
_add_watermark($args['file_object']->filepath);
|
| 419 |
break;
|
| 420 |
case 'upload_validate':
|
| 421 |
//Given a file path, function checks if file is valid JPEG
|
| 422 |
if(!_check_image($args['file_object']->filepath)) {
|
| 423 |
form_set_error('upload',t('Uploaded file is not a valid JPEG'));
|
| 424 |
}
|
| 425 |
break;
|
| 426 |
case 'validate':
|
| 427 |
if ($args['form_values']['action'] == 'uc_image_watermark_add_mark') {
|
| 428 |
if (empty($args['form_values']['watermark_text'])) {
|
| 429 |
form_set_error('watermar_text',t('Must fill in text'));
|
| 430 |
}
|
| 431 |
}
|
| 432 |
break;
|
| 433 |
case 'submit':
|
| 434 |
if ($args['form_values']['action'] == 'uc_image_watermark_add_mark') {
|
| 435 |
foreach ($args['form_values']['file_ids'] as $file_id) {
|
| 436 |
$filename = db_result(db_query("SELECT filename FROM {uc_files} WHERE fid = %d",$file_id));
|
| 437 |
//Function adds watermark to image
|
| 438 |
_add_watermark($filename);
|
| 439 |
}
|
| 440 |
}
|
| 441 |
break;
|
| 442 |
}
|
| 443 |
}
|
| 444 |
|
| 445 |
/**
|
| 446 |
* Make changes to a file before it is downloaded by the customer.
|
| 447 |
*
|
| 448 |
* Stores, either for customization, copy protection or other reasons, might want
|
| 449 |
* to send customized downloads to customers. This hook will allow this to happen.
|
| 450 |
* Before a file is opened to be transfered to a customer, this hook will be called
|
| 451 |
* to make any altercations to the file that will be used to transfer the download
|
| 452 |
* to the customer. This, in effect, will allow a developer to create a new,
|
| 453 |
* personalized, file that will get transfered to a customer.
|
| 454 |
*
|
| 455 |
* @param $file_user
|
| 456 |
* The file_user object (i.e. an object containing a row from the uc_file_users
|
| 457 |
* table) that corresponds with the user download being accessed.
|
| 458 |
* @param $ip
|
| 459 |
* The IP address from which the customer is downloading the file
|
| 460 |
* @param $fid
|
| 461 |
* The file id of the file being transfered
|
| 462 |
* @param $file
|
| 463 |
* The file path of the file to be transfered
|
| 464 |
* @return
|
| 465 |
* The path of the new file to transfer to customer.
|
| 466 |
*/
|
| 467 |
function hook_file_transfer_alter($file_user, $ip, $fid, $file) {
|
| 468 |
$file_data = file_get_contents($file)." [insert personalized data]"; //for large files this might be too memory intensive
|
| 469 |
$new_file = tempnam(file_directory_temp(),'tmp');
|
| 470 |
file_put_contents($new_file,$file_data);
|
| 471 |
return $new_file;
|
| 472 |
}
|
| 473 |
|
| 474 |
/**
|
| 475 |
* Used to define line items that are attached to orders.
|
| 476 |
*
|
| 477 |
* A line item is a representation of charges, fees, and totals for an order.
|
| 478 |
* Default line items include the subtotal and total line items, the tax line
|
| 479 |
* item, and the shipping line item. There is also a generic line item that store
|
| 480 |
* admins can use to add extra fees and discounts to manually created orders.
|
| 481 |
* Module developers will use this hook to define new types of line items for
|
| 482 |
* their stores. An example use would be for a module that allows customers to
|
| 483 |
* use coupons and wants to represent an entered coupon as a line item.
|
| 484 |
*
|
| 485 |
* Once a line item has been defined in hook_line_item, Übercart will begin
|
| 486 |
* interacting with it in various parts of the code. One of the primary ways this
|
| 487 |
* is done is through the callback function you specify for the line item.
|
| 488 |
*
|
| 489 |
* @return
|
| 490 |
* Your hook should return an array of associative arrays. Each item in the
|
| 491 |
* array represents a single line item and should use the following keys:
|
| 492 |
* - "id"
|
| 493 |
* - type: string
|
| 494 |
* - value: The internal ID of the line item.
|
| 495 |
* - "title"
|
| 496 |
* - type: string
|
| 497 |
* - value: The title of the line item shown to the user in various interfaces.
|
| 498 |
* Use t().
|
| 499 |
* - "callback"
|
| 500 |
* - type: string
|
| 501 |
* - value: Name of the line item's callback function, called for various
|
| 502 |
* operations.
|
| 503 |
* - "weight"
|
| 504 |
* - type: integer
|
| 505 |
* - value: Display order of the line item in lists; "lighter" items are
|
| 506 |
* displayed first.
|
| 507 |
* - "stored"
|
| 508 |
* - type: boolean
|
| 509 |
* - value: Whether or not the line item will be stored in the database.
|
| 510 |
* Should be TRUE for any line item that is modifiable from the order
|
| 511 |
* edit screen.
|
| 512 |
* - "add_list"
|
| 513 |
* - type: boolean
|
| 514 |
* - value: Whether or not a line item should be included in the "Add a Line
|
| 515 |
* Item" select box on the order edit screen.
|
| 516 |
* - "calculated"
|
| 517 |
* - type: boolean
|
| 518 |
* - value: Whether or not the value of this line item should be added to the
|
| 519 |
* order total. (Ex: would be TRUE for a shipping charge line item but
|
| 520 |
* FALSE for the subtotal line item since the product prices are already
|
| 521 |
* taken into account.)
|
| 522 |
* - "display_only"
|
| 523 |
* - type: boolean
|
| 524 |
* - value: Whether or not this line item is simply a display of information
|
| 525 |
* but not calculated anywhere. (Ex: the total line item uses display to
|
| 526 |
* simply show the total of the order at the bottom of the list of line
|
| 527 |
* items.)
|
| 528 |
*/
|
| 529 |
function hook_line_item() {
|
| 530 |
$items[] = array(
|
| 531 |
'id' => 'generic',
|
| 532 |
'title' => t('Empty Line'),
|
| 533 |
'weight' => 2,
|
| 534 |
'default' => FALSE,
|
| 535 |
'stored' => TRUE,
|
| 536 |
'add_list' => TRUE,
|
| 537 |
'calculated' => TRUE,
|
| 538 |
'callback' => 'uc_line_item_generic',
|
| 539 |
);
|
| 540 |
|
| 541 |
return $items;
|
| 542 |
}
|
| 543 |
|
| 544 |
/**
|
| 545 |
* Perform actions on orders.
|
| 546 |
*
|
| 547 |
* An order in Übercart represents a single transaction. Orders are created
|
| 548 |
* during the checkout process where they sit in the database with a status of In
|
| 549 |
* Checkout. When a customer completes checkout, the order's status gets updated
|
| 550 |
* to show that the sale has gone through. Once an order is created, and even
|
| 551 |
* during its creation, it may be acted on by any module to connect extra
|
| 552 |
* information to an order. Every time an action occurs to an order, hook_order()
|
| 553 |
* gets invoked to let your modules know what's happening and make stuff happen.
|
| 554 |
*
|
| 555 |
* @param $op
|
| 556 |
* The action being performed.
|
| 557 |
* @param &$arg1
|
| 558 |
* This is the order object or a reference to it as noted below.
|
| 559 |
* @param $arg2
|
| 560 |
* This is variable and is based on the value of $op:
|
| 561 |
* - new: Called when an order is created. $arg1 is a reference to the new
|
| 562 |
* order object, so modules may add to or modify the order at creation.
|
| 563 |
* - save: When an order object is being saved, the hook gets invoked with this
|
| 564 |
* op to let other modules do any necessary saving. $arg1 is a reference to
|
| 565 |
* the order object.
|
| 566 |
* - load: Called when an order is loaded after the order and product data has
|
| 567 |
* been loaded from the database. Passes $arg1 as the reference to the
|
| 568 |
* order object, so modules may add to or modify the order object when it's
|
| 569 |
* loaded.
|
| 570 |
* - submit: When a sale is being completed and the customer has clicked the
|
| 571 |
* Submit order button from the checkout screen, the hook is invoked with
|
| 572 |
* this op. This gives modules a chance to determine whether or not the
|
| 573 |
* order should be allowed. An example use of this is the credit module
|
| 574 |
* attempting to process payments when an order is submitted and returning
|
| 575 |
* a failure message if the payment failed.
|
| 576 |
*
|
| 577 |
* To prevent an order from passing through, you must return an array
|
| 578 |
* resembling the following one with the failure message:
|
| 579 |
* @code
|
| 580 |
* return array(array('pass' => FALSE, 'message' => t('We were unable to process your credit card.')));
|
| 581 |
* @endcode
|
| 582 |
* - can_update: Called before an order's status is changed to make sure the
|
| 583 |
* order can be updated. $arg1 is the order object with the old order
|
| 584 |
* status ID ($arg1->order_status), and $arg2 is simply the new order
|
| 585 |
* status ID. Return FALSE to stop the update for some reason.
|
| 586 |
* - update: Called when an order's status is changed. $arg1 is the order
|
| 587 |
* object with the old order status ID ($arg1->order_status), and $arg2 is
|
| 588 |
* the new order status ID.
|
| 589 |
* - can_delete: Called before an order is deleted to verify that the order may
|
| 590 |
* be deleted. Returning FALSE will prevent a delete from happening. (For
|
| 591 |
* example, the payment module returns FALSE by default when an order has
|
| 592 |
* already received payments.)
|
| 593 |
* - delete: Called when an order is deleted and before the rest of the order
|
| 594 |
* information is removed from the database. Passes $arg1 as the order
|
| 595 |
* object to let your module clean up it's tables.
|
| 596 |
* - total: Called when the total for an order is being calculated after the
|
| 597 |
* total of the products has been added. Passes $arg1 as the order object.
|
| 598 |
* Expects in return a value (positive or negative) by which to modify the
|
| 599 |
* order total.
|
| 600 |
*/
|
| 601 |
function hook_order($op, &$arg1, $arg2) {
|
| 602 |
switch ($op) {
|
| 603 |
case 'save':
|
| 604 |
// Do something to save payment info!
|
| 605 |
break;
|
| 606 |
}
|
| 607 |
}
|
| 608 |
|
| 609 |
/**
|
| 610 |
* Add links to local tasks for orders on the admin's list of orders.
|
| 611 |
*
|
| 612 |
* @param $order
|
| 613 |
* An order object.
|
| 614 |
* @return
|
| 615 |
* An array of specialized link arrays. Each link has the following keys:
|
| 616 |
* - "name": The title of page being linked.
|
| 617 |
* - "url": The link path. Do not use url(), but do use the $order's order_id.
|
| 618 |
* - "icon": HTML of an image.
|
| 619 |
* - "title": Title attribute text (mouseover tool-tip).
|
| 620 |
*/
|
| 621 |
function hook_order_actions($order) {
|
| 622 |
$actions = array();
|
| 623 |
$module_path = base_path() . drupal_get_path('module', 'uc_shipping');
|
| 624 |
if (user_access('fulfill orders')) {
|
| 625 |
$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);
|
| 626 |
if (db_num_rows($result)) {
|
| 627 |
$title = t('Package order !order_id products.', array('!order_id' => $order->order_id));
|
| 628 |
$actions[] = array(
|
| 629 |
'name' => t('Package'),
|
| 630 |
'url' => 'admin/store/orders/'. $order->order_id .'/packages',
|
| 631 |
'icon' => '<img src="'. $module_path .'/images/package.gif" alt="'. $title .'" />',
|
| 632 |
'title' => $title,
|
| 633 |
);
|
| 634 |
$result = db_query("SELECT package_id FROM {uc_packages} WHERE order_id = %d", $order->order_id);
|
| 635 |
if (db_num_rows($result)) {
|
| 636 |
$title = t('Ship order !order_id packages.', array('!order_id' => $order->order_id));
|
| 637 |
$actions[] = array(
|
| 638 |
'name' => t('Ship'),
|
| 639 |
'url' => 'admin/store/orders/'. $order->order_id .'/shipments',
|
| 640 |
'icon' => '<img src="'. $module_path .'/images/ship.gif" alt="'. $title .'" />',
|
| 641 |
'title' => $title,
|
| 642 |
);
|
| 643 |
}
|
| 644 |
}
|
| 645 |
}
|
| 646 |
return $actions;
|
| 647 |
}
|
| 648 |
|
| 649 |
/**
|
| 650 |
* Register callbacks for an order pane.
|
| 651 |
*
|
| 652 |
* This hook is used to add panes to the order viewing and administration screens.
|
| 653 |
* The default panes include areas to display and edit addresses, products,
|
| 654 |
* comments, etc. Developers should use this hook when they need to display or
|
| 655 |
* modify any custom data pertaining to an order. For example, a store that uses
|
| 656 |
* a custom checkout pane to find out a customer's desired delivery date would
|
| 657 |
* then create a corresponding order pane to show the data on the order screens.
|
| 658 |
*
|
| 659 |
* hook_order_pane() works by defining new order panes and providing a little bit
|
| 660 |
* of information about them. View the return value section below for information
|
| 661 |
* about what parts of an order pane are defined by the hook.
|
| 662 |
*
|
| 663 |
* The real meat of an order pane is its callback function (which is specified in
|
| 664 |
* the hook). The callback function handles what gets displayed on which screen
|
| 665 |
* and what data can be manipulated. That is all somewhat out of the scope of
|
| 666 |
* this API page, so you'll have to click here to read more about what a callback
|
| 667 |
* function should contain.
|
| 668 |
*/
|
| 669 |
function hook_order_pane() {
|
| 670 |
$panes[] = array(
|
| 671 |
'id' => 'payment',
|
| 672 |
'callback' => 'uc_order_pane_payment',
|
| 673 |
'title' => t('Payment'),
|
| 674 |
'desc' => t('Specify and collect payment for an order.'),
|
| 675 |
'class' => 'pos-left',
|
| 676 |
'weight' => 4,
|
| 677 |
'show' => array('view', 'edit', 'customer'),
|
| 678 |
);
|
| 679 |
return $panes;
|
| 680 |
}
|
| 681 |
|
| 682 |
/**
|
| 683 |
* Register payment gateway callbacks.
|
| 684 |
*
|
| 685 |
* @see @link http://www.ubercart.org/docs/api/hook_payment_gateway @endlink
|
| 686 |
*
|
| 687 |
* @return
|
| 688 |
* Returns an array of payment gateways, which are arrays with the following keys:
|
| 689 |
* - "id"
|
| 690 |
* - type: string
|
| 691 |
* - value: The internal ID of the payment gateway, using a-z, 0-9, and - or
|
| 692 |
* _.
|
| 693 |
* - "title"
|
| 694 |
* - type: string
|
| 695 |
* - value: The name of the payment gateway displayed to the user. Use t().
|
| 696 |
* - "description"
|
| 697 |
* - type: string
|
| 698 |
* - value: A short description of the payment gateway.
|
| 699 |
* - "settings"
|
| 700 |
* - type: string
|
| 701 |
* - value: The name of a function that returns an array of settings form
|
| 702 |
* elements for the gateway.
|
| 703 |
*/
|
| 704 |
function hook_payment_gateway() {
|
| 705 |
$gateways[] = array(
|
| 706 |
'id' => 'test_gateway',
|
| 707 |
'title' => t('Test Gateway'),
|
| 708 |
'description' => t('Process credit card payments through the Test Gateway.'),
|
| 709 |
'credit' => 'test_gateway_charge',
|
| 710 |
);
|
| 711 |
return $gateways;
|
| 712 |
}
|
| 713 |
|
| 714 |
/**
|
| 715 |
* Register callbacks for payment methods.
|
| 716 |
*
|
| 717 |
* Payment methods are different ways to collect payment. By default, Übercart
|
| 718 |
* comes with support for check, credit card, and generic payments. Payment
|
| 719 |
* methods show up at checkout or on the order administration screens, and they
|
| 720 |
* collect different sorts of information from the user that is used to process
|
| 721 |
* or track the payment.
|
| 722 |
*
|
| 723 |
* @return
|
| 724 |
* An array of payment methods.
|
| 725 |
*/
|
| 726 |
function hook_payment_method() {
|
| 727 |
$methods[] = array(
|
| 728 |
'id' => 'check',
|
| 729 |
'name' => t('Check'),
|
| 730 |
'title' => t('Check or Money Order'),
|
| 731 |
'desc' => t('Pay by mailing a check or money order.'),
|
| 732 |
'callback' => 'uc_payment_method_check',
|
| 733 |
'weight' => 1,
|
| 734 |
'checkout' => TRUE,
|
| 735 |
);
|
| 736 |
return $methods;
|
| 737 |
}
|
| 738 |
|
| 739 |
/**
|
| 740 |
* Perform actions on product classes.
|
| 741 |
*
|
| 742 |
* @param $type
|
| 743 |
* The node type of the product class.
|
| 744 |
* @param $op
|
| 745 |
* The action being performed on the product class:
|
| 746 |
* - "insert": A new node type is created, or an existing node type is being
|
| 747 |
* converted into a product type.
|
| 748 |
* - "update": A product class has been updated.
|
| 749 |
* - "delete": A product class has been deleted. Modules that have attached
|
| 750 |
* additional information to the node type because it is a product type
|
| 751 |
* should delete this information.
|
| 752 |
*/
|
| 753 |
function hook_product_class($type, $op) {
|
| 754 |
switch ($op) {
|
| 755 |
case 'delete':
|
| 756 |
db_query("DELETE FROM {uc_class_attributes} WHERE pcid = '%s'", $type);
|
| 757 |
db_query("DELETE FROM {uc_class_attribute_options} WHERE pcid = '%s'", $type);
|
| 758 |
break;
|
| 759 |
}
|
| 760 |
}
|
| 761 |
|
| 762 |
/**
|
| 763 |
* List node types which should be considered products.
|
| 764 |
*
|
| 765 |
* Trusts the duck philosophy of object identification: if it walks like a duck,
|
| 766 |
* quacks like a duck, and has feathers like a duck, it's probably a duck.
|
| 767 |
* Products are nodes with prices, SKUs, and everything else Übercart expects
|
| 768 |
* them to have.
|
| 769 |
*
|
| 770 |
* @return
|
| 771 |
* Array of node type ids.
|
| 772 |
*/
|
| 773 |
function hook_product_types() {
|
| 774 |
return array('product_kit');
|
| 775 |
}
|
| 776 |
|
| 777 |
/**
|
| 778 |
* Handle additional data for shipments.
|
| 779 |
*
|
| 780 |
* @param $op
|
| 781 |
* The action being taken on the shipment. One of the following values:
|
| 782 |
* - "load": The shipment and its packages are loaded from the database.
|
| 783 |
* - "save": Changes to the shipment have been written.
|
| 784 |
* - "delete": The shipment has been deleted and the packages are available
|
| 785 |
* for reshipment.
|
| 786 |
* @param &$shipment
|
| 787 |
* The shipment object.
|
| 788 |
* @return
|
| 789 |
* Only given when $op is "load". An array of extra data to be added to the
|
| 790 |
* shipment object.
|
| 791 |
*/
|
| 792 |
function hook_shipment($op, &$shipment) {
|
| 793 |
switch ($op) {
|
| 794 |
case 'save':
|
| 795 |
$google_order_number = uc_google_checkout_get_google_number($shipment->order_id);
|
| 796 |
if ($google_order_number && $shipment->is_new) {
|
| 797 |
$xml_data = '';
|
| 798 |
foreach ($shipment->packages as $package) {
|
| 799 |
if ($package->tracking_number) {
|
| 800 |
$tracking_number = $package->tracking_number;
|
| 801 |
}
|
| 802 |
else if ($shipment->tracking_number) {
|
| 803 |
$tracking_number = $shipment->tracking_number;
|
| 804 |
}
|
| 805 |
if ($tracking_number) {
|
| 806 |
foreach ($package->products as $product) {
|
| 807 |
$xml_data .= '<item-shipping-information>';
|
| 808 |
$xml_data .= '<item-id>';
|
| 809 |
$xml_data .= '<merchant-item-id>'. check_plain($product->nid .'|'. $product->model) .'</merchant-item-id>';
|
| 810 |
$xml_data .= '</item-id>';
|
| 811 |
$xml_data .= '<tracking-data-list>';
|
| 812 |
$xml_data .= '<tracking-data>';
|
| 813 |
$xml_data .= '<carrier>'. check_plain($shipment->carrier) .'</carrier>';
|
| 814 |
$xml_data .= '<tracking-number>'. check_plain($tracking_number) .'</tracking-number>';
|
| 815 |
$xml_data .= '</tracking-data>';
|
| 816 |
$xml_data .= '</tracking-data-list>';
|
| 817 |
$xml_data .= '</item-shipping-information>';
|
| 818 |
}
|
| 819 |
}
|
| 820 |
}
|
| 821 |
if ($xml_data) {
|
| 822 |
$request = '<?xml version="1.0" encoding="UTF-8"?>'. "\n";
|
| 823 |
$request .= '<ship-items xmlns="http://checkout.google.com/schema/2" google-order-number="'. $google_order_number .'">';
|
| 824 |
$request .= '<item-shipping-information-list>';
|
| 825 |
$request .= $xml_data;
|
| 826 |
$request .= '</item-shipping-information-list>';
|
| 827 |
$request .= '<send-email>true</send-email>';
|
| 828 |
$request .= '</ship-items>';
|
| 829 |
$response = uc_google_checkout_send_request('request', $request);
|
| 830 |
}
|
| 831 |
}
|
| 832 |
break;
|
| 833 |
case 'delete':
|
| 834 |
$google_order_number = uc_google_checkout_get_google_number($shipment->order_id);
|
| 835 |
if ($google_order_number) {
|
| 836 |
foreach ($shipment->packages as $package) {
|
| 837 |
foreach ($package->products as $product) {
|
| 838 |
$reset_ids[] = check_plain($product->nid .'|'. $product->model);
|
| 839 |
}
|
| 840 |
}
|
| 841 |
$request = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
|
| 842 |
$request .= '<reset-items-shipping-information xmlns="http://checkout.google.com/schema/2" google-order-number="'. $google_order_number .'">';
|
| 843 |
$request .= '<item-ids>';
|
| 844 |
foreach (array_unique($reset_ids) as $item_id) {
|
| 845 |
$request .= '<item-id>';
|
| 846 |
$request .= '<merchant-item-id>'. $item_id .'</merchant-item-id>';
|
| 847 |
$request .= '</item-id>';
|
| 848 |
}
|
| 849 |
$request .= '</item-ids>';
|
| 850 |
$request .= '<send-email>false</send-email>';
|
| 851 |
$request .= '</reset-items-shipping-information>';
|
| 852 |
}
|
| 853 |
$response = uc_google_checkout_send_request('request', $request);
|
| 854 |
break;
|
| 855 |
}
|
| 856 |
}
|
| 857 |
|
| 858 |
/**
|
| 859 |
* Define callbacks and service options for shipping methods.
|
| 860 |
*
|
| 861 |
* The shipping quote controller module, uc_quote, expects a very specific
|
| 862 |
* structured array of methods from the implementations of this hook.
|
| 863 |
*
|
| 864 |
* The weights and enabled flags for shipping methods and types are set at the
|
| 865 |
* Shipping Quote Settings page under Store Configuration. They keys of the
|
| 866 |
* variables are the ids of the shipping methods. The "quote" and "ship" arrays of
|
| 867 |
* the method are both optional.
|
| 868 |
*
|
| 869 |
* @return
|
| 870 |
* An array of shipping methods which have the following keys.
|
| 871 |
* - "type": The quote and shipping types are ids of the product shipping type
|
| 872 |
* that these methods apply to. type may also be 'order' which indicates
|
| 873 |
* that the quote applies to the entire order, regardless of the shipping
|
| 874 |
* types of its products. This is used by quote methods that are base on
|
| 875 |
* the location of the customer rather than their purchase.
|
| 876 |
* - "callback": The function that is called by uc_quote when a shipping quote
|
| 877 |
* is requested. Its arguments are the array of products and an array of
|
| 878 |
* order details (the shipping address). The return value is an array
|
| 879 |
* representing the rates quoted and errors returned (if any) for each
|
| 880 |
* option in the accessorials array.
|
| 881 |
* - "accessorials": This array represents the different options the customer
|
| 882 |
* may choose for their shipment. The callback function should generate a
|
| 883 |
* quote for each option in accessorials and return them via an array.
|
| 884 |
* drupal_to_js() is very useful for this.
|
| 885 |
* @code
|
| 886 |
* return array(
|
| 887 |
* '03' => array('rate' => 15.75, 'format' => uc_currency_format(15.75) 'option_label' => t('UPS Ground'),
|
| 888 |
* 'error' => 'Additional handling charge automatically applied.'),
|
| 889 |
* '14' => array('error' => 'Invalid package type.'),
|
| 890 |
* '59' => array('rate' => 26.03, 'format' => uc_currency_format(26.03), 'option_label' => t('UPS 2nd Day Air A.M.'))
|
| 891 |
* );
|
| 892 |
* @endcode
|
| 893 |
* - "pkg_types": The list of package types that the shipping method can handle.
|
| 894 |
* This should be an associative array that can be used as the #options of
|
| 895 |
* a select form element. It is recommended that a function be written to
|
| 896 |
* output this array so the method doesn't need to be found just for the
|
| 897 |
* package types.
|
| 898 |
*/
|
| 899 |
function hook_shipping_method() {
|
| 900 |
$methods = array();
|
| 901 |
|
| 902 |
$enabled = variable_get('uc_quote_enabled', array('ups' => true));
|
| 903 |
$weight = variable_get('uc_quote_method_weight', array('ups' => 0));
|
| 904 |
$methods['ups'] = array(
|
| 905 |
'id' => 'ups',
|
| 906 |
'title' => t('UPS'),
|
| 907 |
'enabled' => $enabled['ups'],
|
| 908 |
'weight' => $weight['ups'],
|
| 909 |
'quote' => array(
|
| 910 |
'type' => 'small package',
|
| 911 |
'callback' => 'uc_ups_quote',
|
| 912 |
'accessorials' => array(
|
| 913 |
'03' => t('UPS Ground'),
|
| 914 |
'11' => t('UPS Standard'),
|
| 915 |
'01' => t('UPS Next Day Air'),
|
| 916 |
'13' => t('UPS Next Day Air Saver'),
|
| 917 |
'14' => t('UPS Next Day Early A.M.'),
|
| 918 |
'02' => t('UPS 2nd Day Air'),
|
| 919 |
'59' => t('UPS 2nd Day Air A.M.'),
|
| 920 |
'12' => t('UPS 3-Day Select'),
|
| 921 |
),
|
| 922 |
),
|
| 923 |
'ship' => array(
|
| 924 |
'type' => 'small package',
|
| 925 |
'callback' => 'uc_ups_fulfill_order',
|
| 926 |
'pkg_types' => array(
|
| 927 |
'01' => t('UPS Letter'),
|
| 928 |
'02' => t('Customer Supplied Package'),
|
| 929 |
'03' => t('Tube'),
|
| 930 |
'04' => t('PAK'),
|
| 931 |
'21' => t('UPS Express Box'),
|
| 932 |
'24' => t('UPS 25KG Box'),
|
| 933 |
'25' => t('UPS 10KG Box'),
|
| 934 |
'30' => t('Pallet'),
|
| 935 |
),
|
| 936 |
),
|
| 937 |
);
|
| 938 |
|
| 939 |
return $methods;
|
| 940 |
}
|
| 941 |
|
| 942 |
/**
|
| 943 |
* Define shipping types for shipping methods.
|
| 944 |
*
|
| 945 |
* This hook defines a shipping type that this module is designed to handle.
|
| 946 |
* These types are specified by a machine- and human-readable name called 'id',
|
| 947 |
* and 'title' respectively. Shipping types may be set for individual products,
|
| 948 |
* manufacturers, and for the entire store catalog. Shipping modules should be
|
| 949 |
* careful to use the same shipping type ids as other similar shipping modules
|
| 950 |
* (i.e., FedEx and UPS both operate on "small package" shipments). Modules that
|
| 951 |
* do not fulfill orders may not need to implement this hook.
|
| 952 |
*
|
| 953 |
* @return
|
| 954 |
* An array of shipping types keyed by a machine-readable name.
|
| 955 |
*/
|
| 956 |
function hook_shipping_type() {
|
| 957 |
$weight = variable_get('uc_quote_type_weight', array('small_package' => 0));
|
| 958 |
|
| 959 |
$types = array();
|
| 960 |
$types['small_package'] = array(
|
| 961 |
'id' => 'small_package',
|
| 962 |
'title' => t('Small Packages'),
|
| 963 |
'weight' => $weight['small_package'],
|
| 964 |
);
|
| 965 |
|
| 966 |
return $types;
|
| 967 |
}
|
| 968 |
|
| 969 |
/**
|
| 970 |
* Add status messages to the "Store administration" page.
|
| 971 |
*
|
| 972 |
* This hook is used to add items to the store status table on the main store
|
| 973 |
* administration screen. Each item gets a row in the table that consists of a
|
| 974 |
* status icon, title, and description. These items should be used to give
|
| 975 |
* special instructions, notifications, or indicators for components of the cart
|
| 976 |
* enabled by the modules. At a glance, a store owner should be able to look here
|
| 977 |
* and see if a critical component of your module is not functioning properly.
|
| 978 |
*
|
| 979 |
* For example, if the catalog module is installed and it cannot find the catalog
|
| 980 |
* taxonomy vocabulary, it will show an error message here to alert the store
|
| 981 |
* administrator.
|
| 982 |
*
|
| 983 |
* @return
|
| 984 |
* An array of tore status items which are arrays with the following keys:
|
| 985 |
* - "status": "ok", "warning", or "error" depending on the message.
|
| 986 |
* - "title" The title of the status message or module that defines it.
|
| 987 |
* - "desc": The description; can be any message, including links to pages and
|
| 988 |
* forms that deal with the issue being reported.
|
| 989 |
*/
|
| 990 |
function hook_store_status() {
|
| 991 |
if ($key = uc_credit_encryption_key()) {
|
| 992 |
$statuses[] = array(
|
| 993 |
'status' => 'ok',
|
| 994 |
'title' => t('Credit card encryption'),
|
| 995 |
'desc' => t('Credit card data in the database is currently being encrypted.'),
|
| 996 |
);
|
| 997 |
}
|
| 998 |
return $statuses;
|
| 999 |
}
|
| 1000 |
|
| 1001 |
/**
|
| 1002 |
* Convenience function to display large blocks of text in several places.
|
| 1003 |
*
|
| 1004 |
* There are many instances where Ubercart modules have configurable blocks of
|
| 1005 |
* text. These usually come with default messages, like e-mail templates for new
|
| 1006 |
* orders. Because of the way default values are normally set, you're then stuck
|
| 1007 |
* having to copy and paste a large chunk of text in at least two different
|
| 1008 |
* places in the module (when you're wanting to use the variable or to display
|
| 1009 |
* the settings form with the default value). To cut down code clutter, this hook
|
| 1010 |
* was introduced. It lets you put your messages in one place and use the
|
| 1011 |
* function uc_get_message() to retrieve the default value at any time (and from
|
| 1012 |
* any module).
|
| 1013 |
*
|
| 1014 |
* The function is very simple, expecting no arguments and returning a basic
|
| 1015 |
* associative array with keys being message IDs and their values being the
|
| 1016 |
* default message. When you call uc_get_message(), use the message ID you set
|
| 1017 |
* here to refer to the message you want.
|
| 1018 |
*
|
| 1019 |
* Note: When using t(), you must not pass it a concatenated string! So our
|
| 1020 |
* example has no line breaks in the message even though it is much wider than 80
|
| 1021 |
* characters. Using concatenation breaks translation.
|
| 1022 |
*
|
| 1023 |
* @return
|
| 1024 |
* An array of messages.
|
| 1025 |
*/
|
| 1026 |
function hook_uc_message() {
|
| 1027 |
$messages['configurable_message_example'] = t('This block of text represents a configurable message such as a set of instructions or an e-mail template. Using hook_uc_message to handle the default values for these is so easy even your grandma can do it!');
|
| 1028 |
|
| 1029 |
return $messages;
|
| 1030 |
}
|
| 1031 |
|
| 1032 |
/**
|
| 1033 |
* Handle requests to update a cart item.
|
| 1034 |
*
|
| 1035 |
* @param $nid
|
| 1036 |
* Node id of the cart item.
|
| 1037 |
* @param $data
|
| 1038 |
* Array of extra information about the item.
|
| 1039 |
* @param $qty
|
| 1040 |
* The quantity of this item in the cart.
|
| 1041 |
* @param $cid
|
| 1042 |
* The cart id. Defaults to NULL, which indicates that the current user's cart
|
| 1043 |
* should be retrieved with uc_cart_get_id().
|
| 1044 |
*/
|
| 1045 |
function hook_update_cart_item($nid, $data = array(), $qty, $cid = NULL) {
|
| 1046 |
if (!$nid) return NULL;
|
| 1047 |
$cid = !(is_null($cid) || empty($cid)) ? $cid : uc_cart_get_id();
|
| 1048 |
if ($qty < 1) {
|
| 1049 |
uc_cart_remove_item($nid, $cid, $data);
|
| 1050 |
}
|
| 1051 |
else {
|
| 1052 |
db_query("UPDATE {uc_cart_products} SET qty = %d, changed = %d WHERE nid = %d AND cart_id = '%s' AND data = '%s'", $qty, time(), $nid, $cid, serialize($data));
|
| 1053 |
cache_clear_all();
|
| 1054 |
}
|
| 1055 |
|
| 1056 |
// Rebuild the items hash
|
| 1057 |
uc_cart_get_contents(NULL, 'rebuild');
|
| 1058 |
if (!substr(request_uri(), 'cart', -4)) {
|
| 1059 |
drupal_set_message(t('Your item(s) have been updated.'));
|
| 1060 |
}
|
| 1061 |
}
|
| 1062 |
|
| 1063 |
/**
|
| 1064 |
* @} End of "addtogroup hooks".
|
| 1065 |
*/
|