· 8 years ago · Mar 12, 2018, 01:20 PM
1<?php
2// $Id$
3/**
4 * @file
5 * Extend ecommerce functionality
6 *
7 * This module addiing following features:
8 * 1) Add quantity field for variations
9 * 2) Allow to add addition items to the cart ( not only one item )
10 * 3) Insert image field for every product variation
11 * 4)
12 */
13
14// Set new permissions
15function ecommerce_addition_perm (){
16 return array('show product types','show all product info');
17}
18
19/*
20 * Hook nodeapi
21 */
22function ecommerce_addition_nodeapi(&$node, $op, $a3, $a4) {
23
24 ################## PRODUCT ############################
25 if ($node->type == 'product') {
26 switch ($op) {
27 // Handle image upload here - using altered image module
28 case 'prepare':
29 // Existent image was selected
30 if (!is_array($node->images)) {
31 $node->iid = $node->images;
32 } else {
33 // Upload images here!
34 // Keep this part for now - build new image object
35 $image->title = $_POST['image_title'];
36 $image->uid = $node->uid;
37 $image->name = $node->name;
38 $image->created = $node->created;
39 $image->type = 'image';
40 $node_options = variable_get('node_options_image', array('status', 'promote'));
41 $image->status = in_array('status', $node_options);
42 $image->promote = in_array('promote', $node_options);
43 $image->destFolder = 'testFolder';
44 if (module_exists('comment')) {
45 $image->comment = variable_get('comment_image', COMMENT_NODE_READ_WRITE);
46 }
47 // Here we set new path where our images for specific company should be stored
48 $image->destFolder = 'testFolder';
49
50 image_prepare($image, $node->imageKey);
51 if ($image->images) {
52 if (empty($image->title)) {
53 $image->title = basename($image->images[IMAGE_ORIGINAL]);
54 }
55 node_validate($image);
56 if (!form_get_errors()) {
57 $image = node_submit($image);
58 node_save($image);
59 $node->iid = $image->nid;
60 $node->new_image = TRUE;
61 }
62 }
63 }
64 //dprint_r($image);
65 break;
66 case 'insert':
67 // Insert info about company
68 _e_product_save($node,$a3);
69 // If there was image assigned to that node ( variation ) - handle it here
70 if (!empty($node->images)) {
71 node_invoke_nodeapi($node,'prepare');
72 }
73 break;
74 case 'update':
75 _e_product_save($node,$a3);
76 // Add image here
77 break;
78
79 case 'load':
80 _get_companyId($node);
81 break;
82
83 case 'delete':
84 // Delete pictures in case of deleting variation
85 if (!empty($node->iid)) {
86 // If image not in use somewhere else - delete it from hardrive
87 $imageInUse = db_result(db_query("SELECT COUNT(ia.nid) FROM {image_attach} ia INNER JOIN {node} n on n.nid = ia.iid WHERE ia.iid=%d and n.type='image'",$node->iid));
88 if ($imageInUse==1) {
89 $image = node_load($node->iid); // Get image node instead product node
90 image_delete($image);
91 db_query('DELETE FROM {node} WHERE nid = %d', $node->iid);
92 }
93 }
94 break;
95 }
96 }
97
98 ########################### Companies ################################
99 if ($node->type == 'company') {
100 // Set breadcrump
101 switch ($op) {
102 case 'view':
103 $breadcrumb[] = l(t('Home'), '');
104 $breadcrumb[] = l(t('Companies'), 'companies');
105 drupal_set_breadcrumb($breadcrumb);
106 break;
107 }
108 }
109}
110
111/*
112 * Hook form_alter
113 */
114function ecommerce_addition_form_alter($form_id,&$form) {
115 switch ($form_id) {
116 // Add quantity field to the product order page
117 case 'subproducts_add_to_cart':
118
119 $form['addQty'] = array (
120 '#title' => t('Quantity'),
121 '#type' => 'textfield',
122 '#size' => '8',
123 '#default_value' => '1',
124 '#weight' => '1',
125 '#description' => t('Set desired quantity')
126 );
127
128 $form['add_to_cart'] = array (
129 '#type' => 'submit',
130 '#weight' => '2',
131 '#value' => 'Add to cart'
132 );
133 $form['#action'] = preg_replace('|(/cart/)(.*)(/.*)|isU','${1}update${3}',$form['#action']);
134 break;
135
136 // Alter apparel product form
137 case 'product_node_form':
138 if ($form['product']['ptype']['#value']=='apparel') {
139 // Disable addition information for product
140 if (!user_access('show all product info')) {
141 unset($form['product']['sku']);
142 unset($form['product']['hide_cart_link']);
143 unset($form['product']['ec_anon']);
144 unset($form['product']['inventory']);
145 unset($form['product']['availability']);
146 // Delete image fields just before form will be rendered
147 $form['#after_build'] = array('_deleteImageForm');
148 }
149
150 // Change title of main node
151 $form['title']['#title'] = t('Item number');
152 $form['title']['#size'] = 10;
153 $form['body_filter']['body']['#title'] = t('Description of the item');
154 $form['body_filter']['body']['#required'] = FALSE;
155 $form['body_filter']['body']['#rows'] = 7;
156
157 // Parent product edit form
158 if ($form['#node']->pparent==0) {
159 $form['product']['company'] = array (
160 '#type' => 'select',
161 '#title' => t('Company'),
162 '#required' => TRUE,
163 '#description' => t('Choose company of the product'),
164 '#disabled' => count($arr=get_companies_list())==1?TRUE:FALSE,
165 '#default_value' => _get_companyId(),
166 '#options' => _get_companies_list(),
167 '#weight' => -21,
168 '#validate' => array('e_product_form_validate' => array())
169 );
170 $form['title']['#validate'] = array('e_product_form_validate' => array());
171 }
172 }
173 break;
174
175 // Add multipart attribute to variation form ( image upload support )
176 case 'ecommerce_addition_subproducts_generate':
177 $form['#attributes'] = array("enctype" => "multipart/form-data");
178 break;
179 }
180}
181
182/*
183 * Implement hook_menu
184 */
185function ecommerce_addition_menu($may_cache) {
186 $items = array();
187 if ($may_cache) {
188 // Hide some menu links ( from other modules )
189 $items[] = array(
190 'path' => 'node/add/product/ec_live_subproducts_tangible',
191 'title' => 'Tangible Product',
192 'access' => user_access('show product types')
193 );
194 $items[] = array(
195 'path' => 'node/add/product/tangible',
196 'title' => 'Shippable Product',
197 'access' => user_access('show product types')
198 );
199 $items[] = array(
200 'path' => 'product',
201 'title' => t('Products'),
202 'callback' => 'product_page',
203 'access' => TRUE,
204 'type' => MENU_CALLBACK
205 );
206 $items[] = array(
207 'path' => 'admin/ecsettings/variation/ec_live_subproducts_tangible',
208 'access' => user_access('show product types')
209 );
210 $items[] = array(
211 'path' => 'node/add/product',
212 'title' => t('Product'),
213 'access' => user_access('show product types')
214 );
215 $items[] = array(
216 'path' => 'companies',
217 'callback' => '_ecommerce_addition_list_companies',
218 'title' => t('Companies'),
219 'access' => TRUE,
220 'type' => MENU_CALLBACK
221 );
222 // Using JSON to return data to front-end ( AJAX call )
223 $items[] = array(
224 'path' => 'variations',
225 'callback' => '_return_variation_data',
226 'access' => TRUE,
227 'type' => MENU_CALLBACK
228 );
229
230 } else {
231 drupal_add_css(drupal_get_path('module', 'ecommerce_addition') .'/ecommerce_addition.css');
232 $items[] = array(
233 'path' => 'cart/update',
234 'callback' => '_ecommerce_addition_quantity',
235 'type' => MENU_CALLBACK
236 );
237
238 // New theme for variations
239 if ((arg(0) == 'node' || arg(0) == 'send') && is_numeric(arg(1))) {
240 $node = node_load(arg(1));
241
242 if ($access = subproducts_access('administer', $node) && is_array($node->children)) {
243 $items[] = array(
244 'path' => 'node/'. arg(1) .'/subproducts/generate',
245 'callback' => 'drupal_get_form',
246 'callback arguments' => array('ecommerce_addition_subproducts_generate'),
247 'type' => MENU_CALLBACK
248 );
249 }
250 }
251 }
252 return $items;
253}
254
255# ----------------------------------------------- THEMES ----------------------------------------------------------- #
256
257// New theme for variations
258function ecommerce_addition_subproducts_generate($form_values = NULL) {
259
260 include_once(drupal_get_path('module', 'subproducts'). '/subproducts.inc');
261
262 $node = node_load(arg(1));
263
264 //drupal_add_js(drupal_get_path('module','ecommerce_addition').'/jquery.livequery.js');
265 drupal_add_js(drupal_get_path('module', 'subproducts') .'/subproducts.js');
266 drupal_add_js(drupal_get_path('module','ecommerce_addition').'/ecommerce_addition.js');
267
268 $variation_type = ($node->ptype && !$node->pparent && (in_array($node->ptype, subproducts_variations_product_types())));
269
270 if ($variation_type) {
271 switch($form_values['op']) {
272 case t('Review options'):
273 //drupal_add_js(drupal_get_path('module', 'subproducts') .'/subproducts.js');
274 $form = ecommerce_addition_subproducts_generate_wizard_2($form_values, $node);
275 break;
276 default:
277 $form = subproducts_generate_wizard1($node);
278 $form['#redirect'] = FALSE;
279 break;
280 }
281 $form['#multistep'] = TRUE;
282 return $form;
283 }
284}
285
286function ecommerce_addition_subproducts_generate_wizard_2($form_values, $node) {
287 $settings = $form_values['settings'];
288
289 if ($form_values['default']) {
290 variable_set('subproducts_' . $node->ptype . '_defaults', $settings);
291 }
292
293 $variations = subproducts_get_variations($node->ptype);
294
295 // flter settings to show only selected types
296 $keepThatVariation = 0;
297 foreach ($settings as $varId => $attrArr) {
298 foreach ($attrArr as $attrId => $attrValuesArr) {
299 if (isset($attrValuesArr['use'])) {
300 $keepThatVariation = 1;
301 }
302 }
303 if (!$keepThatVariation) {
304 unset($variations[$varId]);
305 unset($settings[$varId]);
306 }
307 $keepThatVariation = 0;
308 }
309
310 //dprint_r($variations);
311
312 drupal_set_title(t('%title: refine settings', array('%title' => $node->title)));
313
314 $form['node'] = array('#type' => 'value', '#value' => $node);
315
316 $help = '<h2>' . t('%product: refine settings for each subproduct.', array('%product' => $node->title)) . '</h2>';
317 $help .= '<p>' . t('Here is the full list of subproducts. You can select which ones you wish to create and adjust their settings before generating.') . '</p>';
318 $form['help'] = array('#type' => 'markup', '#value' => $help);
319
320 $options = array();
321 foreach($variations as $variation) {
322 if (is_array($variation->attributes)) {
323 $form['header'][$variation->vid] = array('#type' => 'markup', '#value' => $variation->name);
324 foreach ($variation->attributes as $attribute) {
325 // Only include this option in the array if it was selected in the previous screen.
326 if ($settings[$variation->vid][$attribute->aid]['use']) {
327 $options[$variation->vid][] = $attribute->aid;
328 }
329 }
330 }
331 }
332
333 $permutations = subproducts_permute($options);
334 foreach ($permutations as $permutation) {
335 // Check if this permutation already exists. If so, skip.
336 if(subproducts_get_variations_subproduct($node->nid, $permutation)) continue;
337 $price = $node->price;
338 $stock = 0;
339 $fields = array();
340 foreach ($permutation as $key => $value) {
341 $fields[] = $key . '|' . $value;
342 }
343 $fields = implode('||', $fields);
344 $form['permutations']['#tree'] = TRUE;
345 //$form['images']['#tree'] = TRUE;
346
347 /*
348 $form['extra'] = array(
349 '#type' => 'markup',
350 '#value' => '<input type="hidden" maxlength="128" name="edit[images]" id="edit-parent-2" size="60" value="" class="form-text" />'
351 );
352 */
353 $form['permutations'][$fields]['use'] = array( '#type' => 'checkbox',
354 '#title' => '',
355 '#default_value' => 1,
356 '#attributes' => array('class' => 'permutation'),
357 );
358 $i=0;
359 foreach ($permutation as $vid => $aid) {
360 $form['name'][$fields][$aid] = array('#type' => 'markup', '#value' => $variations[$vid]->attributes[$aid]->name);
361 $price += $variations[$vid]->attributes[$aid]->surcharge;
362 $stock += $settings[$vid][$aid]['stock'];
363 //$form['files'][$fields]['image']=array('#type' => 'markup', '#value' => '<div class="form-item"><span class="uploader">'.l(t('Upload new'),"variations/upload/$i",array("id"=>"upload$i")).'</span> / <span class="chooser">'.l(t('Choose existent'),"variations/choose/$i",array("id"=>"choose$i")).'</span></div>');
364 $i++;
365 }
366 // Set price and stock data.
367 $form['price'][$fields] = array('#type' => 'markup', '#value' => $price);
368 $form['permutations'][$fields]['price'] = array(
369 '#type' => 'hidden',
370 '#value' => $price
371 );
372 $form['permutations'][$fields]['stock'] = array(
373 '#type' => 'textfield',
374 '#title' => '',
375 '#default_value' => $stock,
376 '#size' => 10,
377 '#maxlength' => 10
378 );
379 }
380 // Placeholder for JS to fill in.
381 $form['checkbox-checkall'] = array( '#prefix' => '<div class="check-all">',
382 '#value' => '<span class="nojs">'. t('Check all currently requires javascript support.') .'</span>'.
383 t('Check all: '),
384 '#suffix' => '</div>',
385 );
386 $form['submit'] = array(
387 '#type' => 'submit',
388 '#value' => t('Generate'),
389 );
390 $form['#theme'] = 'ecommerce_addition_subproducts_generate_wizard_2';
391 $form['#submit'] = array('_ecommerce_addition_subproducts_generate_wizard2_submit' => '');
392 $form['#validate'] = array('ecommerce_addition_subproducts_generate_wizard2_validate' => array());
393 return $form;
394}
395
396function theme_ecommerce_addition_subproducts_generate_wizard_2($form) {
397 $header = array(array('data' => ''));
398 foreach (element_children($form['header']) as $key) {
399 $header[] = array('data' => drupal_render($form['header'][$key]));
400 }
401 $header[] = array('data' => t('Price'));
402 $header[] = array('data' => t('Stock'));
403 $header[] = array('data' => t('Add picture'));
404 $rows = array();
405 $i = 0;
406 foreach (element_children($form['permutations']) as $key) {
407 $rows[$i] = array( array('data' => drupal_render($form['permutations'][$key]['use'])) );
408 foreach(element_children($form['name'][$key]) as $aid) {
409 $rows[$i][] = array(
410 'data' => drupal_render($form['name'][$key][$aid]),
411 'align' => 'center'
412 );
413 }
414 $rows[$i][] = array('data' => drupal_render($form['price'][$key]));
415 $rows[$i][] = array('data' => drupal_render($form['permutations'][$key]['stock']));
416 $rows[$i][] = array('data' => drupal_render($form['permutations'][$key]['image']=array('#type' => 'markup', '#value' => '<div class="base"><span class="uploader">'.l(t('Upload new'),"variations/upload/$key/$i",array("id"=>"upload$i")).'</span> / <span class="chooser">'.l(t('Choose existent'),"variations/choose/$key/$i",array("id"=>"choose$i")).'</span></div>')));
417 //=array('#type' => 'markup', '#value' => '<div class="form-item"><span class="uploader">'.l(t('Upload new'),"variations/upload/$i",array("id"=>"upload$i")).'</span> / <span class="chooser">'.l(t('Choose existent'),"variations/choose/$i",array("id"=>"choose$i"
418 $i++;
419 }
420 $output = drupal_render($form['help']);
421 $output .= theme('table', $header, $rows);
422 $output .= drupal_render($form['submit']);
423 $output .= drupal_render($form['validate']);
424 $output .= drupal_render($form);
425 return $output;
426}
427
428
429function theme_ecommerce_addition_view_collection() {
430
431 $columns = 2;
432 $result = pager_query(db_rewrite_sql('SELECT n.nid FROM {node} n LEFT JOIN {content_type_company} c ON n.vid = c.vid WHERE n.status = 1 and n.type="company" ORDER BY n.sticky DESC, n.created DESC'), 10, 0);
433
434 $output = '<div class="e_addition_company_main">';
435 for ($i = 0; $node = db_fetch_object($result); $i++) {
436
437 $node = node_load($node->nid);
438 //dprint_r($node);
439
440 $teaser = true;
441 $page = false;
442
443 $node->body = str_replace('<!--break-->', '', $node->body);
444 if (node_hook($node, 'view')) {
445 node_invoke($node, 'view', $teaser, $page);
446 } else {
447 $node = node_prepare($node, $teaser);
448 }
449 // node_invoke_nodeapi($node, 'view', $teaser, $page);
450 $output .= '<div class="e_addition_company_child"><p class="e_comp_discr">'. l($node->title, "node/$node->nid") ."$node->teaser</p></div>\n";
451 }
452
453 $output .= '</div>';
454
455 if ($pager = theme('pager', NULL, $columns, 0)) {
456 $output .= $pager;
457 }
458
459 return $output;
460}
461
462
463# ------------------------------------------------ CALLBACKS ------------------------------------------------------- #
464
465// Show companies
466function _ecommerce_addition_list_companies() {
467 return theme('ecommerce_addition_view_collection');
468}
469
470// Hide image_attach block
471function _deleteImageForm($form,$form_id) {
472 unset($form['image_attach']);
473 return $form;
474}
475
476//The third stage of the variation generation wizard.
477function _ecommerce_addition_subproducts_generate_wizard2_submit($form_id, $form_values) {
478
479 $node = $form_values['node'];
480
481 $node->pparent = $node->nid;
482 $node->status = 0;
483 $node->comment = 0;
484 $node->voting = 0;
485 $children = $node->children;
486 $title = $node->title;
487 unset($node->path);
488 $permutations = $form_values['permutations'];
489 foreach ($permutations as $key => $value) {
490 if ($value['use']) {
491 $title_bits = array();
492 $node->variations = array();
493 $pairs = explode('||', $key);
494 foreach ($pairs as $pair) {
495 $item = explode('|', $pair);
496 $node->variations[] = $item[1];
497 $attribute = subproducts_get_attribute($item[1]);
498 $title_bits[] = $attribute->name;
499 }
500 $node->title = $title . ' ' . implode(' ', $title_bits);
501 $node->price = $value['price'];
502 $node->stock = $value['stock'];
503 $node->images = $value['image'];
504 $node->imageKey = $key;
505 unset($node->nid);
506 unset($node->path);
507
508 // Addition check - if image with the same title already exists - use it
509 if (!empty($node->images) && is_array($node->images)) {
510 $existImageNodeId = db_result(db_query("SELECT nid FROM {node} WHERE title='%s'",$node->images['name']));
511 if (!empty($existImageNodeId)) $node->images = $existImageNodeId;
512 }
513 node_save($node);
514 }
515 }
516 return 'node/' . $node->pparent;
517}
518
519// Show upload form or list of available images
520function _return_variation_data($action,$vid,$id) {
521 $base = strtolower(substr($_SERVER['SERVER_PROTOCOL'],0,strpos($_SERVER['SERVER_PROTOCOL'],'/'))).'://'.$_SERVER['HTTP_HOST'].'/';
522 $imgSrc = drupal_get_path('module','ecommerce_addition').'/misc/switchuser.png';
523 switch($action) {
524 case 'upload':
525 $responseArr = array(
526 'data'=>0,
527 'imgPath' => $base.'variations/choose/'.$vid.'/'.$id
528 );
529 break;
530 case 'choose':
531 $rows = _image_attach_get_image_nodes();
532 $responseArr = array(
533 'data' => $rows,
534 'imgPath' => $base.'variations/upload/'.$vid.'/'.$id
535 );
536 break;
537 }
538 $tempArr = array (
539 'imgSrc' => $base.$imgSrc,
540 'id' => $vid,
541 'num' => $id
542 );
543
544 $responseArr = array_merge($responseArr,$tempArr);
545 // Response for jQuery
546 echo drupal_to_js($responseArr);
547}
548
549// Retrieve companyId
550function _get_companyId($node=NULL) {
551 static $compId = '';
552 //echo "we $compId <br />";
553 if (!$node && $compId!=='') {
554 return $compId;
555 } elseif ($node) {
556 $compId = $node->companyId;
557 } else {
558 return false;
559 }
560}
561
562// Saving companyId ( node ) for product
563function _e_product_save($node,$form_values) {
564 if ($node->ptype) {
565 @db_query("ALTER TABLE {ec_product} ADD companyId INT UNSIGNED NOT NULL");
566 db_query("UPDATE {ec_product} SET companyId=%d WHERE nid=%d",$node->company,$node->nid);
567 }
568}
569
570// Get companies names and Id-s
571function _get_companies_list () {
572 $nodeType = 'company';
573 $compArr = array('Choose company');
574 $query = db_query("SELECT nid,title FROM {node} WHERE type='%s'",$nodeType);
575 while ($data = db_fetch_object($query)) {
576 $compArr[$data->nid] = $data->title;
577 }
578
579 return $compArr;
580}
581
582/*
583 * Add addition items to the cart. Act only when cart/update path was specified
584 * @int $nid - parent node Id
585 */
586function _ecommerce_addition_quantity($nid = NULL) {
587
588 $data = $_POST;
589
590 $node = node_load($nid);
591
592 product_invoke_productapi($node, 'cart add item', (object)$data);
593
594 $item_count = db_result(db_query("SELECT qty FROM {ec_cart} WHERE cookie_id = '%s' AND nid = %d", cart_get_id(), $node->nid));
595
596 // If user set quantity > 0
597 if ($data['addQty']>0) {
598 $message = cart_add_item($nid, $item_count + (int)$data['addQty'], $data);
599 } else {
600 $message = t("You should add at least one item");
601 }
602
603 if ($message) {
604 drupal_set_message($message);
605 }
606
607 drupal_goto('cart/view');
608}
609
610
611# ---------------------------------------------------- VALIDATION -------------------------------------------------- #
612
613// Special trick for image upload support
614function ecommerce_addition_subproducts_generate_wizard2_validate($form_id='', $form_values='',$form='') {
615 //dprint_r($form_values);
616 //dprint_r($_POST);
617 foreach($_POST['permutations'] as $key=>$valArr) {
618 // New image upload
619 if (!isset($_POST['imId'][$key])) {
620 $fileArr['image'] = array(
621 'name' => $_FILES['files']['name'][$key],
622 'type' => $_FILES['files']['type'][$key],
623 'tmp_name' => $_FILES['files']['tmp_name'][$key],
624 'error' => $_FILES['files']['error'][$key],
625 'size' => $_FILES['files']['size'][$key]
626 );
627 } else {
628 // Existent image
629 $fileArr['image'] = $_POST['imId'][$key];
630 }
631 $finArr[$key]=array_merge($fileArr,$valArr);
632 }
633 form_set_value($form['permutations'],$finArr);
634}
635
636function e_product_form_validate($form_values) {
637 if ($form_values['#post']['company']==0) {
638 form_set_error('company',t('You should select company from the list!'));
639 } else {
640 // Check if company is model with this number is already exists for this company
641 $checkQ = db_query("SELECT n.nid FROM node n LEFT JOIN ec_product ec on n.nid=ec.nid WHERE n.title='%s' and ec.companyId=%d",$form_values['#post']['title'],$form_values['#post']['company']);
642 if (($total = db_result($checkQ))>0) {
643 form_set_error('company',t('Model is alredy exists for this company!'));
644 }
645 }
646
647 // Item number should be digit
648 if ((int)$form_values['#post']['title']==0) {
649 form_set_error('title',t('Item number should be digit and more than 0!'));
650 }
651
652 preg_match('|^[[:punct:]]*((\d+)[[:punct:]]*\d*)$|is',$form_values['#post']['price'],$finArr);
653 if(!isset($finArr[2])) {
654 form_set_error('price',t('You should specify price of the item!'));
655 } elseif (isset($finArr[2]) && $finArr[2]<=0) {
656 form_set_error('price',t('Price should be more than 0!'));
657 }
658}