PluginProbe
FV Player 8 / 8.1
FV Player 8 v8.1
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 8.1, at view/stats.php

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