PluginProbe ʕ •ᴥ•ʔ
Post Views Counter / 1.5.0
Post Views Counter v1.5.0
1.7.13 1.7.12 1.7.11 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.2.0 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3 1.3.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.2 1.3.2.1 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.7.0 1.7.1 1.7.10 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9
post-views-counter / post-views-counter.php
post-views-counter Last commit date
assets 1 year ago blocks 1 year ago css 1 year ago includes 1 year ago js 1 year ago languages 1 year ago index.php 6 years ago post-views-counter.php 1 year ago readme.txt 1 year ago
post-views-counter.php
939 lines
1 <?php
2 /*
3 Plugin Name: Post Views Counter
4 Description: Post Views Counter allows you to display how many times a post, page or custom post type had been viewed in a simple, fast and reliable way.
5 Version: 1.5.0
6 Author: dFactory
7 Author URI: https://dfactory.co/
8 Plugin URI: https://postviewscounter.com/
9 License: MIT License
10 License URI: http://opensource.org/licenses/MIT
11 Text Domain: post-views-counter
12 Domain Path: /languages
13
14 Post Views Counter
15 Copyright (C) 2014-2025, Digital Factory - info@digitalfactory.pl
16
17 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24 // exit if accessed directly
25 if ( ! defined( 'ABSPATH' ) )
26 exit;
27
28 if ( ! class_exists( 'Post_Views_Counter' ) ) {
29 /**
30 * Post Views Counter final class.
31 *
32 * @class Post_Views_Counter
33 * @version 1.5.0
34 */
35 final class Post_Views_Counter {
36
37 private static $instance;
38 private $notices;
39 public $options;
40 public $defaults = [
41 'general' => [
42 'post_types_count' => [ 'post' ],
43 'taxonomies_count' => false,
44 'users_count' => false,
45 'other_count' => false,
46 'data_storage' => 'cookies',
47 'amp_support' => false,
48 'counter_mode' => 'php',
49 'post_views_column' => true,
50 'restrict_edit_views' => false,
51 'time_between_counts' => [
52 'number' => 24,
53 'type' => 'hours'
54 ],
55 'reset_counts' => [
56 'number' => 0,
57 'type' => 'days'
58 ],
59 'object_cache' => false,
60 'flush_interval' => [
61 'number' => 0,
62 'type' => 'minutes'
63 ],
64 'exclude' => [
65 'groups' => [],
66 'roles' => []
67 ],
68 'exclude_ips' => [],
69 'strict_counts' => false,
70 'cron_run' => true,
71 'cron_update' => true,
72 'update_version' => 1,
73 'update_notice' => true,
74 'update_delay_date' => 0
75 ],
76 'display' => [
77 'label' => 'Post Views:',
78 'display_period' => 'total',
79 'taxonomies_display' => [],
80 'user_display' => false,
81 'post_types_display' => [ 'post' ],
82 'page_types_display' => [ 'singular' ],
83 'restrict_display' => [
84 'groups' => [],
85 'roles' => []
86 ],
87 'position' => 'after',
88 'dynamic_loading' => false,
89 'use_format' => true,
90 'display_style' => [
91 'icon' => true,
92 'text' => true
93 ],
94 'icon_class' => 'dashicons-chart-bar',
95 'toolbar_statistics' => true
96 ],
97 'other' => [
98 'menu_position' => 'top',
99 'import_meta_key' => 'views',
100 'deactivation_delete' => false,
101 'license' => ''
102 ],
103 'version' => '1.5.0'
104 ];
105
106 // instances
107 public $counter;
108 public $crawler;
109 public $cron;
110 public $dashboard;
111 public $frontend;
112 public $functions;
113 public $settings_api;
114
115 /**
116 * Disable object cloning.
117 *
118 * @return void
119 */
120 public function __clone() {}
121
122 /**
123 * Disable unserializing of the class.
124 *
125 * @return void
126 */
127 public function __wakeup() {}
128
129 /**
130 * Main plugin instance, insures that only one instance of the class exists in memory at one time.
131 *
132 * @return object
133 */
134 public static function instance() {
135 if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Post_Views_Counter ) ) {
136 self::$instance = new Post_Views_Counter();
137
138 // short init?
139 if ( defined( 'SHORTINIT' ) && SHORTINIT ) {
140 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-counter.php' );
141 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-crawler-detect.php' );
142 include_once( POST_VIEWS_COUNTER_PATH . 'includes/functions.php' );
143
144 self::$instance->counter = new Post_Views_Counter_Counter();
145 self::$instance->crawler = new Post_Views_Counter_Crawler_Detect();
146 // regular setup
147 } else {
148 add_action( 'init', [ self::$instance, 'load_textdomain' ] );
149
150 self::$instance->includes();
151
152 // create settings API
153 self::$instance->settings_api = new Post_Views_Counter_Settings_API(
154 [
155 'object' => self::$instance,
156 'prefix' => 'post_views_counter',
157 'slug' => 'post-views-counter',
158 'domain' => 'post-views-counter',
159 'plugin' => 'Post Views Counter',
160 'plugin_url' => POST_VIEWS_COUNTER_URL
161 ]
162 );
163
164 // initialize other classes
165 self::$instance->functions = new Post_Views_Counter_Functions();
166
167 new Post_Views_Counter_Update();
168 new Post_Views_Counter_Settings();
169 new Post_Views_Counter_Admin();
170 new Post_Views_Counter_Query();
171
172 self::$instance->cron = new Post_Views_Counter_Cron();
173 self::$instance->counter = new Post_Views_Counter_Counter();
174
175 new Post_Views_Counter_Columns();
176
177 self::$instance->crawler = new Post_Views_Counter_Crawler_Detect();
178 self::$instance->frontend = new Post_Views_Counter_Frontend();
179 self::$instance->dashboard = new Post_Views_Counter_Dashboard();
180
181 new Post_Views_Counter_Widgets();
182 }
183 }
184
185 return self::$instance;
186 }
187
188 /**
189 * Setup plugin constants.
190 *
191 * @return void
192 */
193 private function define_constants() {
194 // fix plugin_basename empty $wp_plugin_paths var
195 if ( ! ( defined( 'SHORTINIT' ) && SHORTINIT ) ) {
196 define( 'POST_VIEWS_COUNTER_URL', plugins_url( '', __FILE__ ) );
197 define( 'POST_VIEWS_COUNTER_BASENAME', plugin_basename( __FILE__ ) );
198 define( 'POST_VIEWS_COUNTER_REL_PATH', dirname( POST_VIEWS_COUNTER_BASENAME ) );
199 }
200
201 define( 'POST_VIEWS_COUNTER_PATH', plugin_dir_path( __FILE__ ) );
202 }
203
204 /**
205 * Include required files.
206 *
207 * @return void
208 */
209 private function includes() {
210 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-functions.php' );
211 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-update.php' );
212 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-settings-api.php' );
213 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-settings.php' );
214 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-admin.php' );
215 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-columns.php' );
216 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-query.php' );
217 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-cron.php' );
218 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-counter.php' );
219 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-crawler-detect.php' );
220 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-frontend.php' );
221 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-dashboard.php' );
222 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-widgets.php' );
223 }
224
225 /**
226 * Class constructor.
227 *
228 * @return void
229 */
230 private function __construct() {
231 // define plugin constants
232 $this->define_constants();
233
234 // short init?
235 if ( defined( 'SHORTINIT' ) && SHORTINIT ) {
236 $this->options = [
237 'general' => array_merge( $this->defaults['general'], get_option( 'post_views_counter_settings_general', $this->defaults['general'] ) ),
238 'display' => array_merge( $this->defaults['display'], get_option( 'post_views_counter_settings_display', $this->defaults['display'] ) ),
239 'other' => array_merge( $this->defaults['other'], get_option( 'post_views_counter_settings_other', $this->defaults['other'] ) )
240 ];
241
242 return;
243 }
244
245 // activation hooks
246 register_activation_hook( __FILE__, [ $this, 'activation' ] );
247 register_deactivation_hook( __FILE__, [ $this, 'deactivation' ] );
248
249 // settings
250 $this->options = [
251 'general' => array_merge( $this->defaults['general'], get_option( 'post_views_counter_settings_general', $this->defaults['general'] ) ),
252 'display' => array_merge( $this->defaults['display'], get_option( 'post_views_counter_settings_display', $this->defaults['display'] ) ),
253 'other' => array_merge( $this->defaults['other'], get_option( 'post_views_counter_settings_other', $this->defaults['other'] ) )
254 ];
255
256 // actions
257 add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue_scripts' ] );
258 add_action( 'wp_loaded', [ $this, 'load_pluggable_functions' ] );
259 add_action( 'init', [ $this, 'register_blocks' ] );
260 add_action( 'admin_init', [ $this, 'update_notice' ] );
261 add_action( 'wp_initialize_site', [ $this, 'initialize_new_network_site' ] );
262 add_action( 'wp_ajax_pvc_dismiss_notice', [ $this, 'dismiss_notice' ] );
263
264 // filters
265 add_filter( 'plugin_action_links_' . POST_VIEWS_COUNTER_BASENAME, [ $this, 'plugin_settings_link' ] );
266 }
267
268 /**
269 * Register blocks.
270 *
271 * @global object $wp_version
272 *
273 * @return void
274 */
275 public function register_blocks() {
276 global $wp_version;
277
278 // actions
279 add_action( 'enqueue_block_editor_assets', [ $this, 'block_editor_enqueue_scripts' ] );
280
281 // filters
282 if ( version_compare( $wp_version, '5.8', '>=' ) )
283 add_filter( 'block_categories_all', [ $this, 'add_block_category' ] );
284 else
285 add_filter( 'block_categories', [ $this, 'add_block_category' ] );
286
287 add_filter( 'register_block_type_args', [ $this, 'update_block_args' ], 10, 2 );
288
289 register_block_type( __DIR__ . '/blocks/most-viewed-posts/build' );
290 register_block_type( __DIR__ . '/blocks/post-views/build' );
291 }
292
293 /**
294 * Enqueue block scripts.
295 *
296 * @global object $wp_version
297 *
298 * @return void
299 */
300 public function block_editor_enqueue_scripts() {
301 // enqueue script
302 wp_enqueue_script( 'post-views-counter-block-editor-script', POST_VIEWS_COUNTER_URL . '/js/dummy.js', [] );
303
304 $block_image_sizes = [];
305
306 // image sizes
307 $image_sizes = array_merge( [ 'full' ], get_intermediate_image_sizes() );
308
309 // sort image sizes by name, ascending
310 sort( $image_sizes, SORT_STRING );
311
312 foreach ( $image_sizes as $image_size ) {
313 $block_image_sizes[] = [
314 'label' => $image_size,
315 'value' => $image_size
316 ];
317 }
318
319 $post_types = Post_Views_Counter()->functions->get_post_types();
320
321 // prepare script data
322 $script_data = [
323 'postTypesKeys' => array_combine( array_keys( $post_types ), array_fill( 0, count( $post_types ), false ) ),
324 'postTypes' => $post_types,
325 'imageSizes' => $block_image_sizes
326 ];
327
328 // force post as enabled
329 $script_data['postTypesKeys']['post'] = true;
330
331 // prepare script data
332 $script_data['periods'] = [ [
333 'label' => __( 'Total Views', 'post-views-counter' ),
334 'value' => 'total'
335 ] ];
336
337 $script_data = apply_filters( 'pvc_block_editor_data', $script_data );
338
339 wp_add_inline_script( 'post-views-counter-block-editor-script', 'var pvcBlockEditorData = ' . wp_json_encode( $script_data ) . ";\n", 'before' );
340 }
341
342 /**
343 * Update block arguments.
344 *
345 * @param array $args
346 * @param string $block_type
347 *
348 * @return array
349 */
350 function update_block_args( $args, $block_type ) {
351 // most viewed posts block
352 if ( $block_type === 'post-views-counter/most-viewed-posts' )
353 $args['render_callback'] = [ $this, 'most_viewed_posts_render_callback' ];
354 // post views block
355 elseif ( $block_type === 'post-views-counter/post-views' )
356 $args['render_callback'] = [ $this, 'post_views_render_callback' ];
357
358 return $args;
359 }
360
361 /**
362 * Server side block renderer for most viewed posts.
363 *
364 * @param array $attributes
365 * @param string $content
366 *
367 * @return array
368 */
369 function most_viewed_posts_render_callback( $attributes, $content ) {
370 $post_types = [];
371
372 foreach ( $attributes['postTypes'] as $post_type => $enabled ) {
373 if ( $enabled === true || $enabled === 'true' )
374 $post_types[] = $post_type;
375 }
376
377 // map block attributes
378 $args = [
379 'number_of_posts' => max( 1, (int) $attributes['numberOfPosts'] ),
380 'post_type' => $post_types,
381 'period' => $attributes['period'],
382 'order' => $attributes['order'],
383 'thumbnail_size' => $attributes['thumbnailSize'],
384 'list_type' => $attributes['listType'],
385 'show_post_views' => (bool) $attributes['displayPostViews'],
386 'show_post_thumbnail' => (bool) $attributes['displayPostThumbnail'],
387 'show_post_author' => (bool) $attributes['displayPostAuthor'],
388 'show_post_excerpt' => (bool) $attributes['displayPostExcerpt'],
389 'no_posts_message' => $attributes['noPostsMessage']
390 ];
391
392 $title = trim( $attributes['title'] );
393
394 $html = '<div ' . get_block_wrapper_attributes() . '>';
395
396 if ( $title !== '' )
397 $html .= '<h2 class="block-title">' . esc_html( $title ) . '</h2>';
398
399 $html .= pvc_most_viewed_posts( $args, false );
400 $html .= '</div>';
401
402 return $html;
403 }
404
405 /**
406 * Server side block renderer for post views.
407 *
408 * @param array $attributes
409 * @param string $content
410 *
411 * @return array
412 */
413 function post_views_render_callback( $attributes, $content ) {
414 $html = '<div ' . get_block_wrapper_attributes() . '>';
415 $html .= pvc_post_views( (int) $attributes['postID'], false, $attributes['period'] );
416 $html .= '</div>';
417
418 return $html;
419 }
420
421 /**
422 * Add new blocks category.
423 *
424 * @param array $categories
425 *
426 * @return array
427 */
428 function add_block_category( $categories ) {
429 $categories[] = [
430 'slug' => 'post-views-counter',
431 'title' => 'Post Views Counter'
432 ];
433
434 return $categories;
435 }
436
437 /**
438 * Update notice.
439 *
440 * @return void
441 */
442 public function update_notice() {
443 if ( ! current_user_can( 'install_plugins' ) )
444 return;
445
446 $current_update = 2;
447
448 // get current time
449 $current_time = time();
450
451 if ( $this->options['general']['update_version'] < $current_update ) {
452 // check version, if update version is lower than plugin version, set update notice to true
453 $this->options['general'] = array_merge(
454 $this->options['general'],
455 [
456 'update_version' => $current_update,
457 'update_notice' => true
458 ]
459 );
460
461 update_option( 'post_views_counter_settings_general', $this->options['general'] );
462
463 // set activation date
464 $activation_date = get_option( 'post_views_counter_activation_date' );
465
466 if ( $activation_date === false )
467 update_option( 'post_views_counter_activation_date', $current_time );
468 }
469
470 // display current version notice
471 if ( $this->options['general']['update_notice'] === true ) {
472 // include notice js, only if needed
473 add_action( 'admin_print_scripts', [ $this, 'admin_inline_js' ], 999 );
474
475 // get activation date
476 $activation_date = get_option( 'post_views_counter_activation_date' );
477
478 if ( (int) $this->options['general']['update_delay_date'] === 0 ) {
479 if ( $activation_date + 2 * WEEK_IN_SECONDS > $current_time )
480 $this->options['general']['update_delay_date'] = $activation_date + 2 * WEEK_IN_SECONDS;
481 else
482 $this->options['general']['update_delay_date'] = $current_time;
483
484 update_option( 'post_views_counter_settings_general', $this->options['general'] );
485 }
486
487 if ( ( ! empty( $this->options['general']['update_delay_date'] ) ? (int) $this->options['general']['update_delay_date'] : $current_time ) <= $current_time )
488 $this->add_notice( sprintf( __( "Hey, you've been using <strong>Post Views Counter</strong> for more than %s.", 'post-views-counter' ), human_time_diff( $activation_date, $current_time ) ) . '<br />' . __( 'Could you please do me a BIG favor and give it a 5-star rating on WordPress to help us spread the word and boost our motivation.', 'post-views-counter' ) . '<br /><br />' . __( 'Your help is much appreciated. Thank you very much', 'post-views-counter' ) . ' ~ <strong>Bartosz Arendt</strong>, ' . __( 'founder of', 'post-views-counter' ) . ' <a href="https://postviewscounter.com/" target="_blank">Post Views Counter</a>.' . '<br /><br />' . '<a href="https://wordpress.org/support/plugin/post-views-counter/reviews/?filter=5#new-post" class="pvc-dismissible-notice" target="_blank" rel="noopener">' . __( 'Ok, you deserve it', 'post-views-counter' ) . '</a><br /><a href="#" class="pvc-dismissible-notice pvc-delay-notice" rel="noopener">' . __( 'Nope, maybe later', 'post-views-counter' ) . '</a><br /><a href="#" class="pvc-dismissible-notice" rel="noopener">' . __( 'I already did', 'post-views-counter' ) . '</a>', 'notice notice-info is-dismissible pvc-notice' );
489 }
490 }
491
492 /**
493 * Add admin notices.
494 *
495 * @param string $html Notice HTML
496 * @param string $status Notice status
497 * @param bool $paragraph Whether to use paragraph
498 * @param bool $network
499 *
500 * @return void
501 */
502 public function add_notice( $html = '', $status = 'error', $paragraph = true, $network = false ) {
503 $this->notices[] = [
504 'html' => $html,
505 'status' => $status,
506 'paragraph' => $paragraph
507 ];
508
509 add_action( 'admin_notices', [ $this, 'display_notice' ] );
510
511 if ( $network )
512 add_action( 'network_admin_notices', [ $this, 'display_notice' ] );
513 }
514
515 /**
516 * Print admin notices.
517 *
518 * @return void
519 */
520 public function display_notice() {
521 $allowed_html = array_merge(
522 wp_kses_allowed_html( 'post' ),
523 [
524 'input' => [
525 'type' => true,
526 'name' => true,
527 'class' => true,
528 'value' => true
529 ],
530 'form' => [
531 'action' => true,
532 'method' => true
533 ]
534 ]
535 );
536
537 foreach ( $this->notices as $notice ) {
538 echo '
539 <div class="' . esc_attr( $notice['status'] ) . '">
540 ' . ( $notice['paragraph'] ? '<p>' : '' ) . '
541 ' . wp_kses( $notice['html'], $allowed_html ) . '
542 ' . ( $notice['paragraph'] ? '</p>' : '' ) . '
543 </div>';
544 }
545 }
546
547 /**
548 * Print admin scripts.
549 *
550 * @return void
551 */
552 public function admin_inline_js() {
553 if ( ! current_user_can( 'install_plugins' ) )
554 return;
555
556 // register and enqueue styles
557 wp_register_script( 'pvc-notices', false );
558 wp_enqueue_script( 'pvc-notices' );
559
560 // add styles
561 wp_add_inline_script( 'pvc-notices', "
562 ( function( $ ) {
563 // ready event
564 $( function() {
565 // save dismiss state
566 $( '.pvc-notice.is-dismissible' ).on( 'click', '.notice-dismiss, .pvc-dismissible-notice', function( e ) {
567 if ( e.currentTarget.target !== '_blank' )
568 e.preventDefault();
569
570 var notice_action = 'hide';
571
572 if ( e.currentTarget.classList.contains( 'pvc-delay-notice' ) )
573 notice_action = 'delay';
574
575 $.post( ajaxurl, {
576 action: 'pvc_dismiss_notice',
577 notice_action: notice_action,
578 url: '" . esc_url_raw( admin_url( 'admin-ajax.php' ) ) . "',
579 nonce: '" . esc_attr( wp_create_nonce( 'pvc_dismiss_notice' ) ) . "'
580 } );
581
582 $( e.delegateTarget ).slideUp( 'fast' );
583 } );
584 } );
585 } )( jQuery );
586 ", 'after' );
587 }
588
589 /**
590 * Dismiss notice.
591 *
592 * @return void
593 */
594 public function dismiss_notice() {
595 if ( ! current_user_can( 'install_plugins' ) )
596 return;
597
598 if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], 'pvc_dismiss_notice' ) ) {
599 $notice_action = empty( $_REQUEST['notice_action'] ) || $_REQUEST['notice_action'] === 'hide' ? 'hide' : sanitize_text_field( $_REQUEST['notice_action'] );
600
601 switch ( $notice_action ) {
602 // delay notice
603 case 'delay':
604 // set delay period to 1 week from now
605 $this->options['general'] = array_merge(
606 $this->options['general'],
607 [
608 'update_delay_date' => time() + 2 * WEEK_IN_SECONDS
609 ]
610 );
611 update_option( 'post_views_counter_settings_general', $this->options['general'] );
612 break;
613
614 // hide notice
615 default:
616 $this->options['general'] = array_merge(
617 $this->options['general'],
618 [
619 'update_notice' => false
620 ]
621 );
622 $this->options['general'] = array_merge(
623 $this->options['general'],
624 [
625 'update_delay_date' => 0
626 ]
627 );
628
629 update_option( 'post_views_counter_settings_general', $this->options['general'] );
630 }
631 }
632
633 exit;
634 }
635
636 /**
637 * Plugin activation.
638 *
639 * @global object $wpdb
640 *
641 * @param bool $network
642 *
643 * @return void
644 */
645 public function activation( $network ) {
646 // network activation?
647 if ( is_multisite() && $network ) {
648 global $wpdb;
649
650 // get all available sites
651 $blogs_ids = $wpdb->get_col( 'SELECT blog_id FROM ' . $wpdb->blogs );
652
653 foreach ( $blogs_ids as $blog_id ) {
654 // change to another site
655 switch_to_blog( (int) $blog_id );
656
657 // run current site activation process
658 $this->activate_site();
659
660 restore_current_blog();
661 }
662 } else
663 $this->activate_site();
664 }
665
666 /**
667 * Single site activation.
668 *
669 * @global object $wpdb
670 * @global string $charset_collate
671 *
672 * @return void
673 */
674 public function activate_site() {
675 global $wpdb, $charset_collate;
676
677 // required for dbdelta
678 require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
679
680 // create post views table
681 dbDelta( '
682 CREATE TABLE IF NOT EXISTS ' . $wpdb->prefix . 'post_views (
683 `id` bigint unsigned NOT NULL,
684 `type` tinyint(1) unsigned NOT NULL,
685 `period` varchar(8) NOT NULL,
686 `count` bigint unsigned NOT NULL,
687 PRIMARY KEY (type, period, id),
688 UNIQUE INDEX id_type_period_count (id, type, period, count) USING BTREE,
689 INDEX type_period_count (type, period, count) USING BTREE
690 ) ' . $charset_collate . ';'
691 );
692
693 // add default options
694 add_option( 'post_views_counter_settings_general', $this->defaults['general'], null, false );
695 add_option( 'post_views_counter_settings_display', $this->defaults['display'], null, false );
696 add_option( 'post_views_counter_settings_other', $this->defaults['other'], null, false );
697 add_option( 'post_views_counter_version', $this->defaults['version'], null, false );
698 }
699
700 /**
701 * Plugin deactivation.
702 *
703 * @global object $wpdb
704 *
705 * @param bool $network
706 *
707 * @return void
708 */
709 public function deactivation( $network ) {
710 // network deactivation?
711 if ( is_multisite() && $network ) {
712 global $wpdb;
713
714 // get all available sites
715 $blogs_ids = $wpdb->get_col( 'SELECT blog_id FROM ' . $wpdb->blogs );
716
717 foreach ( $blogs_ids as $blog_id ) {
718 // change to another site
719 switch_to_blog( (int) $blog_id );
720
721 // run current site deactivation process
722 $this->deactivate_site( true );
723
724 restore_current_blog();
725 }
726 } else
727 $this->deactivate_site();
728 }
729
730 /**
731 * Single site deactivation.
732 *
733 * @global object $wpdb
734 *
735 * @param bool $multi
736 *
737 * @return void
738 */
739 public function deactivate_site( $multi = false ) {
740 if ( $multi === true ) {
741 $options = get_option( 'post_views_counter_settings_other' );
742 $check = $options['deactivation_delete'];
743 } else
744 $check = $this->options['other']['deactivation_delete'];
745
746 // delete options if needed
747 if ( $check ) {
748 // delete options
749 delete_option( 'post_views_counter_settings_general' );
750 delete_option( 'post_views_counter_settings_display' );
751 delete_option( 'post_views_counter_settings_other' );
752 delete_option( 'post_views_counter_activation_date' );
753 delete_option( 'post_views_counter_version' );
754
755 // delete transients
756 delete_transient( 'post_views_counter_ip_cache' );
757
758 global $wpdb;
759
760 // delete table from database
761 $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'post_views' );
762 }
763
764 // remove schedule
765 wp_clear_scheduled_hook( 'pvc_reset_counts' );
766
767 remove_action( 'pvc_reset_counts', [ $this->cron, 'reset_counts' ] );
768 }
769
770 /**
771 * Initialize new network site.
772 *
773 * @param object $site
774 *
775 * @return void
776 */
777 public function initialize_new_network_site( $site ) {
778 if ( is_multisite() ) {
779 // change to another site
780 switch_to_blog( $site->blog_id );
781
782 // run current site activation process
783 $this->activate_site();
784
785 restore_current_blog();
786 }
787 }
788
789 /**
790 * Load text domain.
791 *
792 * @return void
793 */
794 public function load_textdomain() {
795 load_plugin_textdomain( 'post-views-counter', false, POST_VIEWS_COUNTER_REL_PATH . '/languages/' );
796 }
797
798 /**
799 * Load pluggable template functions.
800 *
801 * @return void
802 */
803 public function load_pluggable_functions() {
804 include_once( POST_VIEWS_COUNTER_PATH . 'includes/functions.php' );
805 }
806
807 /**
808 * Enqueue admin scripts and styles.
809 *
810 * @global string $post_type
811 * @global string $wp_version
812 *
813 * @param string $page
814 *
815 * @return void
816 */
817 public function admin_enqueue_scripts( $page ) {
818 global $post_type;
819 global $wp_version;
820
821 // register styles
822 wp_register_style( 'pvc-admin', POST_VIEWS_COUNTER_URL . '/css/admin.min.css', [], $this->defaults['version'] );
823
824 // register scripts
825 wp_register_script( 'pvc-admin-settings', POST_VIEWS_COUNTER_URL . '/js/admin-settings.js', [ 'jquery' ], $this->defaults['version'] );
826 wp_register_script( 'pvc-admin-post', POST_VIEWS_COUNTER_URL . '/js/admin-post.js', [ 'jquery' ], $this->defaults['version'] );
827 wp_register_script( 'pvc-admin-quick-edit', POST_VIEWS_COUNTER_URL . '/js/admin-quick-edit.js', [ 'jquery' ], $this->defaults['version'] );
828
829 // load on pvc settings page
830 if ( in_array( $page, [ 'toplevel_page_post-views-counter', 'settings_page_post-views-counter' ], true ) ) {
831 wp_enqueue_script( 'pvc-admin-settings' );
832
833 // prepare script data
834 $script_data = [
835 'resetToDefaults' => esc_html__( 'Are you sure you want to reset these settings to defaults?', 'post-views-counter' ),
836 'resetViews' => esc_html__( 'Are you sure you want to delete all existing data?', 'post-views-counter' )
837 ];
838
839 wp_add_inline_script( 'pvc-admin-settings', 'var pvcArgsSettings = ' . wp_json_encode( $script_data ) . ";\n", 'before' );
840
841 wp_enqueue_style( 'pvc-admin' );
842 // load on single post page
843 } elseif ( $page === 'post.php' || $page === 'post-new.php' ) {
844 $post_types = Post_Views_Counter()->options['general']['post_types_count'];
845
846 if ( ! in_array( $post_type, (array) $post_types ) )
847 return;
848
849 wp_enqueue_style( 'pvc-admin' );
850 wp_enqueue_script( 'pvc-admin-post' );
851 // edit post
852 } elseif ( $page === 'edit.php' ) {
853 $post_types = Post_Views_Counter()->options['general']['post_types_count'];
854
855 if ( ! in_array( $post_type, (array) $post_types ) )
856 return;
857
858 wp_enqueue_style( 'pvc-admin' );
859
860 // woocommerce
861 if ( get_post_type() !== 'product' ) {
862 wp_enqueue_script( 'pvc-admin-quick-edit' );
863
864 // prepare script data
865 $script_data = [
866 'nonce' => wp_create_nonce( 'pvc_save_bulk_post_views' ),
867 'wpVersion59' => version_compare( $wp_version, '5.9', '>=' )
868 ];
869
870 wp_add_inline_script( 'pvc-admin-quick-edit', 'var pvcArgsQuickEdit = ' . wp_json_encode( $script_data ) . ";\n", 'before' );
871 }
872 // widgets
873 } elseif ( $page === 'widgets.php' )
874 wp_enqueue_script( 'pvc-admin-widgets', POST_VIEWS_COUNTER_URL . '/js/admin-widgets.js', [ 'jquery' ], $this->defaults['version'] );
875 // media
876 elseif ( $page === 'upload.php' )
877 wp_enqueue_style( 'pvc-admin' );
878
879 // register and enqueue styles
880 wp_register_style( 'pvc-pro-style', false );
881 wp_enqueue_style( 'pvc-pro-style' );
882
883 // add styles
884 wp_add_inline_style( 'pvc-pro-style', '
885 .post-views-counter-settings tr.pvc-pro th:after, .nav-tab-wrapper a.nav-tab.nav-tab-disabled.pvc-pro:after, .post-views-counter-settings tr.pvc-pro-extended label[for="post_views_counter_general_counter_mode_ajax"]:after {
886 content: \'PRO\';
887 display: inline;
888 background-color: #ffc107;
889 color: white;
890 padding: 2px 4px;
891 text-align: center;
892 border-radius: 4px;
893 margin-left: 4px;
894 font-weight: bold;
895 font-size: 11px;
896 }' );
897 }
898
899 /**
900 * Add link to Settings page.
901 *
902 * @param array $links
903 *
904 * @return array
905 */
906 public function plugin_settings_link( $links ) {
907 if ( ! current_user_can( 'manage_options' ) )
908 return $links;
909
910 // submenu?
911 if ( $this->options['other']['menu_position'] === 'sub' )
912 $url = admin_url( 'options-general.php?page=post-views-counter' );
913 // topmenu?
914 else
915 $url = admin_url( 'admin.php?page=post-views-counter' );
916
917 array_unshift( $links, sprintf( '<a href="%s">%s</a>', esc_url_raw( $url ), esc_html__( 'Settings', 'post-views-counter' ) ) );
918
919 return $links;
920 }
921 }
922 }
923
924 /**
925 * Initialize Post Views Counter.
926 *
927 * @return object
928 */
929 function Post_Views_Counter() {
930 static $instance;
931
932 // first call to instance() initializes the plugin
933 if ( $instance === null || ! ( $instance instanceof Post_Views_Counter ) )
934 $instance = Post_Views_Counter::instance();
935
936 return $instance;
937 }
938
939 Post_Views_Counter();