/[drupal]/contributions/modules/ubercart/uc_product_kit/uc_product_kit.module
ViewVC logotype

Contents of /contributions/modules/ubercart/uc_product_kit/uc_product_kit.module

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


Revision 1.11 - (show annotations) (download) (as text)
Thu Jul 10 12:41:03 2008 UTC (16 months, 2 weeks ago) by islandusurper
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-6--2
Changes since 1.10: +312 -143 lines
File MIME type: text/x-php
Begin the Ubercart 6.x-2.x branch.
1 <?php
2 // $Id$
3
4 /**
5 * @file
6 * The product kit module for Übercart.
7 *
8 * Product kits are groups of products that are sold as a unit.
9 *
10 * Coded by: Lyle Mantooth
11 */
12
13 /******************************************************************************
14 * Drupal Hooks *
15 ******************************************************************************/
16
17 /**
18 * Implementation of hook_access().
19 */
20 function uc_product_kit_access($op, $node) {
21 global $user;
22
23 switch ($op) {
24 case 'create':
25 return user_access('create products');
26 case 'update':
27 case 'delete':
28 if ($user->uid == $node->uid) {
29 return user_access('edit own products');
30 }
31 else {
32 return user_access('edit products');
33 }
34 }
35 }
36
37 function uc_product_kit_enable() {
38 $node_type = node_get_types('type', 'product_kit');
39 if ($node_type->module == 'node') {
40 $node_type->module = 'uc_product_kit';
41 $node_type->custom = 0;
42 node_type_save($node_type);
43 }
44 }
45
46 function uc_product_kit_disable() {
47 $node_type = node_get_types('type', 'product_kit');
48 $node_type->module = 'node';
49 $node_type->custom = 1;
50 node_type_save($node_type);
51 }
52
53 /**
54 * Implementation of hook_node_info().
55 *
56 * @return Node type information for product kits.
57 */
58 function uc_product_kit_node_info() {
59 return array(
60 'product_kit' => array(
61 'name' => t('Product kit'),
62 'module' => 'uc_product_kit',
63 'description' => t('This node represents two or more products that have been listed together. This presents a logical and convenient grouping of items to the customer.'),
64 'title_label' => t('Name'),
65 'body_label' => t('Description'),
66 ),
67 );
68 }
69
70 /**
71 * Implementation of hook_insert().
72 *
73 * Add a row to {uc_products} to make a product. Extra information about the
74 * component products are stored in {uc_product_kits}.
75 * @param &$node The node object being saved.
76 * @see uc_product_insert
77 */
78 function uc_product_kit_insert(&$node) {
79 $obj = new stdClass();
80 $obj->vid = $node->vid;
81 $obj->nid = $node->nid;
82 $obj->model = '';
83 $obj->list_price = 0;
84 $obj->cost = 0;
85 $obj->sell_price = 0;
86 $obj->weight = 0;
87 $obj->weight_units = variable_get('uc_weight_unit', 'lb');
88
89 $obj->ordering = $node->ordering;
90 $obj->shippable = false;
91
92 $values = array();
93 $placeholders = array();
94 foreach ($node->products as $product) {
95 $product = node_load($product);
96
97 $values[] = $node->vid;
98 $values[] = $node->nid;
99 $values[] = $product->nid;
100 $values[] = $node->mutable;
101 $values[] = 1;
102 $values[] = $product->sell_price;
103 $placeholders[] = '(%d, %d, %d, %d, %d, %f)';
104
105 $obj->model .= $product->model . ' / ';
106 $obj->list_price += $product->list_price;
107 $obj->cost += $product->cost;
108 $obj->sell_price += $product->sell_price;
109 $obj->weight += $product->weight * uc_weight_conversion($product->weight_units, $obj->weight_units);
110 if ($product->shippable) {
111 $obj->shippable = true;
112 }
113 }
114 db_query("INSERT INTO {uc_product_kits} (vid, nid, product_id, mutable, qty, discount) VALUES ". implode(',', $placeholders), $values);
115 $obj->model = rtrim($obj->model, ' / ');
116 db_query("INSERT INTO {uc_products} (vid, nid, model, list_price, cost, sell_price, weight, weight_units, default_qty, unique_hash, ordering, shippable) VALUES (%d, %d, '%s', %f, %f, %f, %f, '%s', %d, '%s', %d, %d)",
117 $obj->vid, $obj->nid, $obj->model, $obj->list_price, $obj->cost, $obj->sell_price, $obj->weight, $obj->weight_units, $obj->default_qty,
118 md5($obj->vid . $obj->nid . $obj->model . $obj->list_price . $obj->cost . $obj->sell_price . $obj->weight . $obj->weight_units . $obj->default_qty . $obj->ordering . $obj->shippable . time()),
119 $obj->ordering, $obj->shippable
120 );
121 }
122
123 /**
124 * Implementation of hook_update().
125 *
126 * Updates information in {uc_products} as well as {uc_product_kits}. Because
127 * component products are known when the form is loaded, discount information
128 * can be input and saved.
129 * @param &$node The node to be updated.
130 * @see uc_product_update
131 */
132 function uc_product_kit_update(&$node) {
133 $obj = new stdClass();
134 $obj->vid = $node->vid;
135 $obj->nid = $node->nid;
136 $obj->model = '';
137 $obj->list_price = 0;
138 $obj->cost = 0;
139 $obj->sell_price = 0;
140 $obj->weight = 0;
141 $obj->weight_units = variable_get('uc_weight_unit', 'lb');
142 $obj->default_qty = $node->default_qty;
143 $obj->ordering = $node->ordering;
144 $obj->shippable = false;
145
146 $values = array();
147 $placeholders = array();
148 foreach ($node->products as $i => $product) {
149 $values[] = $node->vid;
150 $values[] = $node->nid;
151 $values[] = $product;
152 $values[] = $node->mutable;
153 $product = node_load($product);
154 if (is_null($node->items[$i]['qty']) || $node->items[$i]['qty'] === '') {
155 $node->items[$i]['qty'] = 1;
156 }
157 $values[] = $node->items[$i]['qty'];
158 if (is_null($node->items[$i]['discount']) || $node->items[$i]['discount'] === '') {
159 $node->items[$i]['discount'] = $product->sell_price;
160 }
161 $values[] = $node->items[$i]['discount'];
162 $values[] = $node->items[$i]['ordering'];
163 $placeholders[] = '(%d, %d, %d, %d, %d, %f, %d)';
164
165 $product->qty = $node->items[$i]['qty'];
166 if ($node->items[$i]['discount'] < 0) {
167 $product->sell_price += $node->items[$i]['discount'];
168 }
169 else {
170 $product->sell_price = $node->items[$i]['discount'];
171 }
172 $obj->model .= $product->model . ' / ';
173 $obj->list_price += $product->list_price * $product->qty;
174 $obj->cost += $product->cost * $product->qty;
175 $obj->sell_price += $product->sell_price * $product->qty;
176 $obj->weight += $product->weight * $product->qty * uc_weight_conversion($product->weight_units, $obj->weight_units);
177 if ($product->shippable) {
178 $obj->shippable = true;
179 }
180 }
181 $obj->model = rtrim($obj->model, ' / ');
182 if (!$node->revision) {
183 db_query("DELETE FROM {uc_product_kits} WHERE nid = %d", $node->nid);
184 }
185 db_query("INSERT INTO {uc_product_kits} (vid, nid, product_id, mutable, qty, discount, ordering) VALUES ". implode(',', $placeholders), $values);
186 if ($node->revision) {
187 db_query("INSERT INTO {uc_products} (vid, nid, model, list_price, cost, sell_price, weight, weight_units, default_qty, unique_hash, ordering, shippable) VALUES (%d, %d, '%s', %f, %f, %f, %f, '%s', %d, '%s', %d, %d)",
188 $obj->vid, $obj->nid, $obj->model, $obj->list_price, $obj->cost, $obj->sell_price, $obj->weight, $obj->weight_units, $obj->default_qty,
189 md5($obj->vid . $obj->nid . $obj->model . $obj->list_price . $obj->cost . $obj->sell_price . $obj->weight . $obj->weight_units . $obj->default_qty . $obj->ordering . time()),
190 $obj->ordering, $obj->shippable
191 );
192 }
193 else {
194 db_query("UPDATE {uc_products} SET model = '%s', list_price = %f, cost = %f, sell_price = %f, weight = %f, weight_units = '%s', default_qty = %d, ordering = %d, shippable = %d WHERE vid = %d",
195 $obj->model, $obj->list_price, $obj->cost, $obj->sell_price, $obj->weight, $obj->weight_units, $obj->default_qty, $obj->ordering, $obj->shippable, $obj->vid);
196 if (!db_affected_rows()) {
197 db_query("INSERT INTO {uc_products} (vid, nid, model, list_price, cost, sell_price, weight, weight_units, default_qty, unique_hash, ordering, shippable) VALUES (%d, %d, '%s', %f, %f, %f, %f, '%s', %d, '%s', %d, %d)",
198 $obj->vid, $obj->nid, $obj->model, $obj->list_price, $obj->cost, $obj->sell_price, $obj->weight, $obj->weight_units, $obj->default_qty,
199 md5($obj->vid . $obj->nid . $obj->model . $obj->list_price . $obj->cost . $obj->sell_price . $obj->weight . $obj->weight_units . $obj->default_qty . $obj->ordering . $obj->shippable . time()),
200 $obj->ordering, $boj->shippable
201 );
202 }
203 }
204 }
205
206 /**
207 * Implementation of hook_delete().
208 */
209 function uc_product_kit_delete(&$node) {
210 if (module_exists('uc_cart')) {
211 db_query("DELETE FROM {uc_cart_products} WHERE data LIKE '%%s:6:\"kit_id\";s:%d:\"%s\";%%'", strlen($node->nid), $node->nid);
212 }
213 db_query("DELETE FROM {uc_product_kits} WHERE nid = %d", $node->nid);
214 db_query("DELETE FROM {uc_products} WHERE nid = %d", $node->nid);
215 }
216
217 /**
218 * Implementation of hook_load().
219 */
220 function uc_product_kit_load(&$node) {
221 $obj = new stdClass();
222
223 $products = array();
224 $result = db_query("SELECT product_id, mutable, qty, discount, ordering FROM {uc_product_kits} WHERE vid = %d ORDER BY ordering", $node->vid);
225 while ($prod = db_fetch_object($result)) {
226 $obj->mutable = $prod->mutable;
227 $product = node_load($prod->product_id);
228 $product->qty = $prod->qty;
229 $product->discount = $prod->discount;
230 $product->ordering = $prod->ordering;
231 $products[$prod->product_id] = $product;
232 }
233 uasort($products, '_uc_product_kit_sort_products');
234 $obj->products = $products;
235 if ($extra = uc_product_load($node)) {
236 foreach ($extra as $key => $value) {
237 $obj->$key = $value;
238 }
239 }
240
241 return $obj;
242 }
243
244 function uc_product_kit_nodeapi(&$node, $op, $arg3 = null, $arg4 = null) {
245 switch ($op) {
246 case 'update':
247 $result = db_query("SELECT nid FROM {uc_product_kits} WHERE product_id = %d", $node->nid);
248 while ($nid = db_fetch_object($result)) {
249 $kit = node_load($nid, NULL, TRUE);
250 node_object_prepare($kit);
251 $redirect = drupal_execute('product_kit_node_form', array(), $kit);
252 }
253 break;
254 }
255 }
256
257 /**
258 * Register an "Add to Cart" form for each product kit.
259 * @see uc_product_kit_add_to_cart_form
260 * @see uc_catalog_buy_it_now_form
261 */
262 function uc_product_kit_forms($saved_args) {
263 $forms = array();
264 if (substr($saved_args[0], 0, 31) == 'uc_product_kit_add_to_cart_form' || substr($saved_args[0], 0, 27) == 'uc_product_add_to_cart_form' || substr($saved_args[0], 0, 26) == 'uc_catalog_buy_it_now_form') {
265 $products = db_query("SELECT DISTINCT nid FROM {uc_product_kits} WHERE nid = %d", $saved_args[1]->nid);
266
267 while ($prodrow = db_fetch_object($products)) {
268 $forms['uc_product_kit_add_to_cart_form_'. $prodrow->nid] = array('callback' => 'uc_product_kit_add_to_cart_form');
269 $forms['uc_product_add_to_cart_form_'. $prodrow->nid] = array('callback' => 'uc_product_kit_add_to_cart_form');
270 $forms['uc_catalog_buy_it_now_form_'. $prodrow->nid] = array('callback' => 'uc_product_kit_buy_it_now_form');
271 }
272 }
273 return $forms;
274 }
275
276 /**
277 * Add product kit settings to the product settings form.
278 */
279 function uc_product_kit_form_alter($form_id, &$form) {
280 if ($form_id == 'uc_product_settings_form') {
281 $form['uc_product_kit_mutable'] = array('#type' => 'radios',
282 '#title' => t('How are product kits handled by the cart?'),
283 '#options' => array(t('As a unit. Customers may only change how many kits they are buying.'), t('As individual products. Customers may add or remove kit components at will.')),
284 '#default_value' => variable_get('uc_product_kit_mutable', 0),
285 '#weight' => -5,
286 );
287 }
288 }
289
290 /**
291 * Implementation of hook_form().
292 *
293 * @ingroup forms
294 */
295 function uc_product_kit_form(&$node) {
296 $form = array();
297
298 $form['title'] = array('#type' => 'textfield',
299 '#title' => t('Name'),
300 '#required' => TRUE,
301 '#weight' => -5,
302 '#default_value' => $node->title,
303 '#description' => t('Name of the product kit')
304 );
305 $form['body_filter']['body'] = array('#type' => 'textarea',
306 '#title' => t('Description'),
307 '#required' => FALSE,
308 '#default_value' => $node->body,
309 '#rows' => 20,
310 '#description' => t('Explain these whatchamacallits.'),
311 );
312 $form['body_filter']['format'] = filter_form($node->format);
313 $form['body_filter']['#weight'] = -4;
314
315 $product_types = module_invoke_all('product_types');
316 unset($product_types[array_search('product_kit', $product_types)]);
317 $result = db_query("SELECT nid, title FROM {node} WHERE type IN ('". implode("','", $product_types) ."')");
318 $products = array();
319 while ($product = db_fetch_object($result)) {
320 $products[$product->nid] = $product->title;
321 }
322 $form['base'] = array('#type' => 'fieldset',
323 '#title' => t('Product Information'),
324 '#collapsible' => true,
325 '#collapsed' => false,
326 '#weight' => -1,
327 '#attributes' => array('class' => 'product-field'),
328 );
329 $form['base']['mutable'] = array('#type' => 'radios',
330 '#title' => t('How is this product kit handled by the cart?'),
331 '#options' => array(t('As a unit. Customers may only change how many kits they are buying.'), t('As individual products. Customers may add or remove kit components at will.')),
332 '#default_value' => isset($node->mutable) ? $node->mutable : variable_get('uc_product_kit_mutable', 0),
333 );
334 $form['base']['products'] = array('#type' => 'select',
335 '#multiple' => true,
336 '#required' => true,
337 '#title' => t('Products'),
338 '#options' => $products,
339 '#default_value' => isset($node->products) ? array_keys($node->products) : array(),
340 );
341 $form['base']['items'] = array('#tree' => true);
342 if (isset($node->products)) {
343 foreach ($node->products as $i => $product) {
344 $form['base']['items'][$i] = array('#type' => 'fieldset',
345 //'#title' => $product->title,
346 );
347 $form['base']['items'][$i]['link'] = array('#type' => 'item',
348 '#value' => l(t('@product', array('@product' => $product->title)), 'node/'. $i),
349 );
350 $form['base']['items'][$i]['qty'] = array('#type' => 'textfield',
351 '#title' => t('Quantity'),
352 '#default_value' => $product->qty,
353 '#size' => 5,
354 );
355 $form['base']['items'][$i]['ordering'] = array('#type' => 'weight',
356 '#title' => t('Ordering'),
357 '#default_value' => $product->ordering,
358 );
359 $item = node_load($i);
360 $form['base']['items'][$i]['discount'] = array('#type' => 'textfield',
361 '#title' => t('Discount'),
362 '#description' => t('Enter a negative value to lower the item price by that amount. Enter a postive value to set the item price to that amount. This discount is applied to each %product in the kit.', array('%product' => $product->title)),
363 '#default_value' => (is_null($product->discount) || $product->discount === '' ? $item->sell_price : $product->discount),
364 '#size' => 5,
365 );
366 }
367 }
368 $form['base']['default_qty'] = array('#type' => 'textfield',
369 '#title' => t('Default quantity to add to cart'),
370 '#default_value' => !is_null($node->default_qty) ? $node->default_qty : 1,
371 '#description' => t('Leave blank or zero to disable the quantity field in the add to cart form.'),
372 '#weight' => 27,
373 '#size' => 5,
374 '#maxlength' => 6,
375 );
376 $form['base']['ordering'] = array('#type' => 'weight',
377 '#title' => t('List order'),
378 '#delta' => 25,
379 '#default_value' => $node->ordering,
380 '#weight' => 30,
381 );
382
383 return $form;
384 }
385
386 /**
387 * Implementation of hook_view().
388 */
389 function uc_product_kit_view($node, $teaser = 0, $page = 0) {
390 $node = node_prepare($node, $teaser);
391
392 $enabled = variable_get('uc_product_field_enabled', array(
393 'image' => 1,
394 'display_price' => 1,
395 'model' => 1,
396 'list_price' => 0,
397 'cost' => 0,
398 'sell_price' => 1,
399 'weight' => 0,
400 'dimensions' => 0,
401 'add_to_cart' => 1,
402 ));
403 $weight = variable_get('uc_product_field_weight', array(
404 'image' => -2,
405 'display_price' => -1,
406 'model' => 0,
407 'list_price' => 2,
408 'cost' => 3,
409 'sell_price' => 4,
410 'weight' => 5,
411 'dimensions' => 6,
412 'add_to_cart' => 10,
413 ));
414
415 //drupal_set_message('<pre>'. print_r($node->field_image_cache, true) .'</pre>');
416 if (isset($node->field_image_cache) && file_exists($node->field_image_cache[0]['filepath'])) {
417 $node->content['image'] = array('#value' => theme('uc_product_image', $node->field_image_cache),
418 '#access' => $enabled['image'] && module_exists('imagecache'),
419 '#weight' => $weight['image'],
420 );
421 }
422 $node->content['display_price'] = array('#value' => theme('uc_product_display_price', $node->sell_price),
423 '#access' => $enabled['display_price'],
424 '#weight' => $weight['display_price'],
425 );
426 if (!$teaser) {
427 $node->content['model'] = array('#value' => theme('uc_product_model', $node->model),
428 '#access' => $enabled['model'],
429 '#weight' => $weight['model'],
430 );
431 $node->content['body']['#weight'] = 1;
432 $node->content['list_price'] = array('#value' => theme('uc_product_price', $node->list_price, 'list_price'),
433 '#access' => $enabled['list_price'],
434 '#weight' => $weight['list_price'],
435 );
436 $node->content['cost'] = array('#value' => theme('uc_product_price', $node->cost, 'cost'),
437 '#access' => $enabled['cost'] && user_access('administer products'),
438 '#weight' => $weight['cost'],
439 );
440 }
441 else {
442 $node->content['#attributes'] = array('style' => 'display: inline');
443 }
444
445 $node->content['sell_price'] = array('#value' => theme('uc_product_sell_price', $node->sell_price, $teaser),
446 '#access' => $enabled['sell_price'],
447 '#weight' => $weight['sell_price'],
448 );
449
450 if (!$teaser) {
451 $node->content['weight'] = array('#value' => theme('uc_product_weight', $node->weight, $node->weight_units),
452 '#access' => $enabled['weight'],
453 '#weight' => $weight['weight'],
454 );
455 $node->content['products'] = array('#weight' => 6);
456 foreach ($node->products as $product) {
457 $node->content['products'][$product->nid]['qty'] = array('#value' => '<div class="product-qty">'. $product->qty .' x '. l($product->title, 'node/'. $product->nid) .'</div>');
458 $node->content['products'][$product->nid]['#weight'] = $product->ordering;
459 }
460 $node->content['add_to_cart'] = array('#value' => theme('uc_product_kit_add_to_cart', $node),
461 '#weight' => 10,
462 );
463 }
464 else if (variable_get('uc_product_add_to_cart_teaser', true)) {
465 $node->content['add_to_cart'] = array('#value' => theme('uc_product_kit_add_to_cart', $node),
466 '#weight' => 10,
467 );
468 }
469 //print '<pre>'. print_r($node, true) .'</pre>';
470 return $node;
471 }
472
473 /**
474 * Wrap the "Add to Cart" form in a <div>.
475 *
476 * @ingroup themeable
477 */
478 function theme_uc_product_kit_add_to_cart($node) {
479 $output = '<div class="add_to_cart" title="'. t('Click to add to cart.') .'">';
480 if ($node->nid) {
481 $output .= drupal_get_form('uc_product_kit_add_to_cart_form_'. $node->nid, $node);
482 }
483 else {
484 $output .= drupal_get_form('uc_product_kit_add_to_cart_form', $node);
485 }
486 $output .= '</div>';
487 return $output;
488 }
489
490 /**
491 * Lets the cart know how many of which products are included in a kit.
492 *
493 * uc_attribute_form_alter() hooks into this form to add attributes to each
494 * element in $form['products'].
495 * @ingroup forms
496 * @see uc_product_kit_add_to_cart_form_submit
497 */
498 function uc_product_kit_add_to_cart_form($node) {
499 $form = array();
500 $form['#base'] = 'uc_product_kit_add_to_cart_form';
501 $form['nid'] = array('#type' => 'value', '#value' => $node->nid, );
502 $form['products'] = array('#tree' => true);
503 foreach ($node->products as $i => $product) {
504 $form['products'][$i] = array(/* '#type' => 'fieldset', */'#title' => $product->title);
505 $form['products'][$i]['nid'] = array('#type' => 'hidden', '#value' => $product->nid);
506 $form['products'][$i]['qty'] = array('#type' => 'hidden', '#value' => $product->qty);
507 }
508 if ($node->default_qty > 0 && variable_get('uc_product_add_to_cart_qty', false)) {
509 $form['qty'] = array('#type' => 'textfield',
510 '#title' => t('Quantity'),
511 '#default_value' => $node->default_qty,
512 '#size' => 5,
513 '#maxlength' => 6,
514 );
515 }
516 else {
517 $form['qty'] = array('#type' => 'hidden', '#value' => 1);
518 }
519 $form['submit'] = array(
520 '#type' => 'submit',
521 '#value' => variable_get('uc_product_add_to_cart_text', t('Add to cart')),
522 '#id' => 'edit-submit-'. $node->nid,
523 '#attributes' => array(
524 'class' => 'node-add-to-cart',
525 ),
526 );
527 return $form;
528 }
529
530 /**
531 * Submit function for uc_product_kit_add_to_cart_form().
532 *
533 * Iterates through the kit's product list and adds each to the cart in the
534 * correct quantities.
535 */
536 function uc_product_kit_add_to_cart_form_submit($form_id, $form_values) {
537 return uc_cart_add_item($form_values['nid'], $form_values['qty'], $form_values);
538 }
539
540 function uc_product_kit_buy_it_now_form($node) {
541 $form = array();
542 $form['#base'] = 'uc_product_kit_buy_it_now_form';
543 $form['nid'] = array('#type' => 'hidden', '#value' => $node->nid);
544 if ($node->type == 'product_kit') {
545 $form['products'] = array('#tree' => true);
546 foreach ($node->products as $i => $product) {
547 $form['products'][$i] = array(/* '#type' => 'fieldset', */'#title' => $product->title);
548 $form['products'][$i]['nid'] = array('#type' => 'hidden', '#value' => $product->nid);
549 $form['products'][$i]['qty'] = array('#type' => 'hidden', '#value' => $product->qty);
550 }
551 }
552 $form['submit'] = array(
553 '#type' => 'submit',
554 '#value' => variable_get('uc_teaser_add_to_cart_text', t('Add to cart')),
555 '#id' => 'edit-submit-'. $node->nid,
556 '#attributes' => array(
557 'class' => 'list-add-to-cart',
558 ),
559 );
560 return $form;
561 }
562
563 function uc_product_kit_buy_it_now_form_submit($form_id, $form_values) {
564 $node = node_load($form_values['nid']);
565 if (module_exists('uc_attribute')) {
566 $attributes = uc_product_get_attributes($node->nid);
567 if (!empty($attributes)) {
568 drupal_set_message(t('This product has options that need to be selected before purchase. Please select them in the form below.'), 'error');
569 return drupal_get_path_alias('node/'. $form_values['nid']);
570 }
571 if (is_array($node->products)) {
572 foreach ($node->products as $nid => $product) {
573 $attributes = uc_product_get_attributes($nid);
574 if (!empty($attributes)) {
575 drupal_set_message(t('This product has options that need to be selected before purchase. Please select them in the form below.'), 'error');
576 return drupal_get_path_alias('node/'. $form_values['nid']);
577 }
578 }
579 }
580 }
581 return uc_cart_add_item($form_values['nid'], 1, $form_values);
582 }
583
584 /******************************************************************************
585 * Übercart Hooks *
586 ******************************************************************************/
587
588 function uc_product_kit_product_types() {
589 return array('product_kit');
590 }
591
592 function uc_product_kit_store_status() {
593 if (module_exists('imagefield')) {
594 $result = db_query("SELECT field_name FROM {node_field_instance} WHERE field_name = 'field_image_cache' AND widget_type = 'image' AND type_name = 'product_kit'");
595 if (!db_num_rows($result)) {
596 return array(array('status' => 'ok', 'title' => t('Images'), 'desc' => t('Product kits do not have an image field. You may add the existing <em>field_image_cache</em> at the <a href="!url">Add field page</a>.', array('!url' => url('admin/content/types/product-kit/add_field')))));
597 }
598 }
599
600 }
601
602 function uc_product_kit_add_to_cart($nid, $qty, $kit_data) {
603 $node = node_load($nid);
604 if ($node->type == 'product_kit') {
605 $unique = uniqid('', true);
606 foreach ($node->products as $product) {
607 $data = array('kit_id' => $node->nid, 'unique_id' => $unique, 'module' => 'uc_product_kit');
608 uc_cart_add_item($product->nid, $product->qty * $qty, $data + module_invoke_all('add_to_cart_data', $kit_data['products'][$product->nid]), null, true, false);
609 }
610 if ($check_redirect) {
611 if (isset($_GET['destination'])) {
612 drupal_goto();
613 }
614
615 $redirect = variable_get('uc_add_item_redirect', 'cart');
616 if ($redirect != '<none>') {
617 $_SESSION['last_url'] = referer_uri();
618 return $redirect;
619 }
620 else {
621 return referer_uri();
622 }
623 }
624 return array(array('success' => false, 'silent' => true, $message => ''));
625 }
626 }
627
628 /**
629 * Implementation of Übercart's hook_cart_item().
630 */
631 function uc_product_kit_cart_item($op, &$item) {
632 switch ($op) {
633 case 'load':
634 if (isset($item->data['kit_id']) && ($kit = node_load($item->data['kit_id'])) && !$kit->mutable) {
635 $kit_discount = $kit->products[$item->nid]->discount;
636 if ($kit_discount !== '') {
637 if ($kit_discount < 0) {
638 $item->price += $kit_discount;
639 }
640 else {
641 $item->price += $kit_discount - $kit->products[$item->nid]->sell_price;
642 }
643 }
644 }
645 break;
646 }
647 }
648
649 /**
650 * Implementation of Übercart's hook_cart_display().
651 *
652 * Displays either the kit as a whole, or each individual product based on the
653 * store configuration. Each product in the cart that was added by uc_product_kit
654 * was also given a unique kit id in order to help prevent collisions. The side
655 * effect is that identical product kits are listed separately if added separately.
656 * The customer may still change the quantity of kits like other products.
657 *
658 * @param $item
659 * An item in the shopping cart.
660 * @return
661 * A form element array to be processed by uc_cart_view_form().
662 */
663 function uc_product_kit_cart_display($item) {
664 static $elements = array();
665 static $products;
666 $unique_id = $item->data['unique_id'];
667 $kit = node_load($item->data['kit_id']);
668 //print '<pre>'. print_r($kit, true) .'</pre>';
669 if ($kit->mutable) {
670 return uc_product_cart_display($item);
671 }
672 else {
673 if (!isset($products[$unique_id])) {
674 // Initialize table row
675 $element = array();
676 $element['nid'] = array('#type' => 'value', '#value' => $kit->nid);
677 $element['module'] = array('#type' => 'value', '#value' => 'uc_product_kit');
678 $element['remove'] = array('#type' => 'checkbox');
679 $element['options'] = array('#value' => '<div class="item-list"><ul class="cart-options">'. "\n");
680 $element['title'] = array('#value' => l($kit->title, 'node/'. $kit->nid));
681 $element['#total'] = 0;
682 $element['qty'] = array(
683 '#type' => 'textfield',
684 '#default_value' => $item->qty / $kit->products[$item->nid]->qty,
685 '#size' => 3,
686 '#maxlength' => 3,
687 );
688 $elements[$unique_id] = $element;
689 }
690 // Add product specific information
691 $op_names = '';
692 foreach ($item->options as $option) {
693 $op_names .= $option['name'] .', ';
694 }
695 $op_names = substr($op_names, 0, strlen($op_names) - 2);
696 if ($op_names) {
697 $op_names = '-- '. $op_names;
698 }
699 $elements[$unique_id]['options']['#value'] .= '<li>'. $item->qty .' x '. l($item->title, 'node/'. $item->nid) ." <em>$op_names</em></li>\n";
700 $elements[$unique_id]['#total'] += $item->price * $item->qty;
701 $elements[$unique_id]['data'][$item->nid] = $item;
702 $products[$unique_id][] = $item->nid;
703 // Check if all products in this kit have been accounted for.
704 $done = true;
705 foreach ($kit->products as $product) {
706 if (!in_array($product->nid, $products[$unique_id])) {
707 $done = false;
708 break;
709 }
710 }
711 if ($done) {
712 $elements[$unique_id]['data'] = array('#type' => 'value', '#value' => serialize($elements[$unique_id]['data']));
713 $elements[$unique_id]['options']['#value'] .= "</ul></div>\n";
714 $element = $elements[$unique_id];
715 unset($products[$unique_id]);
716 unset($elements[$unique_id]);
717 return $element;
718 }
719 }
720 return array();
721 }
722
723 /**
724 * Implementation of Übercart's hook_update_cart_item().
725 *
726 * Handles individual products or entire kits.
727 */
728 function uc_product_kit_update_cart_item($nid, $data = array(), $qty, $cid = null) {
729 if (!$nid) return NULL;
730 $cid = !(is_null($cid) || empty($cid)) ? $cid : uc_cart_get_id();
731 if ($qty < 1) {
732 foreach ($data as $p_nid => $product) {
733 uc_cart_remove_item($p_nid, $cid, $product->data);
734 }
735 }
736 else {
737 if (isset($data['kit_id'])) { // Product was listed individually
738 uc_product_update_cart_item($nid, $data, $qty, $cid);
739 }
740 else {
741 $kit = node_load($nid);
742 foreach ($data as $p_nid => $product) {
743 uc_product_update_cart_item($p_nid, $product->data, $qty * $kit->products[$p_nid]->qty, $cid);
744 }
745 }
746 }
747 }
748
749 /**
750 * usort() callback.
751 */
752 function _uc_product_kit_sort_products($a, $b) {
753 if ($a->ordering == $b->ordering) {
754 return 0;
755 }
756 else {
757 return ($a->ordering < $b->ordering) ? -1 : 1;
758 }
759 }

  ViewVC Help
Powered by ViewVC 1.1.2