| 1 |
<?php
|
| 2 |
// $Id$
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file
|
| 6 |
* Ajax Attribute Calculations
|
| 7 |
*
|
| 8 |
* Updates product information using AJAX whenever a product attribute is
|
| 9 |
* altered. Also updates the attribute adjustments dynamically if they are
|
| 10 |
* configured to display.
|
| 11 |
*/
|
| 12 |
|
| 13 |
|
| 14 |
/******************************************************************************
|
| 15 |
* Drupal Hooks
|
| 16 |
*****************************************************************************/
|
| 17 |
|
| 18 |
/**
|
| 19 |
* Implementation of hook_menu().
|
| 20 |
*/
|
| 21 |
function uc_aac_menu() {
|
| 22 |
$items['uc_aac'] = array(
|
| 23 |
'title' => t('Product Adjustments'),
|
| 24 |
'description' => t('Calculate the price of your product.'),
|
| 25 |
'page callback' => '_uc_aac_calculate',
|
| 26 |
'access arguments' => array('access content'),
|
| 27 |
'weight' => 5,
|
| 28 |
'type' => MENU_CALLBACK,
|
| 29 |
);
|
| 30 |
|
| 31 |
return $items;
|
| 32 |
}
|
| 33 |
|
| 34 |
/**
|
| 35 |
* Implementation of hook_form_alter().
|
| 36 |
*/
|
| 37 |
function uc_aac_form_alter(&$form, $form_state, $form_id) {
|
| 38 |
if (strstr($form_id, 'uc_product_add_to_cart_form_')) {
|
| 39 |
drupal_add_js('misc/jquery.form.js');
|
| 40 |
drupal_add_js(drupal_get_path('module', 'uc_aac') .'/uc_aac.js');
|
| 41 |
// Call uc_aac_calculate once for each form on page load
|
| 42 |
drupal_add_js("$('.attributes').find('select:first').each(function(i) { uc_aac_calculate(this); });", 'inline', 'footer');
|
| 43 |
|
| 44 |
// If reprice is enabled and price adjustments are to be displayed
|
| 45 |
if (variable_get('uc_aac_reprice', 1) == 1 && variable_get('uc_attribute_option_price_format', 'adjustment') == 'adjustment') {
|
| 46 |
// Alter prices if we were called with POSTed attributes.
|
| 47 |
if (isset($form['#parameters'][2]->attributes)) {
|
| 48 |
$nid = $form['nid']['#value'];
|
| 49 |
$form['qty']['#default_value'] = $form['#parameters'][2]->default_qty;
|
| 50 |
|
| 51 |
foreach (element_children($form['attributes']) as $aid) {
|
| 52 |
$selected_oid = $form['#parameters'][2]->attributes[$aid]->default_option;
|
| 53 |
$form['attributes'][$aid]['#default_value'] = $selected_oid;
|
| 54 |
|
| 55 |
// Reset options for each $aid
|
| 56 |
$options = array();
|
| 57 |
|
| 58 |
foreach ($form['#parameters'][2]->attributes[$aid]->options as $option) {
|
| 59 |
$price = $option->price - $form['#parameters'][2]->attributes[$aid]->options[$selected_oid]->price;
|
| 60 |
$options[$option->oid] = $option->name . ($price != 0 ? ', '. ($price > 0 ? '+' : '') . uc_currency_format($price) : '');
|
| 61 |
}
|
| 62 |
$form['attributes'][$aid]['#options'] = $options;
|
| 63 |
}
|
| 64 |
}
|
| 65 |
}
|
| 66 |
}
|
| 67 |
elseif ($form_id == 'uc_attribute_admin_settings') {
|
| 68 |
$form['uc_attribute_option_price_format']['uc_aac_reprice'] = array(
|
| 69 |
'#type' => 'checkbox',
|
| 70 |
'#title' => t('Ajax Attribute Calculations dynamically adjusts product information as a product\'s attribute options are changed.'),
|
| 71 |
'#default_value' => variable_get('uc_aac_reprice', 1),
|
| 72 |
'#weight' => 0,
|
| 73 |
'#description' => t('When checked, a customer\'s selected attributes will display no price adjustment and all other attribute prices will be relative to the current price.'),
|
| 74 |
);
|
| 75 |
}
|
| 76 |
}
|
| 77 |
|
| 78 |
|
| 79 |
/******************************************************************************
|
| 80 |
* Module Functions
|
| 81 |
*****************************************************************************/
|
| 82 |
|
| 83 |
/**
|
| 84 |
* Calculate product adjustments based on attribute option selections.
|
| 85 |
*/
|
| 86 |
function _uc_aac_calculate() {
|
| 87 |
$nid = array_pop(explode('_', $_POST['form_id']));
|
| 88 |
$output['nid'] = $nid;
|
| 89 |
|
| 90 |
// Load the node and store the submitted data for later.
|
| 91 |
$product = node_load($nid);
|
| 92 |
|
| 93 |
// Set new default attribute options to the currently selected options so the
|
| 94 |
// form regenerates correctly.
|
| 95 |
if (isset($_POST['attributes'])) {
|
| 96 |
foreach ($_POST['attributes'] as $aid => $oid) {
|
| 97 |
$product->attributes[$aid]->default_option = $oid;
|
| 98 |
}
|
| 99 |
}
|
| 100 |
|
| 101 |
// Create a fake cart item with the submitted node, quantity and attributes.
|
| 102 |
$item = new stdClass();
|
| 103 |
$item->nid = $nid;
|
| 104 |
$item->qty = $_POST['qty'];
|
| 105 |
$item->model = $product->model;
|
| 106 |
$item->cost = $product->cost;
|
| 107 |
$item->price = $product->sell_price;
|
| 108 |
$item->weight = $product->weight;
|
| 109 |
$item->data = unserialize($product->data);
|
| 110 |
$item->data['nid'] = $nid;
|
| 111 |
$item->data['attributes'] = $_POST['attributes'];
|
| 112 |
|
| 113 |
// Let other modules adjust our cart item as needed.
|
| 114 |
$item->data = module_invoke_all('add_to_cart_data', $item->data);
|
| 115 |
module_invoke_all('cart_item', 'load', $item);
|
| 116 |
|
| 117 |
$context = array(
|
| 118 |
'revision' => 'themed',
|
| 119 |
'type' => 'product',
|
| 120 |
'class' => array(
|
| 121 |
'product',
|
| 122 |
),
|
| 123 |
'subject' => array(
|
| 124 |
'node' => $product,
|
| 125 |
),
|
| 126 |
);
|
| 127 |
|
| 128 |
// Render the updated display price
|
| 129 |
$context['class'][1] = 'display';
|
| 130 |
$context['field'] = 'sell_price';
|
| 131 |
$output['replacements']['display'] = theme('uc_product_price', $item->price, $context);
|
| 132 |
|
| 133 |
// Render the updated model
|
| 134 |
$output['replacements']['model'] = theme('uc_product_model', $item->model, 0, 0);
|
| 135 |
|
| 136 |
// Render the updated cost
|
| 137 |
$context['class'][1] = 'cost';
|
| 138 |
$context['field'] = 'cost';
|
| 139 |
$output['replacements']['cost'] = theme('uc_product_price', $item->cost, $context);
|
| 140 |
|
| 141 |
// Render the updated sell price
|
| 142 |
$context['class'][1] = 'sell';
|
| 143 |
$context['field'] = 'sell_price';
|
| 144 |
$output['replacements']['sell'] = theme('uc_product_price', $item->price, $context, array('label' => 1));
|
| 145 |
|
| 146 |
// Render the updated weight
|
| 147 |
$output['replacements']['weight'] = theme('uc_product_weight', $item->weight, $product->weight_units, 0, 0);
|
| 148 |
|
| 149 |
// Unset the form id to ensure Drupal doesn't attempt to process it.
|
| 150 |
unset($_POST['form_id']);
|
| 151 |
// Render the updated form
|
| 152 |
$output['form'] = drupal_get_form('uc_product_add_to_cart_form_'. $nid, $product);
|
| 153 |
// TODO: Fix bug where multiple add_to_cart forms on a single page have
|
| 154 |
// elements with identical css id's after regenerating the forms
|
| 155 |
|
| 156 |
drupal_set_header("Content-Type: text/javascript; charset=utf-8");
|
| 157 |
print drupal_to_js($output);
|
| 158 |
exit;
|
| 159 |
}
|