PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.8.15
VikBooking Hotel Booking Engine & PMS v1.8.15
1.8.15 1.8.14 1.8.13 1.8.12 1.8.11 1.8.10 1.8.9 1.8.6 1.8.7 1.8.8 trunk 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 All 36 releases
vikbooking / site / views / oconfirm / view.html.php

view.html.php in VikBooking Hotel Booking Engine & PMS 1.8.15, at site/views/oconfirm/view.html.php

554 lines 18.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package VikBooking
4 * @subpackage com_vikbooking
5 * @author Alessio Gaggii - e4j - Extensionsforjoomla.com
6 * @copyright Copyright (C) 2018 e4j - Extensionsforjoomla.com. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 * @link https://vikwp.com
9 */
10
11 defined('ABSPATH') or die('No script kiddies please!');
12
13 jimport('joomla.application.component.view');
14
15 class VikbookingViewOconfirm extends JViewVikBooking
16 {
17 public function display($tpl = null)
18 {
19 $dbo = JFactory::getDbo();
20 $app = JFactory::getApplication();
21 $session = JFactory::getSession();
22 $vbo_tn = VikBooking::getTranslator();
23
24 $proomid = VikRequest::getVar('roomid', array());
25 $proomindex = VikRequest::getVar('roomindex', array());
26 $pdays = VikRequest::getInt('days', 0, 'request');
27 $pcheckin = VikRequest::getInt('checkin', 0, 'request');
28 $pcheckout = VikRequest::getInt('checkout', 0, 'request');
29 $proomsnum = VikRequest::getInt('roomsnum', 0, 'request');
30 $padults = VikRequest::getVar('adults', array());
31 $pchildren = VikRequest::getVar('children', array());
32 $ppkg_id = VikRequest::getInt('pkg_id', 0, 'request');
33 $split_stay = VikRequest::getVar('split_stay', array());
34 $pitemid = VikRequest::getInt('Itemid', 0, 'request');
35
36 $nowdf = VikBooking::getDateFormat();
37 if ($nowdf == "%d/%m/%Y") {
38 $df = 'd/m/Y';
39 } elseif ($nowdf == "%m/%d/%Y") {
40 $df = 'm/d/Y';
41 } else {
42 $df = 'Y/m/d';
43 }
44
45 $rooms = [];
46 $arrpeople = [];
47 for ($ir = 1; $ir <= $proomsnum; $ir++) {
48 $ind = $ir - 1;
49 if (!empty($proomid[$ind])) {
50 $q = "SELECT * FROM `#__vikbooking_rooms` WHERE `id`=" . (int)$proomid[$ind] . " AND `avail`='1';";
51 $dbo->setQuery($q);
52 $get_room = $dbo->loadAssoc();
53 if ($get_room) {
54 $rooms[$ir] = $get_room;
55 }
56 }
57 if (!empty($padults[$ind])) {
58 $arrpeople[$ir]['adults'] = intval($padults[$ind]);
59 } else {
60 $arrpeople[$ir]['adults'] = 0;
61 }
62 if (!empty($pchildren[$ind])) {
63 $arrpeople[$ir]['children'] = intval($pchildren[$ind]);
64 } else {
65 $arrpeople[$ir]['children'] = 0;
66 }
67 }
68 if (count($rooms) != $proomsnum) {
69 VikError::raiseWarning('', JText::translate('VBROOMNOTFND'));
70 $app->redirect(JRoute::rewrite('index.php?option=com_vikbooking'.(!empty($pitemid) ? '&Itemid='.$pitemid : '')));
71 exit;
72 }
73 $vbo_tn->translateContents($rooms, '#__vikbooking_rooms');
74
75 // collect all room IDs involved
76 $rooms_involved = [];
77 foreach ($rooms as $room_booked) {
78 if (!in_array($room_booked['id'], $rooms_involved)) {
79 $rooms_involved[] = $room_booked['id'];
80 }
81 }
82
83 // calculate total nights of stay
84 $secdiff = $pcheckout - $pcheckin;
85 $daysdiff = $secdiff / 86400;
86 if (is_int($daysdiff)) {
87 if ($daysdiff < 1) {
88 $daysdiff = 1;
89 }
90 } else {
91 if ($daysdiff < 1) {
92 $daysdiff = 1;
93 } else {
94 $sum = floor($daysdiff) * 86400;
95 $newdiff = $secdiff - $sum;
96 $maxhmore = VikBooking::getHoursMoreRb() * 3600;
97 if ($maxhmore >= $newdiff) {
98 $daysdiff = floor($daysdiff);
99 } else {
100 $daysdiff = ceil($daysdiff);
101 }
102 }
103 }
104
105 if ($pdays != $daysdiff) {
106 showSelectVb(JText::translate('VBERRCALCTAR'));
107 return;
108 }
109
110 // get check-in and check-out dates information
111 $checkin_info = getdate($pcheckin);
112 $checkout_info = getdate($pcheckout);
113
114 /**
115 * Check split stay information.
116 *
117 * @since 1.16.0 (J) - 1.6.0 (WP)
118 */
119 if (!empty($split_stay) && count($split_stay) == count($rooms) && count($split_stay) == $proomsnum && $proomsnum > 1) {
120 // valid split stay request vars received
121 $split_stay_checkins = [];
122 $split_stay_checkouts = [];
123 foreach ($split_stay as $sps_k => $split_room) {
124 // calculate and set the exact check-in and check-out timestamps for this split-room
125 $new_room_checkin = VikBooking::getDateTimestamp($split_room['checkin'], $checkin_info['hours'], $checkin_info['minutes'], $checkin_info['seconds']);
126 $new_room_checkout = VikBooking::getDateTimestamp($split_room['checkout'], $checkout_info['hours'], $checkout_info['minutes'], $checkout_info['seconds']);
127 $split_stay_checkins[] = $new_room_checkin;
128 $split_stay_checkouts[] = $new_room_checkout;
129 // update split stay information
130 $split_room['checkin_ts'] = $new_room_checkin;
131 $split_room['checkout_ts'] = $new_room_checkout;
132 $split_stay[$sps_k] = $split_room;
133 }
134 // validate minimum and maximum stay dates for the split stay
135 if (empty($split_stay_checkins) || empty($split_stay_checkouts)) {
136 // error, unset any value for the split stay
137 $split_stay = [];
138 } elseif (min($split_stay_checkins) != $pcheckin) {
139 // error, unset any value for the split stay
140 $split_stay = [];
141 } elseif (max($split_stay_checkouts) != $pcheckout) {
142 // error, unset any value for the split stay
143 $split_stay = [];
144 }
145 } else {
146 // unset any possible value as it's invalid
147 $split_stay = [];
148 }
149
150 // modify booking
151 $mod_booking = [];
152 $skip_busy_ids = [];
153 $cur_mod = $session->get('vboModBooking', '');
154 if (is_array($cur_mod) && count($cur_mod)) {
155 $mod_booking = $cur_mod;
156 $skip_busy_ids = VikBooking::loadBookingBusyIds($mod_booking['id']);
157 }
158
159 // check that room(s) are available and get the price(s)
160 $groupdays = VikBooking::getGroupDays($pcheckin, $pcheckout, $daysdiff);
161 $morehst = VikBooking::getHoursRoomAvail() * 3600;
162 $validtime = true;
163 $prices = [];
164 $rooms_counts = [];
165 $all_busy = VikBooking::loadBusyRecords($rooms_involved, time(), $pcheckout);
166 foreach ($rooms as $num => $r) {
167 // get rate plan ID
168 $ppriceid = VikRequest::getString('priceid' . $num, '', 'request');
169 if (!empty($ppriceid)) {
170 $prices[$num] = intval($ppriceid);
171 }
172 // room busy records
173 $busy = isset($all_busy[$r['id']]) ? $all_busy[$r['id']] : [];
174 // determine the days to consider for the count of the availability
175 $use_groupdays = $groupdays;
176 if (!empty($split_stay) && !empty($split_stay[($num - 1)]) && $split_stay[($num - 1)]['idroom'] == $r['id']) {
177 $split_room = $split_stay[($num - 1)];
178 $use_groupdays = VikBooking::getGroupDays($split_room['checkin_ts'], $split_room['checkout_ts'], (int)$split_room['nights']);
179 }
180 foreach ($use_groupdays as $gday) {
181 $bfound = 0;
182 foreach ($busy as $bu) {
183 if (in_array($bu['id'], $skip_busy_ids)) {
184 // booking modification
185 continue;
186 }
187 if ($gday >= $bu['checkin'] && $gday <= ($morehst + $bu['checkout'])) {
188 $bfound++;
189 }
190 }
191 if ($bfound >= $r['units']) {
192 $validtime = false;
193 break;
194 }
195 }
196 if (!isset($rooms_counts[$r['id']])) {
197 $rooms_counts[$r['id']] = [
198 'name' => $r['name'],
199 'units' => $r['units'],
200 'count' => 0,
201 ];
202 }
203 // increase counter for this room ID in case multiple units of this same room are asked
204 $rooms_counts[$r['id']]['count']++;
205 }
206
207 if (!$validtime) {
208 showSelectVb(JText::translate('VBROOMNOTCONS') . " " . date($df . ' H:i', $pcheckin) . " " . JText::translate('VBROOMNOTCONSTO') . " " . date($df . ' H:i', $pcheckout));
209 return;
210 }
211
212 // validate multiple units of the same room type ID
213 foreach ($rooms_counts as $idr => $unitused) {
214 if ($unitused['count'] > $unitused['units']) {
215 VikError::raiseWarning('', JText::sprintf('VBERRROOMUNITSNOTAVAIL', $unitused['count'], $unitused['name']));
216 $app->redirect(JRoute::rewrite('index.php?option=com_vikbooking'.(!empty($pitemid) ? '&Itemid='.$pitemid : '')));
217 $goonunits = false;
218 break;
219 }
220 }
221
222 if (count($prices) != count($rooms)) {
223 showSelectVb(JText::translate('VBNOTARSELECTED'));
224 return;
225 }
226
227 // load options
228 $optionals = [];
229 $selopt = [];
230
231 $q = "SELECT `opt`.* FROM `#__vikbooking_optionals` AS `opt` ORDER BY `opt`.`ordering` ASC;";
232 $dbo->setQuery($q);
233 $optionals = $dbo->loadAssocList();
234 if ($optionals) {
235 $vbo_tn->translateContents($optionals, '#__vikbooking_optionals');
236 }
237
238 // package
239 $pkg = [];
240 if (!empty($ppkg_id)) {
241 $pkg = VikBooking::validateRoomPackage($ppkg_id, $rooms, $daysdiff, $pcheckin, $pcheckout);
242 if (!is_array($pkg) || (is_array($pkg) && !(count($pkg) > 0)) ) {
243 if (!is_array($pkg)) {
244 VikError::raiseWarning('', $pkg);
245 }
246 $app->redirect(JRoute::rewrite("index.php?option=com_vikbooking&view=packagedetails&pkgid=".$ppkg_id.(!empty($pitemid) ? "&Itemid=".$pitemid : ""), false));
247 exit;
248 }
249 }
250
251 // prepare tariffs available
252 $tars = [];
253 $validfares = true;
254 foreach ($rooms as $num => $r) {
255 // determine the number of nights of stay and dates to consider
256 $use_los = (int)$daysdiff;
257 $room_checkin = $pcheckin;
258 $room_checkout = $pcheckout;
259 if (!empty($split_stay) && !empty($split_stay[($num - 1)]) && $split_stay[($num - 1)]['idroom'] == $r['id']) {
260 $use_los = (int)$split_stay[($num - 1)]['nights'];
261 $room_checkin = $split_stay[($num - 1)]['checkin_ts'];
262 $room_checkout = $split_stay[($num - 1)]['checkout_ts'];
263 }
264 if (!count($pkg)) {
265 $q = "SELECT * FROM `#__vikbooking_dispcost` WHERE `idroom`=" . (int)$r['id'] . " AND `days`=" . $use_los . " AND `idprice`=" . $prices[$num] . ";";
266 $dbo->setQuery($q);
267 $tar = $dbo->loadAssocList();
268 if (!$tar) {
269 $validfares = false;
270 break;
271 }
272 $tar = VikBooking::applySeasonsRoom($tar, $room_checkin, $room_checkout);
273
274 // apply OBP rules
275 $tar = VBORoomHelper::getInstance()->applyOBPRules($tar, $r, $arrpeople[$num]['adults']);
276
277 // push room tariff
278 $tars[$num] = $tar;
279 }
280
281 // load selected options
282 foreach ($optionals as $opt) {
283 if (!empty($opt['ageintervals']) && $arrpeople[$num]['children'] > 0) {
284 $tmpvar = VikRequest::getInt('optid'.$num.$opt['id'], []);
285 if (is_array($tmpvar) && $tmpvar) {
286 $opt['quan'] = 1;
287 $optagenames = VikBooking::getOptionIntervalsAges($opt['ageintervals']);
288 $optagepcent = VikBooking::getOptionIntervalsPercentage($opt['ageintervals']);
289 $optageovrct = VikBooking::getOptionIntervalChildOverrides($opt, $arrpeople[$num]['adults'], $arrpeople[$num]['children']);
290 $optorigname = $opt['name'];
291 foreach ($tmpvar as $child_num => $chvar) {
292 $ageintervals_child_string = isset($optageovrct['ageintervals_child' . ($child_num + 1)]) ? $optageovrct['ageintervals_child' . ($child_num + 1)] : $opt['ageintervals'];
293 $optagecosts = VikBooking::getOptionIntervalsCosts($ageintervals_child_string);
294 $opt['cost'] = $optagecosts[($chvar - 1)];
295 if (array_key_exists(($chvar - 1), $optagepcent) && $optagepcent[($chvar - 1)] == 1 && ( (array_key_exists($num, $tars) && count($tars[$num]) > 0) || (is_array($pkg) && count($pkg) > 0) )) {
296 //percentage value of the adults tariff
297 if (is_array($pkg) && count($pkg) > 0) {
298 $opt['cost'] = ($pkg['pernight_total'] == 1 ? ($pkg['cost'] * $daysdiff) : $pkg['cost']) * $optagecosts[($chvar - 1)] / 100;
299 } else {
300 $opt['cost'] = $tars[$num][0]['cost'] * $optagecosts[($chvar - 1)] / 100;
301 }
302 } elseif (array_key_exists(($chvar - 1), $optagepcent) && $optagepcent[($chvar - 1)] == 2 && ( (array_key_exists($num, $tars) && count($tars[$num]) > 0) || (is_array($pkg) && count($pkg) > 0) )) {
303 //VBO 1.10 - percentage value of room base cost
304 if (is_array($pkg) && count($pkg) > 0) {
305 $opt['cost'] = ($pkg['pernight_total'] == 1 ? ($pkg['cost'] * $daysdiff) : $pkg['cost']) * $optagecosts[($chvar - 1)] / 100;
306 } else {
307 $display_rate = isset($tars[$num][0]['room_base_cost']) ? $tars[$num][0]['room_base_cost'] : $tars[$num][0]['cost'];
308 $opt['cost'] = $display_rate * $optagecosts[($chvar - 1)] / 100;
309 }
310 }
311 $opt['name'] = $optorigname.' ('.$optagenames[($chvar - 1)].')';
312 $opt['chageintv'] = $chvar;
313 $selopt[$num][] = $opt;
314 }
315 }
316 } else {
317 $tmpvar = VikRequest::getString('optid'.$num.$opt['id'], '', 'request');
318 if (!empty($tmpvar)) {
319 $opt['quan'] = $tmpvar;
320 // VBO 1.11 - options percentage cost of the room total fee
321 if (is_array($pkg) && count($pkg) > 0) {
322 $deftar_basecosts = $pkg['pernight_total'] == 1 ? ($pkg['cost'] * $daysdiff) : $pkg['cost'];
323 } else {
324 $deftar_basecosts = $tars[$num][0]['cost'];
325 }
326 $opt['cost'] = (int)$opt['pcentroom'] ? ($deftar_basecosts * $opt['cost'] / 100) : $opt['cost'];
327 //
328 $selopt[$num][] = $opt;
329 }
330 }
331 }
332 }
333
334 if ($validfares !== true) {
335 showSelectVb(JText::translate('VBTARNOTFOUND'));
336 return;
337 }
338
339 // load contents from db
340 $q = "SELECT * FROM `#__vikbooking_gpayments` WHERE `published`='1' ORDER BY `#__vikbooking_gpayments`.`ordering` ASC;";
341 $dbo->setQuery($q);
342 $payments = $dbo->loadAssocList();
343 if ($payments) {
344 $vbo_tn->translateContents($payments, '#__vikbooking_gpayments');
345 }
346
347 /**
348 * Validate payment methods assigned to specific room IDs.
349 *
350 * @since 1.16.0 (J) - 1.6.0
351 */
352 foreach ($payments as $pay_k => $pay_v) {
353 if (empty($pay_v['idrooms'])) {
354 continue;
355 }
356 $rooms_supported = json_decode($pay_v['idrooms']);
357 if (!is_array($rooms_supported) || !count($rooms_supported)) {
358 continue;
359 }
360 // make sure all rooms being booked are supported
361 foreach ($rooms_involved as $room_id_booked) {
362 if (!in_array($room_id_booked, $rooms_supported)) {
363 // we need to unset this payment option as soon as we find one non-matching room ID
364 unset($payments[$pay_k]);
365 break;
366 }
367 }
368 }
369
370 // reset payment array keys in case some methods were unset
371 $payments = array_values($payments);
372
373 $q = "SELECT * FROM `#__vikbooking_custfields` ORDER BY `#__vikbooking_custfields`.`ordering` ASC;";
374 $dbo->setQuery($q);
375 $cfields = $dbo->loadAssocList();
376 if ($cfields) {
377 $vbo_tn->translateContents($cfields, '#__vikbooking_custfields');
378 }
379
380 $countries = [];
381 foreach ($cfields as $cf) {
382 if ($cf['type'] == 'country') {
383 $q = "SELECT * FROM `#__vikbooking_countries` ORDER BY `#__vikbooking_countries`.`country_name` ASC;";
384 $dbo->setQuery($q);
385 $countries = $dbo->loadAssocList();
386 break;
387 }
388 }
389 if (!empty($countries) && is_array($countries)) {
390 $vbo_tn->translateContents($countries, '#__vikbooking_countries');
391 }
392
393 // customer details
394 $cpin = VikBooking::getCPinIstance();
395 $customer_details = $cpin->loadCustomerDetails();
396
397 // coupon
398 $pcouponcode = VikRequest::getString('couponcode', '', 'request');
399 $coupon = [];
400
401 /**
402 * Check if the customer has an automatic discount.
403 *
404 * @since 1.16.0 (J) - 1.6.0 (WP)
405 */
406 $customer_id = null;
407 if (!empty($customer_details['id'])) {
408 $customer_id = $customer_details['id'];
409 $customer_coupon = $cpin->getCustomerCoupon($customer_details, [
410 'checkin' => $pcheckin,
411 'checkout' => $pcheckout,
412 'days' => $daysdiff,
413 'rooms' => $rooms,
414 ]);
415 if ($customer_coupon) {
416 // force the customer coupon code
417 $pcouponcode = $customer_coupon['code'];
418 }
419 }
420
421 if (strlen($pcouponcode) && !count($pkg)) {
422 $coupon = VikBooking::getCouponInfo($pcouponcode);
423 $valid_customer_coupon = true;
424 if (!empty($coupon) && !empty($coupon['customers'])) {
425 if (empty($customer_id) || !in_array($customer_id, $coupon['customers'])) {
426 $valid_customer_coupon = false;
427 }
428 }
429 if (!empty($coupon) && $valid_customer_coupon) {
430 $coupondateok = true;
431 $couponroomok = true;
432 if (strlen($coupon['datevalid']) > 0) {
433 $dateparts = explode("-", $coupon['datevalid']);
434 $pickinfo = getdate($pcheckin);
435 $dropinfo = getdate($pcheckout);
436 $checkpick = mktime(0, 0, 0, $pickinfo['mon'], $pickinfo['mday'], $pickinfo['year']);
437 $checkdrop = mktime(0, 0, 0, $dropinfo['mon'], $dropinfo['mday'], $dropinfo['year']);
438 if (!($checkpick >= $dateparts[0] && $checkpick <= $dateparts[1] && $checkdrop >= $dateparts[0] && $checkdrop <= $dateparts[1])) {
439 $coupondateok = false;
440 }
441 }
442 if (!empty($coupon['minlos']) && $coupon['minlos'] > $daysdiff) {
443 $coupondateok = false;
444 }
445 if ($coupondateok === true) {
446 if ($coupon['allvehicles'] == 0) {
447 foreach ($rooms as $num => $r) {
448 if (!(preg_match("/;".$r['id'].";/i", $coupon['idrooms']))) {
449 $couponroomok = false;
450 break;
451 }
452 }
453 }
454 if ($couponroomok !== true) {
455 $coupon = [];
456 VikError::raiseWarning('', JText::translate('VBCOUPONINVROOM'));
457 }
458
459 /**
460 * Trigger event to allow third-party plugins to implement additional coupon validations or manipulation.
461 *
462 * @since 1.16.7 (J) - 1.6.7 (WP)
463 */
464 if ($couponroomok) {
465 $coupon_validation = VBOFactory::getPlatform()->getDispatcher()->filter('onValidateCouponCode', [&$coupon]);
466 if (is_array($coupon_validation) && in_array(false, $coupon_validation, true)) {
467 // coupon is not valid, errors should be set by the plugin's hook
468 $coupon = [];
469 }
470 }
471
472 } else {
473 $coupon = [];
474 VikError::raiseWarning('', JText::translate('VBCOUPONINVDATES'));
475 }
476 } else {
477 if (!$valid_customer_coupon) {
478 $coupon = [];
479 }
480 VikError::raiseWarning('', JText::translate('VBCOUPONNOTFOUND'));
481 }
482 }
483
484 $this->rooms = $rooms;
485 $this->tars = $tars;
486 $this->prices = $prices;
487 $this->arrpeople = $arrpeople;
488 $this->roomsnum = $proomsnum;
489 $this->selopt = $selopt;
490 $this->days = $daysdiff;
491 $this->coupon = $coupon;
492 $this->first = $pcheckin;
493 $this->second = $pcheckout;
494 $this->payments = $payments;
495 $this->cfields = $cfields;
496 $this->customer_details = $customer_details;
497 $this->countries = $countries;
498 $this->pkg = $pkg;
499 $this->mod_booking = $mod_booking;
500 $this->split_stay = $split_stay;
501 $this->vbo_tn = $vbo_tn;
502 //theme
503 $theme = VikBooking::getTheme();
504 if ($theme != 'default') {
505 $thdir = VBO_SITE_PATH.DS.'themes'.DS.$theme.DS.'oconfirm';
506 if (is_dir($thdir)) {
507 $this->_setPath('template', $thdir.DS);
508 }
509 }
510
511 /**
512 * We append to the booking process the rooms indexes booked through the interactive map, if any.
513 *
514 * @since 1.14 (J) - 1.4.0 (WP)
515 */
516 if (count($proomindex) == count($rooms)) {
517 $only_empty_indexes = true;
518 foreach ($proomindex as $rindex) {
519 if ((int)$rindex > 0) {
520 // a true room index was selected
521 $only_empty_indexes = false;
522 break;
523 }
524 }
525 if ($only_empty_indexes) {
526 // we don't need to pass along the room indexes
527 $proomindex = [];
528 }
529 } else {
530 $proomindex = [];
531 }
532 $this->roomindex = $proomindex;
533
534 // push initial data to tracker
535 $rooms_ids = [];
536 $prices_ids = [];
537 foreach ($rooms as $ir => $r) {
538 $rooms_ids[$ir] = $r['id'];
539 $prices_ids[$ir] = $prices[$ir];
540 }
541 VikBooking::getTracker()
542 ->pushDates($pcheckin, $pcheckout, $daysdiff)
543 ->pushParty($arrpeople)
544 ->pushRooms($rooms_ids, $prices_ids, $proomindex);
545
546 // display the View
547 parent::display($tpl);
548
549 // close tracking
550 VikBooking::getTracker()
551 ->closeTrack();
552 }
553 }
554