PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.21
VikAppointments Services Booking Calendar v1.2.21
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / site / layouts / blocks / checkout.php
vikappointments / site / layouts / blocks Last commit date
calendar 1 day ago login 1 day ago payment 1 day ago alert.php 1 day ago carttotals.php 1 day ago checkout.php 1 day ago couponform.php 1 day ago index.html 1 day ago login.php 1 day ago options.php 1 day ago paymentmethods.php 1 day ago quickcontact.php 1 day ago reviews.php 1 day ago timeline.php 1 day ago waitlist.php 1 day ago
checkout.php
505 lines
1 <?php
2 /**
3 * @package VikAppointments
4 * @subpackage core
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2021 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 $cart_enabled = isset($displayData['cartEnabled']) ? $displayData['cartEnabled'] : false;
15 $cart_empty = isset($displayData['cartEmpty']) ? $displayData['cartEmpty'] : true;
16 $waiting_list_enabled = isset($displayData['waitlistEnabled']) ? $displayData['waitlistEnabled'] : false;
17 $recurrence_enabled = isset($displayData['recurrenceEnabled']) ? $displayData['recurrenceEnabled'] : false;
18 $recurrence = isset($displayData['recurrenceParams']) ? $displayData['recurrenceParams'] : array();
19 $itemid = isset($displayData['itemid']) ? $displayData['itemid'] : null;
20
21 if (is_null($itemid))
22 {
23 // item id not provided, get the current one (if set)
24 $itemid = JFactory::getApplication()->input->getInt('Itemid');
25 }
26
27 $vik = VAPApplication::getInstance();
28
29 if ($recurrence_enabled)
30 {
31 ?>
32 <div class="vaprecurrencediv <?php echo $vik->getThemeClass('background'); ?>" style="display: none;">
33
34 <div class="vaprecurrenceprediv">
35 <input type="checkbox" value="1" onChange="vapRecurrenceConfirmValueChanged();" id="vaprecokcheck" />
36
37 <label for="vaprecokcheck"><?php echo JText::translate('VAPRECURRENCECONFIRM'); ?></label>
38 </div>
39
40 <div class="vaprecurrencenextdiv" style="display: none">
41
42 <div class="recurrence-repeat-box">
43 <span class="vaprecurrencerepeatlabel">
44 <label for="vaprepeatbyrecsel"><?php echo JText::translate('VAPRECURRENCEREPEAT'); ?></label>
45 </span>
46
47 <span class="vaprecurrencerepeatselect">
48 <select id="vaprepeatbyrecsel" onChange="vapRecurrenceSelectChanged();">
49 <option value="0"><?php echo JText::translate('VAPRECURRENCENONE'); ?></option>
50 <?php
51 /**
52 * Added support for "fortnightly" and "bi-monthly" recurrence.
53 *
54 * @since 1.6.4
55 *
56 * Added support for "quarterly", "bi-yearly" and "yearly" recurrence.
57 *
58 * @since 1.7.7
59 */
60 $lookup = array(
61 1 => 'VAPDAY',
62 2 => 'VAPWEEK',
63 4 => 'VAPFORTNIGHT',
64 3 => 'VAPMONTH',
65 5 => 'VAP2MONTHS',
66 6 => 'VAP3MONTHS',
67 7 => 'VAP6MONTHS',
68 8 => 'VAPYEAR',
69 );
70
71 $repeat_text = array();
72
73 foreach ($lookup as $i => $label)
74 {
75 if ($recurrence['repeat'][$i - 1] == 1)
76 {
77 $repeat_text[] = JHtml::fetch('select.option', $i, JText::translate($label));
78 }
79 }
80
81 echo JHtml::fetch('select.options', $repeat_text);
82 ?>
83 </select>
84 </span>
85 </div>
86
87 <div class="recurrence-for-box">
88 <span class="vaprecurrenceforlabel">
89 <label for="vapamountrecsel"><?php echo JText::translate('VAPRECURRENCEFOR'); ?></label>
90 </span>
91
92 <span class="vaprecurrenceamountselect">
93 <select id="vapamountrecsel">
94 <?php
95 for ($i = $recurrence['min']; $i <= $recurrence['max']; $i++)
96 {
97 ?>
98 <option value="<?php echo $i; ?>"><?php echo $i; ?></option>
99 <?php
100 }
101 ?>
102 </select>
103 </span>
104
105 <span class="vaprecurrenceforselect">
106 <select id="vapfornextrecsel">
107 <option value="0"><?php echo JText::translate('VAPRECURRENCENONE'); ?></option>
108 <?php
109 /**
110 * Added support for N "years" recurrence.
111 *
112 * @since 1.7.7
113 */
114 $lookup = array(
115 'VAPDAYS',
116 'VAPWEEKS',
117 'VAPMONTHS',
118 'VAPYEARS',
119 );
120
121 $for_text = array();
122
123 for ($i = 0; $i < count($lookup); $i++)
124 {
125 if ($recurrence['for'][$i] == 1)
126 {
127 $for_text[] = JHtml::fetch('select.option', $i + 1, JText::translate($lookup[$i]));
128 }
129 }
130
131 echo JHtml::fetch('select.options', $for_text);
132 ?>
133 </select>
134 </span>
135 </div>
136
137 </div>
138 </div>
139
140 <?php } ?>
141
142 <div class="vapbookbuttondiv">
143
144 <div class="vapbooksuccessdiv" style="display: none;">
145 <i class="fas fa-check-circle"></i>
146 <span id="booksuccess-msg"><?php echo JText::translate('VAPCARTITEMADDOK'); ?></span>
147 </div>
148
149 <div class="vapbookerrordiv" style="display: none;">
150 <i class="fas fa-times-circle"></i>
151 <span id="bookerror-msg"><?php echo JText::translate('VAPBOOKNOTIMESELECTED'); ?></span>
152 </div>
153
154 <div class="vap-checkout-bar">
155
156 <?php if ($cart_enabled) { ?>
157
158 <div class="vapbookbuttoninnerdiv additem">
159 <button type="button" class="vap-btn blue vapadditembutton" id="vapadditembutton" onClick="vapAddItemToCart();">
160 <?php echo JText::translate('VAPADDCARTBUTTON'); ?>
161 </button>
162 </div>
163
164 <?php } ?>
165
166 <div class="vapbookbuttoninnerdiv checkout">
167 <button type="button" class="vap-btn green vapcheckoutbutton" onClick="vapBookNow();">
168 <?php echo JText::translate('VAPBOOKNOWBUTTON'); ?>
169 </button>
170 </div>
171
172 </div>
173
174 <?php if ($waiting_list_enabled) { ?>
175
176 <div class="vapbookbuttoninnerdiv waitlist" id="vapwaitlistbox" style="display: none;">
177 <?php
178 /**
179 * See waiting list layout for further details about
180 * the vapOpenWaitListOverlay() function.
181 *
182 * @link layouts/blocks/waitlist.php
183 *
184 * See the following views for further details about LAST_TIMESTAMP_USED.
185 *
186 * @link views/servicesearch/tmpl/default.php
187 * @link views/employeesearch/tmpl/default.php
188 */
189 ?>
190 <button type="button" class="vap-btn dark-gray vapwaitlistbutton" onClick="vapOpenWaitListOverlay('vapaddwaitlistoverlay', LAST_TIMESTAMP_USED);">
191 <i class="fas fa-calendar-plus"></i>
192 <?php echo JText::translate('VAPWAITLISTADDBUTTON'); ?>
193 </button>
194 </div>
195
196 <?php } ?>
197
198 </div>
199
200 <?php
201 JText::script('VAPBOOKNOTIMESELECTED');
202 JText::script('VAPCARTITEMADDOK');
203 JText::script('VAPCARTMULTIITEMSADDOK');
204 ?>
205
206 <script>
207
208 var isTimeChoosen = false;
209 var vapCheckoutProceed = <?php echo (!$cart_empty ? 1 : 0); ?>;
210
211 jQuery(function($) {
212 $('#vaprepeatbyrecsel, #vapfornextrecsel').select2({
213 minimumResultsForSearch: -1,
214 allowClear: false,
215 width: 150,
216 });
217
218 $('#vapamountrecsel').select2({
219 minimumResultsForSearch: -1,
220 allowClear: false,
221 width: 70,
222 });
223 });
224
225 /**
226 * Used to register the selected options within the DOM
227 * or to return them as array.
228 */
229 function vapRegisterOptions(what) {
230 try
231 {
232 var options = vapGetSelectedOptions();
233 }
234 catch (error)
235 {
236 if (error == 'MissingRequiredOptionException')
237 {
238 // do not proceed as the customer forgot to fill
239 // one or more required fields
240 return false;
241 }
242
243 // Proceed because the service doesn't own any option
244 // and the function vapGetSelectedOptions() hasn't been declared.
245 // Define an empty options array to avoid breaking the flow.
246 var options = [];
247 }
248
249 if (what === 'ajax') {
250 // return options array
251 return options;
252 }
253
254 options.forEach((opt) => {
255 jQuery('#vapempconfirmapp').append(
256 '<input type="hidden" name="opt_id[]" value="' + opt.id + '" />'+
257 '<input type="hidden" name="opt_quantity[]" value="' + opt.quantity + '" />'+
258 '<input type="hidden" name="opt_var[]" value="' + opt.variation + '" />'
259 );
260 });
261
262 return true;
263 }
264
265 /**
266 * Used to book the selected details by submitting the form.
267 */
268 function vapBookNow() {
269 if (isTimeChoosen) {
270 // register options only in case the time has been selected
271 if (vapRegisterOptions('submit') === false) {
272 // missing some required options
273 return false;
274 }
275
276 // register recurrence only in case the time has been selected
277 var recurrence = vapGetSelectedRecurrence();
278
279 if (recurrence) {
280 jQuery('#vapempconfirmapp').append('<input type="hidden" name="recurrence" value="' + recurrence + '" />');
281 }
282 }
283
284 if (isTimeChoosen || vapCheckoutProceed) {
285 document.confirmapp.submit();
286 } else {
287 vapDisplayWrongMessage(2500, Joomla.JText._('VAPBOOKNOTIMESELECTED'));
288 }
289 }
290
291 var _items_add_count = 0;
292 var _items_timeout = null;
293 var _items_bad_timeout = null;
294
295 /**
296 * Used to book one or more services via AJAX.
297 */
298 function vapAddItemToCart() {
299 if (!isTimeChoosen) {
300 return false;
301 }
302
303 var id_ser = jQuery("#vapconfserselected").val();
304 var id_emp = jQuery("#vapconfempselected").val();
305 var day = jQuery("#vapconfdayselected").val();
306 var hour = jQuery("#vapconfhourselected").val();
307 var min = jQuery("#vapconfminselected").val();
308 var people = jQuery("#vapconfpeopleselected").val();
309
310 // get selected options
311 var options = vapRegisterOptions('ajax');
312
313 if (options === false) {
314 // missing some required options
315 return false;
316 }
317
318 // It doesn't matter if the checkout select exists
319 // as the controller won't use this value (because the
320 // checkout selection is disabled for this service).
321 var factor = jQuery('#vap-checkout-sel').val();
322
323 var recurrence = vapGetSelectedRecurrence();
324
325 // use default URL
326 var _url = '<?php echo $vik->ajaxUrl('index.php?option=com_vikappointments&task=cart.additem' . ($itemid ? '&Itemid=' . $itemid : '')); ?>';
327
328 if (recurrence) {
329 // user recurrence URL
330 _url = '<?php echo $vik->ajaxUrl('index.php?option=com_vikappointments&task=cart.addrecuritem' . ($itemid ? '&Itemid=' . $itemid : '')); ?>';
331 } else {
332 // set default "no" recurrence
333 recurrence = [-1, -1, -1].join(',');
334 }
335
336 jQuery('.option-required').removeClass('vapoptred');
337
338 UIAjax.do(
339 _url,
340 {
341 id_ser: id_ser,
342 id_emp: id_emp,
343 date: day,
344 hour: hour,
345 min: min,
346 people: people,
347 options: options,
348 recurrence: recurrence,
349 duration_factor: factor,
350 },
351 (resp) => {
352 // check if we have recurring items
353 if (typeof resp.items !== 'undefined') {
354 // ok count
355 if (resp.count > 0) {
356 // recurring appointments -> get number of items added
357 vapDisplayRightMessage(resp.count);
358
359 // we can proceed with the checkout
360 vapCheckoutProceed = 1;
361 }
362
363 var wrong = [];
364
365 // fetch all error messages
366 resp.items.forEach((item) => {
367 if (item.status == 0) {
368 wrong.push(item.error);
369 }
370 });
371
372 if (wrong.length) {
373 // at least an error found, display a wrong message too
374 vapDisplayWrongMessage(Math.max(wrong.length * 1500, 2500), wrong.join('<br />'));
375 }
376 } else {
377 // display message for one service only
378 vapDisplayRightMessage(1);
379
380 // we can proceed with the checkout
381 vapCheckoutProceed = 1;
382 }
383
384 /**
385 * Refresh timeline on success.
386 *
387 * @since 1.7.5
388 */
389 vapGetTimeline();
390
391 // inject received response within the event to dispatch
392 var event = jQuery.Event('vikappointments.cart.add');
393 event.params = resp;
394
395 // trigger event
396 jQuery(window).trigger(event);
397 },
398 (err) => {
399 vapDisplayWrongMessage(0, err.responseText || Joomla.JText._('VAPBOOKNOTIMESELECTED'));
400 }
401 );
402 }
403
404 function vapDisplayRightMessage(count) {
405 if (!jQuery('.vapbooksuccessdiv').is(':visible')) {
406 _items_add_count = count;
407 } else {
408 _items_add_count++;
409 }
410
411 if (!_items_bad_timeout) {
412 // no registered timer for error messages, auto hide them
413 jQuery('.vapbookerrordiv').hide();
414 }
415
416 if (_items_add_count == 1) {
417 jQuery('.vapbooksuccessdiv #booksuccess-msg').text(Joomla.JText._('VAPCARTITEMADDOK'));
418 } else {
419 jQuery('.vapbooksuccessdiv #booksuccess-msg').text(_items_add_count + ' ' + Joomla.JText._('VAPCARTMULTIITEMSADDOK'));
420 }
421
422 if (_items_timeout != null) {
423 clearTimeout(_items_timeout);
424 }
425
426 jQuery('.vapbooksuccessdiv').stop(true, true).fadeIn();
427
428 _items_timeout = setTimeout(function() {
429 jQuery('.vapbooksuccessdiv').fadeOut();
430 }, 2500);
431 }
432
433 function vapDisplayWrongMessage(ms, html) {
434 if (_items_bad_timeout != null) {
435 clearTimeout(_items_bad_timeout);
436 }
437
438 if (html) {
439 jQuery('.vapbookerrordiv #bookerror-msg').html(html);
440 }
441
442 jQuery('.vapbookerrordiv').stop(true, true).fadeIn();
443
444 if (ms > 0) {
445 _items_bad_timeout = setTimeout(function() {
446 jQuery('.vapbookerrordiv').fadeOut();
447 }, ms);
448 }
449 }
450
451 function vapRecurrenceSelectChanged() {
452 var val = jQuery('#vaprepeatbyrecsel').val();
453
454 if (val > 0) {
455 if (jQuery('#vapfornextrecsel option[value="' + val + '"]').length > 0) {
456 // update select to have the same interval
457 jQuery('#vapfornextrecsel').select2('val', val);
458
459 } else if (jQuery('#vapfornextrecsel').val() == "0") {
460 // option not found, select the first index available
461 jQuery('#vapfornextrecsel').prop('selectedIndex', 1);
462 // update val on select2
463 jQuery('#vapfornextrecsel').select2('val', jQuery('#vapfornextrecsel').val());
464 }
465 } else {
466 jQuery('#vaprecokcheck').prop('checked', false);
467 jQuery('.vaprecurrencenextdiv').hide();
468 jQuery('.vaprecurrenceprediv').fadeIn();
469 }
470 }
471
472 function vapRecurrenceConfirmValueChanged() {
473 // change index
474 jQuery('#vaprepeatbyrecsel').prop('selectedIndex', 1);
475 // update val on select2
476 jQuery('#vaprepeatbyrecsel').select2('val', jQuery('#vaprepeatbyrecsel').val());
477 // trigger change to update [fornext] select
478 vapRecurrenceSelectChanged();
479
480 jQuery('.vaprecurrenceprediv').hide();
481 jQuery('.vaprecurrencenextdiv').fadeIn();
482 }
483
484 function vapGetSelectedRecurrence() {
485 var enabled = <?php echo (int) $recurrence_enabled; ?>;
486
487 if (!enabled) {
488 return false;
489 }
490
491 var recurrence = [];
492
493 recurrence.push(parseInt(jQuery('#vaprepeatbyrecsel').val()));
494 recurrence.push(parseInt(jQuery('#vapfornextrecsel').val()));
495 recurrence.push(parseInt(jQuery('#vapamountrecsel').val()));
496
497 if (!recurrence[0]) {
498 return false;
499 }
500
501 return recurrence.join(',');
502 }
503
504 </script>
505