PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.7
VikBooking Hotel Booking Engine & PMS v1.6.7
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 / admin / helpers / widgets / departing_today.php

departing_today.php in VikBooking Hotel Booking Engine & PMS 1.6.7, at admin/helpers/widgets/departing_today.php

429 lines 16.7 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 /**
14 * Class handler for admin widget "departing today".
15 *
16 * @since 1.14 (J) - 1.4.0 (WP)
17 */
18 class VikBookingAdminWidgetDepartingToday extends VikBookingAdminWidget
19 {
20 /**
21 * The instance counter of this widget. Since we do not load individual parameters
22 * for each widget's instance, we use a static counter to determine its settings.
23 *
24 * @var int
25 */
26 protected static $instance_counter = -1;
27
28 /**
29 * Class constructor will define the widget name and identifier.
30 */
31 public function __construct()
32 {
33 // call parent constructor
34 parent::__construct();
35
36 $this->widgetName = JText::translate('VBO_W_DEPARTTOD_TITLE');
37 $this->widgetDescr = JText::translate('VBO_W_DEPARTTOD_DESCR');
38 $this->widgetId = basename(__FILE__, '.php');
39
40 /**
41 * Define widget and icon and style name.
42 *
43 * @since 1.15.0 (J) - 1.5.0 (WP)
44 */
45 $this->widgetIcon = '<i class="' . VikBookingIcons::i('plane-departure') . '"></i>';
46 $this->widgetStyleName = 'light-blue';
47 }
48
49 public function render(VBOMultitaskData $data = null)
50 {
51 // increase widget's instance counter
52 static::$instance_counter++;
53
54 // check whether the widget is being rendered via AJAX when adding it through the customizer
55 $is_ajax = $this->isAjaxRendering();
56
57 // widget instance identifier
58 $widget_instance = $is_ajax ? -1 : static::$instance_counter;
59
60 // get departures for today
61 $checkout_today = $this->getDepartures();
62
63 // count departures
64 $tot_departures = count($checkout_today);
65
66 // render the necessary PHP/JS code for the modal window only once
67 if (!defined('VBO_JMODAL_CHECKIN_BOOKING')) {
68 define('VBO_JMODAL_CHECKIN_BOOKING', 1);
69 ?>
70 <script type="text/javascript">
71 function vboJModalShowCallback() {
72 if (typeof vbo_t_on == "undefined") {
73 return;
74 }
75 // simulate STOP click
76 if (vbo_t_on) {
77 vbo_t_on = false;
78 clearTimeout(vbo_t);
79 jQuery(".vbo-dashboard-refresh-play").fadeIn();
80 }
81 }
82 function vboJModalHideCallback() {
83 if (typeof vbo_t_on == "undefined") {
84 return;
85 }
86 // simulate PLAY click
87 if (!vbo_t_on) {
88 vboStartTimer();
89 jQuery(".vbo-dashboard-refresh-play").fadeOut();
90 }
91 }
92 </script>
93 <?php
94 echo $this->vbo_app->getJmodalScript('', 'vboJModalHideCallback();', 'vboJModalShowCallback();');
95 echo $this->vbo_app->getJmodalHtml('vbo-checkin-booking', JText::translate('VBOMANAGECHECKSINOUT'));
96 }
97
98 // prepare tristate toggle switch values
99 $multistate_vals = array(
100 'today',
101 'tomorrow',
102 'yesterday',
103 );
104 $multistate_lbls = array(
105 array(
106 'value' => JText::translate('VBTODAY'),
107 ),
108 array(
109 'value' => JText::translate('VBOTOMORROW'),
110 ),
111 array(
112 'value' => JText::translate('VBOYESTERDAY'),
113 ),
114 );
115 $multistate_attrs = array(
116 array(
117 'label_class' => 'vik-multiswitch-text vik-multiswitch-radiobtn-today',
118 'input' => array(
119 'onchange' => 'vboWidgetLoadDepartures(this.value, \'' . $widget_instance . '\')',
120 ),
121 ),
122 array(
123 'label_class' => 'vik-multiswitch-text vik-multiswitch-radiobtn-tomorrow',
124 'input' => array(
125 'onchange' => 'vboWidgetLoadDepartures(this.value, \'' . $widget_instance . '\')',
126 ),
127 ),
128 array(
129 'label_class' => 'vik-multiswitch-text vik-multiswitch-radiobtn-yesterday',
130 'input' => array(
131 'onchange' => 'vboWidgetLoadDepartures(this.value, \'' . $widget_instance . '\')',
132 ),
133 ),
134 );
135 $wrap_attrs = array(
136 'class' => 'vik-multiswitch-noanimation',
137 );
138
139 ?>
140 <div class="vbo-admin-widget-wrapper" id="vbo-widget-today-checkout-<?php echo $widget_instance; ?>">
141 <div class="vbo-admin-widget-head vbo-dashboard-today-checkout-head">
142 <div class="vbo-admin-widget-head-inline">
143 <h4>
144 <?php echo $this->widgetIcon; ?>
145 <span class="departures-when"><?php echo JText::translate('VBODEPARTING'); ?></span>
146 <span class="departures-tot"><?php echo $tot_departures; ?></span>
147 </h4>
148 <div class="vbo-dashboard-search-input vbo-dashboard-search-checkout">
149 <div class="btn-wrapper input-append pull-right">
150 <input type="text" class="checkout-search form-control" placeholder="<?php echo JText::translate('VBODASHSEARCHKEYS'); ?>">
151 <button type="button" class="btn" onclick="jQuery('.checkout-search').val('').trigger('keyup');"><i class="icon-remove"></i></button>
152 </div>
153 </div>
154 <div class="vbo-widget-today-checkout-tristate"><?php echo $this->vbo_app->multiStateToggleSwitchField('when_departing' . $widget_instance, 'today', $multistate_vals, $multistate_lbls, $multistate_attrs, $wrap_attrs); ?></div>
155 </div>
156 </div>
157 <div class="vbo-dashboard-today-checkout table-responsive">
158 <table class="table vbo-table-search-cout">
159 <thead>
160 <tr class="vbo-dashboard-today-checkout-firstrow">
161 <th class="left"><?php echo JText::translate('VBDASHUPRESONE'); ?></th>
162 <th class="left"><?php echo JText::translate('VBCUSTOMERNOMINATIVE'); ?></th>
163 <th class="center"><?php echo JText::translate('VBDASHUPRESSIX'); ?></th>
164 <th class="center"><?php echo JText::translate('VBDASHUPRESTWO'); ?></th>
165 <th class="center"><?php echo JText::translate('VBDASHUPRESTHREE'); ?></th>
166 <th class="center"><?php echo JText::translate('VBDASHUPRESFIVE'); ?></th>
167 <th class="vbo-tdright"> </th>
168 </tr>
169 <tr class="warning no-results">
170 <td colspan="7"><i class="vboicn-warning"></i> <?php echo JText::translate('VBONORESULTS'); ?></td>
171 </tr>
172 </thead>
173 <tbody>
174 <?php
175 // render the rows for the departures (if any)
176 echo $this->buildDepartureRows($checkout_today);
177 ?>
178 </tbody>
179 </table>
180 </div>
181 </div>
182
183 <?php
184 if (static::$instance_counter === 0 || $is_ajax) {
185 ?>
186 <script type="text/javascript">
187 /**
188 * Retrieves the departures for the given day by making an AJAX request
189 */
190 function vboWidgetLoadDepartures(when, winstance) {
191 // the widget method to call
192 var call_method = 'loadDepartures';
193
194 // make a silent request to get the departures
195 VBOCore.doAjax(
196 "<?php echo $this->getExecWidgetAjaxUri(); ?>",
197 {
198 widget_id: "<?php echo $this->getIdentifier(); ?>",
199 call: call_method,
200 tmpl: "component",
201 when: when,
202 },
203 function(response) {
204 try {
205 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
206 if (!obj_res.hasOwnProperty(call_method)) {
207 console.error('Unexpected JSON response', obj_res);
208 return;
209 }
210
211 var widget_cont = jQuery('#vbo-widget-today-checkout-' + winstance);
212 if (!widget_cont || !widget_cont.length) {
213 console.error('Widget instance not found', winstance);
214 return;
215 }
216
217 // display the list of departures for the given day
218 widget_cont.find('table.vbo-table-search-cout tbody').html(obj_res[call_method]);
219
220 // update counter
221 var tot_departures = widget_cont.find('table.vbo-table-search-cout tbody').find('tr').not('.warning').length;
222 widget_cont.find('.departures-tot').text(tot_departures);
223 } catch(err) {
224 console.error('could not parse JSON response', err, response);
225 }
226 },
227 function(error) {
228 console.error(error);
229 }
230 );
231 }
232
233 jQuery(function() {
234 /* Attempt to append the modal container to the body for the multitask panel */
235 let modal_container = jQuery('[id*="vbo-checkin-booking"][class*="modal"]');
236 if (modal_container.length) {
237 modal_container.first().appendTo('body');
238 }
239
240 /* Check-out Search */
241 jQuery(".checkout-search").keyup(function () {
242 var inp_elem = jQuery(this);
243 var instance_elem = inp_elem.closest('.vbo-admin-widget-wrapper');
244 var searchTerm = inp_elem.val();
245 var listItem = instance_elem.find('.vbo-table-search-cout tbody').children('tr');
246 var searchSplit = searchTerm.replace(/ /g, "'):containsi('");
247 jQuery.extend(jQuery.expr[':'], {'containsi':
248 function(elem, i, match, array) {
249 return (elem.textContent || elem.innerText || '').toLowerCase().indexOf((match[3] || "").toLowerCase()) >= 0;
250 }
251 });
252 instance_elem.find(".vbo-table-search-cout tbody tr td.searchable").not(":containsi('" + searchSplit + "')").each(function(e) {
253 jQuery(this).parent('tr').attr('visible', 'false');
254 });
255 instance_elem.find(".vbo-table-search-cout tbody tr td.searchable:containsi('" + searchSplit + "')").each(function(e) {
256 jQuery(this).parent('tr').attr('visible', 'true');
257 });
258 var jobCount = parseInt(instance_elem.find('.vbo-table-search-cout tbody tr[visible="true"]').length);
259 instance_elem.find('.departures-tot').text(jobCount);
260 if (jobCount > 0) {
261 instance_elem.find('.vbo-table-search-cout').find('.no-results').hide();
262 } else {
263 instance_elem.find('.vbo-table-search-cout').find('.no-results').show();
264 }
265 });
266 });
267 </script>
268 <?php
269 }
270 }
271
272 /**
273 * Custom method for this widget only to load the departures for a given day.
274 * The method is called by the admin controller through an AJAX request.
275 * The visibility should be public, it should not exit the process, and
276 * any content sent to output will be returned to the AJAX response.
277 */
278 public function loadDepartures()
279 {
280 $when = VikRequest::getString('when', 'today', 'request');
281
282 echo $this->buildDepartureRows($this->getDepartures($when), $when);
283 }
284
285 /**
286 * Returns the list of departures for the given day.
287 *
288 * @param string $when either today, tomorrow, or yesterday.
289 *
290 * @return array list of departures, if any.
291 *
292 * @since 1.15.0 (J) - 1.5.0 (WP)
293 */
294 protected function getDepartures($when = 'today')
295 {
296 $dbo = JFactory::getDbo();
297
298 if ($when == 'tomorrow') {
299 $today_start_ts = mktime(0, 0, 0, date("n"), (date("j") + 1), date("Y"));
300 $today_end_ts = mktime(23, 59, 59, date("n"), (date("j") + 1), date("Y"));
301 } elseif ($when == 'yesterday') {
302 $today_start_ts = mktime(0, 0, 0, date("n"), (date("j") - 1), date("Y"));
303 $today_end_ts = mktime(23, 59, 59, date("n"), (date("j") - 1), date("Y"));
304 } else {
305 // today
306 $today_start_ts = mktime(0, 0, 0, date("n"), date("j"), date("Y"));
307 $today_end_ts = mktime(23, 59, 59, date("n"), date("j"), date("Y"));
308 }
309
310 $q = "SELECT `o`.`id`,`o`.`custdata`,`o`.`status`,`o`.`checkin`,`o`.`checkout`,`o`.`roomsnum`,`o`.`country`,`o`.`closure`,`o`.`checked`,`o`.`type`,(SELECT CONCAT_WS(' ',`or`.`t_first_name`,`or`.`t_last_name`) FROM `#__vikbooking_ordersrooms` AS `or` WHERE `or`.`idorder`=`o`.`id` LIMIT 1) AS `nominative`,(SELECT SUM(`or`.`adults`) FROM `#__vikbooking_ordersrooms` AS `or` WHERE `or`.`idorder`=`o`.`id`) AS `tot_adults`,(SELECT SUM(`or`.`children`) FROM `#__vikbooking_ordersrooms` AS `or` WHERE `or`.`idorder`=`o`.`id`) AS `tot_children` FROM `#__vikbooking_orders` AS `o` WHERE `o`.`closure`=0 AND `o`.`status`='confirmed' AND `o`.`checkout`>=".$today_start_ts." AND `o`.`checkout`<=".$today_end_ts." AND `o`.`closure`=0 ORDER BY `o`.`checkout` ASC;";
311
312 $dbo->setQuery($q);
313
314 return $dbo->loadAssocList();
315 }
316
317 /**
318 * Builds the HTML string for the given departures. We use a method
319 * so that the AJAX requests will be able to rely on this as well.
320 *
321 * @param array $departures the list of records found.
322 * @param string $when either today, tomorrow, or yesterday.
323 *
324 * @return string the composed HTML string.
325 *
326 * @since 1.15.0 (J) - 1.5.0 (WP)
327 */
328 protected function buildDepartureRows($departures, $when = 'today')
329 {
330 $rows = '';
331
332 $departures = !is_array($departures) ? array() : $departures;
333
334 // check permissions
335 $vbo_auth_bookings = JFactory::getUser()->authorise('core.vbo.bookings', 'com_vikbooking');
336
337 foreach ($departures as $outk => $outtoday) {
338 $totpeople_str = $outtoday['tot_adults']." ".($outtoday['tot_adults'] > 1 ? JText::translate('VBMAILADULTS') : JText::translate('VBMAILADULT')).($outtoday['tot_children'] > 0 ? ", ".$outtoday['tot_children']." ".($outtoday['tot_children'] > 1 ? JText::translate('VBMAILCHILDREN') : JText::translate('VBMAILCHILD')) : "");
339 $room_names = array();
340 $rooms = VikBooking::loadOrdersRoomsData($outtoday['id']);
341 foreach ($rooms as $rr) {
342 $room_names[] = $rr['room_name'];
343 }
344 if ($outtoday['roomsnum'] == 1) {
345 // parse distintive features
346 $unit_index = '';
347 if (strlen((string)$rooms[0]['roomindex']) && !empty($rooms[0]['params'])) {
348 $room_params = json_decode($rooms[0]['params'], true);
349 if (is_array($room_params) && array_key_exists('features', $room_params) && @count($room_params['features']) > 0) {
350 foreach ($room_params['features'] as $rind => $rfeatures) {
351 if ($rind == $rooms[0]['roomindex']) {
352 foreach ($rfeatures as $fname => $fval) {
353 if (strlen($fval)) {
354 $unit_index = ' #'.$fval;
355 break;
356 }
357 }
358 break;
359 }
360 }
361 }
362 }
363 //
364 $roomstr = '<span class="vbo-smalltext">'.$room_names[0].$unit_index.'</span>';
365 } else {
366 $roomstr = '<span class="hasTooltip vbo-tip-small" title="'.implode(', ', $room_names).'">'.$outtoday['roomsnum'].'</span><span class="hidden-for-search">'.implode(', ', $room_names).'</span>';
367 }
368 $act_status = '';
369 if ($outtoday['status'] == 'confirmed') {
370 switch ($outtoday['checked']) {
371 case -1:
372 $ord_status = '<span class="label label-error vbo-status-label">'.JText::translate('VBOCHECKEDSTATUSNOS').'</span>';
373 break;
374 case 1:
375 $ord_status = '<span class="label label-success vbo-status-label">'.JText::translate('VBOCHECKEDSTATUSIN').'</span>';
376 break;
377 case 2:
378 $ord_status = '<span class="label label-success vbo-status-label">'.JText::translate('VBOCHECKEDSTATUSOUT').'</span>';
379 break;
380 default:
381 $ord_status = '<span class="label label-success vbo-status-label">'.JText::translate('VBCONFIRMED').'</span>';
382 break;
383 }
384 if (!strcasecmp((string)$outtoday['type'], 'overbooking')) {
385 $ord_status .= '<div class="vbo-orders-substatus"><span class="label label-error">' . JText::translate('VBO_BTYPE_OVERBOOKING') . '</span></div>';
386 }
387 if ($vbo_auth_bookings && $outtoday['closure'] != 1) {
388 $act_status = '<button type="button" class="btn btn-small btn-primary" onclick="vboOpenJModal(\'vbo-checkin-booking\', \'index.php?option=com_vikbooking&task=bookingcheckin&cid[]='.$outtoday['id'].'&tmpl=component\');">'.JText::translate('VBOMANAGECHECKOUT').'</button>';
389 }
390 } elseif ($outtoday['status'] == 'standby') {
391 $ord_status = '<span class="label label-warning vbo-status-label">'.JText::translate('VBSTANDBY').'</span>';
392 } else {
393 $ord_status = '<span class="label label-error vbo-status-label">'.JText::translate('VBCANCELLED').'</span>';
394 }
395 $nominative = strlen($outtoday['nominative']) > 1 ? $outtoday['nominative'] : VikBooking::getFirstCustDataField($outtoday['custdata']);
396 $country_flag = '';
397 if (file_exists(VBO_ADMIN_PATH.DS.'resources'.DS.'countries'.DS.$outtoday['country'].'.png')) {
398 $country_flag = '<img src="'.VBO_ADMIN_URI.'resources/countries/'.$outtoday['country'].'.png'.'" title="'.$outtoday['country'].'" class="vbo-country-flag vbo-country-flag-left"/>';
399 }
400
401 $rows .= '<tr class="vbo-dashboard-today-checkout-rows">' . "\n";
402 $rows .= ' <td class="searchable left"><a href="index.php?option=com_vikbooking&amp;task=editorder&amp;cid[]=' . $outtoday['id'] . '">' . $outtoday['id'] . '</a></td>' . "\n";
403 $rows .= ' <td class="searchable left">' . $country_flag . $nominative . '</td>' . "\n";
404 $rows .= ' <td class="center">' . $totpeople_str . '</td>' . "\n";
405 $rows .= ' <td class="searchable center">' . $roomstr . '</td>' . "\n";
406 $rows .= ' <td class="searchable center">' . date(str_replace("/", $this->datesep, $this->df).' H:i', $outtoday['checkin']) . '</td>' . "\n";
407 $rows .= ' <td class="searchable center" data-status="' . $outtoday['id'] . '">' . $ord_status . '</td>' . "\n";
408 $rows .= ' <td class="vbo-tdright pro-feature">' . $act_status . '</td>' . "\n";
409 $rows .= '</tr>' . "\n";
410 }
411
412 if (!count($departures)) {
413 // display just the TR with the warning message
414 $no_departures_when = JText::translate('VBONOCHECKOUTSTODAY');
415 if ($when == 'yesterday') {
416 $no_departures_when = JText::translate('VBONOCHECKOUTSYESTERDAY');
417 } elseif ($when == 'tomorrow') {
418 $no_departures_when = JText::translate('VBONOCHECKOUTSTOMORROW');
419 }
420
421 $rows .= '<tr class="warning">' . "\n";
422 $rows .= ' <td colspan="7"><i class="vboicn-warning"></i> ' . $no_departures_when . '</td>' . "\n";
423 $rows .= '</tr>' . "\n";
424 }
425
426 return $rows;
427 }
428 }
429