PluginProbe ʕ •ᴥ•ʔ
WP Popular Posts / 4.1.1
WP Popular Posts v4.1.1
4.0.8 4.0.9 4.1.0 4.1.1 4.1.2 4.2.0 4.2.1 4.2.2 5.0.0 5.0.1 5.0.2 5.1.0 5.2.0 5.2.1 5.2.2 5.2.3 5.2.4 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 6.0.0 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.1.0 6.1.1 6.1.2 6.1.3 6.1.4 6.2.0 6.2.1 6.3.0 6.3.1 6.3.2 6.3.3 6.3.4 6.4.0 6.4.1 6.4.2 7.0.0 7.0.1 7.1.0 7.2.0 7.3.0 7.3.1 7.3.2 7.3.3 7.3.4 7.3.5 7.3.6 7.3.7 7.3.8 7.4.0 trunk 2.3.7 3.0.0 3.0.1 3.0.2 3.0.3 3.1.0 3.1.1 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 4.0.0 4.0.1 4.0.10 4.0.11 4.0.12 4.0.13 4.0.2 4.0.3 4.0.5 4.0.6
wordpress-popular-posts / admin / class-wordpress-popular-posts-admin.php
wordpress-popular-posts / admin Last commit date
css 8 years ago js 8 years ago partials 8 years ago class-wordpress-popular-posts-admin.php 8 years ago index.php 8 years ago
class-wordpress-popular-posts-admin.php
1345 lines
1 <?php
2
3 /**
4 * The admin-facing functionality of the plugin.
5 *
6 * @link https://cabrerahector.com/
7 * @since 4.0.0
8 *
9 * @package WordPressPopularPosts
10 * @subpackage WordPressPopularPosts/public
11 */
12
13 /**
14 * The public-facing functionality of the plugin.
15 *
16 * Defines the plugin name, version, and hooks to
17 * enqueue the admin-specific stylesheet and JavaScript.
18 *
19 * @package WordPressPopularPosts
20 * @subpackage WordPressPopularPosts/public
21 * @author Hector Cabrera <me@cabrerahector.com>
22 */
23 class WPP_Admin {
24
25 /**
26 * The ID of this plugin.
27 *
28 * @since 4.0.0
29 * @access private
30 * @var string $plugin_name The ID of this plugin.
31 */
32 private $plugin_name;
33
34 /**
35 * The version of this plugin.
36 *
37 * @since 4.0.0
38 * @access private
39 * @var string $version The current version of this plugin.
40 */
41 private $version;
42
43 /**
44 * Administrative settings.
45 *
46 * @since 2.3.3
47 * @var array
48 */
49 private $options = array();
50
51 /**
52 * Slug of the plugin screen.
53 *
54 * @since 3.0.0
55 * @var string
56 */
57 protected $plugin_screen_hook_suffix = NULL;
58
59 /**
60 * Initialize the class and set its properties.
61 *
62 * @since 4.0.0
63 * @param string $plugin_name The name of the plugin.
64 * @param string $version The version of this plugin.
65 */
66 public function __construct( $plugin_name, $version ) {
67
68 $this->plugin_name = $plugin_name;
69 $this->version = $version;
70 $this->options = WPP_Settings::get( 'admin_options' );
71
72 // Delete old data on demand
73 if ( 1 == $this->options['tools']['log']['limit'] ) {
74
75 if ( !wp_next_scheduled( 'wpp_cache_event' ) ) {
76 $tomorrow = time() + 86400;
77 $midnight = mktime(
78 0,
79 0,
80 0,
81 date( "m", $tomorrow ),
82 date( "d", $tomorrow ),
83 date( "Y", $tomorrow )
84 );
85 wp_schedule_event( $midnight, 'daily', 'wpp_cache_event' );
86 }
87
88 } else {
89 // Remove the scheduled event if exists
90 if ( $timestamp = wp_next_scheduled( 'wpp_cache_event' ) ) {
91 wp_unschedule_event( $timestamp, 'wpp_cache_event' );
92 }
93
94 }
95
96 // Allow WP themers / coders to override data sampling status (active/inactive)
97 $this->options['tools']['sampling']['active'] = apply_filters( 'wpp_data_sampling', $this->options['tools']['sampling']['active'] );
98
99 }
100
101 /**
102 * Fired when a new blog is activated on WP Multisite.
103 *
104 * @since 3.0.0
105 * @param int blog_id New blog ID
106 */
107 public function activate_new_site( $blog_id ){
108
109 if ( 1 !== did_action( 'wpmu_new_blog' ) )
110 return;
111
112 // run activation for the new blog
113 switch_to_blog( $blog_id );
114 WPP_Activator::track_new_site();
115
116 // switch back to current blog
117 restore_current_blog();
118
119 } // end activate_new_site
120
121 /**
122 * Fired when a blog is deleted on WP Multisite.
123 *
124 * @since 4.0.0
125 * @param array $tables
126 * @param int $blog_id
127 * @return array
128 */
129 public function delete_site_data( $tables, $blog_id ){
130
131 global $wpdb;
132
133 $tables[] = $wpdb->prefix . 'popularpostsdata';
134 $tables[] = $wpdb->prefix . 'popularpostssummary';
135
136 return $tables;
137
138 } // end delete_site_data
139
140 /**
141 * Display some statistics at the "At a Glance" box from the Dashboard.
142 *
143 * @since 4.1.0
144 */
145 public function at_a_glance_stats(){
146
147 global $wpdb;
148
149 $glances = array();
150 $args = array( 'post', 'page' );
151 $post_type_placeholders = '%s, %s';
152
153 if (
154 isset( $this->options['stats']['post_type'] )
155 && !empty( $this->options['stats']['post_type'] )
156 ) {
157 $args = array_map( 'trim', explode( ',', $this->options['stats']['post_type'] ) );
158 $post_type_placeholders = implode( ', ', array_fill( 0, count( $args ), '%s' ) );
159 }
160
161 $args[] = WPP_Helper::now();
162
163 $query = $wpdb->prepare(
164 "SELECT SUM(pageviews) AS total
165 FROM `{$wpdb->prefix}popularpostssummary` v LEFT JOIN `{$wpdb->prefix}posts` p ON v.postid = p.ID
166 WHERE p.post_type IN( {$post_type_placeholders} ) AND p.post_status = 'publish' AND p.post_password = '' AND v.view_datetime > DATE_SUB( %s, INTERVAL 1 HOUR );"
167 , $args
168 );
169
170 $total_views = $wpdb->get_var( $query );
171
172 $pageviews = sprintf(
173 _n( '1 view in the last hour', '%s views in the last hour', $total_views, 'wordpress-popular-posts' ),
174 number_format_i18n( $total_views )
175 );
176
177 if ( current_user_can('manage_options') ) {
178 $glances[] = '<a class="wpp-views-count" href="' . admin_url( 'options-general.php?page=wordpress-popular-posts' ) .'">' . $pageviews . '</a>';
179 }
180 else {
181 $glances[] = '<span class="wpp-views-count">' . $pageviews . '</a>';
182 }
183
184 return $glances;
185
186 }
187
188 /**
189 * Add custom inline CSS styles for At a Glance stats.
190 *
191 * @since 4.1.0
192 */
193 public function at_a_glance_stats_css(){
194 echo '<style>#dashboard_right_now a.wpp-views-count:before, #dashboard_right_now span.wpp-views-count:before { content: "\f177"; }</style>';
195 }
196
197 /**
198 * Register the stylesheets for the public-facing side of the site.
199 *
200 * @since 4.0.0
201 */
202 public function enqueue_styles() {
203
204 if ( !isset( $this->plugin_screen_hook_suffix ) ) {
205 return;
206 }
207
208 $screen = get_current_screen();
209
210 if ( isset( $screen->id ) && $screen->id == $this->plugin_screen_hook_suffix ) {
211 wp_enqueue_style( 'font-awesome', plugin_dir_url( __FILE__ ) . 'css/vendor/font-awesome.min.css', array(), '4.7.0', 'all' );
212 wp_enqueue_style( 'wpp-datepicker-theme', plugin_dir_url( __FILE__ ) . 'css/datepicker.css', array(), $this->version, 'all' );
213 wp_enqueue_style( 'wordpress-popular-posts-admin-styles', plugin_dir_url( __FILE__ ) . 'css/admin.css', array(), $this->version, 'all' );
214 }
215
216 }
217
218 /**
219 * Register the stylesheets for the public-facing side of the site.
220 *
221 * @since 4.0.0
222 */
223 public function enqueue_scripts() {
224
225 if ( ! isset( $this->plugin_screen_hook_suffix ) ) {
226 return;
227 }
228
229 $screen = get_current_screen();
230
231 if ( $screen->id == $this->plugin_screen_hook_suffix ) {
232
233 wp_enqueue_media();
234 wp_enqueue_script( 'jquery-ui-datepicker' );
235 wp_enqueue_script( 'chartjs', plugin_dir_url( __FILE__ ) . 'js/vendor/Chart.min.js', array(), $this->version );
236 wp_enqueue_script( 'wpp-chart', plugin_dir_url( __FILE__ ) . 'js/chart.js', array('chartjs'), $this->version );
237 wp_register_script( 'wordpress-popular-posts-admin-script', plugin_dir_url( __FILE__ ) . 'js/admin.js', array('jquery'), $this->version, true );
238 wp_localize_script( 'wordpress-popular-posts-admin-script', 'wpp_admin_params', array(
239 'label_media_upload_button' => __( "Use this image", "wordpress-popular-posts" ),
240 'nonce' => wp_create_nonce( "wpp_admin_nonce" )
241 ));
242 wp_enqueue_script( 'wordpress-popular-posts-admin-script' );
243
244 }
245
246 }
247
248 public function add_contextual_help(){
249
250 //get the current screen object
251 $screen = get_current_screen();
252
253 if ( isset( $screen->id ) && $screen->id == $this->plugin_screen_hook_suffix ){
254 $screen->add_help_tab(
255 array(
256 'id' => 'wpp_help_overview',
257 'title' => __('Overview', 'wordpress-popular-posts'),
258 'content' => "<p>" . __( "Welcome to WordPress Popular Posts' Dashboard! In this screen you will find statistics on what's popular on your site, tools to further tweak WPP to your needs, and more!", "wordpress-popular-posts" ) . "</p>"
259 )
260 );
261 $screen->add_help_tab(
262 array(
263 'id' => 'wpp_help_donate',
264 'title' => __('Like this plugin?', 'wordpress-popular-posts'),
265 'content' => '
266 <p style="text-align: center;">' . __( 'Each donation motivates me to keep releasing free stuff for the WordPress community!', 'wordpress-popular-posts' ) . '</p>
267 <form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top" style="margin: 0; padding: 0; text-align: center;">
268 <input type="hidden" name="cmd" value="_s-xclick">
269 <input type="hidden" name="hosted_button_id" value="RP9SK8KVQHRKS">
270 <input type="image" src="//www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" style="display: inline; margin: 0;">
271 <img alt="" border="0" src="//www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
272 </form>
273 <p style="text-align: center;">' . sprintf( __('You can <a href="%s" target="_blank">leave a review</a>, too!', 'wordpress-popular-posts'), 'https://wordpress.org/support/view/plugin-reviews/wordpress-popular-posts?rate=5#postform' ) . '</p>'
274 )
275 );
276
277 //$screen->remove_help_tabs();
278
279 // Help sidebar
280 $screen->set_help_sidebar(
281 sprintf(
282 __( '<p><strong>For more information:</strong></p><ul><li><a href="%1$s">Documentation</a></li><li><a href="%2$s">Support</a></li></ul>', 'wordpress-popular-posts' ),
283 "https://github.com/cabrerahector/wordpress-popular-posts/",
284 "https://wordpress.org/support/plugin/wordpress-popular-posts/"
285 )
286 );
287 }
288
289 }
290
291 /**
292 * Register the administration menu for this plugin into the WordPress Dashboard menu.
293 *
294 * @since 1.0.0
295 */
296 public function add_plugin_admin_menu() {
297
298 $this->plugin_screen_hook_suffix = add_options_page(
299 'WordPress Popular Posts',
300 'WordPress Popular Posts',
301 'manage_options',
302 'wordpress-popular-posts',
303 array( $this, 'display_plugin_admin_page' )
304 );
305
306 }
307
308 public function chart_query_fields( $fields, $options ){
309
310 if ( 'comments' == $options['order_by'] ) {
311 return "DATE(c.comment_date_gmt) AS 'date', COUNT(c.comment_post_ID) AS 'comment_count'";
312 }
313
314 return "v.view_date AS 'date', SUM(v.pageviews) AS 'pageviews'";
315
316 }
317
318 public function chart_query_table( $table, $options ){
319
320 if ( 'comments' == $options['order_by'] ) {
321 global $wpdb;
322 return "`{$wpdb->prefix}comments` c";
323 }
324
325 return $table;
326
327 }
328
329 public function chart_query_join( $join, $options ){
330
331 if ( 'comments' == $options['order_by'] ) {
332 global $wpdb;
333 return "INNER JOIN `{$wpdb->prefix}posts` p ON c.comment_post_ID = p.ID";
334 }
335
336 return $join;
337
338 }
339
340 public function chart_query_where( $where, $options ){
341
342 global $wpdb;
343
344 $now = WPP_Helper::now();
345
346 // Check if custom date range has been requested
347 $dates = null;
348
349 if ( isset( $_GET['dates']) ) {
350
351 $dates = explode( " ~ ", $_GET['dates'] );
352
353 if (
354 !is_array( $dates )
355 || empty( $dates )
356 || !WPP_Helper::is_valid_date( $dates[0] )
357 )
358 {
359 $dates = null;
360 }
361 else {
362 if (
363 !isset( $dates[1] )
364 || !WPP_Helper::is_valid_date( $dates[1] )
365 ) {
366 $dates[1] = $dates[0];
367 }
368 }
369
370 }
371
372 $where = "WHERE 1 = 1";
373
374 // Determine time range
375 switch( $options['range'] ){
376 case "last24hours":
377 case "daily":
378 $interval = "24 HOUR";
379 break;
380
381 case "today":
382 $hours = date( 'H', strtotime($now) );
383 $minutes = $hours * 60 + (int) date( 'i', strtotime($now) );
384 $interval = "{$minutes} MINUTE";
385 break;
386
387 case "last7days":
388 case "weekly":
389 $interval = "6 DAY";
390 break;
391
392 case "last30days":
393 case "monthly":
394 $interval = "29 DAY";
395 break;
396
397 case "custom":
398 $time_units = array( "MINUTE", "HOUR", "DAY" );
399 $interval = "24 HOUR";
400
401 // Valid time unit
402 if (
403 isset( $options['time_unit'] )
404 && in_array( strtoupper( $options['time_unit'] ), $time_units )
405 && isset( $options['time_quantity'] )
406 && filter_var( $options['time_quantity'], FILTER_VALIDATE_INT )
407 && $options['time_quantity'] > 0
408 ) {
409 $interval = "{$options['time_quantity']} " . strtoupper( $options['time_unit'] );
410 }
411
412 break;
413
414 default:
415 $interval = "1 DAY";
416 break;
417 }
418
419 $post_types = array_map( 'trim', explode( ',', $options['post_type'] ) );
420 $placeholders = array();
421
422 if ( empty($post_types) ) {
423 $post_types = array('post', 'page');
424 }
425
426 foreach ( $post_types as $post_type ){
427 $placeholders[] = '%s';
428 }
429
430 $where .= $wpdb->prepare(
431 " AND p.post_type IN(" . implode( ', ', $placeholders ) . ") ",
432 $post_types
433 );
434
435 // Get entries published within the specified time range
436 if ( isset( $options['freshness'] ) && $options['freshness'] ) {
437
438 if ( $dates ) {
439 $where .= " AND p.post_date BETWEEN '{$dates[0]} 00:00:00' AND '{$dates[1]} 23:59:59'";
440 }
441 else {
442 $where .= " AND p.post_date > DATE_SUB('{$now}', INTERVAL {$interval})";
443 }
444
445 }
446
447 if ( 'comments' == $options['order_by'] ) {
448
449 if ( $dates ) {
450 return $where . " AND c.comment_date_gmt BETWEEN '{$dates[0]} 00:00:00' AND '{$dates[1]} 23:59:59' AND c.comment_approved = 1 AND p.post_password = '' AND p.post_status = 'publish'";
451 }
452
453 return $where . " AND c.comment_date_gmt > DATE_SUB('{$now}', INTERVAL {$interval}) AND c.comment_approved = 1 AND p.post_password = '' AND p.post_status = 'publish'";
454 }
455
456 if ( $dates ) {
457 return $where . " AND v.view_datetime BETWEEN '{$dates[0]} 00:00:00' AND '{$dates[1]} 23:59:59' AND p.post_password = '' AND p.post_status = 'publish' ";
458 }
459
460 return $where . " AND v.view_datetime > DATE_SUB('{$now}', INTERVAL {$interval}) AND p.post_password = '' AND p.post_status = 'publish' ";
461
462 }
463
464 public function chart_query_group_by( $groupby, $options ){
465 return "GROUP BY date";
466 }
467
468 public function chart_query_order_by( $orderby, $options ){
469 return "ORDER BY date ASC";
470 }
471
472 public function chart_query_limit( $fields, $options ){
473 return "";
474 }
475
476 public function get_chart_data( $range ){
477
478 $now = new DateTime( WPP_Helper::now() );
479 $data = array(
480 'dates' => null,
481 'totals' => array(
482 'views' => 0,
483 'comments' => 0,
484 'label_summary' => '',
485 'label_date_range' => ''
486 )
487 );
488
489 // Determine time range
490 switch( $range ){
491 case "last24hours":
492 case "daily":
493 /*$start_date = $now->format('Y-m-d');
494 $end_date = $start_date;*/
495 $end_date = $now->format('Y-m-d');
496 $start_date = $now->modify('-1 day')->format('Y-m-d');
497 break;
498
499 case "today":
500 $start_date = $now->format('Y-m-d');
501 $end_date = $start_date;
502 break;
503
504 case "last7days":
505 case "weekly":
506 $end_date = $now->format('Y-m-d');
507 $start_date = $now->modify('-6 day')->format('Y-m-d');
508 break;
509
510 case "last30days":
511 case "monthly":
512 $end_date = $now->format('Y-m-d');
513 $start_date = $now->modify('-29 day')->format('Y-m-d');
514 break;
515
516 case "custom":
517 $time_units = array(
518 "MINUTE" => array("minute", "minutes"),
519 "HOUR" => array("hour", "hours"),
520 "DAY" => array("day", "days")
521 );
522 $interval = "-24 hours";
523
524 // Valid time unit
525 if (
526 isset( $this->options['stats']['time_unit'] )
527 && isset( $time_units[ strtoupper( $this->options['stats']['time_unit'] ) ] )
528 && isset( $this->options['stats']['time_quantity'] )
529 && filter_var( $this->options['stats']['time_quantity'], FILTER_VALIDATE_INT )
530 && $this->options['stats']['time_quantity'] > 0
531 ) {
532 $interval = "-{$this->options['stats']['time_quantity']} " . ( $this->options['stats']['time_quantity'] > 1 ? $time_units[ strtoupper( $this->options['stats']['time_unit'] ) ][1] : $time_units[ strtoupper( $this->options['stats']['time_unit'] ) ][0] );
533 }
534
535 $end_date = date( 'Y-m-d', strtotime( $now->format('Y-m-d H:i:s') ) );
536 $start_date = date( 'Y-m-d', strtotime( $now->modify($interval)->format('Y-m-d H:i:s') ) );
537
538 // Check if custom date range has been requested
539 $dates = null;
540
541 if ( isset( $_GET['dates']) ) {
542
543 $dates = explode( " ~ ", $_GET['dates'] );
544
545 if (
546 !is_array( $dates )
547 || empty( $dates )
548 || !WPP_Helper::is_valid_date( $dates[0] )
549 )
550 {
551 $dates = null;
552 }
553 else {
554 if (
555 !isset( $dates[1] )
556 || !WPP_Helper::is_valid_date( $dates[1] )
557 ) {
558 $dates[1] = $dates[0];
559 }
560
561 $end_date = $dates[1];
562 $start_date = $dates[0];
563 }
564
565 }
566
567 break;
568
569 default:
570 $end_date = $now->format('Y-m-d');
571 $start_date = $now->modify('-6 days')->format('Y-m-d');
572 break;
573 }
574
575 $dates = WPP_Helper::get_date_range( $start_date, $end_date );
576
577 if ( $dates ) {
578
579 for( $d = 0; $d < count($dates); $d++ ) {
580 $data['dates'][ $dates[$d] ] = array(
581 'nicename' => date_i18n( 'D d', strtotime( $dates[$d] ) ),
582 'views' => 0,
583 'comments' => 0
584 );
585 }
586
587 }
588
589 add_filter( 'wpp_query_fields', array( $this, 'chart_query_fields' ), 1, 2 );
590 add_filter( 'wpp_query_where', array( $this, 'chart_query_where' ), 1, 2 );
591 add_filter( 'wpp_query_group_by', array( $this, 'chart_query_group_by' ), 1, 2 );
592 add_filter( 'wpp_query_order_by', array( $this, 'chart_query_order_by' ), 1, 2 );
593 add_filter( 'wpp_query_limit', array( $this, 'chart_query_limit' ), 1, 2 );
594
595 $most_viewed = new WPP_query( array(
596 'post_type' => $this->options['stats']['post_type'],
597 'range' => $this->options['stats']['range'],
598 'time_unit' => $this->options['stats']['time_unit'],
599 'time_quantity' => $this->options['stats']['time_quantity'],
600 'order_by' => 'views'
601 ) );
602 $views_data = $most_viewed->get_posts();
603
604 remove_filter( 'wpp_query_fields', array( $this, 'chart_query_fields' ), 1 );
605 remove_filter( 'wpp_query_where', array( $this, 'chart_query_where' ), 1 );
606 remove_filter( 'wpp_query_group_by', array( $this, 'chart_query_group_by' ), 1 );
607 remove_filter( 'wpp_query_order_by', array( $this, 'chart_query_order_by' ), 1 );
608 remove_filter( 'wpp_query_limit', array( $this, 'chart_query_limit' ), 1 );
609
610 add_filter( 'wpp_query_fields', array( $this, 'chart_query_fields' ), 1, 2 );
611 add_filter( 'wpp_query_table', array( $this, 'chart_query_table' ), 1, 2 );
612 add_filter( 'wpp_query_join', array( $this, 'chart_query_join' ), 1, 2 );
613 add_filter( 'wpp_query_where', array( $this, 'chart_query_where' ), 1, 2 );
614 add_filter( 'wpp_query_group_by', array( $this, 'chart_query_group_by' ), 1, 2 );
615 add_filter( 'wpp_query_order_by', array( $this, 'chart_query_order_by' ), 1, 2 );
616 add_filter( 'wpp_query_limit', array( $this, 'chart_query_limit' ), 1, 2 );
617
618 $most_commented = new WPP_query( array(
619 'post_type' => $this->options['stats']['post_type'],
620 'range' => $this->options['stats']['range'],
621 'time_unit' => $this->options['stats']['time_unit'],
622 'time_quantity' => $this->options['stats']['time_quantity'],
623 'order_by' => 'comments'
624 ) );
625 $comments_data = $most_commented->get_posts();
626
627 remove_filter( 'wpp_query_fields', array( $this, 'chart_query_fields' ), 1 );
628 remove_filter( 'wpp_query_table', array( $this, 'chart_query_table' ), 1 );
629 remove_filter( 'wpp_query_join', array( $this, 'chart_query_join' ), 1 );
630 remove_filter( 'wpp_query_where', array( $this, 'chart_query_where' ), 1 );
631 remove_filter( 'wpp_query_group_by', array( $this, 'chart_query_group_by' ), 1 );
632 remove_filter( 'wpp_query_order_by', array( $this, 'chart_query_order_by' ), 1 );
633 remove_filter( 'wpp_query_limit', array( $this, 'chart_query_limit' ), 1 );
634
635 if (
636 ( is_array($views_data) && !empty($views_data) )
637 || ( is_array($comments_data) && !empty($comments_data) )
638 ) {
639
640 if ( ( is_array($views_data) && !empty($views_data) ) ) {
641 foreach( $views_data as $views ) {
642 if ( isset( $data['dates'][$views->date] ) ) {
643 $data['dates'][$views->date]['views'] = $views->pageviews;
644 $data['totals']['views'] += $views->pageviews;
645 }
646 }
647 }
648
649 if ( ( is_array($comments_data) && !empty($comments_data) ) ) {
650 foreach( $comments_data as $comments ) {
651 if ( isset( $data['dates'][$comments->date] ) ) {
652 $data['dates'][$comments->date]['comments'] = $comments->comment_count;
653 $data['totals']['comments'] += $comments->comment_count;
654 }
655 }
656 }
657
658 $data['totals']['label_summary'] = sprintf( _n( '1 view', '%s views', $data['totals']['views'], 'wordpress-popular-posts' ), '<strong>' . number_format_i18n( $data['totals']['views'] ) . '</strong>' ) . '<br style="display: none;" /> / ' . sprintf( _n( '1 comment', '%s comments', $data['totals']['comments'], 'wordpress-popular-posts' ), '<strong>' . number_format_i18n( $data['totals']['comments'] ) . '</strong>' );
659
660 $data['totals']['label_date_range'] = date_i18n( 'M, D d', strtotime( $start_date ) ) . ' &mdash; ' . date_i18n( 'M, D d', strtotime( $end_date ) );
661 }
662
663 return $data;
664
665 }
666
667 public function print_chart_script( $data, $containter_id ){
668
669 reset( $data['dates'] );
670 $start_date = key( $data['dates'] );
671 $end_date = key( end($data['dates']) );
672 reset( $data['dates'] );
673
674 $color_scheme = $this->get_admin_color_scheme();
675
676 ?>
677 <script>
678
679 if ( WPPChart.canRender() ) {
680
681 jQuery("#<?php echo $containter_id; ?> p").remove();
682
683 var wpp_chart_views_color = '<?php echo $color_scheme[2]; ?>';
684 var wpp_chart_comments_color = '<?php echo $color_scheme[3]; ?>';
685
686 var wpp_chart_data = {
687 labels: [ <?php foreach( $data['dates'] as $date => $date_data ) : echo "'" . date_i18n( 'D d', strtotime( $date ) ) . "', "; endforeach; ?>],
688 datasets: [
689 {
690 label: "<?php _e( "Comments", "wordpress-popular-posts" ); ?>",
691 data: [<?php foreach( $data['dates'] as $date => $date_data ) : echo ( isset($date_data['comments']) ? $date_data['comments'] : '0' ) . ", "; endforeach; ?>],
692 },
693 {
694 label: "<?php _e( "Views", "wordpress-popular-posts" ); ?>",
695 data: [<?php foreach( $data['dates'] as $date => $date_data ) : echo ( isset($date_data['views']) ? $date_data['views'] : '0' ) . ", "; endforeach; ?>],
696 }
697 ]
698 };
699
700 WPPChart.init( '<?php echo $containter_id; ?>' );
701 WPPChart.populate( wpp_chart_data );
702
703 }
704
705 </script>
706 <?php
707 }
708
709 public function update_chart(){
710
711 $response = array(
712 'status' => 'error'
713 );
714 $nonce = isset( $_GET['nonce'] ) ? $_GET['nonce'] : null;
715
716 if ( wp_verify_nonce( $nonce, 'wpp_admin_nonce' ) ) {
717
718 $valid_ranges = array( 'today', 'daily', 'last24hours', 'weekly', 'last7days', 'monthly', 'last30days', 'all', 'custom' );
719 $time_units = array( "MINUTE", "HOUR", "DAY" );
720
721 $range = ( isset( $_GET['range'] ) && in_array( $_GET['range'], $valid_ranges ) ) ? $_GET['range'] : 'last7days';
722 $time_quantity = ( isset( $_GET['time_quantity'] ) && filter_var( $_GET['time_quantity'], FILTER_VALIDATE_INT ) ) ? $_GET['time_quantity'] : 24;
723 $time_unit = ( isset( $_GET['time_unit'] ) && in_array( strtoupper( $_GET['time_unit'] ), $time_units ) ) ? $_GET['time_unit'] : 'hour';
724
725 $admin_options = WPP_Settings::get( 'admin_options' );
726 $admin_options['stats']['range'] = $range;
727 $admin_options['stats']['time_quantity'] = $time_quantity;
728 $admin_options['stats']['time_unit'] = $time_unit;
729 $this->options = $admin_options;
730
731 update_option( 'wpp_settings_config', $this->options );
732
733 $response = array(
734 'status' => 'ok',
735 'data' => $this->get_chart_data( $range )
736 );
737
738 }
739
740 wp_send_json( $response );
741
742 }
743
744 public function get_most_viewed(){
745
746 $args = array(
747 'range' => $this->options['stats']['range'],
748 'time_quantity' => $this->options['stats']['time_quantity'],
749 'time_unit' => $this->options['stats']['time_unit'],
750 'post_type' => $this->options['stats']['post_type'],
751 'freshness' => $this->options['stats']['freshness'],
752 'limit' => $this->options['stats']['limit'],
753 'stats_tag' => array(
754 'comment_count' => 0,
755 'date' => array(
756 'active' => 1
757 )
758 )
759 );
760 add_filter( 'wpp_query_where', array( $this, 'chart_query_where' ), 1, 2 );
761 $most_viewed = new WPP_query( $args );
762 remove_filter( 'wpp_query_where', array( $this, 'chart_query_where' ), 1 );
763 $posts = $most_viewed->get_posts();
764
765 if (
766 is_array( $posts )
767 && !empty( $posts )
768 ) {
769 ?>
770 <ol class="popular-posts-list">
771 <?php
772 foreach ( $posts as $post ) { ?>
773 <li>
774 <p>
775 <a href="<?php echo get_permalink( $post->id ); ?>"><?php echo sanitize_text_field( $post->title ); ?></a>
776 <br />
777 <span><?php printf( _n( '1 view', '%s views', $post->pageviews, 'wordpress-popular-posts' ), number_format_i18n( $post->pageviews ) ); ?></span>
778 <small> &mdash; <a href="<?php echo get_permalink( $post->id ); ?>"><?php _e("View"); ?></a> | <a href="<?php echo get_edit_post_link( $post->id ); ?>"><?php _e("Edit"); ?></a></small>
779 </p>
780 </li>
781 <?php
782 }
783 ?>
784 </ol>
785 <?php
786 }
787 else {
788 ?>
789 <p style="text-align: center;"><?php _e("Looks like traffic to your site is a little light right now. <br />Spread the word and come back later!", "wordpress-popular-posts"); ?></p>
790 <?php
791 }
792
793 if ( defined('DOING_AJAX') && DOING_AJAX ) wp_die();
794
795 }
796
797 public function get_most_commented(){
798
799 $args = array(
800 'range' => $this->options['stats']['range'],
801 'time_quantity' => $this->options['stats']['time_quantity'],
802 'time_unit' => $this->options['stats']['time_unit'],
803 'post_type' => $this->options['stats']['post_type'],
804 'freshness' => $this->options['stats']['freshness'],
805 'order_by' => 'comments',
806 'limit' => $this->options['stats']['limit'],
807 'stats_tag' => array(
808 'comment_count' => 1,
809 'views' => 0,
810 'date' => array(
811 'active' => 1
812 )
813 )
814 );
815 add_filter( 'wpp_query_where', array( $this, 'chart_query_where' ), 1, 2 );
816 $most_commented = new WPP_query( $args );
817 remove_filter( 'wpp_query_where', array( $this, 'chart_query_where' ), 1 );
818 $posts = $most_commented->get_posts();
819
820 if (
821 is_array( $posts )
822 && !empty( $posts )
823 ) {
824 ?>
825 <ol class="popular-posts-list">
826 <?php
827 foreach ( $posts as $post ) { ?>
828 <li>
829 <p>
830 <a href="<?php echo get_permalink( $post->id ); ?>"><?php echo sanitize_text_field( $post->title ); ?></a>
831 <br />
832 <span><?php printf( _n( '1 comment', '%s comments', $post->comment_count, 'wordpress-popular-posts' ), number_format_i18n( $post->comment_count ) ); ?></span>
833 <small> &mdash; <a href="<?php echo get_permalink( $post->id ); ?>"><?php _e("View"); ?></a> | <a href="<?php echo get_edit_post_link( $post->id ); ?>"><?php _e("Edit"); ?></a></small>
834 </p>
835 </li>
836 <?php
837 }
838 ?>
839 </ol>
840 <?php
841 }
842 else {
843 ?>
844 <p style="text-align: center;"><?php _e("Looks like traffic to your site is a little light right now. <br />Spread the word and come back later!", "wordpress-popular-posts"); ?></p>
845 <?php
846 }
847
848 if ( defined('DOING_AJAX') && DOING_AJAX ) wp_die();
849
850 }
851
852 /*
853 * Gets current admin color scheme.
854 *
855 * @return stdClass
856 */
857 private function get_admin_color_scheme(){
858
859 global $_wp_admin_css_colors;
860
861 if (
862 is_array( $_wp_admin_css_colors )
863 && count( $_wp_admin_css_colors )
864 ) {
865
866 $current_user = wp_get_current_user();
867 $color_scheme = get_user_option( 'admin_color', $current_user->ID );
868
869 if (
870 empty( $color_scheme )
871 || !isset( $_wp_admin_css_colors[ $color_scheme ] )
872 ) {
873 $color_scheme = 'fresh';
874 }
875
876 if ( isset($_wp_admin_css_colors[ $color_scheme ]) && isset($_wp_admin_css_colors[ $color_scheme ]->colors) ) {
877 return $_wp_admin_css_colors[ $color_scheme ]->colors;
878 }
879
880 }
881
882 // Fallback, just in case
883 return array( '#333', '#999', '#881111', '#a80000' );
884
885 }
886
887 /**
888 * Render the settings page for this plugin.
889 *
890 * @since 1.0.0
891 */
892 public function display_plugin_admin_page() {
893 include_once( plugin_dir_path(__FILE__) . 'partials/admin.php' );
894 }
895
896 /**
897 * Registers Settings link on plugin description.
898 *
899 * @since 2.3.3
900 * @param array $links
901 * @param string $file
902 * @return array
903 */
904 public function add_plugin_settings_link( $links, $file ){
905
906 $plugin_file = 'wordpress-popular-posts/wordpress-popular-posts.php';
907
908 if (
909 is_plugin_active( $plugin_file )
910 && $plugin_file == $file
911 ) {
912 $links[] = '<a href="' . admin_url( 'options-general.php?page=wordpress-popular-posts' ) . '">' . __( 'Settings' ) . '</a>';
913 }
914
915 return $links;
916
917 }
918
919 /**
920 * Register the WPP widget.
921 *
922 * @since 4.0.0
923 */
924 public function register_widget() {
925 register_widget( 'WPP_Widget' );
926 }
927
928 /**
929 * Flushes post's cached thumbnail(s) when the image is changed.
930 *
931 * @since 3.3.4
932 *
933 * @param integer $meta_id ID of the meta data field
934 * @param integer $object_id Object ID
935 * @param string $meta_key Name of meta field
936 * @param string $meta_value Value of meta field
937 */
938 public function flush_post_thumbnail( $meta_id, $object_id, $meta_key, $meta_value ) {
939
940 // User changed the featured image
941 if ( '_thumbnail_id' == $meta_key ) {
942
943 $wpp_image = WPP_Image::get_instance();
944
945 if ( $wpp_image->can_create_thumbnails() ) {
946
947 $wpp_uploads_dir = $wpp_image->get_plugin_uploads_dir();
948
949 if ( is_array($wpp_uploads_dir) && !empty($wpp_uploads_dir) ) {
950
951 $files = glob( "{$wpp_uploads_dir['basedir']}/{$object_id}-featured-*.*" ); // get all related images
952
953 if ( is_array($files) && !empty($files) ) {
954
955 foreach( $files as $file ){ // iterate files
956 if ( is_file( $file ) ) {
957 @unlink( $file ); // delete file
958 }
959 }
960
961 }
962
963 }
964
965 }
966
967 }
968
969 }
970
971 /**
972 * Truncates thumbnails cache on demand.
973 *
974 * @since 2.0.0
975 * @global object wpdb
976 */
977 public function clear_thumbnails() {
978
979 $wpp_image = WPP_Image::get_instance();
980
981 if ( $wpp_image->can_create_thumbnails() ) {
982
983 $wpp_uploads_dir = $wpp_image->get_plugin_uploads_dir();
984
985 if ( is_array($wpp_uploads_dir) && !empty($wpp_uploads_dir) ) {
986
987 $token = isset( $_POST['token'] ) ? $_POST['token'] : null;
988 $key = get_option( "wpp_rand" );
989
990 if (
991 current_user_can( 'manage_options' )
992 && ( $token === $key )
993 ) {
994
995 if ( is_dir( $wpp_uploads_dir['basedir'] ) ) {
996
997 $files = glob( "{$wpp_uploads_dir['basedir']}/*" ); // get all related images
998
999 if ( is_array($files) && !empty($files) ) {
1000
1001 foreach( $files as $file ){ // iterate files
1002 if ( is_file( $file ) ) {
1003 @unlink( $file ); // delete file
1004 }
1005 }
1006
1007 echo 1;
1008
1009 } else {
1010 echo 2;
1011 }
1012
1013 } else {
1014 echo 3;
1015 }
1016
1017 } else {
1018 echo 4;
1019 }
1020
1021 }
1022
1023 } else {
1024 echo 3;
1025 }
1026
1027 wp_die();
1028
1029 }
1030
1031 /**
1032 * Truncates data and cache on demand.
1033 *
1034 * @since 2.0.0
1035 * @global object wpdb
1036 */
1037 public function clear_data() {
1038
1039 $token = $_POST['token'];
1040 $clear = isset( $_POST['clear'] ) ? $_POST['clear'] : null;
1041 $key = get_option( "wpp_rand" );
1042
1043 if (
1044 current_user_can( 'manage_options' )
1045 && ( $token === $key )
1046 && $clear
1047 ) {
1048
1049 global $wpdb;
1050
1051 // set table name
1052 $prefix = $wpdb->prefix . "popularposts";
1053
1054 if ( $clear == 'cache' ) {
1055
1056 if ( $wpdb->get_var("SHOW TABLES LIKE '{$prefix}summary'") ) {
1057
1058 $wpdb->query("TRUNCATE TABLE {$prefix}summary;");
1059 $this->flush_transients();
1060
1061 echo 1;
1062
1063 } else {
1064 echo 2;
1065 }
1066
1067 } elseif ( $clear == 'all' ) {
1068
1069 if ( $wpdb->get_var("SHOW TABLES LIKE '{$prefix}data'") && $wpdb->get_var("SHOW TABLES LIKE '{$prefix}summary'") ) {
1070
1071 $wpdb->query("TRUNCATE TABLE {$prefix}data;");
1072 $wpdb->query("TRUNCATE TABLE {$prefix}summary;");
1073 $this->flush_transients();
1074
1075 echo 1;
1076
1077 } else {
1078 echo 2;
1079 }
1080
1081 } else {
1082 echo 3;
1083 }
1084 } else {
1085 echo 4;
1086 }
1087
1088 wp_die();
1089
1090 }
1091
1092 /**
1093 * Deletes cached (transient) data.
1094 *
1095 * @since 3.0.0
1096 * @access private
1097 */
1098 private function flush_transients() {
1099
1100 $wpp_transients = get_option( 'wpp_transients' );
1101
1102 if ( $wpp_transients && is_array( $wpp_transients ) && !empty( $wpp_transients ) ) {
1103
1104 for ( $t=0; $t < count( $wpp_transients ); $t++ )
1105 delete_transient( $wpp_transients[$t] );
1106
1107 update_option( 'wpp_transients', array() );
1108
1109 }
1110
1111 }
1112
1113 /**
1114 * Purges post from data/summary tables.
1115 *
1116 * @since 3.3.0
1117 */
1118 public function purge_post_data() {
1119
1120 if ( current_user_can( 'delete_posts' ) )
1121 add_action( 'delete_post', array( $this, 'purge_post' ) );
1122
1123 }
1124
1125 /**
1126 * Purges post from data/summary tables.
1127 *
1128 * @since 3.3.0
1129 * @global object $wpdb
1130 * @return bool
1131 */
1132 public function purge_post( $post_ID ) {
1133
1134 global $wpdb;
1135
1136 if ( $wpdb->get_var( $wpdb->prepare( "SELECT postid FROM {$wpdb->prefix}popularpostsdata WHERE postid = %d", $post_ID ) ) ) {
1137 // Delete from data table
1138 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}popularpostsdata WHERE postid = %d;", $post_ID ) );
1139 // Delete from summary table
1140 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}popularpostssummary WHERE postid = %d;", $post_ID ) );
1141 }
1142
1143 }
1144
1145 /**
1146 * Purges old post data from summary table.
1147 *
1148 * @since 2.0.0
1149 * @global object $wpdb
1150 */
1151 public function purge_data() {
1152
1153 global $wpdb;
1154
1155 $wpdb->query( "DELETE FROM {$wpdb->prefix}popularpostssummary WHERE view_date < DATE_SUB('" . WPP_Helper::curdate() . "', INTERVAL {$this->options['tools']['log']['expires_after']} DAY);" );
1156
1157 } // end purge_data
1158
1159 /**
1160 * Checks if an upgrade procedure is required.
1161 *
1162 * @since 2.4.0
1163 */
1164 public function upgrade_check(){
1165 $this->upgrade_site();
1166 } // end upgrade_check
1167
1168 /**
1169 * Upgrades single site.
1170 *
1171 * @since 4.0.7
1172 */
1173 private function upgrade_site() {
1174 // Get WPP version
1175 $wpp_ver = get_option( 'wpp_ver' );
1176
1177 if ( !$wpp_ver ) {
1178 add_option( 'wpp_ver', $this->version );
1179 } elseif ( version_compare( $wpp_ver, $this->version, '<' ) ) {
1180 $this->upgrade();
1181 }
1182 }
1183
1184 /**
1185 * On plugin upgrade, performs a number of actions: update WPP database tables structures (if needed),
1186 * run the setup wizard (if needed), and some other checks.
1187 *
1188 * @since 2.4.0
1189 * @access private
1190 * @global object wpdb
1191 */
1192 private function upgrade() {
1193
1194 $now = WPP_Helper::now();
1195
1196 // Keep the upgrade process from running too many times
1197 if ( $wpp_update = get_option('wpp_update') ) {
1198
1199 $from_time = strtotime( $wpp_update );
1200 $to_time = strtotime( $now );
1201 $difference_in_minutes = round( abs( $to_time - $from_time ) / 60, 2 );
1202
1203 // Upgrade flag is still valid, abort
1204 if ( $difference_in_minutes <= 15 )
1205 return;
1206
1207 // Upgrade flag expired, delete it and continue
1208 delete_option( 'wpp_update' );
1209
1210 }
1211
1212 add_option( 'wpp_update', $now );
1213
1214 global $wpdb;
1215
1216 // Set table name
1217 $prefix = $wpdb->prefix . "popularposts";
1218
1219 // Update data table structure and indexes
1220 $dataFields = $wpdb->get_results( "SHOW FIELDS FROM {$prefix}data;" );
1221 foreach ( $dataFields as $column ) {
1222 if ( "day" == $column->Field ) {
1223 $wpdb->query( "ALTER TABLE {$prefix}data ALTER COLUMN day DROP DEFAULT;" );
1224 }
1225
1226 if ( "last_viewed" == $column->Field ) {
1227 $wpdb->query( "ALTER TABLE {$prefix}data ALTER COLUMN last_viewed DROP DEFAULT;" );
1228 }
1229 }
1230
1231 // Update summary table structure and indexes
1232 $summaryFields = $wpdb->get_results( "SHOW FIELDS FROM {$prefix}summary;" );
1233 foreach ( $summaryFields as $column ) {
1234 if ( "last_viewed" == $column->Field ) {
1235 $wpdb->query( "ALTER TABLE {$prefix}summary CHANGE last_viewed view_datetime datetime NOT NULL, ADD KEY view_datetime (view_datetime);" );
1236 }
1237
1238 if ( "view_date" == $column->Field ) {
1239 $wpdb->query( "ALTER TABLE {$prefix}summary ALTER COLUMN view_date DROP DEFAULT;" );
1240 }
1241
1242 if ( "view_datetime" == $column->Field ) {
1243 $wpdb->query( "ALTER TABLE {$prefix}summary ALTER COLUMN view_datetime DROP DEFAULT;" );
1244 }
1245 }
1246
1247 $summaryIndexes = $wpdb->get_results( "SHOW INDEX FROM {$prefix}summary;" );
1248 foreach( $summaryIndexes as $index ) {
1249 if ( 'ID_date' == $index->Key_name ) {
1250 $wpdb->query( "ALTER TABLE {$prefix}summary DROP INDEX ID_date;" );
1251 }
1252
1253 if ( 'last_viewed' == $index->Key_name ) {
1254 $wpdb->query( "ALTER TABLE {$prefix}summary DROP INDEX last_viewed;" );
1255 }
1256 }
1257
1258 // Validate the structure of the tables, create missing tables / fields if necessary
1259 WPP_Activator::track_new_site();
1260
1261 // Check storage engine
1262 $storage_engine_data = $wpdb->get_var( "SELECT `ENGINE` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA`='{$wpdb->dbname}' AND `TABLE_NAME`='{$prefix}data';" );
1263
1264 if ( 'InnoDB' != $storage_engine_data ) {
1265 $wpdb->query( "ALTER TABLE {$prefix}data ENGINE=InnoDB;" );
1266 }
1267
1268 $storage_engine_summary = $wpdb->get_var( "SELECT `ENGINE` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA`='{$wpdb->dbname}' AND `TABLE_NAME`='{$prefix}summary';" );
1269
1270 if ( 'InnoDB' != $storage_engine_summary ) {
1271 $wpdb->query( "ALTER TABLE {$prefix}summary ENGINE=InnoDB;" );
1272 }
1273
1274 // Update WPP version
1275 update_option( 'wpp_ver', $this->version );
1276
1277 // Remove upgrade flag
1278 delete_option( 'wpp_update' );
1279
1280 } // end __upgrade
1281
1282 /**
1283 * Checks if the technical requirements are met.
1284 *
1285 * @since 2.4.0
1286 * @access private
1287 * @link http://wordpress.stackexchange.com/questions/25910/uninstall-activate-deactivate-a-plugin-typical-features-how-to/25979#25979
1288 * @global string $wp_version
1289 * @return array
1290 */
1291 private function check_requirements() {
1292
1293 global $wp_version;
1294
1295 $php_min_version = '5.3';
1296 $wp_min_version = '4.7';
1297 $php_current_version = phpversion();
1298 $errors = array();
1299
1300 if ( version_compare( $php_min_version, $php_current_version, '>' ) ) {
1301 $errors[] = sprintf(
1302 __( 'Your PHP installation is too old. WordPress Popular Posts requires at least PHP version %1$s to function correctly. Please contact your hosting provider and ask them to upgrade PHP to %1$s or higher.', 'wordpress-popular-posts' ),
1303 $php_min_version
1304 );
1305 }
1306
1307 if ( version_compare( $wp_min_version, $wp_version, '>' ) ) {
1308 $errors[] = sprintf(
1309 __( 'Your WordPress version is too old. WordPress Popular Posts requires at least WordPress version %1$s to function correctly. Please update your blog via Dashboard &gt; Update.', 'wordpress-popular-posts' ),
1310 $wp_min_version
1311 );
1312 }
1313
1314 return $errors;
1315
1316 } // end check_requirements
1317
1318 /**
1319 * Outputs error messages to wp-admin.
1320 *
1321 * @since 2.4.0
1322 */
1323 public function check_admin_notices() {
1324
1325 $errors = $this->check_requirements();
1326
1327 if ( empty($errors) )
1328 return;
1329
1330 if ( isset($_GET['activate']) )
1331 unset($_GET['activate']);
1332
1333 printf(
1334 __('<div class="notice notice-error"><p>%1$s</p><p><i>%2$s</i> has been <strong>deactivated</strong>.</p></div>', 'wordpress-popular-posts'),
1335 join( '</p><p>', $errors ),
1336 'WordPress Popular Posts'
1337 );
1338
1339 $plugin_file = 'wordpress-popular-posts/wordpress-popular-posts.php';
1340 deactivate_plugins( $plugin_file );
1341
1342 } // end check_admin_notices
1343
1344 } // End WPP_Admin class
1345