/[drupal]/contributions/modules/uc_aac/uc_aac.module
ViewVC logotype

Contents of /contributions/modules/uc_aac/uc_aac.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.9 - (show annotations) (download) (as text)
Thu May 7 14:25:37 2009 UTC (6 months, 3 weeks ago) by cyu
Branch: MAIN
Changes since 1.8: +7 -7 lines
File MIME type: text/x-php
#452914 by cYu - Made compatible with new span ids in UC RC2
#413018 by cYu - Fixed ids starting with numbers that failed w3 validation
1 <?php
2 // $Id: uc_aac.module,v 1.5.2.4 2009/01/14 19:49:42 cyu Exp $
3
4 /**
5 * @file
6 * Updates product display_price and sell_price fields using AJAX
7 * whenever a product attribute is altered. Also updates the attribute
8 * adjustments dynamically if they are configured to display.
9 *
10 * Coded by Chris Yu (cYu).
11 */
12
13
14 /*******************************************************************************
15 * Hook Functions
16 ******************************************************************************/
17
18 /**
19 * Implementation of hook_theme().
20 **/
21 function uc_aac_theme() {
22 return array(
23 'uc_aac_js' => array(
24 'arguments' => array('node' => null),
25 ),
26 );
27 }
28
29
30 /**
31 * Implementation of hook_menu().
32 */
33 function uc_aac_menu() {
34 $items['uc_aac'] = array(
35 'title' => t('Price Calculation'),
36 'description' => t('Calculate the price of your product.'),
37 'page callback' => '_uc_aac_calculate_price',
38 'access arguments' => array('access content'),
39 'weight' => 5,
40 'type' => MENU_CALLBACK,
41 );
42 return $items;
43 }
44
45 /**
46 * Implementation of hook_form_alter().
47 */
48 function uc_aac_form_alter(&$form, $form_state, $form_id) {
49 if (strstr($form_id, 'uc_product_add_to_cart_form_')) {
50 $priced_attributes = count(uc_attribute_priced_attributes($form['nid']['#value']));
51
52 if ($priced_attributes >= 1) {
53 drupal_add_js('misc/jquery.form.js');
54 drupal_add_js(_uc_aac_markup($form_id, $form['nid']['#value']), 'inline');
55 $form[$form_id]['uc_aac_nid'] = array(
56 '#type' => 'hidden',
57 '#value' => $form['nid']['#value'],
58 '#id' => 'uc_aac_nid_'. $form['nid']['#value'],
59 );
60 }
61 }
62
63 if ($form_id == 'uc_attribute_admin_settings') {
64 $form['uc_attribute_option_price_format']['uc_aac_reprice'] = array(
65 '#type' => 'checkbox',
66 '#title' => t('Ajax Attribute Calculations dynamically adjusts attribute prices as a product\'s sell price is updated.'),
67 '#default_value' => variable_get('uc_aac_attribute_reprice', '1'),
68 '#weight' => 0,
69 '#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.'),
70 );
71 $form['#submit'][] = 'uc_aac_settings_submit';
72 }
73 }
74
75 /**
76 * Submit handler for uc_aac attribute setting.
77 */
78 function uc_aac_settings_submit($form, &$form_state) {
79 variable_set('uc_aac_attribute_reprice', $form_state['values']['uc_aac_reprice']);
80 }
81
82 function _uc_aac_markup($form_id, $nid) {
83 $result = db_query('SELECT sell_price FROM {uc_products} WHERE nid=%d AND vid=(SELECT vid FROM {node} WHERE nid=%d)', $nid, $nid);
84 $priced_attributes = count(uc_attribute_priced_attributes($nid));
85
86 $price = 0;
87 if ($product = db_fetch_object($result)) {
88 $price = $product->sell_price;
89 }
90 $update_attributes = 0;
91 if (variable_get('uc_aac_attribute_reprice', '1') == 1 && (variable_get('uc_attribute_option_price_format', 'adjustment') == 'adjustment' || $priced_attributes > 1) && (variable_get('uc_attribute_option_price_format', 'adjustment') != 'none')) {
92 $update_attributes = 1;
93 }
94 return theme('uc_aac_js', $nid, $price, $update_attributes);
95 }
96
97 function theme_uc_aac_js($nid, $price, $update_attributes) {
98 /**
99 * If events aren't being properly attached to form elements, refer to the
100 * note at http://drupal.org/project/uc_aac about themes identifying product
101 * divs as 'node-$nid'.
102 */
103
104 return '
105 var replace_price_'. $nid .' = "'. uc_currency_format($price) .'";
106 var aac_'. $nid .'_update = 0;
107
108 /**
109 * Initialize select attributes so that prices update on change, radio
110 * buttons update on click.
111 */
112 function initialize_fields_'. $nid .'() {
113 $("#node-'. $nid .' select").each(function () {
114 var element = this;
115 if (element.name && element.name.match("attributes")) {
116 $(this).change(function () {
117 perform_ajax_calculation_'. $nid .'();
118 });
119 }
120 });
121 $("#node-'. $nid .' :radio").each(function () {
122 var element = this;
123 if (element.name && element.name.match("attributes")) {
124 // Needed because off odd click() behavior in IE with Jquery Update
125 // See http://drupal.org/node/336350
126 $(this).unbind("click");
127 $(this).bind("click", function () {
128 perform_ajax_calculation_'. $nid .'();
129 });
130 }
131 });
132 }
133
134 function perform_ajax_calculation_'. $nid .'() {
135 var aac_form = document.createElement("div");
136 aac_form.setAttribute( "target", "" );
137 aac_form.setAttribute( "action", "'. url("uc_aac",array('absolute' => TRUE)) .'" );
138 aac_form.setAttribute( "method", "post" );
139 aac_form.elements = [];
140 var element = document.getElementById("uc_aac_nid_'. $nid .'");
141 aac_form.elements[0] = element;
142 $("#node-'. $nid .' select").each(function () {
143 var element = this;
144 if (element.name && element.name.match("attributes")) {
145 aac_form.elements[aac_form.elements.length] = element;
146 }
147 });
148 $("#node-'. $nid .' :radio").each(function () {
149 var element = this;
150 if (element.name && element.name.match("attributes")) {
151 aac_form.elements[aac_form.elements.length] = element;
152 }
153 });
154 var this_update = new Date();
155 aac_'. $nid .'_update = this_update.getTime();
156 $(aac_form).ajaxSubmit( {
157 dataType: "json",
158 success: function(json_results) {
159 if (aac_'. $nid .'_update == this_update.getTime()) {
160 if ('. $update_attributes .' == 1) {
161 for (var i in json_results.attributes) {
162 if (json_results.attributes[i].type == "select") {
163 $("#node-'. $nid .' select").each(function () {
164 if (json_results.attributes[i].name == this.name) {
165 var select_attribute = this;
166 // Assume that any options removed from the select are at the beginning, like "Please select", and adjust selected index accordingly
167 var attribute_index = select_attribute.selectedIndex - select_attribute.length + json_results.attributes[i].options.length;
168 while (select_attribute.length) {
169 select_attribute.remove(0);
170 }
171 for (var j in json_results.attributes[i].options) {
172 select_option = json_results.attributes[i].options[j];
173 new_option = document.createElement("option");
174 new_option.text = select_option.label + " " + select_option.adjustment;
175 new_option.value = select_option.key;
176 if (j == attribute_index) {
177 new_option.selected = true;
178 new_option.defaultSelected = true;
179 }
180 if ($.browser.msie) {
181 select_attribute.add(new_option);
182 }
183 else {
184 select_attribute.add(new_option, null);
185 }
186 }
187 }
188 });
189 }
190 if (json_results.attributes[i].type == "radio") {
191 var radio_index = 0;
192 $("#node-'. $nid .' :radio").parent().each(function (j) {
193 if (this.firstChild.name == json_results.attributes[i].name) {
194 radio_option = json_results.attributes[i].options[radio_index];
195 if (radio_option.adjustment.length > 0) {
196 radio_option.label += ",";
197 }
198 radio_index ++;
199 if ($.browser.msie) {
200 var radio_input = this.innerHTML.slice(0, this.innerHTML.indexOf(">") + 1);
201 this.innerHTML = radio_input + " " + radio_option.label + " " + radio_option.adjustment;
202 }
203 else {
204 this.childNodes[this.childNodes.length-1].textContent = " " + radio_option.label + " " + radio_option.adjustment;
205 }
206 }
207 });
208 if ($.browser.msie) {
209 // Re-apply all of the onClick events that get lost when using innerHTML
210 initialize_fields_'. $nid .'();
211 }
212 }
213 }
214 }
215 var currentsellHTML= $("#node-'. $nid .' .uc-price-sell").html();
216 var currentdisplayHTML = $("#node-'. $nid .' .uc-price-display").html();
217 updated_price = json_results.updated_price;
218 if (currentdisplayHTML) {
219 $("#node-'. $nid .' .uc-price-display").html(currentdisplayHTML.replace(replace_price_'. $nid .', updated_price));
220 }
221 if (currentsellHTML) {
222 $("#node-'. $nid .' .uc-price-sell").html(currentsellHTML.replace(replace_price_'. $nid .', updated_price));
223 }
224 replace_price_'. $nid .' = updated_price;
225 }
226 },
227 error: function() {
228 //alert("Price update failed.");
229 }
230 });
231 }
232
233 function load_function_'. $nid .'() {
234 initialize_fields_'. $nid .'();
235 perform_ajax_calculation_'. $nid .'();
236 }
237 $().ready(load_function_'. $nid .');
238 ';
239 }
240
241 function _uc_aac_calculate_price() {
242 $field_values = $_POST;
243 $nid = $field_values['uc_aac_nid'];
244 $base_price = db_result(db_query('SELECT sell_price FROM {uc_products} WHERE nid=%d AND vid=(SELECT vid FROM {node} WHERE nid=%d)', $nid, $nid));
245 $updated_price = $base_price;
246 $attributes = $field_values['attributes'];
247 $types = array(0 => "text", 1 => "select", 2 => "radio");
248 if ($attributes) {
249 foreach ($attributes as $attribute) {
250 $aid = db_result(db_query('SELECT aid FROM {uc_attribute_options} WHERE oid = %d', $attribute));
251 $display = db_result(db_query('SELECT display FROM {uc_product_attributes} WHERE aid = %d AND nid = %d', $aid, $nid));
252 $options = db_query('SELECT DISTINCT upo.oid, uao.name, upo.cost, upo.price FROM {uc_attribute_options} AS uao LEFT JOIN {uc_product_options} AS upo ON uao.oid = upo.oid WHERE uao.aid = %d AND upo.nid = %d ORDER BY upo.ordering, uao.ordering, uao.name', $aid, $nid);
253 $names = array();
254 $prices = array();
255 while ($option = db_fetch_object($options)) {
256 $names[$option->oid] = $option->name;
257 $prices[$option->oid] = $option->price;
258 if ($option->oid == $attribute) {
259 $used_price[$aid] = $option->price;
260 $updated_price += $option->price;
261 }
262 }
263 $attribute_options = array();
264 foreach ($prices as $oid => $attribute_price) {
265 $adjusted_price = $attribute_price - $used_price[$aid];
266 $price_text = '';
267 if ($adjusted_price != 0) {
268 if ($adjusted_price > 0) {
269 $price_text .= "+";
270 }
271 $price_text .= uc_currency_format($adjusted_price);
272 }
273 $attribute_options[] = array('key' => $oid, 'label' => $names[$oid], 'adjustment' => $price_text);
274 }
275 $output['attributes'][] = array('name' => 'attributes['. $aid .']', 'type' => $types[$display], 'options' => $attribute_options);
276 }
277 }
278 $output['updated_price'] = uc_currency_format($updated_price);
279 drupal_json($output);
280 exit();
281 }

  ViewVC Help
Powered by ViewVC 1.1.2