PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.8.9
VikBooking Hotel Booking Engine & PMS v1.8.9
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.8.9, at site/views/searchsuggestions/view.html.php

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