PluginProbe ʕ •ᴥ•ʔ
Post Views Counter / 1.3.8
Post Views Counter v1.3.8
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 4 years ago css 4 years ago includes 4 years ago js 4 years ago languages 4 years ago index.php 6 years ago post-views-counter.php 4 years ago readme.txt 4 years ago
post-views-counter.php
666 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.3.8
6 Author: Digital Factory
7 Author URI: http://www.dfactory.eu/
8 Plugin URI: http://www.dfactory.eu/plugins/post-views-counter/
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-2021, 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 /**
31 * Post Views Counter final class.
32 *
33 * @class Post_Views_Counter
34 * @version 1.3.8
35 */
36 final class Post_Views_Counter {
37
38 private static $instance;
39 public $options;
40 public $defaults = [
41 'general' => [
42 'post_types_count' => [ 'post' ],
43 'counter_mode' => 'php',
44 'post_views_column' => true,
45 'restrict_edit_views' => false,
46 'time_between_counts' => [
47 'number' => 24,
48 'type' => 'hours'
49 ],
50 'reset_counts' => [
51 'number' => 30,
52 'type' => 'days'
53 ],
54 'flush_interval' => [
55 'number' => 0,
56 'type' => 'minutes'
57 ],
58 'exclude' => [
59 'groups' => [],
60 'roles' => []
61 ],
62 'exclude_ips' => [],
63 'strict_counts' => false,
64 'deactivation_delete' => false,
65 'cron_run' => true,
66 'cron_update' => true,
67 'update_version' => 1,
68 'update_notice' => true,
69 'update_delay_date' => 0
70 ],
71 'display' => [
72 'label' => 'Post Views:',
73 'post_types_display' => [ 'post' ],
74 'page_types_display' => [ 'singular' ],
75 'restrict_display' => [
76 'groups' => [],
77 'roles' => []
78 ],
79 'position' => 'after',
80 'display_style' => [
81 'icon' => true,
82 'text' => true
83 ],
84 'icon_class' => 'dashicons-chart-bar',
85 'toolbar_statistics' => true
86 ],
87 'version' => '1.3.8'
88 ];
89
90 /**
91 * Disable object cloning.
92 *
93 * @return void
94 */
95 public function __clone() {}
96
97 /**
98 * Disable unserializing of the class.
99 *
100 * @return void
101 */
102 public function __wakeup() {}
103
104 /**
105 * Main plugin instance, insures that only one instance of the plugin exists in memory at one time.
106 *
107 * @return object
108 */
109 public static function instance() {
110 if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Post_Views_Counter ) ) {
111 self::$instance = new Post_Views_Counter;
112 self::$instance->define_constants();
113
114 add_action( 'plugins_loaded', [ self::$instance, 'load_textdomain' ] );
115
116 self::$instance->includes();
117
118 // create settings API
119 self::$instance->settings_api = new Post_Views_Counter_Settings_API(
120 [
121 'object' => self::$instance,
122 'prefix' => 'post_views_counter',
123 'slug' => 'post-views-counter',
124 'domain' => 'post-views-counter',
125 'plugin' => 'Post Views Counter',
126 'plugin_url' => 'POST_VIEWS_COUNTER_URL'
127 ]
128 );
129
130 self::$instance->functions = new Post_Views_Counter_Functions();
131 self::$instance->update = new Post_Views_Counter_Update();
132 self::$instance->settings = new Post_Views_Counter_Settings();
133 self::$instance->admin = new Post_Views_Counter_Admin();
134 self::$instance->query = new Post_Views_Counter_Query();
135 self::$instance->cron = new Post_Views_Counter_Cron();
136 self::$instance->counter = new Post_Views_Counter_Counter();
137 self::$instance->columns = new Post_Views_Counter_Columns();
138 self::$instance->crawler_detect = new Post_Views_Counter_Crawler_Detect();
139 self::$instance->frontend = new Post_Views_Counter_Frontend();
140 self::$instance->dashboard = new Post_Views_Counter_Dashboard();
141 self::$instance->widgets = new Post_Views_Counter_Widgets();
142 }
143
144 return self::$instance;
145 }
146
147 /**
148 * Setup plugin constants.
149 *
150 * @return void
151 */
152 private function define_constants() {
153 define( 'POST_VIEWS_COUNTER_URL', plugins_url( '', __FILE__ ) );
154 define( 'POST_VIEWS_COUNTER_REL_PATH', dirname( plugin_basename( __FILE__ ) ) . '/' );
155 define( 'POST_VIEWS_COUNTER_PATH', plugin_dir_path( __FILE__ ) );
156 }
157
158 /**
159 * Include required files.
160 *
161 * @return void
162 */
163 private function includes() {
164 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-functions.php' );
165 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-update.php' );
166 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-settings-api.php' );
167 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-settings.php' );
168 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-admin.php' );
169 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-columns.php' );
170 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-query.php' );
171 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-cron.php' );
172 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-counter.php' );
173 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-crawler-detect.php' );
174 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-frontend.php' );
175 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-dashboard.php' );
176 include_once( POST_VIEWS_COUNTER_PATH . 'includes/class-widgets.php' );
177 }
178
179 /**
180 * Class constructor.
181 *
182 * @return void
183 */
184 public function __construct() {
185 register_activation_hook( __FILE__, [ $this, 'multisite_activation' ] );
186 register_deactivation_hook( __FILE__, [ $this, 'multisite_deactivation' ] );
187
188 // settings
189 $this->options = [
190 'general' => array_merge( $this->defaults['general'], get_option( 'post_views_counter_settings_general', $this->defaults['general'] ) ),
191 'display' => array_merge( $this->defaults['display'], get_option( 'post_views_counter_settings_display', $this->defaults['display'] ) )
192 ];
193
194 // actions
195 add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue_scripts' ] );
196 add_action( 'wp_loaded', [ $this, 'load_pluggable_functions' ], 10 );
197 add_action( 'admin_init', [ $this, 'update_notice' ] );
198 add_action( 'wp_ajax_pvc_dismiss_notice', [ $this, 'dismiss_notice' ] );
199
200 // filters
201 add_filter( 'plugin_row_meta', [ $this, 'plugin_row_meta' ], 10, 2 );
202 add_filter( 'plugin_action_links', [ $this, 'plugin_action_links' ], 10, 2 );
203 }
204
205 /**
206 * Update notice.
207 *
208 * @return void
209 */
210 public function update_notice() {
211 if ( ! current_user_can( 'install_plugins' ) )
212 return;
213
214 $current_update = 2;
215
216 // get current time
217 $current_time = time();
218
219 if ( $this->options['general']['update_version'] < $current_update ) {
220 // check version, if update version is lower than plugin version, set update notice to true
221 $this->options['general'] = array_merge(
222 $this->options['general'],
223 [
224 'update_version' => $current_update,
225 'update_notice' => true
226 ]
227 );
228
229 update_option( 'post_views_counter_settings_general', $this->options['general'] );
230
231 // set activation date
232 $activation_date = get_option( 'post_views_counter_activation_date' );
233
234 if ( $activation_date === false )
235 update_option( 'post_views_counter_activation_date', $current_time );
236 }
237
238 // display current version notice
239 if ( $this->options['general']['update_notice'] === true ) {
240 // include notice js, only if needed
241 add_action( 'admin_print_scripts', [ $this, 'admin_inline_js' ], 999 );
242
243 // get activation date
244 $activation_date = get_option( 'post_views_counter_activation_date' );
245
246 if ( (int) $this->options['general']['update_delay_date'] === 0 ) {
247 if ( $activation_date + 1209600 > $current_time )
248 $this->options['general']['update_delay_date'] = $activation_date + 1209600;
249 else
250 $this->options['general']['update_delay_date'] = $current_time;
251
252 update_option( 'post_views_counter_settings_general', $this->options['general'] );
253 }
254
255 if ( ( ! empty( $this->options['general']['update_delay_date'] ) ? (int) $this->options['general']['update_delay_date'] : $current_time ) <= $current_time )
256 $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>, ' . sprintf( __( 'founder of <a href="%s" target="_blank">dFactory</a> plugins.', 'post-views-counter' ), 'https://dfactory.eu/' ) . '<br /><br />' . sprintf( __( '<a href="%s" class="pvc-dismissible-notice" target="_blank" rel="noopener">Ok, you deserve it</a><br /><a href="javascript:void(0);" class="pvc-dismissible-notice pvc-delay-notice" rel="noopener">Nope, maybe later</a><br /><a href="javascript:void(0);" class="pvc-dismissible-notice" rel="noopener">I already did</a>', 'post-views-counter' ), 'https://wordpress.org/support/plugin/post-views-counter/reviews/?filter=5#new-post' ), 'notice notice-info is-dismissible pvc-notice' );
257 }
258 }
259
260 /**
261 * Add admin notices.
262 *
263 * @param string $html
264 * @param string $status
265 * @param bool $paragraph
266 * @return void
267 */
268 public function add_notice( $html = '', $status = 'error', $paragraph = true ) {
269 $this->notices[] = [
270 'html' => $html,
271 'status' => $status,
272 'paragraph' => $paragraph
273 ];
274
275 add_action( 'admin_notices', [ $this, 'display_notice' ] );
276 }
277
278 /**
279 * Print admin notices.
280 *
281 * @return void
282 */
283 public function display_notice() {
284 foreach( $this->notices as $notice ) {
285 echo '
286 <div class="' . $notice['status'] . '">
287 ' . ( $notice['paragraph'] ? '<p>' : '' ) . '
288 ' . $notice['html'] . '
289 ' . ( $notice['paragraph'] ? '</p>' : '' ) . '
290 </div>';
291 }
292 }
293
294 /**
295 * Print admin scripts.
296 *
297 * @return void
298 */
299 public function admin_inline_js() {
300 if ( ! current_user_can( 'install_plugins' ) )
301 return;
302 ?>
303 <script type="text/javascript">
304 ( function ( $ ) {
305 $( document ).ready( function () {
306 // save dismiss state
307 $( '.pvc-notice.is-dismissible' ).on( 'click', '.notice-dismiss, .pvc-dismissible-notice', function ( e ) {
308 var notice_action = 'hide';
309
310 if ( $( e.currentTarget ).hasClass( 'pvc-delay-notice' ) ) {
311 notice_action = 'delay'
312 }
313
314 $.post( ajaxurl, {
315 action: 'pvc_dismiss_notice',
316 notice_action: notice_action,
317 url: '<?php echo admin_url( 'admin-ajax.php' ); ?>',
318 nonce: '<?php echo wp_create_nonce( 'pvc_dismiss_notice' ); ?>'
319 } );
320
321 $( e.delegateTarget ).slideUp( 'fast' );
322 } );
323 } );
324 } )( jQuery );
325 </script>
326 <?php
327 }
328
329 /**
330 * Dismiss notice.
331 *
332 * @return void
333 */
334 public function dismiss_notice() {
335 if ( ! current_user_can( 'install_plugins' ) )
336 return;
337
338 if ( wp_verify_nonce( esc_attr( $_REQUEST['nonce'] ), 'pvc_dismiss_notice' ) ) {
339 $notice_action = empty( $_REQUEST['notice_action'] ) || $_REQUEST['notice_action'] === 'hide' ? 'hide' : esc_attr( $_REQUEST['notice_action'] );
340
341 switch ( $notice_action ) {
342 // delay notice
343 case 'delay':
344 // set delay period to 1 week from now
345 $this->options['general'] = array_merge(
346 $this->options['general'],
347 [
348 'update_delay_date' => time() + 1209600
349 ]
350 );
351 update_option( 'post_views_counter_settings_general', $this->options['general'] );
352 break;
353
354 // hide notice
355 default:
356 $this->options['general'] = array_merge(
357 $this->options['general'],
358 [
359 'update_notice' => false
360 ]
361 );
362 $this->options['general'] = array_merge(
363 $this->options['general'],
364 [
365 'update_delay_date' => 0
366 ]
367 );
368
369 update_option( 'post_views_counter_settings_general', $this->options['general'] );
370 }
371 }
372
373 exit;
374 }
375
376 /**
377 * Multisite activation.
378 *
379 * @global object $wpdb
380 * @param bool $networkwide
381 * @return void
382 */
383 public function multisite_activation( $networkwide ) {
384 if ( is_multisite() && $networkwide ) {
385 global $wpdb;
386
387 $activated_blogs = [];
388 $current_blog_id = $wpdb->blogid;
389 $blogs_ids = $wpdb->get_col( $wpdb->prepare( 'SELECT blog_id FROM ' . $wpdb->blogs, '' ) );
390
391 foreach ( $blogs_ids as $blog_id ) {
392 switch_to_blog( $blog_id );
393 $this->activate_single();
394 $activated_blogs[] = (int) $blog_id;
395 }
396
397 switch_to_blog( $current_blog_id );
398 update_site_option( 'post_views_counter_activated_blogs', $activated_blogs, [] );
399 } else
400 $this->activate_single();
401 }
402
403 /**
404 * Single site activation.
405 *
406 * @global array $wp_roles
407 * @return void
408 */
409 public function activate_single() {
410 global $wpdb, $charset_collate;
411
412 // required for dbdelta
413 require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
414
415 // create post views table
416 dbDelta( '
417 CREATE TABLE IF NOT EXISTS ' . $wpdb->prefix . 'post_views (
418 `id` bigint unsigned NOT NULL,
419 `type` tinyint(1) unsigned NOT NULL,
420 `period` varchar(8) NOT NULL,
421 `count` bigint unsigned NOT NULL,
422 PRIMARY KEY (type, period, id),
423 UNIQUE INDEX id_type_period_count (id, type, period, count) USING BTREE,
424 INDEX type_period_count (type, period, count) USING BTREE
425 ) ' . $charset_collate . ';'
426 );
427
428 // add default options
429 add_option( 'post_views_counter_settings_general', $this->defaults['general'], '', 'no' );
430 add_option( 'post_views_counter_settings_display', $this->defaults['display'], '', 'no' );
431 add_option( 'post_views_counter_version', $this->defaults['version'], '', 'no' );
432
433 // schedule cache flush
434 $this->schedule_cache_flush();
435 }
436
437 /**
438 * Multisite deactivation.
439 *
440 * @global $wpdb
441 * @param bool $networkwide
442 * @return void
443 */
444 public function multisite_deactivation( $networkwide ) {
445 if ( is_multisite() && $networkwide ) {
446 global $wpdb;
447
448 $current_blog_id = $wpdb->blogid;
449 $blogs_ids = $wpdb->get_col( $wpdb->prepare( 'SELECT blog_id FROM ' . $wpdb->blogs, '' ) );
450
451 if ( ! ( $activated_blogs = get_site_option( 'post_views_counter_activated_blogs', false, false ) ) )
452 $activated_blogs = [];
453
454 foreach ( $blogs_ids as $blog_id ) {
455 switch_to_blog( $blog_id );
456 $this->deactivate_single( true );
457
458 if ( in_array( (int) $blog_id, $activated_blogs, true ) )
459 unset( $activated_blogs[array_search( $blog_id, $activated_blogs )] );
460 }
461
462 switch_to_blog( $current_blog_id );
463 update_site_option( 'post_views_counter_activated_blogs', $activated_blogs );
464 } else
465 $this->deactivate_single();
466 }
467
468 /**
469 * Single site deactivation.
470 *
471 * @global $wpdb
472 * @param bool $multi
473 * @return void
474 */
475 public function deactivate_single( $multi = false ) {
476 if ( $multi ) {
477 $options = get_option( 'post_views_counter_settings_general' );
478 $check = $options['deactivation_delete'];
479 } else
480 $check = $this->options['general']['deactivation_delete'];
481
482 // delete default options
483 if ( $check ) {
484 delete_option( 'post_views_counter_settings_general' );
485 delete_option( 'post_views_counter_settings_display' );
486
487 global $wpdb;
488
489 // delete table from database
490 $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'post_views' );
491 }
492
493 // remove schedule
494 wp_clear_scheduled_hook( 'pvc_reset_counts' );
495 remove_action( 'pvc_reset_counts', [ Post_Views_Counter()->cron, 'reset_counts' ] );
496
497 $this->remove_cache_flush();
498 }
499
500 /**
501 * Schedule cache flushing if it's not already scheduled.
502 *
503 * @param bool $forced
504 * @return void
505 */
506 public function schedule_cache_flush( $forced = true ) {
507 if ( $forced || ! wp_next_scheduled( 'pvc_flush_cached_counts' ) )
508 wp_schedule_event( time(), 'post_views_counter_flush_interval', 'pvc_flush_cached_counts' );
509 }
510
511 /**
512 * Remove scheduled cache flush and the corresponding action.
513 *
514 * @return void
515 */
516 public function remove_cache_flush() {
517 wp_clear_scheduled_hook( 'pvc_flush_cached_counts' );
518 remove_action( 'pvc_flush_cached_counts', [ Post_Views_Counter()->cron, 'flush_cached_counts' ] );
519 }
520
521 /**
522 * Load text domain.
523 *
524 * @return void
525 */
526 public function load_textdomain() {
527 load_plugin_textdomain( 'post-views-counter', false, POST_VIEWS_COUNTER_REL_PATH . 'languages/' );
528 }
529
530 /**
531 * Load pluggable template functions.
532 *
533 * @return void
534 */
535 public function load_pluggable_functions() {
536 include_once( POST_VIEWS_COUNTER_PATH . 'includes/functions.php' );
537 }
538
539 /**
540 * Enqueue admin scripts and styles.
541 *
542 * @global string $post_type
543 * @param string $page.
544 * @return void
545 */
546 public function admin_enqueue_scripts( $page ) {
547 wp_register_style( 'pvc-admin', POST_VIEWS_COUNTER_URL . '/css/admin.css' );
548
549 wp_register_script( 'pvc-admin-settings', POST_VIEWS_COUNTER_URL . '/js/admin-settings.js', [ 'jquery' ], $this->defaults['version'] );
550 wp_register_script( 'pvc-admin-post', POST_VIEWS_COUNTER_URL . '/js/admin-post.js', [ 'jquery' ], $this->defaults['version'] );
551 wp_register_script( 'pvc-admin-quick-edit', POST_VIEWS_COUNTER_URL . '/js/admin-quick-edit.js', [ 'jquery', 'inline-edit-post' ], $this->defaults['version'] );
552
553 // load on PVC settings page
554 if ( $page === 'settings_page_post-views-counter' ) {
555 wp_enqueue_script( 'pvc-admin-settings' );
556
557 wp_localize_script(
558 'pvc-admin-settings', 'pvcArgsSettings', [
559 'resetToDefaults' => __( 'Are you sure you want to reset these settings to defaults?', 'post-views-counter' ),
560 'resetViews' => __( 'Are you sure you want to delete all existing data?', 'post-views-counter' )
561 ]
562 );
563
564 wp_enqueue_style( 'pvc-admin' );
565
566 // load on single post page
567 } elseif ( $page === 'post.php' || $page === 'post-new.php' ) {
568 $post_types = Post_Views_Counter()->options['general']['post_types_count'];
569
570 global $post_type;
571
572 if ( ! in_array( $post_type, (array) $post_types ) )
573 return;
574
575 wp_enqueue_style( 'pvc-admin' );
576 wp_enqueue_script( 'pvc-admin-post' );
577 // edit post
578 } elseif ( $page === 'edit.php' ) {
579 $post_types = Post_Views_Counter()->options['general']['post_types_count'];
580
581 global $post_type;
582
583 if ( ! in_array( $post_type, (array) $post_types ) )
584 return;
585
586 wp_enqueue_style( 'pvc-admin' );
587
588 // woocommerce
589 if ( get_post_type() !== 'product' )
590 wp_enqueue_script( 'pvc-admin-quick-edit' );
591 // widgets
592 } elseif ( $page === 'widgets.php' )
593 wp_enqueue_script( 'pvc-admin-widgets', POST_VIEWS_COUNTER_URL . '/js/admin-widgets.js', [ 'jquery' ], $this->defaults['version'] );
594 // media
595 elseif ( $page === 'upload.php' )
596 wp_enqueue_style( 'pvc-admin' );
597 }
598
599 /**
600 * Add links to plugin support forum.
601 *
602 * @param array $links
603 * @param string $file
604 * @return array
605 */
606 public function plugin_row_meta( $links, $file ) {
607 if ( ! current_user_can( 'install_plugins' ) )
608 return $links;
609
610 $plugin = plugin_basename( __FILE__ );
611
612 if ( $file == $plugin ) {
613 return array_merge(
614 $links,
615 [
616 sprintf( '<a href="http://www.dfactory.eu/support/forum/post-views-counter/" target="_blank">%s</a>', __( 'Support', 'post-views-counter' ) )
617 ]
618 );
619 }
620
621 return $links;
622 }
623
624 /**
625 * Add link to settings page.
626 *
627 * @staticvar string $plugin
628 * @param array $links
629 * @param string $file
630 * @return array
631 */
632 public function plugin_action_links( $links, $file ) {
633 if ( ! is_admin() || ! current_user_can( 'manage_options' ) )
634 return $links;
635
636 static $plugin;
637
638 $plugin = plugin_basename( __FILE__ );
639
640 if ( $file == $plugin ) {
641 $settings_link = sprintf( '<a href="%s">%s</a>', admin_url( 'options-general.php' ) . '?page=post-views-counter', __( 'Settings', 'post-views-counter' ) );
642
643 array_unshift( $links, $settings_link );
644 }
645
646 return $links;
647 }
648 }
649 }
650
651 /**
652 * Initialise Post Views Counter.
653 *
654 * @return object
655 */
656 function Post_Views_Counter() {
657 static $instance;
658
659 // first call to instance() initializes the plugin
660 if ( $instance === null || ! ( $instance instanceof Post_Views_Counter ) )
661 $instance = Post_Views_Counter::instance();
662
663 return $instance;
664 }
665
666 Post_Views_Counter();