widgetName = JText::translate('VBO_W_CHECKAV_TITLE'); $this->widgetDescr = JText::translate('VBO_W_CHECKAV_DESCR'); $this->widgetId = basename(__FILE__, '.php'); // define widget and icon and style name $this->widgetIcon = ''; $this->widgetStyleName = 'blue'; } /** * Custom method for this widget only to load the rates flow records. * The method is called by the admin controller through an AJAX request. * The visibility should be public, it should not exit the process, and * any content sent to output will be returned to the AJAX response. * In this case we return an array because this method requires "return":1. * * It's the actual rendering of the widget which also allows navigation. */ public function loadRoomRates() { $offset = VikRequest::getInt('offset', 0, 'request'); $length = VikRequest::getInt('length', $this->res_per_page, 'request'); $wrapper = VikRequest::getString('wrapper', '', 'request'); $checkin_date = VikRequest::getString('checkin_date', '', 'request'); $num_nights = VikRequest::getInt('num_nights', 1, 'request'); $num_adults = VikRequest::getInt('num_adults', 2, 'request'); $num_children = VikRequest::getInt('num_children', 0, 'request'); // optional room IDs and guests array to consider $room_ids = []; $arr_adults = []; $arr_children = []; // multitask can inject a booking id $bid = VikRequest::getInt('bid', 0, 'request'); if (!empty($bid)) { // get proper loading values for this booking list($b_checkin_date, $b_num_nights, $b_num_adults, $b_num_children, $room_ids) = $this->getBookingLoadValues($bid); // only check the calculated booking checkin date to determine if loading values was successful if (!empty($b_checkin_date)) { // overwrite default values $checkin_date = $b_checkin_date; $num_nights = $b_num_nights; if (is_array($b_num_adults)) { // multiple rooms involved $num_adults = array_sum($b_num_adults); $num_children = array_sum($b_num_children); $arr_adults = $b_num_adults; $arr_children = $b_num_children; } else { // single room involved $num_adults = $b_num_adults; $num_children = $b_num_children; } } } if (empty($checkin_date)) { // default to today's date $checkin_date = date('Y-m-d'); } if ($num_nights < 1) { // minimum number of nights is 1 $num_nights = 1; } // convert date to timestamp to support custom date formats $checkin_ts = VikBooking::getDateTimestamp($checkin_date); $checkin_info = getdate($checkin_ts); $checkout_ts = mktime(0, 0, 0, $checkin_info['mon'], ($checkin_info['mday'] + $num_nights), $checkin_info['year']); $checkout_info = getdate($checkout_ts); // build final dates $checkin_date = date('Y-m-d', $checkin_ts); $checkout_date = date('Y-m-d', $checkout_ts); // we make use of the rates flow report helper class $report = VikBooking::getReportInstance('rates_flow'); if (!$report) { // display nothing return; } // date formats and separator $df = $report->getDateFormat(); $dtpicker_df = $report->getDateFormat('jui'); $date_sep = VikBooking::getDateSeparator(); // currency symbol $currency = VikBooking::getCurrencySymb(); // invoke availability helper class $av_helper = VikBooking::getAvailabilityInstance(); // set stay values $av_helper->setStayDates($checkin_date, $checkout_date); if (count($arr_adults) > 1) { // multiple rooms involved foreach ($arr_adults as $gkey => $radults) { $av_helper->setRoomParty($radults, (isset($arr_children[$gkey]) ? $arr_children[$gkey] : 0)); } } else { // single room involved $av_helper->setRoomParty($num_adults, $num_children); } if ($room_ids) { $av_helper->setRoomIds($room_ids); } // load available room rates (all records, before pagination that will be applied later) $room_rates = $av_helper->getRates([ 'wtax' => 1, ]); // load rooms and rate plans $all_rooms = $av_helper->loadRooms(); $all_rplans = $av_helper->loadRatePlans(); // check if availability errors occurred $has_av_error = strlen($av_helper->getError()); $av_error_code = $av_helper->getErrorCode(); // count total records $tot_records = is_array($room_rates) && !$has_av_error ? count($room_rates) : 0; // check if a next page can be available $has_next_page = (($offset + $length) < $tot_records) ? 1 : 0; // splice the array returned to support pagination if ($tot_records > $length) { $split_room_rates = array(); $index_offset = 0; foreach ($room_rates as $rid => $rates) { if ($index_offset >= $offset) { $split_room_rates[$rid] = $rates; } if (count($split_room_rates) >= $length) { break; } $index_offset++; } $room_rates = $split_room_rates; unset($split_room_rates); } // list of eligible and available room IDs $eligible_rids = []; // start output buffering ob_start(); // display the information about the dates and room party $party_info_parts = array(); // stay dates information $checkin_str = VikBooking::sayWeekDay($checkin_info['wday'], true) . ', ' . date(str_replace('/', $date_sep, $df), $checkin_ts); $checkout_str = VikBooking::sayWeekDay($checkout_info['wday'], true) . ', ' . date(str_replace('/', $date_sep, $df), $checkout_ts); $party_info_parts[] = $checkin_str . ' - ' . $checkout_str; // nights information $nights_lbl = $num_nights > 1 ? JText::translate('VBDAYS') : JText::translate('VBDAY'); $party_info_parts[] = $num_nights . ' ' . $nights_lbl; // adults information $adults_lbl = $num_adults === 1 ? JText::translate('VBMAILADULT') : JText::translate('VBEDITORDERADULTS'); $party_info_parts[] = $num_adults . ' ' . $adults_lbl; // children information $children_lbl = $num_children === 1 ? JText::translate('VBMAILCHILD') : JText::translate('VBEDITORDERCHILDREN'); if ($num_children > 0) { $party_info_parts[] = $num_children . ' ' . $children_lbl; } ?>

explainErrorCode(); $say_error = !empty($explain_err) ? $explain_err : $av_helper->getError(); $say_error = empty($say_error) ? JText::translate('VBOVERVIEWLEGRED') : $say_error; ?>

$rates) { if (!isset($all_rooms[$rid])) { // this is to prevent reserved keys from being displayed continue; } // push room ID as eligible and available $eligible_rids[] = $rid; ?>
0) { // show backward navigation button ?>
findSuggestions(); } elseif ($eligible_rids) { /** * We did return some available rooms, but we still want to calculate if some * split-stay solutions are also available for some rooms that were left unsold. * * @since 1.16.3 (J) - 1.6.3 (WP) */ $parsable_rids = array_diff(array_keys($av_helper->filterPublishedRooms()), $eligible_rids); if ($parsable_rids) { // try to suggest split stay solutions by using the room IDs that were not available $split_stay_sols = $av_helper->findSplitStays($parsable_rids); } } // parse booking split stays if ($split_stay_sols) { // we've got booking split stays to suggest ?>

$checkin_date, 'checkout' => $checkout_date, 'split_stay' => [], ]; // parse rooms for the split stay foreach ($split_stay_sol as $split_k => $split_stay_room) { // parse stay dates into DateTime objects $checkin_dt_obj = new JDate($split_stay_room['checkin']); $checkout_dt_obj = new JDate($split_stay_room['checkout']); // push split stay data for booking $split_stay_values['split_stay'][] = [ 'idroom' => $split_stay_room['idroom'], 'checkin' => $split_stay_room['checkin'], 'checkout' => $split_stay_room['checkout'], 'nights' => $split_stay_room['nights'], ]; ?>
0 ? 'random' : 'arrow-right')); ?>
1 ? JText::translate('VBDAYS') : JText::translate('VBDAY'); ?> format('D, d M Y', true); ?> format('D, d M Y', true); ?>

$alt_rooms) { $alt_displayed++; foreach ($alt_rooms as $rid => $alt_room) { if (empty($alt_room['days_av_left'])) { continue; } $sugg_checkin_dt = null; $sugg_checkout_dt = null; foreach ($alt_room['days_av_left'] as $dayk => $uleft) { if (empty($sugg_checkin_dt)) { // grab the first date $sugg_checkin_dt = $dayk; } // always overwrite until last date $sugg_checkout_dt = $dayk; } // increase check-out date by one day (day after last night of stay) $sugg_out_info = getdate(strtotime($sugg_checkout_dt)); $sugg_checkout_dt = date('Y-m-d', mktime(0, 0, 0, $sugg_out_info['mon'], ($sugg_out_info['mday'] + 1), $sugg_out_info['year'])); // parse stay dates into DateTime objects $checkin_dt_obj = new JDate($sugg_checkin_dt); $checkout_dt_obj = new JDate($sugg_checkout_dt); // count total nights of stay $sug_tot_nights = count($alt_room['days_av_left']); // format suggested check-in date for datepicker $cal_checkin_dt = date($df, strtotime($sugg_checkin_dt)); // js arguments $js_pick_args = "'$wrapper', '{$rid}', '{$cal_checkin_dt}', '{$sug_tot_nights}', '{$num_adults}', '{$num_children}'"; ?>
format('D, d M Y', true); ?> format('D, d M Y', true); ?>
= $this->max_alternative_dates) { break; } } ?>

$alt_parties) { $alt_displayed++; $alt_dates_displayed = false; ?>
$uleft) { if (empty($sugg_checkin_dt)) { // grab the first date $sugg_checkin_dt = $dayk; } // always overwrite until last date $sugg_checkout_dt = $dayk; } // increase check-out date by one day (day after last night of stay) $sugg_out_info = getdate(strtotime($sugg_checkout_dt)); $sugg_checkout_dt = date('Y-m-d', mktime(0, 0, 0, $sugg_out_info['mon'], ($sugg_out_info['mday'] + 1), $sugg_out_info['year'])); // parse stay dates into DateTime objects $checkin_dt_obj = new JDate($sugg_checkin_dt); $checkout_dt_obj = new JDate($sugg_checkout_dt); ?>
format('D, d M Y', true); ?> format('D, d M Y', true); ?>
= $this->max_alternative_parties) { break; } } ?>
$html_content, 'tot_records' => $tot_records, 'next_page' => $has_next_page, ); } /** * Preload the necessary CSS/JS assets. * * @return void */ public function preload() { // load assets $this->vbo_app->loadDatePicker(); } public function render(?VBOMultitaskData $data = null) { // increase widget's instance counter static::$instance_counter++; // check whether the widget is being rendered via AJAX when adding it through the customizer $is_ajax = $this->isAjaxRendering(); // generate a unique ID for the sticky notes wrapper instance $wrapper_instance = !$is_ajax ? static::$instance_counter : rand(); $wrapper_id = 'vbo-widget-checkav-' . $wrapper_instance; // get permissions $vbo_auth_bookings = JFactory::getUser()->authorise('core.vbo.bookings', 'com_vikbooking'); if (!$vbo_auth_bookings) { // display nothing return; } // we make use of the rates flow report helper class $report = VikBooking::getReportInstance('rates_flow'); if (!$report) { // display nothing return; } // date formats $df = $report->getDateFormat(); $dtpicker_df = $report->getDateFormat('jui'); // get highest max adults and max children list($max_adults, $max_children) = $this->getMaxestGuests(); // check multitask data $page_bid = 0; $modal_load_bid = ''; if ($data) { $page_bid = $data->getBookingID(); if ($page_bid && $data->isModalRendering()) { // immediately load contents according to injected multitask data $modal_load_bid = $page_bid; } } ?>

widgetIcon; ?> widgetName; ?>

setQuery($q); $record = $dbo->loadAssoc(); if ($record) { $maxest = array($record['max_adults'], $record['max_children']); } return $maxest; } /** * In case the multitask panel injects a booking ID, this method * prepares the proper values to use for loading room rates. * * @param int $bid the booking id. * @param bool $multi_rooms whether to return array of guests * when multiple rooms booked. * * @return array list of values to use for loading. */ protected function getBookingLoadValues($bid, $multi_rooms = true) { // set default values $checkin_date = ''; $num_nights = 0; $num_adults = 0; $num_children = 0; $room_ids = []; if (empty($bid)) { // do nothing return [$checkin_date, $num_nights, $num_adults, $num_children, $room_ids]; } // get booking details $booking = VikBooking::getBookingInfoFromID($bid); if (!is_array($booking) || !count($booking)) { // do nothing return [$checkin_date, $num_nights, $num_adults, $num_children, $room_ids]; } // get reservation rooms $book_rooms = VikBooking::loadOrdersRoomsData($booking['id']); if (!is_array($book_rooms) || !count($book_rooms)) { // do nothing return [$checkin_date, $num_nights, $num_adults, $num_children, $room_ids]; } // build proper values for this reservation $checkin_date = date('Y-m-d', $booking['checkin']); $num_nights = $booking['days']; $arr_adults = []; $arr_children = []; foreach ($book_rooms as $roomres) { $num_adults += $roomres['adults']; $num_children += $roomres['children']; $arr_adults[] = $roomres['adults']; $arr_children[] = $roomres['children']; $room_ids[] = $roomres['idroom']; if ($booking['split_stay']) { // do not sum the guests in case of split stay $num_adults = $roomres['adults']; $num_children = $roomres['children']; } } if (count($book_rooms) > 1 && $multi_rooms === true && !$booking['split_stay']) { // return the adults and children as array rather than as integers $num_adults = $arr_adults; $num_children = $arr_children; } return [$checkin_date, $num_nights, $num_adults, $num_children, $room_ids]; } }