PluginProbe
FV Player 8 / trunk
FV Player 8 vtrunk
trunk 8.0.18 8.0.19 8.0.20 8.0.21 8.0.25 8.0.27 8.1 8.1.3
fv-player / view / stats.php

stats.php in FV Player 8 trunk, at view/stats.php

479 lines 14.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit;
5 }
6
7 global $FV_Player_Stats;
8
9 // Parse stats now. This helps if WP Cron is having issues.
10 $FV_Player_Stats->parse_cached_files();
11
12 global $fv_wp_flowplayer_ver;
13
14 // This is filtering player stats by user ID, player ID and settings stats range
15 // core WordPress wp-admin -> Posts does not use nonce for filters either
16 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
17 $current_page = isset($_GET['page']) ? sanitize_text_field($_GET['page']) : false;
18
19 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
20 $user_id = isset( $_GET['user_id'] ) ? intval($_GET['user_id']) : false;
21
22 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
23 $player_id = isset( $_GET['player_id'] ) ? intval($_GET['player_id']) : false;
24
25 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
26 $date_range = isset($_REQUEST['stats_range']) ? sanitize_text_field($_REQUEST['stats_range']) : 'this_week';
27
28 // Validate the interval
29 $interval = FV_Player_Stats::get_interval_from_range($date_range);
30 if ( ! $interval || empty( $interval[0] ) || empty( $interval[1] ) ) {
31 $date_range = 'this_week';
32 }
33
34 if( $player_id ) { // specific player stats
35 $fv_single_player_stats_data = $FV_Player_Stats->get_player_stats( $player_id, $date_range );
36 } else { // aggregated top stats
37
38 if( ( strcmp($current_page, 'fv_player_stats') === 0 ) || ( strcmp($current_page, 'fv_player_stats_users') === 0 && is_int($user_id) ) ) { // aggegated top stats for videos, posts and watch time, show for both but for fv_player_stats_users only if user_id is set
39 $fv_video_stats_data = $FV_Player_Stats->get_top_video_post_stats( 'video', $date_range, $user_id);
40
41 $fv_post_stats_data = $FV_Player_Stats->get_top_video_post_stats( 'post', $date_range, $user_id);
42
43 $fv_video_watch_time_stats_data = $FV_Player_Stats->get_top_video_watch_time_stats( 'video', $date_range, $user_id );
44
45 $fv_post_watch_time_stats_data = $FV_Player_Stats->get_top_video_watch_time_stats( 'post', $date_range, $user_id );
46
47 if($user_id) $fv_player_interval_valid = $FV_Player_Stats->get_valid_interval($user_id);
48 }
49
50 if( ! $user_id && strcmp($current_page, 'fv_player_stats_users') === 0 ) { // aggregated top 10 stats for all users, only show on fv_player_stats_users when no user is selected
51 $fv_user_play_stats_data = $FV_Player_Stats->get_top_user_stats( 'play', $date_range);
52
53 $fv_user_watch_time_stats_data = $FV_Player_Stats->get_top_user_stats( 'seconds', $date_range);
54 }
55
56 }
57
58 // select2
59 wp_enqueue_script( 'fv-select2-js', flowplayer::get_plugin_url().'/js/select2/select2.full.min.js' , array('jquery'), $fv_wp_flowplayer_ver );
60 wp_enqueue_style( 'fv-select2-css', flowplayer::get_plugin_url().'/css/select2.min.css', array(), $fv_wp_flowplayer_ver );
61
62 // chartjs
63 wp_enqueue_script( 'fv-chartjs', flowplayer::get_plugin_url().'/js/chartjs/chart.min.js', array('jquery'), $fv_wp_flowplayer_ver );
64 wp_enqueue_script( 'fv-chartjs-html-legend', flowplayer::get_plugin_url().'/js/chartjs/html-legend.js', array('fv-chartjs'), $fv_wp_flowplayer_ver );
65 ?>
66
67 <style>
68 .fv-player-chartjs-html-legend ul {
69 display: flex;
70 flex-direction: row;
71 margin: 0px;
72 padding: 0px;
73 }
74 .fv-player-chartjs-html-legend ul li {
75 align-items: center;
76 cursor: pointer;
77 display: flex;
78 flex-direction: row;
79 margin-left: 10px;
80 }
81 .fv-player-chartjs-html-legend ul li span {
82 display: inline-block;
83 height: 20px;
84 margin-right: 10px;
85 width: 20px;
86 }
87 .fv-player-chartjs-html-legend ul li p {
88 margin: 0px;
89 padding: 0px;
90 }
91
92 #fv_player_stats_filter .chosen-container-single .chosen-single {
93 height: 30px;
94 line-height: 28px;
95 }
96
97 #fv_player_stats_users_select {
98 max-width: 500px;
99 width: 100%;
100 }
101
102 .select2-container--default .select2-results > .select2-results__options {
103 max-height: 80vh !important;
104 }
105 </style>
106
107 <div class="wrap">
108 <h1>FV Player Stats</h1>
109
110 <div>
111 <form id="fv_player_stats_filter" method="get" action="<?php echo admin_url( 'admin.php' ); ?>" >
112 <input type="hidden" name="page" value="<?php echo esc_attr( $current_page ); ?>" />
113 <?php if( $user_id ): ?>
114 <input type="hidden" name="user_id" value="<?php echo intval( $user_id ); ?>" />
115 <?php endif; ?>
116 <?php if( $player_id ): ?>
117 <input type="hidden" name="player_id" value="<?php echo intval( $player_id ); ?>" />
118 <?php endif; ?>
119 <select id="fv_player_stats_select" name="stats_range">
120 <?php
121
122 $dates = $FV_Player_Stats->get_valid_dates($user_id);
123
124 foreach( $dates as $key => $value ) {
125 echo '<option value="' . esc_attr( $key ) . '" '.( $date_range == $key ? 'selected' : '' ) . ' ' . ( $value['disabled'] ? 'disabled' : '' ) . '>'.esc_html( $value['value'] ) . '</option>';
126 }
127 ?>
128 </select>
129
130 <?php if( strcmp($current_page, 'fv_player_stats_users') === 0 ): ?>
131 <select id="fv_player_stats_users_select" name="user_id">
132 <option disabled selected value>Select user you want to show stats for</option>
133 <?php
134 if( $user_id ) {
135 $users = $FV_Player_Stats->get_users_by_time_range( $date_range, $user_id );
136 foreach( $users as $key => $value ) {
137 $plays = !empty($value['play']) && intval($value['play']) ? $value['play'] : 0;
138 $plays = number_format_i18n( $plays, 0 );
139
140 echo '<option value="' . esc_attr( $value['ID'] ) . '" '.( $user_id == $value['ID'] ? 'selected' : '' ). ' ' . ( !$plays ? 'disabled' : '' ) . '>' . esc_html( $value['display_name'] . ' - ' . $value['user_email'] .' ( ' . $plays . ' plays )' ) . '</option>';
141 }
142 }
143 ?>
144 </select>
145 <?php endif; ?>
146
147 <?php if( $user_id ): ?>
148 <a id="export" class="button" href="<?php echo admin_url('admin.php?page=fv_player_stats&fv-stats-export-user=' . intval( $user_id ) . '&stats_range=' . esc_attr( $date_range ) . '&nonce=' . wp_create_nonce( 'fv-stats-export-user-' . $user_id ));?>">Export CSV</a>
149 <?php endif; ?>
150
151 </form>
152
153 </div>
154
155 <script>
156 jQuery(document).ready(function() {
157 jQuery(document).on('change', '#fv_player_stats_select, #fv_player_stats_users_select', function() {
158 jQuery('#fv_player_stats_filter').submit();
159 });
160
161 if( jQuery('#fv_player_stats_select').length > 0 ) {
162 setTimeout(function() {
163 jQuery('#fv_player_stats_select').select2({
164 minimumResultsForSearch: -1 // hide the search
165 });
166 },0);
167 }
168
169 if( jQuery('#fv_player_stats_users_select').length > 0 ) jQuery('#fv_player_stats_users_select').select2({
170 ajax: {
171 url: ajaxurl,
172 dataType: 'json',
173 delay: 250,
174 data: function (params) {
175 return {
176 q: params.term, // search term - user
177 date_range: jQuery('#fv_player_stats_select').val(), // date range
178 action: 'fv_player_stats_users_search',
179 nonce: '<?php echo wp_create_nonce( 'fv-player-stats-users-search' ); ?>'
180 };
181 },
182 cache: false
183 },
184 minimumInputLength: 2,
185 placeholder: 'Search for a user',
186 });
187
188 });
189
190 function fv_player_stats_chartjs_args( data, data_selector, args ) {
191
192 var conf = {
193 type: 'line',
194 data: {
195 labels: data['date-labels'],
196 datasets: fv_chart_add_dataset_items( data, data_selector )
197 },
198 options: {
199 animation: {
200 duration: 0
201 },
202 plugins: {
203 htmlLegend: {
204 containerID: args.legend_containerID,
205 },
206 legend: {
207 display: false,
208 }
209 },
210 responsive: true,
211 scales: {
212 y: {
213 stacked: true,
214 beginAtZero: true,
215 ticks: {
216 precision: 0
217 }
218 }
219 }
220 },
221 plugins: [ htmlLegendPlugin ],
222 }
223
224 if ( args.scales_y_title ) {
225 conf.options.scales.y.title = {
226 display: true,
227 text: args.scales_y_title
228 }
229 }
230
231 return conf;
232 }
233
234 // Randomize color for each line
235 var used_colors = [];
236
237 var fv_chart_dynamic_color = function() {
238 var colors = [
239 '#2660A4',
240 '#F19953',
241 '#8377D1',
242 '#D6D9CE',
243 '#E88EED',
244 '#F3E37C',
245 '#B8B8F3',
246 '#7DD181',
247 '#914D76',
248 '#08415C',
249 ];
250
251 var i = 0;
252 var pick = colors[i];
253
254 while( i < used_colors.length && used_colors.includes(pick) ) {
255 i++;
256 pick = colors[i];
257 }
258
259 used_colors.push(pick);
260
261 return pick;
262 };
263
264 var fv_chart_add_dataset_items = function( top_results, metric ) {
265 used_colors = [];
266
267 var top_datasets = [];
268
269 for ( var id_video in top_results ) {
270 if( !top_results.hasOwnProperty(id_video) || id_video == 'date-labels' ) continue;
271
272 var data = [];
273 var colors = fv_chart_dynamic_color();
274
275 var dataset_item = {
276 label: top_results[id_video]['name'],
277 borderColor: colors,
278 backgroundColor: colors,
279 fill: true
280 }
281
282 for ( var date in top_results[id_video] ) {
283 if( date != 'name' ) {
284 var value = parseInt(top_results[id_video][date][metric]);
285
286 if( metric == 'seconds' ) {
287 if( value > 0 ) value = Math.ceil(value / 60); // convert to minutes
288 }
289
290 data.push(value);
291 }
292 }
293
294 dataset_item['data'] = data;
295 top_datasets.push(dataset_item);
296 }
297
298 return top_datasets;
299 }
300 </script>
301
302 <?php if( isset($fv_video_stats_data) && !empty($fv_video_stats_data) ): ?>
303
304 <div>
305 <h2>Top 10 Videos</h2>
306 <div id="chart-top-users-play-legend" class="fv-player-chartjs-html-legend"></div>
307 <canvas id="chart-top-users-play" style="max-height: 36vh"></canvas>
308 </div>
309
310 <script>
311 jQuery( document ).ready(function() {
312 used_colors = [];
313
314 new Chart(
315 document.getElementById('chart-top-users-play').getContext('2d'),
316 fv_player_stats_chartjs_args(
317 <?php echo wp_json_encode( $fv_video_stats_data ); ?>,
318 'play',
319 {
320 legend_containerID: 'chart-top-users-play-legend'
321 }
322 )
323 );
324 });
325 </script>
326 <?php endif;?>
327
328 <?php if( isset($fv_post_stats_data) && !empty($fv_post_stats_data) ): ?>
329
330 <div>
331 <h2>Top 10 Post Video Plays</h2>
332 <div id="chart-top-posts-legend" class="fv-player-chartjs-html-legend"></div>
333 <canvas id="chart-top-posts" style="max-height: 36vh"></canvas>
334 </div>
335
336 <script>
337 jQuery( document ).ready(function() {
338 used_colors = [];
339
340 new Chart(
341 document.getElementById('chart-top-posts').getContext('2d'),
342 fv_player_stats_chartjs_args(
343 <?php echo wp_json_encode( $fv_post_stats_data ); ?>,
344 'play',
345 {
346 legend_containerID: 'chart-top-posts-legend'
347 }
348 )
349 );
350 });
351 </script>
352 <?php endif; ?>
353
354 <?php if( isset($fv_video_watch_time_stats_data) && !empty($fv_video_watch_time_stats_data) ): ?>
355
356 <div>
357 <h2>Top 10 Videos by Watch Time</h2>
358 <div id="chart-top-users-play-watchtime-legend" class="fv-player-chartjs-html-legend"></div>
359 <canvas id="chart-top-users-play-watchtime" style="max-height: 36vh"></canvas>
360 </div>
361
362 <script>
363 jQuery( document ).ready(function() {
364 new Chart(
365 document.getElementById('chart-top-users-play-watchtime').getContext('2d'),
366 fv_player_stats_chartjs_args(
367 <?php echo wp_json_encode( $fv_video_watch_time_stats_data ); ?>,
368 'seconds',
369 {
370 legend_containerID: 'chart-top-users-play-watchtime-legend',
371 scales_y_title: "Minutes"
372 }
373 )
374 );
375 });
376 </script>
377 <?php endif; ?>
378
379 <?php if( isset($fv_post_watch_time_stats_data) && !empty($fv_post_watch_time_stats_data) ): ?>
380
381 <div>
382 <h2>Top 10 Posts by Watch Time</h2>
383 <div id="chart-top-posts-watchtime-legend" class="fv-player-chartjs-html-legend"></div>
384 <canvas id="chart-top-posts-watchtime" style="max-height: 36vh"></canvas>
385 </div>
386
387 <script>
388 jQuery( document ).ready(function() {
389 new Chart(
390 document.getElementById('chart-top-posts-watchtime').getContext('2d'),
391 fv_player_stats_chartjs_args(
392 <?php echo wp_json_encode( $fv_post_watch_time_stats_data ); ?>,
393 'seconds',
394 {
395 legend_containerID: 'chart-top-posts-watchtime-legend',
396 scales_y_title: "Minutes"
397 }
398 )
399 );
400 });
401 </script>
402 <?php endif; ?>
403
404 <?php if( isset($fv_user_play_stats_data) && !empty($fv_user_play_stats_data) ): ?>
405
406 <div>
407 <h2>Top 10 Users by Plays</h2>
408 <div id="chart-top-10-users-by-play-legend" class="fv-player-chartjs-html-legend"></div>
409 <canvas id="chart-top-10-users-by-play" style="max-height: 36vh"></canvas>
410 </div>
411
412 <script>
413 jQuery( document ).ready(function() {
414 new Chart(
415 document.getElementById('chart-top-10-users-by-play').getContext('2d'),
416 fv_player_stats_chartjs_args(
417 <?php echo wp_json_encode( $fv_user_play_stats_data ); ?>,
418 'play',
419 {
420 legend_containerID: 'chart-top-10-users-by-play-legend'
421 }
422 )
423 );
424 })
425 </script>
426 <?php endif; ?>
427
428 <?php if( isset($fv_user_watch_time_stats_data) && !empty($fv_user_watch_time_stats_data) ): ?>
429
430 <div>
431 <h2>Top 10 Users by Watch Time</h2>
432 <div id="chart-top-10-users-by-watchtime-legend" class="fv-player-chartjs-html-legend"></div>
433 <canvas id="chart-top-10-users-by-watchtime" style="max-height: 36vh"></canvas>
434 </div>
435
436 <script>
437 jQuery( document ).ready(function() {
438 new Chart(
439 document.getElementById('chart-top-10-users-by-watchtime').getContext('2d'),
440 fv_player_stats_chartjs_args(
441 <?php echo wp_json_encode( $fv_user_watch_time_stats_data ); ?>,
442 'seconds',
443 {
444 legend_containerID: 'chart-top-10-users-by-watchtime-legend',
445 scales_y_title: "Minutes"
446 }
447 )
448 );
449 })
450 </script>
451 <?php endif;?>
452
453 <?php if( isset($fv_single_player_stats_data) && !empty($fv_single_player_stats_data) ): ?>
454 <div>
455 <h2>Plays For Player <?php echo intval( $player_id ); ?></h2>
456 <div id="chart-single-player-legend" class="fv-player-chartjs-html-legend"></div>
457 <canvas id="chart-single-player" style="max-height: 36vh"></canvas>
458 </div>
459 <script>
460 jQuery( document ).ready(function() {
461 new Chart(
462 document.getElementById('chart-single-player').getContext('2d'),
463 fv_player_stats_chartjs_args(
464 <?php echo wp_json_encode( $fv_single_player_stats_data ); ?>,
465 'play',
466 {
467 legend_containerID: 'chart-single-player-legend'
468 }
469 )
470 );
471 });
472 </script>
473 <?php elseif ( isset($fv_single_player_stats_data) ): ?>
474 <div>
475 <h2>No Plays For Player <?php echo intval( $player_id ); ?></h2>
476 </div>
477 <?php endif; ?>
478 </div>
479