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 / arriving_today.php

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

434 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 "arriving today".
15 *
16 * @since 1.14 (J) - 1.4.0 (WP)
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 if ($when == 'tomorrow') {
304 $today_start_ts = mktime(0, 0, 0, date("n"), (date("j") + 1), date("Y"));
305 $today_end_ts = mktime(23, 59, 59, date("n"), (date("j") + 1), date("Y"));
306 } elseif ($when == 'yesterday') {
307 $today_start_ts = mktime(0, 0, 0, date("n"), (date("j") - 1), date("Y"));
308 $today_end_ts = mktime(23, 59, 59, date("n"), (date("j") - 1), date("Y"));
309 } else {
310 // today
311 $today_start_ts = mktime(0, 0, 0, date("n"), date("j"), date("Y"));
312 $today_end_ts = mktime(23, 59, 59, date("n"), date("j"), date("Y"));
313 }
314
315 $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`.`checkin`>=" . $today_start_ts . " AND `o`.`checkin`<=" . $today_end_ts . " AND `o`.`status`=" . $dbo->q('confirmed') . " AND `o`.`closure`=0 ORDER BY `o`.`checkin` ASC;";
316
317 $dbo->setQuery($q);
318
319 return $dbo->loadAssocList();
320 }
321
322 /**
323 * Builds the HTML string for the given arrivals. We use a method
324 * so that the AJAX requests will be able to rely on this as well.
325 *
326 * @param array $arrivals the list of records found.
327 * @param string $when either today, tomorrow, or yesterday.
328 *
329 * @return string the composed HTML string.
330 *
331 * @since 1.15.0 (J) - 1.5.0 (WP)
332 */
333 protected function buildArrivalRows($arrivals, $when = 'today')
334 {
335 $rows = '';
336
337 $arrivals = !is_array($arrivals) ? array() : $arrivals;
338
339 // check permissions
340 $vbo_auth_bookings = JFactory::getUser()->authorise('core.vbo.bookings', 'com_vikbooking');
341
342 foreach ($arrivals as $ink => $intoday) {
343 $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')) : "");
344 $room_names = array();
345 $rooms = VikBooking::loadOrdersRoomsData($intoday['id']);
346 foreach ($rooms as $rr) {
347 $room_names[] = $rr['room_name'];
348 }
349 if ($intoday['roomsnum'] == 1) {
350 // parse distintive features
351 $unit_index = '';
352 if (strlen((string)$rooms[0]['roomindex']) && !empty($rooms[0]['params'])) {
353 $room_params = json_decode($rooms[0]['params'], true);
354 if (is_array($room_params) && array_key_exists('features', $room_params) && @count($room_params['features']) > 0) {
355 foreach ($room_params['features'] as $rind => $rfeatures) {
356 if ($rind == $rooms[0]['roomindex']) {
357 foreach ($rfeatures as $fname => $fval) {
358 if (strlen($fval)) {
359 $unit_index = ' #'.$fval;
360 break;
361 }
362 }
363 break;
364 }
365 }
366 }
367 }
368 //
369 $roomstr = '<span class="vbo-smalltext">'.$room_names[0].$unit_index.'</span>';
370 } else {
371 $roomstr = '<span class="hasTooltip vbo-tip-small" title="'.implode(', ', $room_names).'">'.$intoday['roomsnum'].'</span><span class="hidden-for-search">'.implode(', ', $room_names).'</span>';
372 }
373 $act_status = '';
374 if ($intoday['status'] == 'confirmed') {
375 switch ($intoday['checked']) {
376 case -1:
377 $ord_status = '<span class="label label-error vbo-status-label">'.JText::translate('VBOCHECKEDSTATUSNOS').'</span>';
378 break;
379 case 1:
380 $ord_status = '<span class="label label-success vbo-status-label">'.JText::translate('VBOCHECKEDSTATUSIN').'</span>';
381 break;
382 case 2:
383 $ord_status = '<span class="label label-success vbo-status-label">'.JText::translate('VBOCHECKEDSTATUSOUT').'</span>';
384 break;
385 default:
386 $ord_status = '<span class="label label-success vbo-status-label">'.JText::translate('VBCONFIRMED').'</span>';
387 break;
388 }
389 if (!strcasecmp((string)$intoday['type'], 'overbooking')) {
390 $ord_status .= '<div class="vbo-orders-substatus"><span class="label label-error">' . JText::translate('VBO_BTYPE_OVERBOOKING') . '</span></div>';
391 }
392 if ($vbo_auth_bookings && $intoday['closure'] != 1) {
393 $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>';
394 }
395 } elseif ($intoday['status'] == 'standby') {
396 $ord_status = '<span class="label label-warning vbo-status-label">'.JText::translate('VBSTANDBY').'</span>';
397 } else {
398 $ord_status = '<span class="label label-error vbo-status-label">'.JText::translate('VBCANCELLED').'</span>';
399 }
400 $nominative = strlen($intoday['nominative']) > 1 ? $intoday['nominative'] : VikBooking::getFirstCustDataField($intoday['custdata']);
401 $country_flag = '';
402 if (file_exists(VBO_ADMIN_PATH.DS.'resources'.DS.'countries'.DS.$intoday['country'].'.png')) {
403 $country_flag = '<img src="'.VBO_ADMIN_URI.'resources/countries/'.$intoday['country'].'.png'.'" title="'.$intoday['country'].'" class="vbo-country-flag vbo-country-flag-left"/>';
404 }
405
406 $rows .= '<tr class="vbo-dashboard-today-checkin-rows">' . "\n";
407 $rows .= ' <td class="searchable left"><a href="index.php?option=com_vikbooking&amp;task=editorder&amp;cid[]=' . $intoday['id'] . '">' . $intoday['id'] . '</a></td>' . "\n";
408 $rows .= ' <td class="searchable left">' . $country_flag . $nominative . '</td>' . "\n";
409 $rows .= ' <td class="center">' . $totpeople_str . '</td>' . "\n";
410 $rows .= ' <td class="searchable center">' . $roomstr . '</td>' . "\n";
411 $rows .= ' <td class="searchable center">' . date(str_replace("/", $this->datesep, $this->df).' H:i', $intoday['checkout']) . '</td>' . "\n";
412 $rows .= ' <td class="searchable center" data-status="' . $intoday['id'] . '">' . $ord_status . '</td>' . "\n";
413 $rows .= ' <td class="vbo-tdright pro-feature">' . $act_status . '</td>' . "\n";
414 $rows .= '</tr>' . "\n";
415 }
416
417 if (!$arrivals) {
418 // display just the TR with the warning message
419 $no_arrivals_when = JText::translate('VBONOCHECKINSTODAY');
420 if ($when == 'yesterday') {
421 $no_arrivals_when = JText::translate('VBONOCHECKINSYESTERDAY');
422 } elseif ($when == 'tomorrow') {
423 $no_arrivals_when = JText::translate('VBONOCHECKINSTOMORROW');
424 }
425
426 $rows .= '<tr class="warning">' . "\n";
427 $rows .= ' <td colspan="7"><i class="vboicn-warning"></i> ' . $no_arrivals_when . '</td>' . "\n";
428 $rows .= '</tr>' . "\n";
429 }
430
431 return $rows;
432 }
433 }
434