PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.6
VikBooking Hotel Booking Engine & PMS v1.6.6
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 / searchsuggestions / view.html.php

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

615 lines 24.3 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 VikbookingViewSearchsuggestions extends JViewVikBooking
16 {
17 function display($tpl = null)
18 {
19 $dbo = JFactory::getDbo();
20 $vbo_tn = VikBooking::getTranslator();
21
22 // invoke availability helper class and define settings
23 $av_helper = VikBooking::getAvailabilityInstance()
24 ->setBackForthDays(14)
25 ->setIsFrontBooking(true)
26 ->setNightsTransfersRatio(true);
27
28 $code = VikRequest::getInt('code', 0, 'request');
29 $fromts = VikRequest::getInt('fromts', 0, 'request');
30 $tots = VikRequest::getInt('tots', 0, 'request');
31 $party = $padults = VikRequest::getVar('party', array());
32 $pcategories = VikRequest::getString('categories', '', 'request');
33
34 // set stay values
35 $checkin_date = date('Y-m-d', $fromts);
36 $checkout_date = date('Y-m-d', $tots);
37 $av_helper->setStayDates($checkin_date, $checkout_date);
38
39 // count nights of stay
40 $daysdiff = $av_helper->countNightsOfStay();
41
42 // get how many guests were asked in the party
43 $party_guests = [
44 'adults' => 0,
45 'children' => 0,
46 ];
47 foreach ($party as $guests) {
48 // set party involved for this room
49 $av_helper->setRoomParty((isset($guests['adults']) ? (int)$guests['adults'] : 0), (isset($guests['children']) ? (int)$guests['children'] : 0));
50 if (isset($guests['adults'])) {
51 $party_guests['adults'] += (int)$guests['adults'];
52 }
53 if (isset($guests['children'])) {
54 $party_guests['children'] += (int)$guests['children'];
55 }
56 }
57
58 // get nights requested
59 $info_from = getdate($fromts);
60 $nights_requested = [
61 mktime(0, 0, 0, $info_from['mon'], $info_from['mday'], $info_from['year']),
62 ];
63 for ($n = 1; $n < $daysdiff; $n++) {
64 $nights_requested[] = mktime(0, 0, 0, $info_from['mon'], ($info_from['mday'] + $n), $info_from['year']);
65 }
66
67 // get rooms IDs available
68 $rooms_info = [];
69 $q = "SELECT * FROM `#__vikbooking_rooms` WHERE `avail`=1 ORDER BY `name` ASC;";
70 $dbo->setQuery($q);
71 $dbo->execute();
72 if ($dbo->getNumRows() > 0) {
73 $getrooms = $dbo->loadAssocList();
74 $vbo_tn->translateContents($getrooms, '#__vikbooking_rooms');
75 foreach ($getrooms as $r) {
76 /**
77 * If requested, we apply the same category filter used for the search.
78 *
79 * @since 1.14 (J) - 1.4.0 (WP)
80 */
81 if (!empty($pcategories) && $pcategories != 'all' && !empty($r['idcat'])) {
82 $room_cats = explode(';', $r['idcat']);
83 if (!empty($room_cats[0]) && !in_array($pcategories, $room_cats)) {
84 // room has got categories, but the filtered one is not available, so skip this room
85 continue;
86 }
87 }
88
89 // push room
90 $rooms_info[$r['id']] = $r;
91 }
92 }
93
94 // set rooms
95 $av_helper->setRooms($rooms_info);
96
97 // check for turnover day between bookings
98 $inonout_allowed = true;
99 $timeopst = VikBooking::getTimeOpenStore();
100 if (is_array($timeopst)) {
101 if ($timeopst[0] < $timeopst[1]) {
102 // check-in not allowed on a day where there is already a check out (no arrivals/depatures on the same day)
103 $inonout_allowed = false;
104 }
105 }
106
107 // get closest timestamps to the requested dates (14 days before and after the requested dates, if not in the past)
108 $info_from = getdate($fromts);
109 // get nights requested
110 $nights_requested = [];
111 $nights_requested[] = mktime(0, 0, 0, $info_from['mon'], $info_from['mday'], $info_from['year']);
112 for ($n = 1; $n < $daysdiff; $n++) {
113 $nights_requested[] = mktime(0, 0, 0, $info_from['mon'], ($info_from['mday'] + $n), $info_from['year']);
114 }
115 // count suggested dates back/forth
116 $info_to = getdate($tots);
117 $lim_past_ts = mktime($info_from['hours'], $info_from['minutes'], $info_from['seconds'], date('n'), ((int)date('j') + VikBooking::getMinDaysAdvance()), date('Y'));
118 $sug_from_ts = mktime($info_from['hours'], $info_from['minutes'], $info_from['seconds'], $info_from['mon'], ($info_from['mday'] - 14), $info_from['year']);
119 $sug_from_ts = $sug_from_ts < $lim_past_ts ? $lim_past_ts : $sug_from_ts;
120 $sug_to_ts = mktime($info_to['hours'], $info_to['minutes'], $info_to['seconds'], $info_to['mon'], ($info_to['mday'] + 14), $info_to['year']);
121 $sug_to_ts = $sug_to_ts < $sug_from_ts ? $sug_from_ts : $sug_to_ts;
122
123 // get days for suggestions
124 $groupdays = [];
125 $sug_start_info = getdate($sug_from_ts);
126 $sug_from_midnight = mktime(0, 0, 0, $sug_start_info['mon'], $sug_start_info['mday'], $sug_start_info['year']);
127 $sug_start_info = getdate($sug_from_midnight);
128 while ($sug_start_info[0] <= $sug_to_ts) {
129 array_push($groupdays, $sug_start_info[0]);
130 $sug_start_info = getdate(mktime(0, 0, 0, $sug_start_info['mon'], ($sug_start_info['mday'] + 1), $sug_start_info['year']));
131 }
132
133 // build suggestions array of dates with some availability
134 $suggestions = [];
135 $fully_booked = [];
136 $allbusy = VikBooking::loadBusyRecords(array_keys($rooms_info), $sug_from_ts, strtotime('+1 day', $sug_to_ts));
137 foreach ($rooms_info as $rid => $room) {
138 foreach ($groupdays as $gday) {
139 $day_key = date('Y-m-d', $gday);
140 $bfound = 0;
141 if (!isset($allbusy[$rid])) {
142 $allbusy[$rid] = [];
143 }
144 foreach ($allbusy[$rid] as $bu) {
145 $busy_info_in = getdate($bu['checkin']);
146 $busy_info_out = getdate($bu['checkout']);
147 $busy_in_ts = mktime(0, 0, 0, $busy_info_in['mon'], $busy_info_in['mday'], $busy_info_in['year']);
148 $busy_out_ts = mktime(0, 0, 0, $busy_info_out['mon'], $busy_info_out['mday'], $busy_info_out['year']);
149 if ($gday >= $busy_in_ts && $gday == $busy_out_ts && !$inonout_allowed && $room['units'] < 2) {
150 // check-ins on check-outs not allowed
151 $bfound++;
152 if ($bfound >= $room['units']) {
153 break;
154 }
155 }
156 if ($gday >= $busy_in_ts && $gday < $busy_out_ts) {
157 $bfound++;
158 if ($bfound >= $room['units']) {
159 break;
160 }
161 }
162 }
163 if ($bfound < $room['units']) {
164 if (!isset($suggestions[$day_key])) {
165 $suggestions[$day_key] = [];
166 }
167 $room_day = $room;
168 $room_day['units_left'] = $room['units'] - $bfound;
169 $suggestions[$day_key] = $suggestions[$day_key] + array($rid => $room_day);
170 } else {
171 if (!in_array($room['id'], $fully_booked)) {
172 // push fully booked room ID
173 $fully_booked[] = $room['id'];
174 }
175 }
176 }
177 }
178
179 // build the solutions array with keys=checkin, values=all rooms suited for the requested number of nights
180 $solutions = [];
181 if (count($suggestions)) {
182 //get all rooms available for the number of nights requested in the suggestions array of dates
183 foreach ($suggestions as $kday => $rooms) {
184 $day_ts_info = getdate(strtotime($kday));
185 foreach ($rooms as $rid => $room) {
186 $suitable = true;
187 $room_days_av_left = array($kday => $room['units_left']);
188 for ($i = 1; $i < $daysdiff; $i++) {
189 $next_night = mktime(0, 0, 0, $day_ts_info['mon'], ($day_ts_info['mday'] + $i), $day_ts_info['year']);
190 $next_night_dt = date('Y-m-d', $next_night);
191 if (!isset($suggestions[$next_night_dt]) || !isset($suggestions[$next_night_dt][$rid])) {
192 $suitable = false;
193 break;
194 }
195 $room_days_av_left[$next_night_dt] = $suggestions[$next_night_dt][$rid]['units_left'];
196 }
197 if ($suitable === true) {
198 if (!isset($solutions[$day_ts_info[0]])) {
199 $solutions[$day_ts_info[0]] = [];
200 }
201 unset($room['units_left']);
202 $room['days_av_left'] = $room_days_av_left;
203 $solutions[$day_ts_info[0]] = $solutions[$day_ts_info[0]] + array($rid => $room);
204 }
205 }
206 }
207 }
208
209 if (count($solutions)) {
210 //sort the solutions by the closest checkin date to the one requested
211 $sortmap = [];
212 foreach ($solutions as $kdayts => $solution) {
213 $sortmap[$kdayts] = $kdayts > $fromts ? ($kdayts - $fromts) : ($fromts - $kdayts);
214 }
215 asort($sortmap);
216 $sorted = [];
217 foreach ($sortmap as $kdayts => $v) {
218 $sorted[$kdayts] = $solutions[$kdayts];
219 }
220 $solutions = $sorted;
221
222 /**
223 * Load rooms involved in the final alternative solutions in order
224 * to validate global/room-level restrictions and closing dates.
225 *
226 * @since 1.15.4 (J) - 1.5.10 (WP)
227 */
228 $rooms_involved = [];
229 foreach ($solutions as $kdayts => $roomsol) {
230 foreach (array_keys($roomsol) as $rid) {
231 if (!in_array($rid, $rooms_involved)) {
232 $rooms_involved[] = $rid;
233 }
234 }
235 }
236
237 // load restrictions for all rooms involved
238 $all_restrictions = VikBooking::loadRestrictions(true, $rooms_involved);
239 $glob_restrictions = VikBooking::globalRestrictions($all_restrictions);
240 $room_level_restr = [];
241
242 foreach ($solutions as $kdayts => $roomsol) {
243 // build suggested stay dates
244 $sug_in = getdate($kdayts);
245 $sug_out = getdate(mktime(0, 0, 0, $sug_in['mon'], ($sug_in['mday'] + $daysdiff), $sug_in['year']));
246 // validate global restrictions
247 if (VikBooking::validateRoomRestriction($glob_restrictions, $sug_in, $sug_out, $daysdiff)) {
248 // global restrictions apply over this stay
249 unset($solutions[$kdayts]);
250 continue;
251 }
252 // validate closing dates
253 if (VikBooking::validateClosingDates($sug_in[0], $sug_out[0])) {
254 // global closing dates apply over this stay
255 unset($solutions[$kdayts]);
256 continue;
257 }
258 // validate restrictions at room level
259 foreach ($roomsol as $rid => $rdata) {
260 if (!isset($room_level_restr[$rid])) {
261 // load restrictions at room level
262 $room_level_restr[$rid] = VikBooking::roomRestrictions($rid, $all_restrictions);
263 }
264 if (VikBooking::validateRoomRestriction($room_level_restr[$rid], $sug_in, $sug_out, $daysdiff)) {
265 // room-level restrictions apply over this stay
266 unset($solutions[$kdayts][$rid]);
267 if (!count($solutions[$kdayts])) {
268 // unset the entire suggested date
269 unset($solutions[$kdayts]);
270 break;
271 }
272 continue;
273 }
274 }
275 }
276 }
277
278 // this array should only be parsed in case of error codes 2 and 3. It is not populated in case of error code 1
279 $booking_solutions = [];
280
281 /**
282 * In case of error code 1, we try to check for some split stay solutions.
283 *
284 * @since 1.16.0 (J) - 1.6.0 (WP)
285 */
286 $split_stay_solutions = [];
287
288 // parse the solutions depending on the error code to give the right booking solutions
289 if (count($solutions)) {
290 switch ($code) {
291 case 1:
292 // no availability for the dates requested (there are rates defined for this number of nights and rooms compatible with the party requested)
293 // the solution is to suggest another date for check-in/out when there is availability for the requested party
294
295 // check if the party requested is suited for the current solutions and unset the ones we can't suggest
296 foreach ($solutions as $kdayts => $solution) {
297 $party_solutions = [];
298 foreach ($party as $nump => $guests) {
299 foreach ($solution as $rid => $roomsol) {
300 if (($roomsol['fromadult'] <= $guests['adults'] && $roomsol['toadult'] >= $guests['adults']) &&
301 ($roomsol['fromchild'] <= $guests['children'] && $roomsol['tochild'] >= $guests['children']) &&
302 ($roomsol['mintotpeople'] <= ($guests['adults'] + $guests['children'])) &&
303 ($roomsol['totpeople'] >= ($guests['adults'] + $guests['children']))) {
304 // this room-solution can fit this party
305 $sol_min_rooms = min($roomsol['days_av_left']);
306 $solutions[$kdayts][$rid]['minrooms'] = $sol_min_rooms;
307 if (!isset($party_solutions[$nump])) {
308 $party_solutions[$nump] = [];
309 }
310 $party_solutions[$nump] = $party_solutions[$nump] + array($rid => $solutions[$kdayts][$rid]);
311 }
312 }
313 }
314 if (count($party_solutions) != count($party)) {
315 // in this type of error-code we can't suggest other booking solutions for a specific day, so we unset this solution that doesn't fit the party
316 unset($solutions[$kdayts]);
317 continue;
318 }
319
320 // check if the rooms-solutions have enough units to be used
321 $rooms_usage = [];
322 $rooms_avail = [];
323 foreach ($party_solutions as $nump => $party_sol) {
324 foreach ($party_sol as $rid => $roomsol) {
325 if (!isset($rooms_avail[$rid])) {
326 $rooms_avail[$rid] = $roomsol['minrooms'];
327 }
328 if (!isset($rooms_usage[$rid])) {
329 $rooms_usage[$rid] = 0;
330 }
331 $rooms_usage[$rid]++;
332 }
333 }
334 foreach ($rooms_usage as $rid => $usage) {
335 if ($usage > $rooms_avail[$rid]) {
336 // this room has been suggested too many times for its remaining availability on this day. Remove it until it's okay
337 while ($usage > $rooms_avail[$rid]) {
338 foreach ($party_solutions as $nump => $party_sol) {
339 if (isset($party_sol[$rid])) {
340 $usage--;
341 unset($party_solutions[$nump][$rid]);
342 if (!(count($party_solutions[$nump]) > 0)) {
343 // this party has no more solutions
344 unset($party_solutions[$nump]);
345 }
346 if (!($usage > $rooms_avail[$rid])) {
347 break;
348 }
349 }
350 }
351 }
352 }
353 }
354 if (count($party_solutions) != count($party)) {
355 // in this type of error-code we can't suggest other booking solutions for a specific day, so we unset this solution that doesn't fit the party
356 unset($solutions[$kdayts]);
357 continue;
358 }
359 }
360
361 // try to populate the split stays available according to settings
362 $split_stay_solutions = $av_helper->findSplitStays($fully_booked, $allbusy);
363
364 break;
365 case 2:
366 case 3:
367 // (error code 2) query failed for fetching the rooms (no rates defined for this number of nights or no rooms for the party requested)
368 // the solution is to suggest another combination of party for booking (as long as there are rates for the requested number of nights and the number of guests can fit in the available rooms).
369 // (error code 3) not enough rooms available for the party requested
370 // the solution to suggest is the same as for the error code 2.
371
372 // unset the rooms in the solutions that have no rates for this number of nights as they are useless.
373 foreach ($solutions as $kdayts => $solution) {
374 $rooms_with_rates = [];
375 $q = "SELECT `p`.`idroom` FROM `#__vikbooking_dispcost` AS `p` WHERE `p`.`idroom` IN (".implode(', ', array_keys($solution)).") AND `p`.`days`=".(int)$daysdiff." GROUP BY `p`.`idroom`;";
376 $dbo->setQuery($q);
377 $dbo->execute();
378 if ($dbo->getNumRows() > 0) {
379 $getrooms = $dbo->loadAssocList();
380 foreach ($getrooms as $r) {
381 array_push($rooms_with_rates, (int)$r['idroom']);
382 }
383 }
384 foreach ($solution as $rid => $roomsol) {
385 if (!in_array($rid, $rooms_with_rates)) {
386 unset($solutions[$kdayts][$rid]);
387 continue;
388 }
389 $solutions[$kdayts][$rid]['minrooms'] = min($roomsol['days_av_left']);
390 }
391 if (!(count($solutions[$kdayts]))) {
392 unset($solutions[$kdayts]);
393 }
394 }
395 if (!(count($solutions))) {
396 break;
397 }
398
399 // build the booking solution to suggest, for example, to book some rooms more or less.
400 // Example: 1 room for 8 adults can be booked as 3 double rooms (3 adults, 3 adults, 2 adults = 8 adults)
401 // Example: 2 quadruple rooms for 4 adults each, can be booked as 4 double rooms, with 2 adults each.
402
403 // sort rooms-solutions by 'max-adults' (toadult), 'max-guests' (totpeople), 'max-children' (tochild), in a Descending order
404 foreach ($solutions as $kdayts => $solution) {
405 // with this sorting, we will have the bigger rooms on top to quickly fit the party requested
406 uasort($solutions[$kdayts], function($a, $b) {
407 if ($a['toadult'] == $b['toadult']) {
408 if ($a['totpeople'] == $b['totpeople']) {
409 return $a['tochild'] > $b['tochild'] ? -1 : 1;
410 }
411 return $a['totpeople'] > $b['totpeople'] ? -1 : 1;
412 }
413 return $a['toadult'] > $b['toadult'] ? -1 : 1;
414 });
415 }
416
417 // check if the rooms of each solution can fit the number of guests requested, unset the solution otherwise
418 foreach ($solutions as $kdayts => $solution) {
419 $solution_guests = array(
420 'adults' => 0,
421 'children' => 0
422 );
423 foreach ($solution as $rid => $roomsol) {
424 //check if this solution of rooms can allocate all the guests requested
425 if ($roomsol['totpeople'] < ($roomsol['toadult'] + $roomsol['tochild']) && !$party_guests['children']) {
426 // in case of no children requested, we ignore them to avoid adjusting the room capacity
427 $roomsol['tochild'] = 0;
428 }
429 if ($roomsol['totpeople'] < ($roomsol['toadult'] + $roomsol['tochild'])) {
430 // the sum of the max_adults and max_children exceeds the max_guests: lower the adults we can take first (if party children > 0), then the children, until sum=max_guests
431 while (($roomsol['toadult'] > 0 || $roomsol['tochild'] > 0)) {
432 if (!$party_guests['children'] && $roomsol['totpeople'] == $roomsol['toadult']) {
433 /**
434 * When no children requested in the party, we cannot under-utilize rooms.
435 * Break the loop without lowering the 'toadult'.
436 * @since 1.10 - August 2018
437 */
438 $roomsol['tochild'] = 0;
439 break;
440 }
441 if ($party_guests['children'] && $solution_guests['children'] >= $party_guests['children']) {
442 /**
443 * If all the children requested were allocated in other solutions,
444 * we should not under-utilize rooms by reduing the number of adults.
445 * @since 1.10 - August 2018
446 */
447 break;
448 }
449 if ($roomsol['toadult'] > 0 && $party_guests['children'] > 0 && !($roomsol['tochild'] > $party_guests['children'])) {
450 //we lower first the adults that we put in this room, only if there are children in the party and if the children in the party are more than the 'max_children' of this room
451 $roomsol['toadult']--;
452 if ($roomsol['totpeople'] >= ($roomsol['toadult'] + $roomsol['tochild'])) {
453 break;
454 }
455 }
456 if ($roomsol['tochild'] > 0) {
457 // if the max_guests is still greater than the sum of adults+children we take, take out one child
458 $roomsol['tochild']--;
459 if ($roomsol['totpeople'] >= ($roomsol['toadult'] + $roomsol['tochild'])) {
460 break;
461 }
462 }
463 if ($roomsol['toadult'] > 0) {
464 // if even at this point we still have a high sum of guests to take compared to the max_guests, take out again one adult
465 $roomsol['toadult']--;
466 if ($roomsol['totpeople'] >= ($roomsol['toadult'] + $roomsol['tochild'])) {
467 break;
468 }
469 }
470 }
471 }
472 $solution_guests['adults'] += $roomsol['toadult'] * $roomsol['minrooms'];
473 $solution_guests['children'] += $roomsol['tochild'] * $roomsol['minrooms'];
474 // update 'max_adults' and 'max_children' for this solution (for later guests allocation in $booking_solution)
475 $solution[$rid]['toadult'] = $roomsol['toadult'];
476 $solution[$rid]['tochild'] = $roomsol['tochild'];
477 }
478 $solutions[$kdayts] = $solution;
479 if ($solution_guests['adults'] < $party_guests['adults'] || $solution_guests['children'] < $party_guests['children']) {
480 // the guests we can allocate with the solution of this day are not enough: unset the solution
481 unset($solutions[$kdayts]);
482 continue;
483 }
484 // if we get to this point we can suggest a booking solution for the party requested, but in different rooms
485 if (!isset($booking_solutions[$kdayts])) {
486 $booking_solutions[$kdayts] = [];
487 }
488 // re-loop over the rooms in this solution to build the booking solution for this day
489 $guests_allocated = array(
490 'adults' => 0,
491 'children' => 0
492 );
493
494 /**
495 * The rooms available for an alternative booking solutions have been sorted by capacity
496 * in a descending order to quickly fit the guest party requested. However, if a smaller
497 * and cheaper room was capable of fitting all guests, we should opt for this solution.
498 *
499 * @since 1.15.4 (J) - 1.5.9 (WP)
500 */
501 $smaller_fit_found = false;
502 $smaller_solutions = array_reverse($solution, true);
503 foreach ($smaller_solutions as $rid => $roomsol) {
504 if ($party_guests['adults'] > 0 && $party_guests['adults'] > $roomsol['toadult']) {
505 // too many adults requested for this small room
506 continue;
507 }
508 if ($party_guests['children'] > 0 && $party_guests['children'] > $roomsol['tochild']) {
509 // too many children requested for this small room
510 continue;
511 }
512 if (($party_guests['adults'] + $party_guests['children']) > $roomsol['totpeople']) {
513 // too many guests requested for this small room
514 continue;
515 }
516 // we've got a fitting room which could be smaller
517 $roomsol['guests_allocation'] = [
518 'adults' => $party_guests['adults'],
519 'children' => $party_guests['children'],
520 ];
521 array_push($booking_solutions[$kdayts], $roomsol);
522 // turn flag on and break the loop
523 $smaller_fit_found = true;
524 break;
525 }
526 if ($smaller_fit_found) {
527 // no need to parse the rooms from the largest to the smallest
528 continue;
529 }
530
531 foreach ($solution as $rid => $roomsol) {
532 // fullfil all the units of this room
533 for ($units_taken = 0; $units_taken < $roomsol['minrooms']; $units_taken++) {
534 $current_allocation = array(
535 'adults' => 0,
536 'children' => 0
537 );
538 if ($guests_allocated['adults'] < $party_guests['adults']) {
539 $humans_taken = $roomsol['toadult'];
540 $missing_humans = $party_guests['adults'] - $guests_allocated['adults'];
541 $humans_taken = $humans_taken > $missing_humans ? $missing_humans : $humans_taken;
542 $current_allocation['adults'] = $humans_taken;
543 $guests_allocated['adults'] += $humans_taken;
544 }
545 if ($guests_allocated['children'] < $party_guests['children']) {
546 $humans_taken = $roomsol['tochild'];
547 $missing_humans = $party_guests['children'] - $guests_allocated['children'];
548 $humans_taken = $humans_taken > $missing_humans ? $missing_humans : $humans_taken;
549 $current_allocation['children'] = $humans_taken;
550 $guests_allocated['children'] += $humans_taken;
551 }
552 $roomsol['guests_allocation'] = $current_allocation;
553 array_push($booking_solutions[$kdayts], $roomsol);
554 if ($guests_allocated['adults'] >= $party_guests['adults'] && $guests_allocated['children'] >= $party_guests['children']) {
555 //we have allocated all guests, exit the for-loop
556 break;
557 }
558 }
559 if ($guests_allocated['adults'] >= $party_guests['adults'] && $guests_allocated['children'] >= $party_guests['children']) {
560 // we have allocated all guests with this solution, no need to loop over other rooms available in this day.
561 break;
562 }
563 }
564 }
565
566 break;
567 default:
568 break;
569 }
570 }
571
572 $this->code = $code;
573 $this->nights = $daysdiff;
574 $this->checkin = $fromts;
575 $this->checkout = $tots;
576 $this->nights_requested = $nights_requested;
577 $this->party = $party;
578 $this->party_guests = $party_guests;
579 $this->suggestions = $suggestions;
580 $this->solutions = $solutions;
581 $this->booking_solutions = $booking_solutions;
582 $this->sug_from_ts = $sug_from_ts;
583 $this->sug_to_ts = $sug_to_ts;
584 $this->vbo_tn = $vbo_tn;
585 $this->split_stay_solutions = $split_stay_solutions;
586 //theme
587 $theme = VikBooking::getTheme();
588 if ($theme != 'default') {
589 $thdir = VBO_SITE_PATH.DS.'themes'.DS.$theme.DS.'searchsuggestions';
590 if (is_dir($thdir)) {
591 $this->_setPath('template', $thdir.DS);
592 }
593 }
594
595 /**
596 *
597 * This view is displayed via Ajax, so the output must be buffered and echoed as JSON-encoded, then exit the process.
598 * This is to avoid printing meta data values of the head. However, we need to receive the request var getjson=1 for bc.
599 *
600 * @since 1.13 (J) - 1.3.1 (WP)
601 */
602 $getjson = VikRequest::getInt('getjson', 0, 'request');
603 if ($getjson) {
604 ob_start();
605 parent::display($tpl);
606 $ajax_buffer = ob_get_contents();
607 ob_end_clean();
608 echo json_encode(array($ajax_buffer));
609 exit;
610 }
611
612 parent::display($tpl);
613 }
614 }
615