PluginProbe
VikBooking Hotel Booking Engine & PMS / trunk
VikBooking Hotel Booking Engine & PMS vtrunk
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 1.7.3 All 36 releases
vikbooking / admin / helpers / widgets / visitors_counter.php

visitors_counter.php in VikBooking Hotel Booking Engine & PMS trunk, at admin/helpers/widgets/visitors_counter.php

261 lines 9.0 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 "visitors counter".
15 *
16 * @since 1.4.0
17 */
18 class VikBookingAdminWidgetVisitorsCounter 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_VISITCOUNT_TITLE');
37 $this->widgetDescr = JText::translate('VBO_W_VISITCOUNT_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('binoculars') . '"></i>';
46 $this->widgetStyleName = 'blue';
47 }
48
49 /**
50 * Custom method for this widget only to count the visitors.
51 * The method is called by the admin controller through an AJAX request.
52 * The visibility should be public, it should not exit the process, and
53 * any content sent to output will be returned to the AJAX response.
54 */
55 public function countVisitors()
56 {
57 // load the tracker object without starting to track any data
58 VikBooking::getTracker(true);
59
60 // total unique and active visitors today
61 $today_from = date('Y-m-d') . ' 00:00:00';
62 $today_to = date('Y-m-d') . ' 23:59:59';
63 $tot_today = VikBookingTracker::countTrackedRecords($today_from, $today_to);
64
65 // total unique and active visitors this month until the end of today
66 $month_from = date('Y-m') . '-01 00:00:00';
67 $tot_month = VikBookingTracker::countTrackedRecords($month_from, $today_to);
68
69 // total unique and active visitors last month until the end of today's month day
70 $now = getdate();
71 $last_month_from = date('Y-m-d H:i:s', mktime(0, 0, 0, ($now['mon'] - 1), 1, $now['year']));
72 $last_month_to = date('Y-m-d H:i:s', mktime(23, 59, 59, ($now['mon'] - 1), $now['mday'], $now['year']));
73 $tot_last_month = VikBookingTracker::countTrackedRecords($last_month_from, $last_month_to);
74
75 // percentage of this month and last month (tot_month : x = tot_last_month : 100)
76 $last_mon_divisor = $tot_last_month < 1 ? 1 : $tot_last_month;
77 $pcent_month_full = $tot_month * 100 / $last_mon_divisor;
78 $pcent_month = 0;
79 if ($pcent_month_full > 0 && $pcent_month_full < 100) {
80 // less visitors (-x %)
81 $pcent_month = round((100 - $pcent_month_full), 1);
82 $pcent_month = $pcent_month - ($pcent_month * 2);
83 } elseif ($tot_last_month > 0 && $pcent_month_full > 100) {
84 // more visitors (+x %)
85 $pcent_month = '+' . round(($pcent_month_full - 100), 1);
86 } elseif ($pcent_month_full > 0 && $tot_month != $tot_last_month) {
87 // more visitors (+x %)
88 $pcent_month = '+' . round($pcent_month_full, 1);
89 }
90
91 echo implode(';', array($tot_today, $tot_month, $tot_last_month, $pcent_month));
92 }
93
94 public function render(?VBOMultitaskData $data = null)
95 {
96 // increase widget's instance counter
97 static::$instance_counter++;
98
99 // check whether the widget is being rendered via AJAX when adding it through the customizer
100 $is_ajax = $this->isAjaxRendering();
101
102 // generate a unique ID for the sticky notes wrapper instance
103 $wrapper_instance = !$is_ajax ? static::$instance_counter : rand();
104 $wrapper_id = 'vbo-widget-visitscounter-' . $wrapper_instance;
105
106 ?>
107 <div class="vbo-admin-widget-wrapper">
108 <div class="vbo-admin-widget-head">
109 <h4><?php echo $this->widgetIcon; ?> <span><?php echo $this->widgetName; ?></span></h4>
110 </div>
111 <div id="<?php echo $wrapper_id; ?>" class="vbo-widget-visitscounter-wrap">
112 <div class="vbo-widget-visitscounter-number">
113 <span class="vbo-widget-visitscounter-number-count" data-period="tot_today">0</span>
114 <div class="vbo-widget-visitscounter-number-lbl"><?php echo JText::translate('VBO_W_VISITCOUNT_VTODAY'); ?></div>
115 </div>
116 <div class="vbo-widget-visitscounter-number">
117 <span class="vbo-widget-visitscounter-number-count" data-period="tot_month">0</span>
118 <div class="vbo-widget-visitscounter-number-lbl"><?php echo JText::translate('VBO_W_VISITCOUNT_VTMON'); ?></div>
119 </div>
120 <div class="vbo-widget-visitscounter-number">
121 <span class="vbo-widget-visitscounter-number-count" data-period="tot_last_month">0</span>
122 <div class="vbo-widget-visitscounter-number-lbl"><?php echo JText::translate('VBO_W_VISITCOUNT_VLMON'); ?></div>
123 </div>
124 <div class="vbo-widget-visitscounter-number">
125 <span class="vbo-widget-visitscounter-number-count" data-period="pcent_month">0 %</span>
126 <div class="vbo-widget-visitscounter-number-lbl"><?php echo JText::translate('VBO_W_VISITCOUNT_VDIFF'); ?></div>
127 </div>
128 </div>
129 </div>
130 <?php
131
132 if (static::$instance_counter === 0 || $is_ajax) {
133 /**
134 * Print the JS code only once for all instances of this widget.
135 * The real rendering is made through AJAX, not when the page loads.
136 */
137 ?>
138 <script type="text/javascript">
139
140 /**
141 * Calculates the proper duration of the animation given the steps.
142 *
143 * @param int steps the number of steps to animate (target number).
144 *
145 * @return int the suggested duration for the animation in ms.
146 */
147 function vboWidgetVscCounterDuration(steps) {
148 var min_duration = 500,
149 max_duration = 10000,
150 tms_per_step = 250;
151
152 var duration = tms_per_step * steps;
153
154 if (duration < min_duration) {
155 return min_duration;
156 }
157
158 if (duration > max_duration) {
159 return max_duration;
160 }
161
162 return duration;
163 }
164
165 /**
166 * Updates the counter(s) by making an AJAX request and starts their animation.
167 */
168 function vboWidgetVscCountVisitors() {
169 // the widget method to call
170 var call_method = 'countVisitors';
171
172 // make a silent request to count the visitors
173 VBOCore.doAjax(
174 "<?php echo $this->getExecWidgetAjaxUri(); ?>",
175 {
176 widget_id: "<?php echo $this->getIdentifier(); ?>",
177 call: call_method,
178 tmpl: "component"
179 },
180 function(response) {
181 try {
182 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
183 if (!obj_res.hasOwnProperty(call_method)) {
184 console.error('Unexpected JSON response', obj_res);
185 return;
186 }
187
188 // response must contain 4 values separated by ;
189 var data_numbers = obj_res[call_method].split(';');
190 if (data_numbers.length != 4) {
191 return;
192 }
193
194 // compose stats vars
195 var stat_vars = {
196 tot_today: parseInt(data_numbers[0]),
197 tot_month: parseInt(data_numbers[1]),
198 tot_last_month: parseInt(data_numbers[2]),
199 pcent_month: data_numbers[3]
200 }
201
202 // update all counter values (in case of multiple instances)
203 jQuery('.vbo-widget-visitscounter-number-count').each(function() {
204 var counter_type = jQuery(this).attr('data-period');
205 if (!counter_type || !stat_vars.hasOwnProperty(counter_type)) {
206 // continue as this property is not available
207 return;
208 }
209
210 if (counter_type == 'pcent_month') {
211 // this is not a real counter
212 jQuery(this).text(stat_vars[counter_type] + ' %');
213 // continue
214 return;
215 }
216
217 var current_counter = parseInt(jQuery(this).text());
218 if (current_counter >= stat_vars[counter_type]) {
219 // do nothing if we do not have a higher counter value
220 return;
221 }
222
223 // make sure the duration is valid for these steps
224 var counter_duration = current_counter > 0 ? vboWidgetVscCounterDuration(stat_vars[counter_type] - current_counter) : vboWidgetVscCounterDuration(stat_vars[counter_type]);
225
226 // set new counter value and property, then start counter animation
227 jQuery(this).text(stat_vars[counter_type]).prop('Counter', current_counter).animate({
228 Counter: jQuery(this).text()
229 }, {
230 duration: counter_duration,
231 easing: 'swing',
232 step: function (cur) {
233 jQuery(this).text(Math.ceil(cur));
234 }
235 });
236 });
237 } catch(err) {
238 console.error('could not parse JSON response', err, response);
239 }
240 },
241 function(error) {
242 console.error(error);
243 // make counter value empty
244 jQuery('.vbo-widget-visitscounter-number-count').text('');
245 }
246 );
247 }
248
249 jQuery(function() {
250 // run the AJAX request when the page loads
251 vboWidgetVscCountVisitors();
252
253 // set an interval of 5 minutes for updating the counter value
254 setInterval(vboWidgetVscCountVisitors, (1000 * 60 * 5));
255 });
256 </script>
257 <?php
258 }
259 }
260 }
261