| 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 "weekly bookings" (donut charts). |
| 15 |
* |
| 16 |
* @since 1.4.0 |
| 17 |
*/ |
| 18 |
class VikBookingAdminWidgetWeeklyBookings 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_WEEKLYB_TITLE'); |
| 37 |
$this->widgetDescr = JText::translate('VBO_W_WEEKLYB_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('calendar-check') . '"></i>'; |
| 46 |
$this->widgetStyleName = 'brown'; |
| 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 |
JFactory::getDocument()->addScript(VBO_ADMIN_URI.'resources/donutChart.js'); |
| 61 |
$wdaysmap = array( |
| 62 |
'0' => JText::translate('VBSUNDAY'), |
| 63 |
'1' => JText::translate('VBMONDAY'), |
| 64 |
'2' => JText::translate('VBTUESDAY'), |
| 65 |
'3' => JText::translate('VBWEDNESDAY'), |
| 66 |
'4' => JText::translate('VBTHURSDAY'), |
| 67 |
'5' => JText::translate('VBFRIDAY'), |
| 68 |
'6' => JText::translate('VBSATURDAY') |
| 69 |
); |
| 70 |
$today_end_ts = mktime(23, 59, 59, date("n"), date("j"), date("Y")); |
| 71 |
$busy = VikBooking::getAdminWidgetsInstance()->loadBusyRecordsUnclosed(); |
| 72 |
$info_rooms = array( |
| 73 |
'unpublished_rooms' => VikBooking::getAdminWidgetsInstance()->getRoomsData('unpublished_rooms'), |
| 74 |
'tot_rooms_units' => VikBooking::getAdminWidgetsInstance()->getRoomsData('tot_rooms_units'), |
| 75 |
); |
| 76 |
$no_av_rooms = false; |
| 77 |
if (!$info_rooms['tot_rooms_units']) { |
| 78 |
$no_av_rooms = true; |
| 79 |
$info_rooms['tot_rooms_units'] = 1; |
| 80 |
} |
| 81 |
|
| 82 |
// chart for rooms sold today and all week |
| 83 |
?> |
| 84 |
<script type="text/javascript"> |
| 85 |
function renderDonutChart(elemid, params) { |
| 86 |
// default object parameters |
| 87 |
defparams = { |
| 88 |
start: 0, |
| 89 |
tot_booked_today: 0, // should be specified |
| 90 |
tot_rooms_units: 1, // should be specified |
| 91 |
size: 160, |
| 92 |
animationSpeed: 3, |
| 93 |
textColor: "#22485d", |
| 94 |
titlePosition: "outer-top", //outer-bottom, outer-top, inner-bottom, inner-top |
| 95 |
titleText: "", |
| 96 |
titleColor: '#333333', |
| 97 |
outer_color: '#2a762c', // should be specified |
| 98 |
innerCircleColor: '#ffffff', |
| 99 |
innerCircleStroke: '#333333' |
| 100 |
} |
| 101 |
// merge given parameters with the default ones |
| 102 |
Object.assign(defparams, params); |
| 103 |
// adjust prop unitText |
| 104 |
defparams.unitText = " / " + defparams.tot_rooms_units; |
| 105 |
// render donut chart |
| 106 |
var todaychart = new donutChart(elemid); |
| 107 |
todaychart.draw({ |
| 108 |
start: defparams.start, |
| 109 |
end: defparams.tot_booked_today, |
| 110 |
maxValue: defparams.tot_rooms_units, |
| 111 |
size: defparams.size, |
| 112 |
unitText: defparams.unitText, |
| 113 |
animationSpeed: defparams.animationSpeed, |
| 114 |
textColor: defparams.textColor, |
| 115 |
titlePosition: defparams.titlePosition, |
| 116 |
titleText: defparams.titleText, |
| 117 |
titleColor: defparams.titleColor, |
| 118 |
outerCircleColor: defparams.outer_color, |
| 119 |
innerCircleColor: defparams.innerCircleColor, |
| 120 |
innerCircleStroke: defparams.innerCircleStroke |
| 121 |
}); |
| 122 |
} |
| 123 |
</script> |
| 124 |
|
| 125 |
<div class="vbo-admin-widget-wrapper"> |
| 126 |
<div class="vbo-admin-widget-head"> |
| 127 |
<div class="vbo-admin-widget-head-inline"> |
| 128 |
<h4><?php echo $this->widgetIcon; ?> <span><?php echo JText::translate('VBDASHWEEKGLOBAVAIL'); ?></span></h4> |
| 129 |
<div class="vbo-admin-widget-head-commands"> |
| 130 |
<div class="vbo-reportwidget-commands"> |
| 131 |
<div class="vbo-reportwidget-commands-main"> |
| 132 |
<div class="vbo-reportwidget-command-chevron vbo-dash-chart-prev" style="display: none;"> |
| 133 |
<span class="vbo-dash-chart-nav"><?php VikBookingIcons::e('chevron-left'); ?></span> |
| 134 |
</div> |
| 135 |
<div class="vbo-reportwidget-command-chevron vbo-dash-chart-next"> |
| 136 |
<span class="vbo-dash-chart-nav"><?php VikBookingIcons::e('chevron-right'); ?></span> |
| 137 |
</div> |
| 138 |
</div> |
| 139 |
</div> |
| 140 |
</div> |
| 141 |
</div> |
| 142 |
</div> |
| 143 |
<div class="vbo-dashboard-charts-wrapper"> |
| 144 |
<?php |
| 145 |
$info_end = getdate($today_end_ts); |
| 146 |
for ($i = 0; $i < 7; $i++) { |
| 147 |
$today_ts = mktime($info_end['hours'], $info_end['minutes'], $info_end['seconds'], $info_end['mon'], ($info_end['mday'] + $i), $info_end['year']); |
| 148 |
$today_info = getdate($today_ts); |
| 149 |
$tot_booked_today = 0; |
| 150 |
if (count($busy) > 0) { |
| 151 |
foreach ($busy as $idroom => $rbusy) { |
| 152 |
if (in_array($idroom, $info_rooms['unpublished_rooms'])) { |
| 153 |
continue; |
| 154 |
} |
| 155 |
foreach ($rbusy as $b) { |
| 156 |
$tmpone = getdate($b['checkin']); |
| 157 |
$ritts = mktime(0, 0, 0, $tmpone['mon'], $tmpone['mday'], $tmpone['year']); |
| 158 |
$tmptwo = getdate($b['checkout']); |
| 159 |
$conts = mktime(0, 0, 0, $tmptwo['mon'], $tmptwo['mday'], $tmptwo['year']); |
| 160 |
if ($today_ts >= $ritts && $today_ts < $conts) { |
| 161 |
$tot_booked_today++; |
| 162 |
} |
| 163 |
} |
| 164 |
} |
| 165 |
} |
| 166 |
$percentage_booked = $no_av_rooms ? 0 : round((100 * $tot_booked_today / $info_rooms['tot_rooms_units']), 2); |
| 167 |
|
| 168 |
$outer_color = '#ff4d4d'; //red |
| 169 |
if ($percentage_booked > 33 && $percentage_booked <= 66) { |
| 170 |
$outer_color = '#ffa64d'; //orange |
| 171 |
} elseif ($percentage_booked > 66 && $percentage_booked < 100) { |
| 172 |
$outer_color = '#2a762c'; //green |
| 173 |
} elseif ($percentage_booked >= 100) { |
| 174 |
$outer_color = '#2482b4'; //light-blue |
| 175 |
} |
| 176 |
?> |
| 177 |
<div class="vbo-dashboard-chart-container" id="vbo-dashboard-chart-<?php echo $widget_instance; ?>-container-<?php echo ($i + 1); ?>"> |
| 178 |
<span class="vbo-dashboard-chart-date"><?php echo $i == 0 ? JText::translate('VBTODAY').', ' : ''; ?><?php echo $wdaysmap[(string)$today_info['wday']]; ?> <?php echo $today_info['mday']; ?></span> |
| 179 |
</div> |
| 180 |
<script type="text/javascript"> |
| 181 |
renderDonutChart("vbo-dashboard-chart-<?php echo $widget_instance; ?>-container-<?php echo ($i + 1); ?>", { |
| 182 |
tot_booked_today: <?php echo $tot_booked_today; ?>, |
| 183 |
tot_rooms_units: <?php echo $info_rooms['tot_rooms_units']; ?>, |
| 184 |
outer_color: '<?php echo $outer_color; ?>' |
| 185 |
}); |
| 186 |
</script> |
| 187 |
<?php |
| 188 |
} |
| 189 |
// next week first day for navigation between donut charts |
| 190 |
$nextwk_ymd = date('Y-m-d', mktime(0, 0, 0, $today_info['mon'], ($today_info['mday'] + 1), $today_info['year'])); |
| 191 |
?> |
| 192 |
<script type="text/javascript"> |
| 193 |
var nextwk_ymd = '<?php echo $nextwk_ymd; ?>'; |
| 194 |
jQuery(function() { |
| 195 |
jQuery('.vbo-dash-chart-nav').click(function() { |
| 196 |
var instance_elem = jQuery(this).closest('.vbo-admin-widget-wrapper'); |
| 197 |
var direction = jQuery(this).parent().hasClass('vbo-dash-chart-prev') ? 'prev' : 'next'; |
| 198 |
var jqxhr = jQuery.ajax({ |
| 199 |
type: "POST", |
| 200 |
url: "<?php echo $this->getExecWidgetAjaxUri('index.php?option=com_vikbooking&task=donut_charts_data'); ?>", |
| 201 |
data: { |
| 202 |
direction: direction, |
| 203 |
fromdt: nextwk_ymd, |
| 204 |
tmpl: "component" |
| 205 |
} |
| 206 |
}).done(function(res) { |
| 207 |
try { |
| 208 |
var obj_res = typeof res === 'string' ? JSON.parse(res) : res; |
| 209 |
// clean up current HTML |
| 210 |
instance_elem.find('.vbo-dashboard-charts-wrapper').html(''); |
| 211 |
// |
| 212 |
for (var i = 0; i < obj_res.data.length; i++) { |
| 213 |
var identifier = 'vbo-dashboard-chart-<?php echo $widget_instance; ?>-container-' + obj_res.data[i]['ymd']; |
| 214 |
var container = '<div class="vbo-dashboard-chart-container" id="' + identifier + '">' + |
| 215 |
' <span class="vbo-dashboard-chart-date">' + obj_res.data[i]['lbl'] + '</span>' + |
| 216 |
'</div>'; |
| 217 |
instance_elem.find('.vbo-dashboard-charts-wrapper').append(container); |
| 218 |
var donut_params = { |
| 219 |
tot_booked_today: obj_res.data[i]['tot_booked'], |
| 220 |
tot_rooms_units: obj_res.tot_units, |
| 221 |
outer_color: obj_res.data[i]['color'] |
| 222 |
} |
| 223 |
renderDonutChart(identifier, donut_params); |
| 224 |
} |
| 225 |
// update date for the next request and navigation data |
| 226 |
nextwk_ymd = obj_res.tod; |
| 227 |
if (obj_res.prevweek === true) { |
| 228 |
instance_elem.find('.vbo-dash-chart-prev').fadeIn(); |
| 229 |
} else { |
| 230 |
instance_elem.find('.vbo-dash-chart-prev').hide(); |
| 231 |
} |
| 232 |
if (obj_res.nextweek === true) { |
| 233 |
instance_elem.find('.vbo-dash-chart-next').fadeIn(); |
| 234 |
} else { |
| 235 |
instance_elem.find('.vbo-dash-chart-next').hide(); |
| 236 |
} |
| 237 |
|
| 238 |
} catch(err) { |
| 239 |
console.error('could not parse JSON response', err, res); |
| 240 |
} |
| 241 |
}).fail(function(err) { |
| 242 |
alert(err); |
| 243 |
}); |
| 244 |
}); |
| 245 |
}); |
| 246 |
</script> |
| 247 |
</div> |
| 248 |
<div class="vbo-dashboard-refresh-container" style="display: none;"> |
| 249 |
<div class="vbo-dashboard-refresh-head"><span class="vbo-dashboard-refresh-label"><?php echo JText::translate('VBDASHNEXTREFRESH'); ?></span> <span class="vbo-dashboard-refresh-minutes">05</span>:<span class="vbo-dashboard-refresh-seconds">00</span></div> |
| 250 |
<span class="vbo-dashboard-refresh-stop"> </span> |
| 251 |
<span class="vbo-dashboard-refresh-play" style="display: none;"> </span> |
| 252 |
</div> |
| 253 |
</div> |
| 254 |
<script type="text/javascript"> |
| 255 |
var vbo_dash_counter = 300; |
| 256 |
var vbo_t; |
| 257 |
var vbo_m = 5; |
| 258 |
var vbo_s = 0; |
| 259 |
var vbo_t_on = false; |
| 260 |
function vboRefreshTimer() { |
| 261 |
vbo_dash_counter--; |
| 262 |
if (vbo_dash_counter <= 0) { |
| 263 |
vbo_t_on = false; |
| 264 |
clearTimeout(vbo_t); |
| 265 |
location.reload(); |
| 266 |
return true; |
| 267 |
} |
| 268 |
vbo_m = Math.floor(vbo_dash_counter / 60); |
| 269 |
vbo_s = Math.floor((vbo_dash_counter - (vbo_m * 60))); |
| 270 |
jQuery(".vbo-dashboard-refresh-minutes").text("0"+vbo_m); |
| 271 |
jQuery(".vbo-dashboard-refresh-seconds").text((parseInt(vbo_s) < 10 ? "0"+vbo_s : vbo_s)); |
| 272 |
vbo_t = setTimeout(vboRefreshTimer, 1000); |
| 273 |
} |
| 274 |
function vboStartTimer() { |
| 275 |
vbo_t = setTimeout(vboRefreshTimer, 1000); |
| 276 |
vbo_t_on = true; |
| 277 |
} |
| 278 |
jQuery(function() { |
| 279 |
/** |
| 280 |
* We disable the automatic reload timer. To restore it, remove the display: none |
| 281 |
* attribute to the DIV.vbo-dashboard-refresh-container and decomment "vboStartTimer();". |
| 282 |
* |
| 283 |
* @since 1.14 (J) - 1.4.0 (WP) |
| 284 |
*/ |
| 285 |
// vboStartTimer(); |
| 286 |
// |
| 287 |
|
| 288 |
jQuery(".vbo-dashboard-refresh-stop").click(function() { |
| 289 |
if (vbo_t_on) { |
| 290 |
vbo_t_on = false; |
| 291 |
clearTimeout(vbo_t); |
| 292 |
jQuery(".vbo-dashboard-refresh-play").fadeIn(); |
| 293 |
} else { |
| 294 |
jQuery(this).parent().fadeOut(); |
| 295 |
} |
| 296 |
}); |
| 297 |
jQuery(".vbo-dashboard-refresh-play").click(function() { |
| 298 |
if (!vbo_t_on) { |
| 299 |
// vboStartTimer(); |
| 300 |
jQuery(this).fadeOut(); |
| 301 |
} |
| 302 |
}); |
| 303 |
}); |
| 304 |
</script> |
| 305 |
<?php |
| 306 |
} |
| 307 |
} |
| 308 |
|