PluginProbe ʕ •ᴥ•ʔ
Post Views Counter / 1.7.0
Post Views Counter v1.7.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 / includes / class-settings.php
post-views-counter / includes Last commit date
class-admin.php 6 months ago class-columns.php 6 months ago class-counter.php 6 months ago class-crawler-detect.php 6 months ago class-cron.php 6 months ago class-dashboard.php 6 months ago class-frontend.php 6 months ago class-functions.php 6 months ago class-import.php 6 months ago class-integration-gutenberg.php 6 months ago class-integrations.php 6 months ago class-query.php 6 months ago class-settings-api.php 6 months ago class-settings-display.php 6 months ago class-settings-general.php 6 months ago class-settings-integrations.php 6 months ago class-settings-other.php 6 months ago class-settings-reports.php 6 months ago class-settings.php 6 months ago class-toolbar.php 6 months ago class-update.php 6 months ago class-widgets.php 6 months ago functions.php 6 months ago
class-settings.php
633 lines
1 <?php
2 // exit if accessed directly
3 if ( ! defined( 'ABSPATH' ) )
4 exit;
5
6 /**
7 * Post_Views_Counter_Settings class.
8 *
9 * @class Post_Views_Counter_Settings
10 */
11 class Post_Views_Counter_Settings {
12
13 /**
14 * @var Post_Views_Counter_Settings_General
15 */
16 public $general;
17
18 /**
19 * @var Post_Views_Counter_Settings_Display
20 */
21 public $display;
22
23 /**
24 * @var Post_Views_Counter_Settings_Reports
25 */
26 public $reports;
27
28 /**
29 * @var Post_Views_Counter_Settings_Other
30 */
31 public $other;
32
33 /**
34 * @var Post_Views_Counter_Settings_Integrations
35 */
36 public $integrations;
37
38 /**
39 * Class constructor.
40 *
41 * @return void
42 */
43 public function __construct() {
44 // actions
45 add_action( 'pvc_settings_sidebar', [ $this, 'settings_sidebar' ], 12 );
46 add_action( 'pvc_settings_form', [ $this, 'settings_form' ], 10, 4 );
47
48 // filters
49 add_filter( 'post_views_counter_settings_data', [ $this, 'settings_data' ], 1 );
50 add_filter( 'post_views_counter_settings_data', [ $this, 'settings_fields_compat' ], 2 );
51 add_filter( 'post_views_counter_settings_data', [ $this, 'settings_sections_compat' ], 99 );
52 add_filter( 'post_views_counter_settings_pages', [ $this, 'settings_page' ] );
53 add_filter( 'post_views_counter_settings_page_class', [ $this, 'settings_page_class' ] );
54 add_filter( 'pvc_plugin_status_tables', [ $this, 'register_core_tables' ] );
55
56 // instantiate page classes
57 $this->general = new Post_Views_Counter_Settings_General();
58 $this->display = new Post_Views_Counter_Settings_Display();
59 $this->reports = new Post_Views_Counter_Settings_Reports();
60 $this->integrations = new Post_Views_Counter_Settings_Integrations();
61 $this->other = new Post_Views_Counter_Settings_Other( $this );
62 }
63
64 /**
65 * Magic method to proxy method calls to page classes for backward compatibility.
66 *
67 * @param string $method
68 * @param array $args
69 *
70 * @return mixed
71 */
72 public function __call( $method, $args ) {
73 // Check if method exists in general page class
74 if ( method_exists( $this->general, $method ) ) {
75 return call_user_func_array( [ $this->general, $method ], $args );
76 }
77
78 // Check if method exists in display page class
79 if ( method_exists( $this->display, $method ) ) {
80 return call_user_func_array( [ $this->display, $method ], $args );
81 }
82
83 // Check if method exists in reports page class
84 if ( method_exists( $this->reports, $method ) ) {
85 return call_user_func_array( [ $this->reports, $method ], $args );
86 }
87
88 // Check if method exists in integrations page class
89 if ( method_exists( $this->integrations, $method ) ) {
90 return call_user_func_array( [ $this->integrations, $method ], $args );
91 }
92
93 // Check if method exists in other page class
94 if ( method_exists( $this->other, $method ) ) {
95 return call_user_func_array( [ $this->other, $method ], $args );
96 }
97
98 // Method not found
99 throw new BadMethodCallException( "Method {$method} does not exist" );
100 }
101
102 /**
103 * Add hidden inputs to redirect to valid page after changing menu position.
104 *
105 * @param string $setting
106 * @param string $page_type
107 * @param string $url_page
108 * @param string $tab_key
109 *
110 * @return void
111 */
112 public function settings_form( $setting, $page_type, $url_page, $tab_key ) {
113 // get main instance
114 $pvc = Post_Views_Counter();
115 $menu_position = $pvc->get_menu_position();
116
117 // topmenu referer
118 $topmenu = '<input type="hidden" name="_wp_http_referer" data-pvc-menu="topmenu" value="' .esc_url( admin_url( 'admin.php?page=post-views-counter' . ( $tab_key !== '' ? '&tab=' . $tab_key : '' ) ) ) . '" />';
119
120 // submenu referer
121 $submenu = '<input type="hidden" name="_wp_http_referer" data-pvc-menu="submenu" value="' .esc_url( admin_url( 'options-general.php?page=post-views-counter' . ( $tab_key !== '' ? '&tab=' . $tab_key : '' ) ) ) . '" />';
122
123 if ( $menu_position === 'sub' )
124 echo $topmenu . $submenu;
125 else
126 echo $submenu . $topmenu;
127 }
128
129 /**
130 * Display settings sidebar.
131 *
132 * @return void
133 */
134 public function settings_sidebar() {
135 // get main instance
136 $pvc = Post_Views_Counter();
137
138 if ( ! class_exists( 'Post_Views_Counter_Pro' ) ) {
139 echo '
140 <div class="post-views-sidebar">
141 <div class="post-views-credits">
142 <div class="inside">
143 <div class="inner">
144 <div class="pvc-sidebar-info">
145 <div class="pvc-sidebar-head">
146 <h3 class="pvc-sidebar-title">Get Post Views Counter Pro</h3>
147 </div>
148 <div class="pvc-sidebar-body">
149 <p><span class="pvc-icon pvc-icon-check"></span>' . __( '<b>Collect more accurate data</b> about the number of views of your site, regardless of what the user is visiting.', 'post-views-counter' ) . '</p>
150 <p><span class="pvc-icon pvc-icon-check"></span>' . __( '<b>Unlock optimization features</b> and caching plugins compatibility to speed up view count tracking.', 'post-views-counter' ) . '</p>
151 <p><span class="pvc-icon pvc-icon-check"></span>' . __( '<b>Take your insights to the next level</b> with customizable Views by Date, Post and Author reporting.', 'post-views-counter' ) . '</p>
152 <p><span class="pvc-icon pvc-icon-check"></span>' . __( '<b>Order posts by views count</b> using built-in Elementor Pro, Divi Theme and GenerateBlocks integration.', 'post-views-counter' ) . '</p>
153 </div>
154 <div class="pvc-pricing-footer">
155 <a href="https://postviewscounter.com/upgrade/?utm_source=post-views-counter-lite&utm_medium=button&utm_campaign=upgrade-to-pro" class="button button-secondary button-hero pvc-button" target="_blank">' . esc_html__( 'Upgrade to Pro', 'post-views-counter' ) . ' &rarr;</a>
156 <p>Starting from $29 per year<br />14-day money back guarantee.</p>
157 </div>
158 </div>
159 </div>
160 </div>
161 </div>
162 </div>';
163 }
164 }
165
166 /**
167 * Add settings data.
168 *
169 * @param array $settings
170 *
171 * @return array
172 */
173 public function settings_data( $settings ) {
174 // add settings
175 $settings['post-views-counter'] = [
176 'label' => __( 'Post Views Counter Settings', 'post-views-counter' ),
177 'form' => [
178 'reports' => [
179 'buttons' => false
180 ]
181 ],
182 'option_name' => [
183 'general' => 'post_views_counter_settings_general',
184 'display' => 'post_views_counter_settings_display',
185 'reports' => 'post_views_counter_settings_reports',
186 'integrations' => 'post_views_counter_settings_integrations',
187 'other' => 'post_views_counter_settings_other'
188 ],
189 'validate' => [ $this, 'validate_settings' ],
190 'sections' => array_merge(
191 $this->general->get_sections(),
192 $this->display->get_sections(),
193 $this->reports->get_sections(),
194 $this->other->get_sections(),
195 $this->integrations->get_sections()
196 ),
197 'fields' => array_merge(
198 $this->general->get_fields(),
199 $this->display->get_fields(),
200 $this->reports->get_fields(),
201 $this->other->get_fields(),
202 $this->integrations->get_fields()
203 )
204 ];
205
206 return $settings;
207 }
208
209 /**
210 * Backward compatibility for missing fields.
211 *
212 * @param array $settings
213 * @return array
214 */
215 public function settings_fields_compat( $settings ) {
216 if ( empty( $settings['post-views-counter']['fields'] ) )
217 return $settings;
218
219 $fields =& $settings['post-views-counter']['fields'];
220
221 $canonical_fields = array_merge(
222 $this->general->get_fields(),
223 $this->display->get_fields(),
224 $this->reports->get_fields(),
225 $this->other->get_fields(),
226 $this->integrations->get_fields()
227 );
228
229 $compat_fields = [
230 'data_storage',
231 'restrict_edit_views',
232 'post_views_column',
233 'count_time',
234 'caching_compatibility',
235 'counter_mode',
236 'other_count'
237 ];
238
239 $fallback_fields = [
240 'amp_support' => [
241 'tab' => 'general',
242 'title' => __( 'AMP Support', 'post-views-counter' ),
243 'section' => 'post_views_counter_general_tracking_behavior',
244 'type' => 'boolean',
245 'class' => 'pvc-pro',
246 'disabled' => true,
247 'skip_saving' => true,
248 'value' => false,
249 'label' => __( 'Enable support for Accelerated Mobile Pages.', 'post-views-counter' )
250 ]
251 ];
252
253 foreach ( $compat_fields as $field_key ) {
254 if ( empty( $fields[$field_key] ) || ! is_array( $fields[$field_key] ) ) {
255 if ( isset( $canonical_fields[$field_key] ) && is_array( $canonical_fields[$field_key] ) ) {
256 $fields[$field_key] = $canonical_fields[$field_key];
257 } else if ( isset( $fallback_fields[$field_key] ) ) {
258 $fields[$field_key] = $fallback_fields[$field_key];
259 } else {
260 $fields[$field_key] = [];
261 }
262 }
263 }
264
265 if ( empty( $fields['amp_support'] ) || ! is_array( $fields['amp_support'] ) ) {
266 $fields['amp_support'] = $fallback_fields['amp_support'];
267 }
268
269 return $settings;
270 }
271
272 /**
273 * Add settings page.
274 *
275 * @param array $pages
276 *
277 * @return array
278 */
279 public function settings_page( $pages ) {
280 // get main instance
281 $pvc = Post_Views_Counter();
282 $menu_position = $pvc->get_menu_position();
283
284 // default page
285 $pages['post-views-counter'] = [
286 'menu_slug' => 'post-views-counter',
287 'page_title' => __( 'Post Views Counter Settings', 'post-views-counter' ),
288 'menu_title' => $menu_position === 'sub' ? __( 'Post Views Counter', 'post-views-counter' ) : __( 'Post Views', 'post-views-counter' ),
289 'capability' => apply_filters( 'pvc_settings_capability', 'manage_options' ),
290 'callback' => null,
291 'tabs' => [
292 'general' => [
293 'label' => __( 'Counting', 'post-views-counter' ),
294 'option_name' => 'post_views_counter_settings_general'
295 ],
296 'display' => [
297 'label' => __( 'Display', 'post-views-counter' ),
298 'option_name' => 'post_views_counter_settings_display'
299 ],
300 'reports' => [
301 'label' => __( 'Reports', 'post-views-counter' ),
302 'option_name' => 'post_views_counter_settings_reports'
303 ],
304 'integrations' => [
305 'label' => __( 'Integrations', 'post-views-counter' ),
306 'option_name' => 'post_views_counter_settings_integrations'
307 ],
308 'other' => [
309 'label' => __( 'Other', 'post-views-counter' ),
310 'option_name' => 'post_views_counter_settings_other'
311 ]
312 ]
313 ];
314
315 // update admin title
316 add_filter( 'admin_title', [ $this, 'admin_title' ], 10, 2 );
317
318 // submenu?
319 if ( $menu_position === 'sub' ) {
320 $pages['post-views-counter']['type'] = 'settings_page';
321 // topmenu?
322 } else {
323 // highlight submenus
324 add_filter( 'submenu_file', [ $this, 'submenu_file' ], 10, 2 );
325
326 // add parameters
327 $pages['post-views-counter']['type'] = 'page';
328 $pages['post-views-counter']['icon'] = 'dashicons-chart-bar';
329 $pages['post-views-counter']['position'] = '99.301';
330
331 // add subpages
332 $pages['post-views-counter-general'] = [
333 'menu_slug' => 'post-views-counter',
334 'parent_slug' => 'post-views-counter',
335 'type' => 'subpage',
336 'page_title' => __( 'Counting', 'post-views-counter' ),
337 'menu_title' => __( 'Counting', 'post-views-counter' ),
338 'capability' => apply_filters( 'pvc_settings_capability', 'manage_options' ),
339 'callback' => null
340 ];
341
342 $pages['post-views-counter-display'] = [
343 'menu_slug' => 'post-views-counter&tab=display',
344 'parent_slug' => 'post-views-counter',
345 'type' => 'subpage',
346 'page_title' => __( 'Display', 'post-views-counter' ),
347 'menu_title' => __( 'Display', 'post-views-counter' ),
348 'capability' => apply_filters( 'pvc_settings_capability', 'manage_options' ),
349 'callback' => null
350 ];
351
352 $pages['post-views-counter-reports'] = [
353 'menu_slug' => 'post-views-counter&tab=reports',
354 'parent_slug' => 'post-views-counter',
355 'type' => 'subpage',
356 'page_title' => __( 'Reports', 'post-views-counter' ),
357 'menu_title' => __( 'Reports', 'post-views-counter' ),
358 'capability' => apply_filters( 'pvc_settings_capability', 'manage_options' ),
359 'callback' => null
360 ];
361
362 $pages['post-views-counter-integrations'] = [
363 'menu_slug' => 'post-views-counter&tab=integrations',
364 'parent_slug' => 'post-views-counter',
365 'type' => 'subpage',
366 'page_title' => __( 'Integrations', 'post-views-counter' ),
367 'menu_title' => self::mark_new( __( 'Integrations', 'post-views-counter' ) ),
368 'capability' => apply_filters( 'pvc_settings_capability', 'manage_options' ),
369 'callback' => null
370 ];
371
372 $pages['post-views-counter-other'] = [
373 'menu_slug' => 'post-views-counter&tab=other',
374 'parent_slug' => 'post-views-counter',
375 'type' => 'subpage',
376 'page_title' => __( 'Other', 'post-views-counter' ),
377 'menu_title' => __( 'Other', 'post-views-counter' ),
378 'capability' => apply_filters( 'pvc_settings_capability', 'manage_options' ),
379 'callback' => null
380 ];
381 }
382
383 return $pages;
384 }
385
386 /**
387 * Settings page CSS class(es).
388 *
389 * @param array $class
390 * @return array
391 */
392 public function settings_page_class( $class ) {
393 $is_pro = class_exists( 'Post_Views_Counter_Pro' );
394
395 if ( ! $is_pro )
396 $class[] = 'has-sidebar';
397
398 return $class;
399 }
400
401 /**
402 * Highlight submenu items.
403 *
404 * @param string|null $submenu_file
405 * @param string $parent_file
406 *
407 * @return string|null
408 */
409 public function submenu_file( $submenu_file, $parent_file ) {
410 if ( $parent_file === 'post-views-counter' ) {
411 $tab = isset( $_GET['tab'] ) ? sanitize_key( $_GET['tab'] ) : 'general';
412
413 if ( $tab !== 'general' )
414 return 'post-views-counter&tab=' . $tab;
415 }
416
417 return $submenu_file;
418 }
419
420 /**
421 * Update admin title.
422 *
423 * @global array $submenu
424 * @global string $pagenow
425 *
426 * @param string $admin_title
427 * @param string $title
428 *
429 * @return string
430 */
431 public function admin_title( $admin_title, $title ) {
432 global $submenu, $pagenow;
433
434 // get main instance
435 $pvc = Post_Views_Counter();
436 $menu_position = $pvc->get_menu_position();
437
438 if ( isset( $_GET['page'] ) && $_GET['page'] === 'post-views-counter' ) {
439 if ( $menu_position === 'sub' && $pagenow === 'options-general.php' ) {
440 // get tab
441 $tab = isset( $_GET['tab'] ) ? sanitize_key( $_GET['tab'] ) : 'general';
442
443 // get settings pages
444 $pages = $pvc->settings_api->get_pages();
445
446 if ( array_key_exists( $tab, $pages['post-views-counter']['tabs'] ) ) {
447 // update title
448 $admin_title = preg_replace( '/' . $pages['post-views-counter']['page_title'] . '/', $pages['post-views-counter']['page_title'] . ' - ' . $pages['post-views-counter']['tabs'][$tab]['label'], $admin_title, 1 );
449 }
450 } else if ( $menu_position === 'top' && get_admin_page_parent() === 'post-views-counter' && ! empty( $submenu['post-views-counter'] ) ) {
451 // get tab
452 $tab = isset( $_GET['tab'] ) ? sanitize_key( $_GET['tab'] ) : 'general';
453
454 // get settings pages
455 $pages = $pvc->settings_api->get_pages();
456
457 if ( array_key_exists( 'post-views-counter-' . $tab, $pages ) ) {
458 // update title
459 $admin_title = $pages['post-views-counter']['page_title'] . ' - ' . preg_replace( '/' . $title . '/', $pages['post-views-counter-' . $tab]['page_title'], $admin_title, 1 );
460 }
461 }
462 }
463
464 return $admin_title;
465 }
466
467 /**
468 * Validate options.
469 *
470 * @global object $wpdb
471 *
472 * @param array $input
473 *
474 * @return array
475 */
476 public function validate_settings( $input ) {
477 // check capability
478 if ( ! current_user_can( 'manage_options' ) )
479 return $input;
480
481 global $wpdb;
482
483 // get main instance
484 $pvc = Post_Views_Counter();
485
486 // use internal settings api to validate settings first
487 $input = $pvc->settings_api->validate_settings( $input );
488
489 // handle new provider-based import/analyse
490 if ( isset( $_POST['post_views_counter_import_views'] ) || isset( $_POST['post_views_counter_analyse_views'] ) ) {
491 // make sure we do not change anything in the settings
492 $input = $pvc->options['other'];
493
494 // delegate to import class
495 $result = $pvc->import->handle_manual_action( $_POST );
496
497 if ( isset( $result['message'] ) ) {
498 add_settings_error( 'pvc_' . ( isset( $_POST['post_views_counter_analyse_views'] ) ? 'analyse' : 'import' ), 'pvc_' . ( isset( $_POST['post_views_counter_analyse_views'] ) ? 'analyse' : 'import' ), $result['message'], isset( $result['type'] ) ? $result['type'] : 'updated' );
499 }
500
501 if ( isset( $result['provider_settings'] ) ) {
502 $input['import_provider_settings'] = $result['provider_settings'];
503 }
504
505 return $input;
506 // delete all post views data
507 } elseif ( isset( $_POST['post_views_counter_reset_views'] ) ) {
508 // make sure we do not change anything in the settings
509 $input = $pvc->options['other'];
510
511 if ( $wpdb->query( 'TRUNCATE TABLE ' . $wpdb->prefix . 'post_views' ) )
512 add_settings_error( 'reset_post_views', 'reset_post_views', __( 'All existing data deleted successfully.', 'post-views-counter' ), 'updated' );
513 else
514 add_settings_error( 'reset_post_views', 'reset_post_views', __( 'Error occurred. All existing data were not deleted.', 'post-views-counter' ), 'error' );
515 // save general settings
516 } elseif ( isset( $_POST['save_post_views_counter_settings_general'] ) ) {
517 $input['update_version'] = $pvc->options['general']['update_version'];
518 $input['update_notice'] = $pvc->options['general']['update_notice'];
519 $input['update_delay_date'] = $pvc->options['general']['update_delay_date'];
520 // reset general settings
521 } elseif ( isset( $_POST['reset_post_views_counter_settings_general'] ) ) {
522 $input['update_version'] = $pvc->options['general']['update_version'];
523 $input['update_notice'] = $pvc->options['general']['update_notice'];
524 $input['update_delay_date'] = $pvc->options['general']['update_delay_date'];
525 // save other settings (handle provider inputs)
526 } elseif ( isset( $_POST['save_post_views_counter_settings_other'] ) ) {
527 $input['import_provider_settings'] = $pvc->import->prepare_provider_settings_from_request( $_POST );
528
529 // keep menu position for backward compatibility with older add-ons expecting it under "other" settings
530 if ( ! isset( $input['menu_position'] ) ) {
531 $input['menu_position'] = $pvc->get_menu_position();
532 }
533 // save integrations settings
534 } elseif ( isset( $_POST['save_post_views_counter_settings_integrations'] ) ) {
535 // ensure integrations array exists
536 if ( ! isset( $input['integrations'] ) ) {
537 $input['integrations'] = [];
538 }
539
540 // get all known integrations
541 $known_integrations = array_keys( Post_Views_Counter_Integrations::get_base_integrations() );
542
543 // preserve unknown slugs from existing settings
544 $existing = $pvc->options['integrations']['integrations'];
545 foreach ( $existing as $slug => $status ) {
546 if ( ! in_array( $slug, $known_integrations, true ) ) {
547 $input['integrations'][$slug] = $status;
548 }
549 }
550
551 // set missing known integrations to false (unchecked boxes don't submit)
552 foreach ( $known_integrations as $slug ) {
553 if ( ! isset( $input['integrations'][$slug] ) ) {
554 $input['integrations'][$slug] = false;
555 }
556 }
557 }
558
559 return $input;
560 }
561
562 /**
563 * Register core PVC database tables for status checking.
564 *
565 * @param array $tables Existing table definitions
566 * @return array
567 */
568 public function register_core_tables( $tables ) {
569 $tables[] = [
570 'name' => 'post_views',
571 'label' => 'post_views'
572 ];
573
574 return $tables;
575 }
576
577 /**
578 * Backward compatibility for section IDs.
579 *
580 * @param array $settings
581 * @return array
582 */
583 public function settings_sections_compat( $settings ) {
584 if ( empty( $settings['post-views-counter']['fields'] ) )
585 return $settings;
586
587 $fields =& $settings['post-views-counter']['fields'];
588
589 $compat_sections = [
590 'technology_count' => [
591 'legacy' => 'post_views_counter_general_settings',
592 'current' => 'post_views_counter_general_tracking_targets'
593 ],
594 'post_views_column' => [
595 'legacy' => 'post_views_counter_display_settings',
596 'current' => 'post_views_counter_display_admin'
597 ],
598 'restrict_edit_views' => [
599 'legacy' => 'post_views_counter_display_settings',
600 'current' => 'post_views_counter_display_admin'
601 ],
602 'menu_position' => [
603 'legacy' => 'post_views_counter_other_management',
604 'current' => 'post_views_counter_display_admin'
605 ]
606 ];
607
608 foreach ( $compat_sections as $field => $map ) {
609 if ( empty( $fields[$field] ) )
610 continue;
611
612 if ( isset( $fields[$field]['section'] ) && $fields[$field]['section'] === $map['legacy'] )
613 $fields[$field]['section'] = $map['current'];
614 }
615
616 return $settings;
617 }
618
619 /**
620 * Mark menu item as new.
621 *
622 * @param string $text
623 * @return string
624 */
625 public static function mark_new( $text ) {
626 return sprintf(
627 '%s<span class="pvc-admin-menu-new">&nbsp;%s</span>',
628 $text,
629 __( 'NEW!', 'post-views-counter' )
630 );
631 }
632 }
633