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