PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.7.2
VikBooking Hotel Booking Engine & PMS v1.7.2
1.8.16 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 All 37 releases
vikbooking / site / views / search / view.html.php

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

1,427 lines 66.8 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 VikbookingViewSearch extends JViewVikBooking
16 {
17 public function display($tpl = null)
18 {
19 $dbo = JFactory::getDbo();
20 if (VikBooking::allowBooking()) {
21 $session = JFactory::getSession();
22 $mainframe = JFactory::getApplication();
23 $vbo_tn = VikBooking::getTranslator();
24 $pcheckindate = VikRequest::getString('checkindate', '', 'request');
25 $pcheckinm = VikRequest::getString('checkinm', '', 'request');
26 $pcheckinh = VikRequest::getString('checkinh', '', 'request');
27 $pcheckoutdate = VikRequest::getString('checkoutdate', '', 'request');
28 $pcheckoutm = VikRequest::getString('checkoutm', '', 'request');
29 $pcheckouth = VikRequest::getString('checkouth', '', 'request');
30 $pcategories = VikRequest::getString('categories', '', 'request');
31 $proomsnum = VikRequest::getInt('roomsnum', '', 'request');
32 $proomsnum = $proomsnum < 1 ? 1 : $proomsnum;
33 $showchildren = VikBooking::showChildrenFront();
34 $padults = VikRequest::getVar('adults', []);
35 $pchildren = VikRequest::getVar('children', []);
36 $ppkg_id = VikRequest::getInt('pkg_id', '', 'request');
37 $pcategory_ids = VikRequest::getVar('category_ids', []);
38 $nowdf = VikBooking::getDateFormat();
39 if ($nowdf == "%d/%m/%Y") {
40 $df = 'd/m/Y';
41 } elseif ($nowdf == "%m/%d/%Y") {
42 $df = 'm/d/Y';
43 } else {
44 $df = 'Y/m/d';
45 }
46 $timeopst = VikBooking::getTimeOpenStore();
47 if (!(strlen($pcheckinh) > 0) && !(strlen($pcheckouth) > 0) && is_array($timeopst)) {
48 $opent = VikBooking::getHoursMinutes($timeopst[0]);
49 $closet = VikBooking::getHoursMinutes($timeopst[1]);
50 $pcheckinh = $opent[0];
51 $pcheckinm = $opent[1];
52 $pcheckouth = $closet[0];
53 $pcheckoutm = $closet[1];
54 }
55 //vikbooking 1.5 channel manager
56 $ch_start_date = VikRequest::getString('start_date', '', 'request');
57 $ch_end_date = VikRequest::getString('end_date', '', 'request');
58 $ch_num_adults = VikRequest::getInt('num_adults', '', 'request');
59 $ch_num_children = VikRequest::getInt('num_children', '', 'request');
60 if (!empty($ch_start_date) && !empty($ch_end_date)) {
61 if (!empty($ch_num_adults) && $ch_num_adults > 0) {
62 $padults = [$ch_num_adults];
63 }
64 if (!empty($ch_num_children) && $ch_num_children > 0) {
65 $pchildren = [$ch_num_children];
66 }
67 if ($ch_start_date_ts = strtotime($ch_start_date)) {
68 if ($ch_end_date_ts = strtotime($ch_end_date)) {
69 $pcheckindate = date($df, $ch_start_date_ts);
70 $pcheckoutdate = date($df, $ch_end_date_ts);
71 if (is_array($timeopst)) {
72 $opent = VikBooking::getHoursMinutes($timeopst[0]);
73 $closet = VikBooking::getHoursMinutes($timeopst[1]);
74 $pcheckinh = $opent[0];
75 $pcheckinm = $opent[1];
76 $pcheckouth = $closet[0];
77 $pcheckoutm = $closet[1];
78 } else {
79 $pcheckinh = 0;
80 $pcheckinm = 0;
81 $pcheckouth = 0;
82 $pcheckoutm = 0;
83 }
84 }
85 }
86 }
87 //
88
89 /**
90 * To facilitate the search suggestions to drive more bookings in case of low
91 * availability on the requested dates, we grab all rooms by ignoring their
92 * minimum needed occupancy, and by considering only their maximum capacity.
93 * This can make sense because "solo-rates" (for single-occupancy) are, most
94 * of the times, forced by most OTAs. If the "search suggestions" are enabled
95 * then the minimum occupancy of the rooms will be ignored to guarantee the
96 * completion of a reservation by the guest, which would be booking a greater
97 * room. In terms of pricing and availability nothing changes of course.
98 *
99 * @since 1.14.3 (J) - 1.4.3 (WP)
100 */
101 $booking_suggestion = VikRequest::getInt('suggestion', 0, 'request');
102
103 /**
104 * It is possible to display some listings as unavailable in case they are fully booked.
105 * If enabled, the unavailable listings will be displayed as long as some are available.
106 *
107 * @since 1.17.2 (J) - 1.7.2 (WP)
108 */
109 $unavailable_listings = [];
110
111 $arradultsrooms = [];
112 $arradultsclause = [];
113 $arrpeople = [];
114 if ($padults) {
115 foreach ($padults as $kad => $adu) {
116 $roomnumb = $kad + 1;
117 if (strlen($adu)) {
118 $numadults = intval($adu);
119 if ($numadults >= 0) {
120 $arradultsrooms[$roomnumb] = $numadults;
121 $arrpeople[$roomnumb]['adults'] = $numadults;
122 // build capacity requirement clauses
123 $room_requirements = [];
124 if (!$booking_suggestion) {
125 array_push($room_requirements, "`r`.`fromadult`<=" . $numadults);
126 }
127 array_push($room_requirements, "`r`.`toadult`>=" . $numadults);
128 if ($showchildren && !empty($pchildren[$kad]) && intval($pchildren[$kad]) > 0) {
129 $numchildren = intval($pchildren[$kad]);
130 $arrpeople[$roomnumb]['children'] = $numchildren;
131 if (!$booking_suggestion) {
132 array_push($room_requirements, "`r`.`fromchild`<=" . $numchildren);
133 }
134 array_push($room_requirements, "`r`.`tochild`>=" . $numchildren);
135 } else {
136 $arrpeople[$roomnumb]['children'] = 0;
137 //VikBooking 1.4 May Patch: if no children then the room must accept no children
138 if ($showchildren && intval($pchildren[$kad]) == 0) {
139 array_push($room_requirements, "`r`.`fromchild` = 0");
140 }
141 //
142 }
143 array_push($room_requirements, "`r`.`totpeople` >= " . ($arrpeople[$roomnumb]['adults'] + $arrpeople[$roomnumb]['children']));
144 if (!$booking_suggestion) {
145 array_push($room_requirements, "`r`.`mintotpeople` <= " . ($arrpeople[$roomnumb]['adults'] + $arrpeople[$roomnumb]['children']));
146 }
147 $strclause = '(' . implode(' AND ', $room_requirements) . ')';
148 $arradultsclause[] = $strclause;
149 }
150 }
151 }
152 }
153
154 //VBO 1.10 - Modify booking
155 $mod_booking = [];
156 $skip_busy_ids = [];
157 $cur_mod = $session->get('vboModBooking', '');
158 if (is_array($cur_mod) && $cur_mod) {
159 $mod_booking = $cur_mod;
160 $skip_busy_ids = VikBooking::loadBookingBusyIds($mod_booking['id']);
161 }
162 //
163 $session->set('vbroomsnum', $proomsnum);
164 $session->set('vbarrpeople', $arrpeople);
165 if (!empty($pcheckindate) && !empty($pcheckoutdate) && $proomsnum > 0 && count($arradultsrooms) == $proomsnum) {
166 if (VikBooking::dateIsValid($pcheckindate) && VikBooking::dateIsValid($pcheckoutdate)) {
167 $first = VikBooking::getDateTimestamp($pcheckindate, $pcheckinh, $pcheckinm);
168 $second = VikBooking::getDateTimestamp($pcheckoutdate, $pcheckouth, $pcheckoutm);
169 $actnow = time();
170 $today_bookings = VikBooking::todayBookings();
171 if ($today_bookings) {
172 $actnow = mktime(0, 0, 0, date('n'), date('j'), date('Y'));
173 }
174 if ($second > $first && $first >= $actnow) {
175 $session->set('vbcheckin', $first);
176 $session->set('vbcheckout', $second);
177 $secdiff = $second - $first;
178 $daysdiff = $secdiff / 86400;
179 if (is_int($daysdiff)) {
180 if ($daysdiff < 1) {
181 $daysdiff = 1;
182 }
183 } else {
184 if ($daysdiff < 1) {
185 $daysdiff = 1;
186 } else {
187 $sum = floor($daysdiff) * 86400;
188 $newdiff = $secdiff - $sum;
189 $maxhmore = VikBooking::getHoursMoreRb() * 3600;
190 if ($maxhmore >= $newdiff) {
191 $daysdiff = floor($daysdiff);
192 } else {
193 $daysdiff = ceil($daysdiff);
194 }
195 }
196 }
197 // VBO 1.11 - push data to tracker
198 VikBooking::getTracker()->pushDates($first, $second, $daysdiff)->pushParty($arrpeople);
199 //
200 //Restrictions
201 $allrestrictions = VikBooking::loadRestrictions(false);
202 $restrictions = VikBooking::globalRestrictions($allrestrictions);
203 $restrcheckin = getdate($first);
204 $restrcheckout = getdate($second);
205 $restrictionsvalid = true;
206 $restrictions_affcount = 0;
207 $restrictionerrmsg = '';
208 if ($restrictions) {
209 if (array_key_exists($restrcheckin['mon'], $restrictions)) {
210 //restriction found for this month, checking:
211 $restrictions_affcount++;
212 if (strlen((string)$restrictions[$restrcheckin['mon']]['wday'])) {
213 $rvalidwdays = [$restrictions[$restrcheckin['mon']]['wday']];
214 if (strlen((string)$restrictions[$restrcheckin['mon']]['wdaytwo'])) {
215 $rvalidwdays[] = $restrictions[$restrcheckin['mon']]['wdaytwo'];
216 }
217 if (!in_array($restrcheckin['wday'], $rvalidwdays)) {
218 $restrictionsvalid = false;
219 $restrictionerrmsg = JText::sprintf('VBRESTRERRWDAYARRIVAL', VikBooking::sayMonth($restrcheckin['mon']), VikBooking::sayWeekDay($restrictions[$restrcheckin['mon']]['wday']).(strlen($restrictions[$restrcheckin['mon']]['wdaytwo']) > 0 ? '/'.VikBooking::sayWeekDay($restrictions[$restrcheckin['mon']]['wdaytwo']) : ''));
220 } elseif ($restrictions[$restrcheckin['mon']]['multiplyminlos'] == 1) {
221 if (($daysdiff % $restrictions[$restrcheckin['mon']]['minlos']) != 0) {
222 $restrictionsvalid = false;
223 $restrictionerrmsg = JText::sprintf('VBRESTRERRMULTIPLYMINLOS', VikBooking::sayMonth($restrcheckin['mon']), $restrictions[$restrcheckin['mon']]['minlos']);
224 }
225 }
226 $comborestr = VikBooking::parseJsDrangeWdayCombo($restrictions[$restrcheckin['mon']]);
227 if ($comborestr) {
228 if (array_key_exists($restrcheckin['wday'], $comborestr)) {
229 if (!in_array($restrcheckout['wday'], $comborestr[$restrcheckin['wday']])) {
230 $restrictionsvalid = false;
231 $restrictionerrmsg = JText::sprintf('VBRESTRERRWDAYCOMBO', VikBooking::sayMonth($restrcheckin['mon']), VikBooking::sayWeekDay($comborestr[$restrcheckin['wday']][0]).(count($comborestr[$restrcheckin['wday']]) == 2 ? '/'.VikBooking::sayWeekDay($comborestr[$restrcheckin['wday']][1]) : ''), VikBooking::sayWeekDay($restrcheckin['wday']));
232 }
233 }
234 }
235 } elseif (!empty($restrictions[$restrcheckin['mon']]['ctad']) || !empty($restrictions[$restrcheckin['mon']]['ctdd'])) {
236 if (!empty($restrictions[$restrcheckin['mon']]['ctad'])) {
237 $ctarestrictions = explode(',', $restrictions[$restrcheckin['mon']]['ctad']);
238 if (in_array('-'.$restrcheckin['wday'].'-', $ctarestrictions)) {
239 $restrictionsvalid = false;
240 $restrictionerrmsg = JText::sprintf('VBRESTRERRWDAYCTAMONTH', VikBooking::sayWeekDay($restrcheckin['wday']), VikBooking::sayMonth($restrcheckin['mon']));
241 }
242 }
243 if (!empty($restrictions[$restrcheckin['mon']]['ctdd'])) {
244 $ctdrestrictions = explode(',', $restrictions[$restrcheckin['mon']]['ctdd']);
245 if (in_array('-'.$restrcheckout['wday'].'-', $ctdrestrictions)) {
246 $restrictionsvalid = false;
247 $restrictionerrmsg = JText::sprintf('VBRESTRERRWDAYCTDMONTH', VikBooking::sayWeekDay($restrcheckout['wday']), VikBooking::sayMonth($restrcheckin['mon']));
248 }
249 }
250 }
251 if (!empty($restrictions[$restrcheckin['mon']]['maxlos']) && $restrictions[$restrcheckin['mon']]['maxlos'] > 0 && $restrictions[$restrcheckin['mon']]['maxlos'] > $restrictions[$restrcheckin['mon']]['minlos']) {
252 if ($daysdiff > $restrictions[$restrcheckin['mon']]['maxlos']) {
253 $restrictionsvalid = false;
254 $restrictionerrmsg = JText::sprintf('VBRESTRERRMAXLOSEXCEEDED', VikBooking::sayMonth($restrcheckin['mon']), $restrictions[$restrcheckin['mon']]['maxlos']);
255 }
256 }
257 if ($daysdiff < $restrictions[$restrcheckin['mon']]['minlos']) {
258 $restrictionsvalid = false;
259 $restrictionerrmsg = JText::sprintf('VBRESTRERRMINLOSEXCEEDED', VikBooking::sayMonth($restrcheckin['mon']), $restrictions[$restrcheckin['mon']]['minlos']);
260 }
261 } elseif (array_key_exists('range', $restrictions)) {
262 /**
263 * We use this map to know which restriction IDs are okay or not okay with the Min LOS.
264 * The most recent restrictions will have a higher priority over the oldest ones.
265 *
266 * @since 1.13.5 (J) - 1.3.6 (WP)
267 */
268 $minlos_priority = [
269 'ok' => [],
270 'nok' => [],
271 ];
272 //
273 foreach ($restrictions['range'] as $restr) {
274 /**
275 * We should not always add 82799 seconds to the end date of the restriction
276 * because if they only last for one day (like a Saturday), then $restr['dto']
277 * will be already set to the time 23:59:59.
278 *
279 * @since 1.13 (J) - 1.3.0 (WP)
280 */
281 $end_operator = date('Y-m-d', $restr['dfrom']) != date('Y-m-d', $restr['dto']) ? 82799 : 0;
282 //
283 if ($restr['dfrom'] <= $restrcheckin[0] && ($restr['dto'] + $end_operator) >= $restrcheckin[0]) {
284 // restriction found for this date range based on arrival date, check if compliant
285 $restrictions_affcount++;
286 if (strlen((string)$restr['wday'])) {
287 $rvalidwdays = [$restr['wday']];
288 if (strlen((string)$restr['wdaytwo'])) {
289 $rvalidwdays[] = $restr['wdaytwo'];
290 }
291 if (!in_array($restrcheckin['wday'], $rvalidwdays)) {
292 $restrictionsvalid = false;
293 $restrictionerrmsg = JText::sprintf('VBRESTRERRWDAYARRIVALRANGE', VikBooking::sayWeekDay($restr['wday']).(strlen((string)$restr['wdaytwo']) ? '/'.VikBooking::sayWeekDay($restr['wdaytwo']) : ''));
294 } elseif ($restr['multiplyminlos'] == 1) {
295 if (($daysdiff % $restr['minlos']) != 0) {
296 $restrictionsvalid = false;
297 $restrictionerrmsg = JText::sprintf('VBRESTRERRMULTIPLYMINLOSRANGE', $restr['minlos']);
298 }
299 }
300 $comborestr = VikBooking::parseJsDrangeWdayCombo($restr);
301 if ($comborestr) {
302 if (array_key_exists($restrcheckin['wday'], $comborestr)) {
303 if (!in_array($restrcheckout['wday'], $comborestr[$restrcheckin['wday']])) {
304 $restrictionsvalid = false;
305 $restrictionerrmsg = JText::sprintf('VBRESTRERRWDAYCOMBORANGE', VikBooking::sayWeekDay($comborestr[$restrcheckin['wday']][0]).(count($comborestr[$restrcheckin['wday']]) == 2 ? '/'.VikBooking::sayWeekDay($comborestr[$restrcheckin['wday']][1]) : ''), VikBooking::sayWeekDay($restrcheckin['wday']));
306 }
307 }
308 }
309 } elseif (!empty($restr['ctad']) || !empty($restr['ctdd'])) {
310 if (!empty($restr['ctad'])) {
311 $ctarestrictions = explode(',', $restr['ctad']);
312 if (in_array('-'.$restrcheckin['wday'].'-', $ctarestrictions)) {
313 $restrictionsvalid = false;
314 $restrictionerrmsg = JText::sprintf('VBRESTRERRWDAYCTARANGE', VikBooking::sayWeekDay($restrcheckin['wday']));
315 }
316 }
317 if (!empty($restr['ctdd'])) {
318 $ctdrestrictions = explode(',', $restr['ctdd']);
319 if (in_array('-'.$restrcheckout['wday'].'-', $ctdrestrictions) && $restrcheckout[0] <= ($restr['dto'] + $end_operator)) {
320 $restrictionsvalid = false;
321 $restrictionerrmsg = JText::sprintf('VBRESTRERRWDAYCTDRANGE', VikBooking::sayWeekDay($restrcheckout['wday']));
322 }
323 }
324 }
325 if (!empty($restr['maxlos']) && $restr['maxlos'] > 0 && $restr['maxlos'] > $restr['minlos']) {
326 if ($daysdiff > $restr['maxlos']) {
327 $restrictionsvalid = false;
328 $restrictionerrmsg = JText::sprintf('VBRESTRERRMAXLOSEXCEEDEDRANGE', $restr['maxlos']);
329 }
330 }
331 if ($daysdiff < $restr['minlos']) {
332 $restrictionsvalid = false;
333 $restrictionerrmsg = JText::sprintf('VBRESTRERRMINLOSEXCEEDEDRANGE', $restr['minlos']);
334 array_push($minlos_priority['nok'], (int)$restr['id']);
335 } else {
336 array_push($minlos_priority['ok'], (int)$restr['id']);
337 }
338 } elseif ($restr['dfrom'] <= $restrcheckout[0] && ($restr['dto'] + $end_operator) >= $restrcheckout[0] && !empty($restr['ctdd'])) {
339 /**
340 * We validate the CTD restrictions depending on the check-out date.
341 *
342 * @since 1.16.3 (J) - 1.6.3 (WP)
343 */
344 $ctdrestrictions = explode(',', $restr['ctdd']);
345 if (in_array('-'.$restrcheckout['wday'].'-', $ctdrestrictions)) {
346 $restrictions_affcount++;
347 $restrictionsvalid = false;
348 $restrictionerrmsg = JText::sprintf('VBRESTRERRWDAYCTDRANGE', VikBooking::sayWeekDay($restrcheckout['wday']));
349 }
350 }
351 }
352 /**
353 * We give priority to more recent restrictions to override MinLOS.
354 *
355 * @since 1.13.5 (J) - 1.3.6 (WP)
356 */
357 if (!$restrictionsvalid && $minlos_priority['ok'] && $minlos_priority['nok'] && max($minlos_priority['ok']) > max($minlos_priority['nok'])) {
358 // we unset the error message and we reset the validity because a more recent restriction is allowing this MinLOS
359 $restrictionsvalid = true;
360 $restrictionerrmsg = '';
361 }
362 //
363 }
364 }
365 /**
366 * We are no longer counting the "global restriction records" applied to all rooms, but
367 * we are rather counting all restriction records, global and for individual rooms. This
368 * way we apply the default Min LOS only when there are no restrictions at all. We are
369 * also ignoring if some restrictions were applied. This is the previous IF statement:
370 *
371 * if (!$restrictions || $restrictions_affcount <= 0) {
372 *
373 * @since 1.15.0 (J) - 1.5.0 (WP)
374 */
375 if (!$allrestrictions) {
376 // check global MinLOS (only in case there are no restrictions affecting these dates or no restrictions at all)
377 $globminlos = VikBooking::getDefaultNightsCalendar();
378 if ($globminlos > 1 && $daysdiff < $globminlos) {
379 $restrictionsvalid = false;
380 $restrictionerrmsg = JText::sprintf('VBRESTRERRMINLOSEXCEEDEDRANGE', $globminlos);
381 }
382 }
383 //VBO 1.9 - check if we are coming from a package to not consider the global restrictions for the standard booking procedure
384 if (!empty($ppkg_id)) {
385 $pkg = VikBooking::getPackage($ppkg_id);
386 if ($pkg) {
387 //the package exists so we let the next view perform the validation of the package criteria (MinLOS, MaxLOS etc..).
388 $restrictionsvalid = true;
389 $restrictionerrmsg = '';
390 }
391 }
392 //
393 //Closing Dates
394 $err_closingdates = VikBooking::validateClosingDates($first, $second, $df);
395 if (!empty($err_closingdates)) {
396 $restrictionsvalid = false;
397 $restrictionerrmsg = JText::sprintf('VBERRDATESCLOSED', $err_closingdates);
398 }
399 //
400 //Maximum date in the future for bookings
401 $err_maxdatefuture = VikBooking::validateMaxDateBookings($first);
402 if (!empty($err_maxdatefuture)) {
403 $restrictionsvalid = false;
404 $restrictionerrmsg = JText::sprintf('VBOERRMAXDATEBOOKINGS', $err_maxdatefuture);
405 }
406 //
407 //Minimum days in advance for bookings
408 $err_mindaysadv = VikBooking::validateMinDaysAdvance($first);
409 if (!empty($err_mindaysadv)) {
410 $restrictionsvalid = false;
411 $restrictionerrmsg = JText::sprintf('VBOERRMINDAYSADV', $err_mindaysadv);
412 }
413 //
414 if ($restrictionsvalid === true) {
415 $hoursdiff = VikBooking::countHoursToArrival($first);
416 $q = "SELECT `p`.*,`r`.`id` AS `r_reference_id`,`r`.`name`,`r`.`img`,`r`.`idcat`,`r`.`idcarat`,`r`.`units`,`r`.`moreimgs`,`r`.`fromadult`,`r`.`toadult`,`r`.`fromchild`,`r`.`tochild`,`r`.`smalldesc`,`r`.`totpeople`,`r`.`params`,`r`.`imgcaptions`,`rp`.`name` AS `rpname`,`rp`.`minlos`,`rp`.`minhadv` FROM `#__vikbooking_dispcost` AS `p`, `#__vikbooking_rooms` AS `r`, `#__vikbooking_prices` AS `rp` WHERE `p`.`days`=".(int)$daysdiff." AND `p`.`idroom`=`r`.`id` AND `p`.`idprice`=`rp`.`id` AND `r`.`avail`='1' AND (".implode(" OR ", $arradultsclause).") ORDER BY `p`.`cost` ASC, `p`.`idprice` DESC, `p`.`idroom` ASC;";
417 $dbo->setQuery($q);
418 $tars = $dbo->loadAssocList();
419 if ($tars) {
420 $vbo_tn->translateContents($tars, '#__vikbooking_rooms', ['id' => 'r_reference_id']);
421 $arrtar = [];
422 foreach ($tars as $tar) {
423 $arrtar[$tar['idroom']][] = $tar;
424 }
425 //Closed rate plans on these dates
426 $roomrpclosed = VikBooking::getRoomRplansClosedInDates(array_keys($arrtar), $first, $daysdiff);
427 if ($roomrpclosed) {
428 foreach ($arrtar as $kk => $tt) {
429 if (array_key_exists($kk, $roomrpclosed)) {
430 foreach ($tt as $tk => $tv) {
431 if (array_key_exists($tv['idprice'], $roomrpclosed[$kk])) {
432 unset($arrtar[$kk][$tk]);
433 }
434 }
435 if (!$arrtar[$kk]) {
436 unset($arrtar[$kk]);
437 } else {
438 $arrtar[$kk] = array_values($arrtar[$kk]);
439 }
440 }
441 }
442 }
443 //
444 //VBO 1.10 - rate plans with a minlos, or with a min hours in advance
445 foreach ($arrtar as $kk => $tt) {
446 foreach ($tt as $tk => $tv) {
447 if (!empty($tv['minlos']) && $tv['minlos'] > $daysdiff) {
448 unset($arrtar[$kk][$tk]);
449 } elseif ($hoursdiff < $tv['minhadv']) {
450 unset($arrtar[$kk][$tk]);
451 }
452 }
453 if (!$arrtar[$kk]) {
454 unset($arrtar[$kk]);
455 } else {
456 $arrtar[$kk] = array_values($arrtar[$kk]);
457 }
458 }
459 //
460 $filtercat = (!empty($pcategories) && $pcategories != "all");
461 $filtermulticat = (is_array($pcategory_ids) && $pcategory_ids);
462 //vikbooking 1.1
463 $groupdays = VikBooking::getGroupDays($first, $second, $daysdiff);
464 $morehst = VikBooking::getHoursRoomAvail() * 3600;
465 //
466 $allbusy = VikBooking::loadBusyRecords(array_keys($arrtar), $first, $second);
467 $all_locked = VikBooking::loadLockedRecords(array_keys($arrtar), $actnow);
468 foreach ($arrtar as $kk => $tt) {
469 $cats = explode(";", $tt[0]['idcat']);
470 if ($filtercat) {
471 if (!in_array($pcategories, $cats)) {
472 unset($arrtar[$kk]);
473 continue;
474 }
475 }
476 if ($filtermulticat) {
477 /**
478 * Added support for multiple category IDs as filter
479 *
480 * @since 1.13
481 */
482 $multicat_found = false;
483 foreach ($pcategory_ids as $fcatid) {
484 if (!empty($fcatid) && in_array($fcatid, $cats)) {
485 $multicat_found = true;
486 break;
487 }
488 }
489 if (!$multicat_found) {
490 unset($arrtar[$kk]);
491 continue;
492 }
493 }
494 $arrtar[$kk][0]['unitsavail'] = $tt[0]['units'];
495 if ($allbusy && isset($allbusy[$kk]) && $allbusy[$kk]) {
496 $units_booked = [];
497 $check_locked = (bool)($all_locked && isset($all_locked[$kk]) && $all_locked[$kk]);
498 foreach ($groupdays as $gday) {
499 $bfound = 0;
500 foreach ($allbusy[$kk] as $bu) {
501 if (in_array($bu['id'], $skip_busy_ids)) {
502 //VBO 1.10 - Booking modification
503 continue;
504 }
505 if ($gday >= $bu['checkin'] && $gday <= ($morehst + $bu['checkout'])) {
506 $bfound++;
507 }
508 }
509 if ($bfound >= $tt[0]['units']) {
510 // listing is fully booked
511 $unavailable_listings[] = $kk;
512 unset($arrtar[$kk]);
513 break;
514 } else {
515 $units_booked[] = $bfound;
516 if ($check_locked === true) {
517 foreach ($all_locked[$kk] as $bu) {
518 if ($gday >= $bu['checkin'] && $gday <= $bu['realback']) {
519 $bfound++;
520 }
521 }
522 if ($bfound >= $tt[0]['units']) {
523 unset($arrtar[$kk]);
524 break;
525 } else {
526 // push peak to properly calculate the units left by considering the locked records
527 $units_booked[] = $bfound;
528 }
529 }
530 }
531 }
532 if (isset($arrtar[$kk]) && $units_booked) {
533 $tot_u_booked = max($units_booked);
534 $tot_u_left = ($tt[0]['units'] - $tot_u_booked);
535 $arrtar[$kk][0]['unitsavail'] = $tot_u_left >= 0 ? $tot_u_left : 0;
536 }
537 } elseif (!VikBooking::roomNotLocked($kk, $tt[0]['units'], $first, $second)) {
538 // room is fully locked
539 unset($arrtar[$kk]);
540 } elseif ($all_locked && isset($all_locked[$kk]) && $all_locked[$kk]) {
541 // update number of units left by counting the units temporary locked
542 $units_booked = [];
543 foreach ($groupdays as $gday) {
544 $bfound = 0;
545 foreach ($all_locked[$kk] as $bu) {
546 if ($gday >= $bu['checkin'] && $gday <= $bu['realback']) {
547 $bfound++;
548 }
549 }
550 // push peak to properly calculate the units left
551 $units_booked[] = $bfound;
552 }
553 if (isset($arrtar[$kk]) && $units_booked) {
554 $tot_u_booked = max($units_booked);
555 $tot_u_left = ($tt[0]['units'] - $tot_u_booked);
556 $arrtar[$kk][0]['unitsavail'] = $tot_u_left >= 0 ? $tot_u_left : 0;
557 }
558 }
559 // single room restrictions
560 if (isset($arrtar[$kk]) && $allrestrictions) {
561 $roomrestr = VikBooking::roomRestrictions($kk, $allrestrictions);
562 if ($roomrestr) {
563 $restrictionerrmsg = VikBooking::validateRoomRestriction($roomrestr, $restrcheckin, $restrcheckout, $daysdiff);
564 if (strlen($restrictionerrmsg) > 0) {
565 //VBO 1.9 - check if we are coming from a package to not consider the restrictions for the standard booking procedure
566 $canunset = true;
567 if (!empty($ppkg_id)) {
568 $pkg = VikBooking::getPackage($ppkg_id);
569 if ($pkg) {
570 //the package exists so we let the next view perform the validation of the package criterai (MinLOS, MaxLOS etc..).
571 $canunset = false;
572 }
573 }
574 if ($canunset === true) {
575 unset($arrtar[$kk]);
576 } else {
577 $restrictionerrmsg = '';
578 }
579 //
580 }
581 }
582 }
583 //end single room restrictions
584
585 /**
586 * Room-level maximum advance booking notice validation.
587 *
588 * @since 1.16.3 (J) - 1.6.3 (WP)
589 */
590 $err_maxdatefuture_room = VikBooking::validateMaxDateBookings($first, $kk);
591 if (!empty($err_maxdatefuture_room)) {
592 // unset non-compliant room and register last error
593 unset($arrtar[$kk]);
594 $restrictionerrmsg = JText::sprintf('VBOERRMAXDATEBOOKINGS', $err_maxdatefuture_room);
595 }
596 }
597 if (is_array($arrtar) && $arrtar) {
598 /**
599 * Despite of the higher resources needed, we parse all rate plans for all rooms.
600 *
601 * @since 1.13 (J) - 1.3.0 (WP)
602 */
603 $arrtar = VikBooking::applySeasonalPrices($arrtar, $first, $second);
604 $multi_rates = 1;
605 foreach ($arrtar as $idr => $tars) {
606 $multi_rates = count($tars) > $multi_rates ? count($tars) : $multi_rates;
607 }
608 if ($multi_rates > 1) {
609 for ($r = 1; $r < $multi_rates; $r++) {
610 $deeper_rates = [];
611 foreach ($arrtar as $idr => $tars) {
612 foreach ($tars as $tk => $tar) {
613 if ($tk == $r) {
614 $deeper_rates[$idr][0] = $tar;
615 break;
616 }
617 }
618 }
619 if (!$deeper_rates) {
620 continue;
621 }
622 $deeper_rates = VikBooking::applySeasonalPrices($deeper_rates, $first, $second);
623 foreach ($deeper_rates as $idr => $dtars) {
624 foreach ($dtars as $dtk => $dtar) {
625 $arrtar[$idr][$r] = $dtar;
626 }
627 }
628 }
629 }
630 $arrtar = VikBooking::sortResults($arrtar);
631 //
632
633 // separate results per number of rooms with $results
634 $tmparrtar = $arrtar;
635 $results = [];
636 $multiroomcount = [];
637 foreach ($arrpeople as $numroom => $aduchild) {
638 $arrtar = $tmparrtar;
639 $diffusage = [];
640 $aduchild['children'] = !array_key_exists('children', $aduchild) ? 0 : $aduchild['children'];
641 $nowtotpeople = $aduchild['adults'] + $aduchild['children'];
642 foreach ($arrtar as $kk => $tt) {
643 $validchildren = true;
644 if ($showchildren) {
645 if (!($tt[0]['fromchild'] <= $aduchild['children'] && $tt[0]['tochild'] >= $aduchild['children']) && $aduchild['children'] > 0) {
646 $validchildren = false;
647 }
648 }
649 $validtotpeople = true;
650 if ($nowtotpeople > $tt[0]['totpeople']) {
651 $errmess = JText::sprintf('VBERRPEOPLEPERROOM', $nowtotpeople, $aduchild['adults'], $aduchild['children']);
652 $validtotpeople = false;
653 }
654 if ($validchildren && $validtotpeople) {
655 if ($tt[0]['toadult'] == $aduchild['adults']) {
656 //clean the diffusage from best usage in case it exists from before
657 foreach ($arrtar[$kk] as $kpr => $vpr) {
658 if (array_key_exists('diffusage', $arrtar[$kk][$kpr])) {
659 unset($arrtar[$kk][$kpr]['diffusage']);
660 }
661 if (array_key_exists('diffusagecost', $arrtar[$kk][$kpr])) {
662 //restore original price
663 $operator = substr($arrtar[$kk][$kpr]['diffusagecost'], 0, 1);
664 $valpcent = substr($arrtar[$kk][$kpr]['diffusagecost'], -1);
665 if ($operator == "+") {
666 if ($valpcent == "%") {
667 $diffvalue = substr($arrtar[$kk][$kpr]['diffusagecost'], 1, (strlen($arrtar[$kk][$kpr]['diffusagecost']) - 1));
668 if (array_key_exists('diffusagecostpernight', $arrtar[$kk][$kpr]) && $arrtar[$kk][$kpr]['diffusagecostpernight'] > 0) {
669 $arrtar[$kk][$kpr]['cost'] = $arrtar[$kk][$kpr]['diffusagecostpernight'];
670 } else {
671 $arrtar[$kk][$kpr]['cost'] = round(($vpr['cost'] * (100 - $diffvalue) / 100), 2);
672 }
673 } else {
674 $diffvalue = substr($arrtar[$kk][$kpr]['diffusagecost'], 1);
675 $arrtar[$kk][$kpr]['cost'] = $vpr['cost'] - $diffvalue;
676 }
677 } elseif ($operator == "-") {
678 if ($valpcent == "%") {
679 $diffvalue = substr($arrtar[$kk][$kpr]['diffusagecost'], 1, (strlen($arrtar[$kk][$kpr]['diffusagecost']) - 1));
680 if (array_key_exists('diffusagecostpernight', $arrtar[$kk][$kpr]) && $arrtar[$kk][$kpr]['diffusagecostpernight'] > 0) {
681 $arrtar[$kk][$kpr]['cost'] = $arrtar[$kk][$kpr]['diffusagecostpernight'];
682 } else {
683 $arrtar[$kk][$kpr]['cost'] = round(($vpr['cost'] * (100 + $diffvalue) / 100), 2);
684 }
685 } else {
686 $diffvalue = substr($arrtar[$kk][$kpr]['diffusagecost'], 1);
687 $arrtar[$kk][$kpr]['cost'] = $vpr['cost'] + $diffvalue;
688 }
689 }
690 //
691 unset($arrtar[$kk][$kpr]['diffusagecost']);
692 unset($arrtar[$kk][$kpr]['diffusagecostpernight']);
693 }
694 }
695 //
696 //VikBooking 1.3 - Maximum Occupancy Charges/Discounts
697 $diffusageprice = VikBooking::loadAdultsDiff($kk, $aduchild['adults']);
698 //Occupancy Override
699 if (array_key_exists('occupancy_ovr', $tt[0]) && array_key_exists($aduchild['adults'], $tt[0]['occupancy_ovr']) && strlen($tt[0]['occupancy_ovr'][$aduchild['adults']]['value'])) {
700 $diffusageprice = $tt[0]['occupancy_ovr'][$aduchild['adults']];
701 }
702 //
703 if (is_array($diffusageprice)) {
704 //set a charge or discount to the price(s) for the different usage of the room
705 foreach ($arrtar[$kk] as $kpr => $vpr) {
706 $arrtar[$kk][$kpr]['diffusage'] = $aduchild['adults'];
707 if ($diffusageprice['chdisc'] == 1) {
708 //charge
709 if ($diffusageprice['valpcent'] == 1) {
710 //fixed value
711 $arrtar[$kk][$kpr]['diffusagecostpernight'] = $diffusageprice['pernight'] == 1 ? 1 : 0;
712 $aduseval = $diffusageprice['pernight'] == 1 ? $diffusageprice['value'] * $arrtar[$kk][$kpr]['days'] : $diffusageprice['value'];
713 $arrtar[$kk][$kpr]['diffusagecost'] = "+".$aduseval;
714 $arrtar[$kk][$kpr]['cost'] = $vpr['cost'] + $aduseval;
715 } else {
716 //percentage value
717 $arrtar[$kk][$kpr]['diffusagecostpernight'] = $diffusageprice['pernight'] == 1 ? $vpr['cost'] : 0;
718 $aduseval = $diffusageprice['pernight'] == 1 ? round(($vpr['cost'] * $diffusageprice['value'] / 100) * $arrtar[$kk][$kpr]['days'] + $vpr['cost'], 2) : round(($vpr['cost'] * (100 + $diffusageprice['value']) / 100), 2);
719 $arrtar[$kk][$kpr]['diffusagecost'] = "+".$diffusageprice['value']."%";
720 $arrtar[$kk][$kpr]['cost'] = $aduseval;
721 }
722 } else {
723 //discount
724 if ($diffusageprice['valpcent'] == 1) {
725 //fixed value
726 $arrtar[$kk][$kpr]['diffusagecostpernight'] = $diffusageprice['pernight'] == 1 ? 1 : 0;
727 $aduseval = $diffusageprice['pernight'] == 1 ? $diffusageprice['value'] * $arrtar[$kk][$kpr]['days'] : $diffusageprice['value'];
728 $arrtar[$kk][$kpr]['diffusagecost'] = "-".$aduseval;
729 $arrtar[$kk][$kpr]['cost'] = $vpr['cost'] - $aduseval;
730 } else {
731 //percentage value
732 $arrtar[$kk][$kpr]['diffusagecostpernight'] = $diffusageprice['pernight'] == 1 ? $vpr['cost'] : 0;
733 $aduseval = $diffusageprice['pernight'] == 1 ? round($vpr['cost'] - ((($vpr['cost'] / $arrtar[$kk][$kpr]['days']) * $diffusageprice['value'] / 100) * $arrtar[$kk][$kpr]['days']), 2) : round(($vpr['cost'] * (100 - $diffusageprice['value']) / 100), 2);
734 $arrtar[$kk][$kpr]['diffusagecost'] = "-".$diffusageprice['value']."%";
735 $arrtar[$kk][$kpr]['cost'] = $aduseval;
736 }
737 }
738 }
739 }
740 //VikBooking 1.3 - Maximum Occupancy Charges/Discounts
741 //best usage
742 $results[$numroom][] = $arrtar[$kk];
743 if (!isset($multiroomcount[$arrtar[$kk][0]['idroom']])) {
744 $multiroomcount[$arrtar[$kk][0]['idroom']] = ['count' => 0];
745 }
746 $multiroomcount[$arrtar[$kk][0]['idroom']]['count'] += 1;
747 $multiroomcount[$arrtar[$kk][0]['idroom']]['unitsavail'] = (int)$arrtar[$kk][0]['unitsavail'];
748 $multiroomcount[$arrtar[$kk][0]['idroom']]['diffusage_r'.$numroom] = 0;
749 } elseif (($tt[0]['fromadult'] <= $aduchild['adults'] || $booking_suggestion) && $tt[0]['toadult'] > $aduchild['adults']) {
750 //different usage
751 $diffusageprice = VikBooking::loadAdultsDiff($kk, $aduchild['adults']);
752 //Occupancy Override
753 if (array_key_exists('occupancy_ovr', $tt[0]) && array_key_exists($aduchild['adults'], $tt[0]['occupancy_ovr']) && strlen($tt[0]['occupancy_ovr'][$aduchild['adults']]['value'])) {
754 $diffusageprice = $tt[0]['occupancy_ovr'][$aduchild['adults']];
755 }
756 //
757 if (is_array($diffusageprice)) {
758 //set a charge or discount to the price(s) for the different usage of the room
759 foreach ($arrtar[$kk] as $kpr => $vpr) {
760 $arrtar[$kk][$kpr]['diffusage'] = $aduchild['adults'];
761 if ($diffusageprice['chdisc'] == 1) {
762 //charge
763 if ($diffusageprice['valpcent'] == 1) {
764 //fixed value
765 $arrtar[$kk][$kpr]['diffusagecostpernight'] = $diffusageprice['pernight'] == 1 ? 1 : 0;
766 $aduseval = $diffusageprice['pernight'] == 1 ? $diffusageprice['value'] * $arrtar[$kk][$kpr]['days'] : $diffusageprice['value'];
767 $arrtar[$kk][$kpr]['diffusagecost'] = "+".$aduseval;
768 $arrtar[$kk][$kpr]['cost'] = $vpr['cost'] + $aduseval;
769 } else {
770 //percentage value
771 $arrtar[$kk][$kpr]['diffusagecostpernight'] = $diffusageprice['pernight'] == 1 ? $vpr['cost'] : 0;
772 $aduseval = $diffusageprice['pernight'] == 1 ? round(($vpr['cost'] * $diffusageprice['value'] / 100) * $arrtar[$kk][$kpr]['days'] + $vpr['cost'], 2) : round(($vpr['cost'] * (100 + $diffusageprice['value']) / 100), 2);
773 $arrtar[$kk][$kpr]['diffusagecost'] = "+".$diffusageprice['value']."%";
774 $arrtar[$kk][$kpr]['cost'] = $aduseval;
775 }
776 } else {
777 //discount
778 if ($diffusageprice['valpcent'] == 1) {
779 //fixed value
780 $arrtar[$kk][$kpr]['diffusagecostpernight'] = $diffusageprice['pernight'] == 1 ? 1 : 0;
781 $aduseval = $diffusageprice['pernight'] == 1 ? $diffusageprice['value'] * $arrtar[$kk][$kpr]['days'] : $diffusageprice['value'];
782 $arrtar[$kk][$kpr]['diffusagecost'] = "-".$aduseval;
783 $arrtar[$kk][$kpr]['cost'] = $vpr['cost'] - $aduseval;
784 } else {
785 //percentage value
786 $arrtar[$kk][$kpr]['diffusagecostpernight'] = $diffusageprice['pernight'] == 1 ? $vpr['cost'] : 0;
787 $aduseval = $diffusageprice['pernight'] == 1 ? round($vpr['cost'] - ((($vpr['cost'] / $arrtar[$kk][$kpr]['days']) * $diffusageprice['value'] / 100) * $arrtar[$kk][$kpr]['days']), 2) : round(($vpr['cost'] * (100 - $diffusageprice['value']) / 100), 2);
788 $arrtar[$kk][$kpr]['diffusagecost'] = "-".$diffusageprice['value']."%";
789 $arrtar[$kk][$kpr]['cost'] = $aduseval;
790 }
791 }
792 }
793 } else {
794 $arrtar[$kk][0]['diffusage'] = $aduchild['adults'];
795 }
796 $diffusage[$numroom][] = $arrtar[$kk];
797 if (!isset($multiroomcount[$arrtar[$kk][0]['idroom']])) {
798 $multiroomcount[$arrtar[$kk][0]['idroom']] = ['count' => 0];
799 }
800 $multiroomcount[$arrtar[$kk][0]['idroom']]['count'] += 1;
801 $multiroomcount[$arrtar[$kk][0]['idroom']]['unitsavail'] = (int)$arrtar[$kk][0]['unitsavail'];
802 $multiroomcount[$arrtar[$kk][0]['idroom']]['diffusage_r'.$numroom] = 1;
803 }
804 }
805 }
806 //merge $diffusage rooms with and after best usage rooms in $results
807 if ($diffusage) {
808 foreach ($diffusage as $nr => $du) {
809 foreach ($du as $duroom) {
810 $results[$nr][]=$duroom;
811 }
812 }
813 }
814 //
815 }
816 //
817 //check if rooms repeated passed the availability
818 $limitpassed = false;
819 $search_type = VikBooking::getSmartSearchType();
820 $js_search = $search_type == 'dynamic' ? true : false;
821 //dynamic smart search via PHP
822 $js_overcounter = [];
823 if ($js_search && $proomsnum > 1 && $multiroomcount) {
824 $tot_avail = 0;
825 foreach ($multiroomcount as $idroom => $info) {
826 $tot_avail += $info['unitsavail'];
827 }
828 if ($tot_avail >= $proomsnum) {
829 $gen_avail = $results;
830 foreach ($multiroomcount as $idroom => $info) {
831 $multiroomcount[$idroom]['used'] = 0;
832 if ($info['count'] > $info['unitsavail']) {
833 $excessnum = $info['count'] - $info['unitsavail'];
834 if ($excessnum > 0) {
835 for ($z = $proomsnum; $z >= 1; $z--) {
836 if ($excessnum > 0) {
837 /**
838 * VBO 1.10 Patch May 2018
839 * @see comments below
840 */
841 $excessproc = false;
842 //
843 foreach ($results[$z] as $kres => $res) {
844 if ($res[0]['idroom'] == $idroom) {
845 /**
846 * We do not need to unset the rooms as we risk to produce no results.
847 * We skip this control if the "search type" setting is set to "dynamic".
848 *
849 * @since 1.12 Patch October 2nd 2019
850 */
851 if (!$js_search) {
852 unset($gen_avail[$z][$kres]);
853 }
854 $excessproc = true;
855 }
856 }
857 if ($excessproc) {
858 /**
859 * VBO 1.10 Patch May 2018
860 * @see comments below
861 */
862 $excessnum--;
863 }
864 }
865 }
866 }
867 }
868 }
869 /**
870 * We do not need to unset the rooms as we risk to produce no results.
871 * We skip this control if the "search type" setting is set to "dynamic".
872 *
873 * @since 1.12 Patch October 2nd 2019
874 */
875 if (!$js_search) {
876 for ($z = $proomsnum; $z >= 1; $z--) {
877 if (!isset($gen_avail[$z]) || !$gen_avail[$z]) {
878 foreach ($gen_avail as $oknroom => $res) {
879 if (count($gen_avail[$oknroom]) > 1) {
880 $searchfrom = min(array_keys($res));
881 foreach ($res as $kr => $rr) {
882 if (intval($kr) > intval($searchfrom)) {
883 //check if the second, third.. cheapest room(s) is compatible
884 if ($rr[0]['fromadult'] <= $arrpeople[$z]['adults'] && $rr[0]['toadult'] >= $arrpeople[$z]['adults'] && $rr[0]['fromchild'] <= $arrpeople[$z]['children'] && $rr[0]['tochild'] >= $arrpeople[$z]['children']) {
885 $gen_avail[$z][] = $gen_avail[$oknroom][$kr];
886 unset($gen_avail[$oknroom][$kr]);
887 break 2;
888 }
889 }
890 }
891 }
892 }
893 }
894 }
895 }
896 /**
897 * VBO 1.10 Patch May 2018
898 *
899 * Scenario: One room with 3 units in total, 2 units booked and 1 free on certain dates, for 6 adults.
900 * Another room with 5 units available on these dates, for 2 adults. Dynamic search enabled.
901 *
902 * Reservation: 3 room types, 6 adults 1st room, 6 adults 2nd room, 2 adults 3rd room.
903 *
904 * Results: the 6-adult room is displayed for the 1st and 2nd rooms requested, the 2-adult room for the 3rd.
905 * With the Dynamic search enabled, by selecting the 6-adult room once, it gets removed from the other combo.
906 * This leaves one room-party empty, with no results, but no errors are displayed for the search suggestions,
907 * the search results page just gets stuck in there because for a party there are no rooms that can be chosen.
908 *
909 * Solution: if one room-party has no more rooms, unset it so that $js_overcounter won't be set, and the
910 * "automatic smart search via PHP" statement will be processed below. This will raise the error "not enough rooms",
911 * and the Search Suggestions will correctly calculate the availability.
912 *
913 */
914 foreach ($gen_avail as $oknroom => $res) {
915 if (!$gen_avail[$oknroom]) {
916 unset($gen_avail[$oknroom]);
917 }
918 }
919 //
920 if (count($gen_avail) == $proomsnum) {
921 $js_overcounter = $multiroomcount;
922 unset($gen_avail);
923 }
924 }
925 }
926 //
927 //automatic smart search via PHP
928 if ($proomsnum > 1 && $multiroomcount) {
929 foreach ($multiroomcount as $idroom => $info) {
930 if ($info['count'] > $info['unitsavail']) {
931 $excessnum = $info['count'] - $info['unitsavail'];
932 for ($z = $proomsnum; $z >= 1; $z--) {
933 /**
934 * VBO 1.10 Patch June 2018
935 * the different usage clause below should be ignored, or we risk to keep a room in excess
936 * for some room parties when there should be actually no availability for booking multiple times.
937 * This room in excess may be removed only for the parties with different usage, and this is incorrect.
938 */
939 if (true || (array_key_exists('diffusage_r'.$z, $info) && $info['diffusage_r'.$z] == 1)) {
940 //remove repeated room where diffusage and excessnum still exceeds
941 if ($excessnum > 0 && !$js_overcounter) {
942 foreach ($results[$z] as $kres => $res) {
943 if ($res[0]['idroom'] == $idroom) {
944 unset($results[$z][$kres]);
945 $limitpassed = true;
946 }
947 }
948 if ($limitpassed) {
949 $excessnum--;
950 }
951 }
952 //
953 }
954 }
955 //if excessnum still exceeds, means that the room is not available for the repeated best usages
956 if ($excessnum > 0) {
957 for ($z = $proomsnum; $z >= 1; $z--) {
958 if ($excessnum > 0 && !$js_overcounter) {
959 foreach ($results[$z] as $kres => $res) {
960 if ($res[0]['idroom'] == $idroom) {
961 unset($results[$z][$kres]);
962 $limitpassed = true;
963 }
964 }
965 if ($limitpassed) {
966 $excessnum--;
967 }
968 }
969 }
970 }
971 //
972 }
973 }
974 }
975 //
976 //if some room was repeated and removed from the multi rooms searched, check if enough results for each room
977 if ($limitpassed == true) {
978 $critic = [];
979 for ($z = $proomsnum; $z >= 1; $z--) {
980 if (!isset($results[$z]) || !$results[$z]) {
981 $critic[] = $z;
982 unset($results[$z]);
983 }
984 }
985 if ($critic) {
986 //some rooms have 0 results, check if something good for this num of adults can be placed here
987 $moved = [];
988 foreach ($critic as $kcr => $nroom) {
989 foreach ($results as $oknroom => $res) {
990 if (count($results[$oknroom]) > 1) {
991 $searchfrom = min(array_keys($res));
992 foreach ($res as $kr => $rr) {
993 if (intval($kr) > intval($searchfrom)) {
994 //check if the second, third.. cheapest room(s) is compatible
995 if ($rr[0]['fromadult'] <= $arrpeople[$nroom]['adults'] && $rr[0]['toadult'] >= $arrpeople[$nroom]['adults'] && $rr[0]['fromchild'] <= $arrpeople[$nroom]['children'] && $rr[0]['tochild'] >= $arrpeople[$nroom]['children']) {
996 $results[$nroom][] = $results[$oknroom][$kr];
997 $moved[] = $oknroom.'_'.$nroom;
998 unset($results[$oknroom][$kr]);
999 unset($critic[$kcr]);
1000 break 2;
1001 }
1002 }
1003 }
1004 }
1005 }
1006 }
1007 ksort($results);
1008 if ($moved) {
1009 //check if moved rooms had charges/discounts for adults occupancy to update it
1010 foreach ($moved as $move) {
1011 $movedata = explode('_', $move);
1012 if ($arrpeople[$movedata[0]]['adults'] != $arrpeople[$movedata[1]]['adults'] && array_key_exists('diffusagecost', $results[$movedata[1]][0][0])) {
1013 //reset prices of the room
1014 foreach ($results[$movedata[1]][0] as $kpr => $vpr) {
1015 if (array_key_exists('diffusage', $results[$movedata[1]][0][$kpr])) {
1016 unset($results[$movedata[1]][0][$kpr]['diffusage']);
1017 }
1018 if (array_key_exists('diffusagecost', $results[$movedata[1]][0][$kpr])) {
1019 //restore original price
1020 $operator = substr($results[$movedata[1]][0][$kpr]['diffusagecost'], 0, 1);
1021 $valpcent = substr($results[$movedata[1]][0][$kpr]['diffusagecost'], -1);
1022 if ($operator == "+") {
1023 if ($valpcent == "%") {
1024 $diffvalue = substr($results[$movedata[1]][0][$kpr]['diffusagecost'], 1, (strlen($results[$movedata[1]][0][$kpr]['diffusagecost']) - 1));
1025 if (array_key_exists('diffusagecostpernight', $results[$movedata[1]][0][$kpr]) && $results[$movedata[1]][0][$kpr]['diffusagecostpernight'] > 0) {
1026 $results[$movedata[1]][0][$kpr]['cost'] = $results[$movedata[1]][0][$kpr]['diffusagecostpernight'];
1027 } else {
1028 $results[$movedata[1]][0][$kpr]['cost'] = round(($vpr['cost'] * (100 - $diffvalue) / 100), 2);
1029 }
1030 } else {
1031 $diffvalue = substr($results[$movedata[1]][0][$kpr]['diffusagecost'], 1);
1032 $results[$movedata[1]][0][$kpr]['cost'] = $vpr['cost'] - $diffvalue;
1033 }
1034 } elseif ($operator == "-") {
1035 if ($valpcent == "%") {
1036 $diffvalue = substr($results[$movedata[1]][0][$kpr]['diffusagecost'], 1, (strlen($results[$movedata[1]][0][$kpr]['diffusagecost']) - 1));
1037 if (array_key_exists('diffusagecostpernight', $results[$movedata[1]][0][$kpr]) && $results[$movedata[1]][0][$kpr]['diffusagecostpernight'] > 0) {
1038 $results[$movedata[1]][0][$kpr]['cost'] = $results[$movedata[1]][0][$kpr]['diffusagecostpernight'];
1039 } else {
1040 $results[$movedata[1]][0][$kpr]['cost'] = round(($vpr['cost'] * (100 + $diffvalue) / 100), 2);
1041 }
1042 } else {
1043 $diffvalue = substr($results[$movedata[1]][0][$kpr]['diffusagecost'], 1);
1044 $results[$movedata[1]][0][$kpr]['cost'] = $vpr['cost'] + $diffvalue;
1045 }
1046 }
1047 //
1048 unset($results[$movedata[1]][0][$kpr]['diffusagecost']);
1049 unset($results[$movedata[1]][0][$kpr]['diffusagecostpernight']);
1050 }
1051 }
1052 //end reset prices of the room
1053 $diffusageprice = VikBooking::loadAdultsDiff($results[$movedata[1]][0][0]['idroom'], $arrpeople[$movedata[1]]['adults']);
1054 //Occupancy Override - Special Price may be setting a charge/discount for this occupancy while default price had no occupancy pricing
1055 if (!is_array($diffusageprice)) {
1056 foreach ($results[$movedata[1]][0] as $kpr => $vpr) {
1057 if (array_key_exists('occupancy_ovr', $vpr) && array_key_exists($arrpeople[$movedata[1]]['adults'], $vpr['occupancy_ovr']) && strlen($vpr['occupancy_ovr'][$arrpeople[$movedata[1]]['adults']]['value'])) {
1058 $diffusageprice = $vpr['occupancy_ovr'][$arrpeople[$movedata[1]]['adults']];
1059 break;
1060 }
1061 }
1062 reset($results[$movedata[1]][0]);
1063 }
1064 //
1065 if (is_array($diffusageprice)) {
1066 //set a charge or discount to the price(s) for the different usage of the room
1067 foreach ($results[$movedata[1]][0] as $kpr => $vpr) {
1068 //Occupancy Override
1069 if (array_key_exists('occupancy_ovr', $results[$movedata[1]][0][$kpr]) && array_key_exists($arrpeople[$movedata[1]]['adults'], $results[$movedata[1]][0][$kpr]['occupancy_ovr']) && strlen($results[$movedata[1]][0][$kpr]['occupancy_ovr'][$arrpeople[$movedata[1]]['adults']]['value'])) {
1070 $diffusageprice = $results[$movedata[1]][0][$kpr]['occupancy_ovr'][$arrpeople[$movedata[1]]['adults']];
1071 }
1072 //
1073 $results[$movedata[1]][0][$kpr]['diffusage'] = $arrpeople[$movedata[1]]['adults'];
1074 if ($diffusageprice['chdisc'] == 1) {
1075 //charge
1076 if ($diffusageprice['valpcent'] == 1) {
1077 //fixed value
1078 $results[$movedata[1]][0][$kpr]['diffusagecostpernight'] = $diffusageprice['pernight'] == 1 ? 1 : 0;
1079 $aduseval = $diffusageprice['pernight'] == 1 ? $diffusageprice['value'] * $results[$movedata[1]][0][$kpr]['days'] : $diffusageprice['value'];
1080 $results[$movedata[1]][0][$kpr]['diffusagecost'] = "+".$aduseval;
1081 $results[$movedata[1]][0][$kpr]['cost'] = $vpr['cost'] + $aduseval;
1082 } else {
1083 //percentage value
1084 $results[$movedata[1]][0][$kpr]['diffusagecostpernight'] = $diffusageprice['pernight'] == 1 ? $vpr['cost'] : 0;
1085 $aduseval = $diffusageprice['pernight'] == 1 ? round(($vpr['cost'] * $diffusageprice['value'] / 100) * $results[$movedata[1]][0][$kpr]['days'] + $vpr['cost'], 2) : round(($vpr['cost'] * (100 + $diffusageprice['value']) / 100), 2);
1086 $results[$movedata[1]][0][$kpr]['diffusagecost'] = "+".$diffusageprice['value']."%";
1087 $results[$movedata[1]][0][$kpr]['cost'] = $aduseval;
1088 }
1089 } else {
1090 //discount
1091 if ($diffusageprice['valpcent'] == 1) {
1092 //fixed value
1093 $results[$movedata[1]][0][$kpr]['diffusagecostpernight'] = $diffusageprice['pernight'] == 1 ? 1 : 0;
1094 $aduseval = $diffusageprice['pernight'] == 1 ? $diffusageprice['value'] * $results[$movedata[1]][0][$kpr]['days'] : $diffusageprice['value'];
1095 $results[$movedata[1]][0][$kpr]['diffusagecost'] = "-".$aduseval;
1096 $results[$movedata[1]][0][$kpr]['cost'] = $vpr['cost'] - $aduseval;
1097 } else {
1098 //percentage value
1099 $results[$movedata[1]][0][$kpr]['diffusagecostpernight'] = $diffusageprice['pernight'] == 1 ? $vpr['cost'] : 0;
1100 $aduseval = $diffusageprice['pernight'] == 1 ? round($vpr['cost'] - ((($vpr['cost'] / $results[$movedata[1]][0][$kpr]['days']) * $diffusageprice['value'] / 100) * $results[$movedata[1]][0][$kpr]['days']), 2) : round(($vpr['cost'] * (100 - $diffusageprice['value']) / 100), 2);
1101 $results[$movedata[1]][0][$kpr]['diffusagecost'] = "-".$diffusageprice['value']."%";
1102 $results[$movedata[1]][0][$kpr]['cost'] = $aduseval;
1103 }
1104 }
1105 }
1106 }
1107 }
1108 }
1109 //end check if moved rooms had charges/discounts for adults occupancy to update it
1110 }
1111 //
1112 }
1113 }
1114 //
1115 $results = VikBooking::sortMultipleResults($results);
1116 //save prices in session for the modules
1117 $sessvals = [];
1118 $modprices = [];
1119 $sessvals['roomsnum'] = $proomsnum;
1120 $sessvals['checkin'] = $first;
1121 $sessvals['checkout'] = $second;
1122 for ($i = 1; $i <= $proomsnum; $i++) {
1123 if (!isset($results[$i])) {
1124 continue;
1125 }
1126 foreach ($results[$i] as $indres => $res) {
1127 $modprices[$i][] = $res[0]['cost'];
1128 }
1129 }
1130 for ($i = 1; $i <= $proomsnum; $i++) {
1131 if (!isset($modprices[$i])) {
1132 continue;
1133 }
1134 $mincost = min($modprices[$i]);
1135 $maxcost = max($modprices[$i]);
1136 $sessvals[$i]['min'] = $mincost;
1137 $sessvals[$i]['max'] = $maxcost;
1138 $sessvals[$i]['adults'] = $arrpeople[$i]['adults'];
1139 $sessvals[$i]['children'] = $arrpeople[$i]['children'];
1140 }
1141 $session->set('vbsearchdata', $sessvals);
1142 //end save prices in session for the modules
1143 //apply price filters
1144 $ppricefrom = VikRequest::getInt('r1pricefrom', '', 'request');
1145 $ppriceto = VikRequest::getInt('r1priceto', '', 'request');
1146 if (!empty($ppricefrom) && !empty($ppriceto)) {
1147 foreach ($results as $oknroom => $res) {
1148 $totroomres = count($res);
1149 foreach ($res as $kr => $rr) {
1150 if ($oknroom > 1) {
1151 $ppricefrom = VikRequest::getInt('r'.$oknroom.'pricefrom', '', 'request');
1152 $ppriceto = VikRequest::getInt('r'.$oknroom.'priceto', '', 'request');
1153 }
1154 if (!empty($ppricefrom) && !empty($ppriceto)) {
1155 if ($rr[0]['cost'] < $ppricefrom || $rr[0]['cost'] > $ppriceto) {
1156 if ($totroomres > 1) {
1157 unset($results[$oknroom][$kr]);
1158 $totroomres--;
1159 }
1160 }
1161 }
1162 }
1163 }
1164 }
1165 //end apply price filters
1166 if (count($results) == $proomsnum) {
1167 // check whether the user is coming from roomdetails
1168 $proomdetail = VikRequest::getInt('roomdetail', 0, 'request');
1169 $rate_plan_id = VikRequest::getInt('rate_plan_id', 0, 'request');
1170 $user_currency = VikRequest::getString('user_currency', '', 'request');
1171 $children_age = VikRequest::getVar('children_age', []);
1172 $pitemid = VikRequest::getInt('Itemid', 0, 'request');
1173 if (!empty($proomdetail) && array_key_exists($proomdetail, $arrtar) && $proomsnum == 1) {
1174 // VBO 1.11 - push data to tracker and close
1175 VikBooking::getTracker()->pushRooms($proomdetail)->closeTrack();
1176 // store in the session that we are coming from the room details page
1177 $session->set('vboSearchRoomId', $proomdetail);
1178
1179 /**
1180 * Build redirect URI to the "showprc" View to continue the booking process, and
1181 * keep some special vars that may serve to reflect the original booking link.
1182 *
1183 * @since 1.15.0 (J) - 1.5.0 (WP)
1184 */
1185 $url_query_args = [
1186 'option' => 'com_vikbooking',
1187 'task' => 'showprc',
1188 'roomsnum' => '1',
1189 'roomopt' => [
1190 $proomdetail,
1191 ],
1192 'adults' => [
1193 $arrpeople[1]['adults'],
1194 ],
1195 'children' => [
1196 $arrpeople[1]['children'],
1197 ],
1198 'days' => $daysdiff,
1199 'checkin' => $first,
1200 'checkout' => $second,
1201 ];
1202 if (!empty($ppkg_id)) {
1203 $url_query_args['pkg_id'] = $ppkg_id;
1204 }
1205 if (!empty($rate_plan_id)) {
1206 $url_query_args['rate_plan_id'] = $rate_plan_id;
1207 }
1208 if (is_array($children_age) && $children_age) {
1209 $url_query_args['children_age'] = $children_age;
1210 }
1211 if (!empty($user_currency)) {
1212 $url_query_args['user_currency'] = $user_currency;
1213 }
1214 if (!empty($pcategory_ids)) {
1215 $url_query_args['category_ids'] = $pcategory_ids;
1216 }
1217 if (!empty($pitemid)) {
1218 $url_query_args['Itemid'] = $pitemid;
1219 }
1220
1221 $mainframe->redirect(JRoute::rewrite('index.php?' . http_build_query($url_query_args), false));
1222 exit;
1223 } else {
1224 if (!empty($proomdetail) && $proomsnum == 1) {
1225 $q = "SELECT `id`,`name` FROM `#__vikbooking_rooms` WHERE `id`=".intval($proomdetail).";";
1226 $dbo->setQuery($q);
1227 $cdet = $dbo->loadAssocList();
1228 if ($cdet) {
1229 $vbo_tn->translateContents($cdet, '#__vikbooking_rooms');
1230 $msg = JText::sprintf('VBDETAILCNOTAVAIL', $cdet[0]['name'], $daysdiff);
1231 VikError::raiseWarning('', $msg);
1232 // VBO 1.11 - push data to tracker and close
1233 VikBooking::getTracker()->pushRooms($proomdetail)->pushMessage($msg, 'warning')->closeTrack();
1234 //
1235 }
1236 } elseif (!empty($proomdetail) && $proomsnum > 1) {
1237 //check whether the user is coming from roomdetails and if the room is available for any room party
1238 $room_missing = false;
1239 foreach ($results as $indroom => $rooms) {
1240 $room_found = false;
1241 foreach ($rooms as $room) {
1242 if ($room[0]['idroom'] == $proomdetail && (!array_key_exists('unitsavail', $room[0]) || $room[0]['unitsavail'] >= $proomsnum)) {
1243 $room_found = true;
1244 break;
1245 }
1246 }
1247 if (!$room_found) {
1248 $room_missing = true;
1249 break;
1250 }
1251 }
1252 if ($room_missing === false) {
1253 $aduchild_str = '';
1254 foreach ($arrpeople as $people) {
1255 $aduchild_str .= '&adults[]='.$people['adults'].'&children[]='.$people['children'];
1256 }
1257 $roomopt_str = '';
1258 for ($ri = 0; $ri < $proomsnum; $ri++) {
1259 $roomopt_str .= '&roomopt[]='.$proomdetail;
1260 }
1261 // store in the session that we are coming from the room details page
1262 $session->set('vboSearchRoomId', $proomdetail);
1263 //
1264 $mainframe->redirect(JRoute::rewrite("index.php?option=com_vikbooking&task=showprc&roomsnum=".$proomsnum.$roomopt_str.$aduchild_str."&days=".$daysdiff."&checkin=".$first."&checkout=".$second.(!empty($ppkg_id) ? "&pkg_id=" . $ppkg_id : "").(!empty($pitemid) ? "&Itemid=" . $pitemid : ""), false));
1265 // VBO 1.11 - push data to tracker and close
1266 VikBooking::getTracker()->pushRooms(array_fill(0, $proomsnum, $proomdetail))->closeTrack();
1267 //
1268 exit;
1269 } else {
1270 $q = "SELECT `id`,`name` FROM `#__vikbooking_rooms` WHERE `id`=".intval($proomdetail).";";
1271 $dbo->setQuery($q);
1272 $cdet = $dbo->loadAssocList();
1273 if ($cdet) {
1274 $vbo_tn->translateContents($cdet, '#__vikbooking_rooms');
1275 $msg = JText::sprintf('VBDETAILMULTIRNOTAVAIL', $proomsnum, $cdet[0]['name'], $daysdiff);
1276 VikError::raiseWarning('', $msg);
1277 // VBO 1.11 - push data to tracker and close
1278 VikBooking::getTracker()->pushMessage($msg, 'warning')->closeTrack();
1279 //
1280 }
1281 }
1282 }
1283
1284 // filter unavailable listing IDs
1285 $unavailable_listings = array_filter(array_map('intval', array_unique($unavailable_listings)));
1286
1287 // set View properties
1288 $this->res = $results;
1289 $this->days = $daysdiff;
1290 $this->checkin = $first;
1291 $this->checkout = $second;
1292 $this->roomsnum = $proomsnum;
1293 $this->arrpeople = $arrpeople;
1294 $showchildren = $showchildren ? 1 : 0;
1295 $this->showchildren = $showchildren;
1296 $this->js_overcounter = $js_overcounter;
1297 $this->mod_booking = $mod_booking;
1298 $this->unavailable_listings = $unavailable_listings;
1299 $this->vbo_tn = $vbo_tn;
1300 // theme
1301 $theme = VikBooking::getTheme();
1302 if ($theme != 'default') {
1303 $thdir = VBO_SITE_PATH.DS.'themes'.DS.$theme.DS.'search';
1304 if (is_dir($thdir)) {
1305 $this->_setPath('template', $thdir.DS);
1306 }
1307 }
1308
1309 // unset the session if we were coming from the room details page
1310 $session->set('vboSearchRoomId', '');
1311
1312 // VBO 1.11 - close tracker
1313 VikBooking::getTracker()
1314 ->setExtraInfo('results', $results)
1315 ->closeTrack();
1316
1317 parent::display($tpl);
1318 }
1319 //
1320 } else {
1321 //zero results for some room
1322 $errmess = [];
1323 if (isset($critic) && $critic) {
1324 foreach ($critic as $nroom) {
1325 $errmess[] = $arrpeople[$nroom]['adults']." ".($arrpeople[$nroom]['adults'] == 1 ? JText::translate('VBSEARCHRESADULT') : JText::translate('VBSEARCHRESADULTS')).($arrpeople[$nroom]['children'] > 0 ? ", ".$arrpeople[$nroom]['children']." ".($arrpeople[$nroom]['children'] == 1 ? JText::translate('VBSEARCHRESCHILD') : JText::translate('VBSEARCHRESCHILDREN')) : "");
1326 }
1327 $errmess = array_unique($errmess);
1328 } else {
1329 $errmess[] = JText::translate('VBOSEARCHERRCODETHREEBASE');
1330 }
1331 $err_code_info = [
1332 'code' => 3,
1333 'fromts' => $first,
1334 'tots' => $second,
1335 'party' => $arrpeople
1336 ];
1337 $msg = JText::sprintf('VBSEARCHERRNOTENOUGHROOMS', implode(" - ", $errmess));
1338 // VBO 1.11 - push data to tracker and close
1339 VikBooking::getTracker()->pushMessage($msg, 'error')->closeTrack();
1340 //
1341 $this->setVboError($msg, $err_code_info);
1342 }
1343 } else {
1344 $err_code_info = [];
1345 if (strlen($restrictionerrmsg)) {
1346 VikError::raiseWarning('', $restrictionerrmsg);
1347 } else {
1348 $err_code_info = [
1349 'code' => 1,
1350 'fromts' => $first,
1351 'tots' => $second,
1352 'party' => $arrpeople
1353 ];
1354 }
1355 $msg = JText::translate('VBNOROOMSINDATE');
1356 // VBO 1.11 - push data to tracker and close
1357 VikBooking::getTracker()->pushMessage($msg, 'error')->closeTrack();
1358 //
1359 $this->setVboError($msg, $err_code_info);
1360 }
1361 } else {
1362 $sayerr = JText::translate('VBNOROOMAVFOR') . " " . $daysdiff . " " . ($daysdiff > 1 ? JText::translate('VBDAYS') : JText::translate('VBDAY'));
1363 if (count($padults) == 1) {
1364 $sayerr .= ", ".$arrpeople[1]['adults']." ".($arrpeople[1]['adults'] > 1 ? JText::translate('VBSEARCHRESADULTS') : JText::translate('VBSEARCHRESADULT'));
1365 if ($arrpeople[1]['children'] > 0) {
1366 $sayerr .= ", ".$arrpeople[1]['children']." ".($arrpeople[1]['children'] > 1 ? JText::translate('VBSEARCHRESCHILDREN') : JText::translate('VBSEARCHRESCHILD'));
1367 }
1368 }
1369 $err_code_info = [
1370 'code' => 2,
1371 'fromts' => $first,
1372 'tots' => $second,
1373 'party' => $arrpeople
1374 ];
1375 // VBO 1.11 - push data to tracker and close
1376 VikBooking::getTracker()->pushMessage($sayerr, 'error')->closeTrack();
1377 //
1378 $this->setVboError($sayerr, $err_code_info);
1379 }
1380 } else {
1381 $this->setVboError($restrictionerrmsg);
1382 }
1383 } else {
1384 $session->set('vbcheckin', '');
1385 $session->set('vbcheckout', '');
1386 if ($first <= $actnow) {
1387 if (date('d/m/Y', $first) == date('d/m/Y', $actnow)) {
1388 $emess = JText::translate('VBSRCHERRCHKINPASSED');
1389 } else {
1390 $emess = JText::translate('VBSRCHERRCHKINPAST');
1391 }
1392 } else {
1393 $emess = JText::translate('VBPICKBRET');
1394 }
1395 $this->setVboError($emess);
1396 }
1397 } else {
1398 $this->setVboError(JText::translate('VBWRONGDF') . ": " . VikBooking::sayDateFormat());
1399 }
1400 } else {
1401 $this->setVboError(JText::translate('VBSELPRDATE'));
1402 }
1403 } else {
1404 echo VikBooking::getDisabledBookingMsg();
1405 }
1406 }
1407
1408 protected function setVboError($err, $err_code_info = [])
1409 {
1410 $app = JFactory::getApplication();
1411
1412 $ppkg_id = VikRequest::getInt('pkg_id', '', 'request');
1413 $pitemid = VikRequest::getInt('Itemid', '', 'request');
1414
1415 if (!empty($ppkg_id)) {
1416 if (!empty($err)) {
1417 VikError::raiseWarning('', $err);
1418 }
1419
1420 $app->redirect(JRoute::rewrite("index.php?option=com_vikbooking&view=packagedetails&pkgid=".$ppkg_id.(!empty($pitemid) ? "&Itemid=".$pitemid : ""), false));
1421 $app->close();
1422 } else {
1423 showSelectVb($err, $err_code_info);
1424 }
1425 }
1426 }
1427