PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.4
VikBooking Hotel Booking Engine & PMS v1.6.4
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 / arriving_today.php

arriving_today.php in VikBooking Hotel Booking Engine & PMS 1.6.4, at admin/helpers/widgets/arriving_today.php

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