PluginProbe ʕ •ᴥ•ʔ
Post Views Counter / 1.7.13
Post Views Counter v1.7.13
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-display.php
post-views-counter / includes Last commit date
class-admin.php 2 weeks ago class-columns-modal.php 2 weeks ago class-columns.php 2 weeks ago class-counter.php 2 weeks ago class-crawler-detect.php 2 weeks ago class-cron.php 2 weeks ago class-dashboard.php 2 weeks ago class-emails-mailer.php 2 weeks ago class-emails-period.php 2 weeks ago class-emails-query.php 2 weeks ago class-emails-scheduler.php 2 weeks ago class-emails-template.php 2 weeks ago class-emails.php 2 weeks ago class-frontend.php 2 weeks ago class-functions.php 2 weeks ago class-import.php 2 weeks ago class-integration-gutenberg.php 2 weeks ago class-integrations.php 2 weeks ago class-query.php 2 weeks ago class-settings-api.php 2 weeks ago class-settings-display.php 2 weeks ago class-settings-emails.php 2 weeks ago class-settings-general.php 2 weeks ago class-settings-integrations.php 2 weeks ago class-settings-other.php 2 weeks ago class-settings-reports.php 2 weeks ago class-settings.php 2 weeks ago class-toolbar.php 2 weeks ago class-traffic-signals.php 2 weeks ago class-update.php 2 weeks ago class-widgets.php 2 weeks ago functions.php 2 weeks ago
class-settings-display.php
552 lines
1 <?php
2 // exit if accessed directly
3 if ( ! defined( 'ABSPATH' ) )
4 exit;
5
6 /**
7 * Post_Views_Counter_Settings_Display class.
8 *
9 * @class Post_Views_Counter_Settings_Display
10 */
11 class Post_Views_Counter_Settings_Display {
12
13 private $pvc;
14 private static $syncing_menu_position = false;
15
16 /**
17 * Class constructor.
18 *
19 * @return void
20 */
21 public function __construct() {
22 $this->pvc = Post_Views_Counter();
23
24 // actions
25 add_action( 'update_option_post_views_counter_settings_display', [ $this, 'sync_menu_position_option' ], 10, 3 );
26 add_action( 'add_option_post_views_counter_settings_display', [ $this, 'sync_menu_position_option_on_add' ], 10, 2 );
27
28 // filters
29 add_filter( 'pre_update_option_post_views_counter_settings_other', [ $this, 'sync_menu_position_from_other' ], 10, 2 );
30 }
31
32 /**
33 * Get sections for display tab.
34 *
35 * @return array
36 */
37 public function get_sections() {
38 return [
39 'post_views_counter_display_appearance' => [
40 'tab' => 'display',
41 'title' => __( 'Counter Appearance', 'post-views-counter' ),
42 'callback' => [ $this, 'section_display_appearance' ],
43 ],
44 'post_views_counter_display_locations' => [
45 'tab' => 'display',
46 'title' => __( 'Display Targets', 'post-views-counter' ),
47 'callback' => [ $this, 'section_display_targets' ],
48 ],
49 'post_views_counter_display_visibility' => [
50 'tab' => 'display',
51 'title' => __( 'Display Audience', 'post-views-counter' ),
52 'callback' => [ $this, 'section_display_audience' ],
53 ],
54 'post_views_counter_display_admin' => [
55 'tab' => 'display',
56 'title' => __( 'Admin Interface', 'post-views-counter' ),
57 'callback' => [ $this, 'section_display_admin' ],
58 ]
59 ];
60 }
61
62 /**
63 * Get fields for display tab.
64 *
65 * @return array
66 */
67 public function get_fields() {
68 // get post types
69 $post_types = $this->pvc->functions->get_post_types();
70
71 // user groups
72 $groups = [
73 'users' => __( 'logged in users', 'post-views-counter' ),
74 'guests' => __( 'guests', 'post-views-counter' ),
75 'roles' => __( 'selected user roles', 'post-views-counter' )
76 ];
77
78 // get user roles
79 $user_roles = $this->pvc->functions->get_user_roles();
80
81 return [
82 'label' => [
83 'tab' => 'display',
84 'title' => __( 'Views Label', 'post-views-counter' ),
85 'section' => 'post_views_counter_display_appearance',
86 'type' => 'input',
87 'html_id' => 'pvc-label',
88 'description' => __( 'Text shown next to the view count.', 'post-views-counter' ),
89 'subclass' => 'regular-text',
90 'validate' => [ $this, 'validate_label' ],
91 'reset' => [ $this, 'reset_label' ]
92 ],
93 'display_period' => [
94 'tab' => 'display',
95 'title' => __( 'Views Period', 'post-views-counter' ),
96 'section' => 'post_views_counter_display_appearance',
97 'type' => 'select',
98 'class' => 'pvc-pro',
99 'disabled' => true,
100 'skip_saving' => true,
101 'description' => __( 'Time range used when displaying the number of views.', 'post-views-counter' ),
102 'pro_only' => true,
103 'options' => [
104 'total' => __( 'Total Views', 'post-views-counter' )
105 ]
106 ],
107 'display_style' => [
108 'tab' => 'display',
109 'title' => __( 'Display Style', 'post-views-counter' ),
110 'section' => 'post_views_counter_display_appearance',
111 'type' => 'custom',
112 'html_id' => 'pvc-display-style',
113 'description' => __( 'Choose whether to show an icon, label text, or both.', 'post-views-counter' ),
114 'callback' => [ $this, 'setting_display_style' ],
115 'validate' => [ $this, 'validate_display_style' ],
116 'options' => [
117 'icon' => __( 'Icon', 'post-views-counter' ),
118 'text' => __( 'Label', 'post-views-counter' )
119 ]
120 ],
121 'icon_class' => [
122 'tab' => 'display',
123 'title' => __( 'Icon Class', 'post-views-counter' ),
124 'section' => 'post_views_counter_display_appearance',
125 'type' => 'class',
126 'default' => '',
127 'html_id' => 'pvc-icon-class',
128 'parent' => 'pvc-display-style',
129 'logic' => [
130 'field' => 'pvc-display-style-icon',
131 'operator' => 'is',
132 'value' => 'icon'
133 ],
134 'animation' => 'slide',
135 'description' => sprintf( __( 'Enter the CSS class for the views icon. Any Dashicons class is supported.', 'post-views-counter' ), 'https://developer.wordpress.org/resource/dashicons/' ),
136 'subclass' => 'regular-text'
137 ],
138 'position' => [
139 'tab' => 'display',
140 'title' => __( 'Position', 'post-views-counter' ),
141 'section' => 'post_views_counter_display_locations',
142 'type' => 'select',
143 'html_id' => 'pvc-position',
144 'description' => sprintf( __( 'Where to insert the counter automatically. Use %s shortcode for manual placement.', 'post-views-counter' ), '<code>[post-views]</code>' ),
145 'options' => [
146 'before' => __( 'Before the content', 'post-views-counter' ),
147 'after' => __( 'After the content', 'post-views-counter' ),
148 'manual' => __( 'Manual only', 'post-views-counter' )
149 ]
150 ],
151 'post_views_column' => [
152 'tab' => 'display',
153 'title' => __( 'Admin Column', 'post-views-counter' ),
154 'section' => 'post_views_counter_display_admin',
155 'type' => 'boolean',
156 'description' => '',
157 'label' => __( 'Show a "Views" column on post and page list screens.', 'post-views-counter' )
158 ],
159 'restrict_edit_views' => [
160 'tab' => 'display',
161 'title' => __( 'Admin Edit', 'post-views-counter' ),
162 'section' => 'post_views_counter_display_admin',
163 'type' => 'boolean',
164 'description' => '',
165 'label' => __( 'Allow editing the view count on the post edit screen.', 'post-views-counter' )
166 ],
167 'dynamic_loading' => [
168 'tab' => 'display',
169 'title' => __( 'Dynamic Loading', 'post-views-counter' ),
170 'section' => 'post_views_counter_display_appearance',
171 'type' => 'boolean',
172 'class' => 'pvc-pro',
173 'disabled' => true,
174 'skip_saving' => true,
175 'value' => false,
176 'label' => __( 'Load the view count dynamically to avoid caching the displayed value.', 'post-views-counter' ),
177 'pro_only' => true
178 ],
179 'use_format' => [
180 'tab' => 'display',
181 'title' => __( 'Format Number', 'post-views-counter' ),
182 'section' => 'post_views_counter_display_appearance',
183 'type' => 'boolean',
184 'label' => __( 'Format the view count according to the site locale (uses the WordPress number_format_i18n function).', 'post-views-counter' )
185 ],
186 'taxonomies' => [
187 'tab' => 'display',
188 'title' => __( 'Taxonomies', 'post-views-counter' ),
189 'section' => 'post_views_counter_display_locations',
190 'type' => 'boolean',
191 'class' => 'pvc-pro',
192 'disabled' => true,
193 'skip_saving' => true,
194 'value' => false,
195 'label' => __( 'Display the view count on category, tag, or custom taxonomy archive pages.', 'post-views-counter' ),
196 'pro_only' => true
197 ],
198 'taxonomies_display' => [
199 'tab' => 'display',
200 'section' => 'post_views_counter_display_locations',
201 'type' => 'checkbox',
202 'class' => 'pvc-pro',
203 'description' => __( 'Select taxonomies where the view counter will be displayed.', 'post-views-counter' ), 'skip_saving' => true,
204 'options' => $this->pvc->functions->get_taxonomies( 'labels' ),
205 'disabled' => true,
206 'name' => 'post_views_counter_settings_display[taxonomies_display]',
207 'value' => $this->pvc->options['display']['taxonomies_display'],
208 'pro_only' => true,
209 'logic' => [
210 'field' => 'taxonomies',
211 'operator' => 'is',
212 'value' => 'true'
213 ],
214 'animation' => 'slide'
215 ],
216 'user_display' => [
217 'tab' => 'display',
218 'title' => __( 'Author Archives', 'post-views-counter' ),
219 'section' => 'post_views_counter_display_locations',
220 'type' => 'boolean',
221 'class' => 'pvc-pro',
222 'disabled' => true,
223 'skip_saving' => true,
224 'value' => false,
225 'label' => __( 'Display the view count on author archive pages.', 'post-views-counter' ),
226 'pro_only' => true
227 ],
228 'post_types_display' => [
229 'tab' => 'display',
230 'title' => __( 'Post Types', 'post-views-counter' ),
231 'section' => 'post_views_counter_display_locations',
232 'type' => 'checkbox',
233 'description' => __( 'Select post types where the view counter will be displayed.', 'post-views-counter' ),
234 'options' => $post_types
235 ],
236 'page_types_display' => [
237 'tab' => 'display',
238 'title' => __( 'Page Type', 'post-views-counter' ),
239 'section' => 'post_views_counter_display_locations',
240 'type' => 'checkbox',
241 'description' => __( 'Select page contexts where the view counter will be displayed.', 'post-views-counter' ),
242 'options' => apply_filters(
243 'pvc_page_types_display_options',
244 [
245 'home' => __( 'Home', 'post-views-counter' ),
246 'archive' => __( 'Archives', 'post-views-counter' ),
247 'singular' => __( 'Single posts and pages', 'post-views-counter' ),
248 'search' => __( 'Search results', 'post-views-counter' ),
249 ]
250 )
251 ],
252 'restrict_display_groups' => [
253 'tab' => 'display',
254 'title' => __( 'User Type', 'post-views-counter' ),
255 'section' => 'post_views_counter_display_visibility',
256 'type' => 'checkbox',
257 'description' => __( 'Hide the view counter for selected visitor groups.', 'post-views-counter' ),
258 'options' => $groups,
259 'name' => 'post_views_counter_settings_display[restrict_display][groups]',
260 'value' => $this->pvc->options['display']['restrict_display']['groups'],
261 'validate' => [ $this, 'validate_restrict_display_groups' ],
262 ],
263 'restrict_display_roles' => [
264 'tab' => 'display',
265 'title' => __( 'User Roles', 'post-views-counter' ),
266 'section' => 'post_views_counter_display_visibility',
267 'type' => 'checkbox',
268 'description' => __( 'Hide the view counter for selected user roles.', 'post-views-counter' ),
269 'options' => $user_roles,
270 'name' => 'post_views_counter_settings_display[restrict_display][roles]',
271 'value' => $this->pvc->options['display']['restrict_display']['roles'],
272 'logic' => [ [ 'field' => 'restrict_display_groups', 'operator' => 'contains', 'value' => 'roles' ] ],
273 'animation' => 'slide',
274 'validate' => [ $this, 'validate_restrict_display_roles' ],
275 ],
276 'toolbar_statistics' => [
277 'tab' => 'display',
278 'title' => __( 'Toolbar Chart', 'post-views-counter' ),
279 'section' => 'post_views_counter_display_admin',
280 'type' => 'boolean',
281 'description' => __( 'A views chart is shown for content types that are being counted.', 'post-views-counter' ),
282 'label' => __( 'Show a views chart in the admin toolbar.', 'post-views-counter' )
283 ],
284 'menu_position' => [
285 'tab' => 'display',
286 'title' => __( 'Menu Position', 'post-views-counter' ),
287 'section' => 'post_views_counter_display_admin',
288 'type' => 'radio', 'html_id' => 'pvc-menu-position', 'options' => [
289 'top' => __( 'Top menu', 'post-views-counter' ),
290 'sub' => __( 'Settings submenu', 'post-views-counter' )
291 ],
292 'description' => __( 'Choose where the plugin menu appears in the admin sidebar.', 'post-views-counter' ),
293 ]
294 ];
295 }
296
297 /**
298 * Validate label.
299 *
300 * @param array $input
301 * @param array $field
302 * @return array
303 */
304 public function validate_label( $input, $field ) {
305 if ( ! isset( $input ) )
306 $input = $this->pvc->defaults['display']['label'];
307
308 // use internal settings API to validate settings first
309 $input = $this->pvc->settings_api->validate_field( $input, 'input', $field );
310
311 if ( function_exists( 'icl_register_string' ) )
312 icl_register_string( 'Post Views Counter', 'Post Views Label', $input );
313
314 return $input;
315 }
316
317 /**
318 * Restore post views label to default value.
319 *
320 * @param array $default
321 * @param array $field
322 * @return array
323 */
324 public function reset_label( $default, $field ) {
325 if ( function_exists( 'icl_register_string' ) )
326 icl_register_string( 'Post Views Counter', 'Post Views Label', $default );
327
328 return $default;
329 }
330
331 /**
332 * Setting: display style.
333 *
334 * @param array $field
335 * @return string
336 */
337 public function setting_display_style( $field ) {
338 $html = '<div class="pvc-field-group pvc-checkbox-group">';
339 $html .= '<input type="hidden" name="post_views_counter_settings_display[display_style]" value="empty" />';
340
341 foreach ( $field['options'] as $key => $label ) {
342 $html .= '
343 <label><input id="pvc-display-style-' . esc_attr( $key ) . '" type="checkbox" name="post_views_counter_settings_display[display_style][]" value="' . esc_attr( $key ) . '" ' . checked( ! empty( $this->pvc->options['display']['display_style'][$key] ), true, false ) . ' />' . esc_html( $label ) . '</label> ';
344 }
345 $html .= '</div>';
346
347 return $html;
348 }
349
350 /**
351 * Validate display style.
352 *
353 * @param array $input
354 * @param array $field
355 * @return array
356 */
357 public function validate_display_style( $input, $field ) {
358 $data = [];
359
360 foreach ( $field['options'] as $value => $label ) {
361 $data[$value] = false;
362 }
363
364 if ( ! isset( $input['display_style'] ) ) {
365 $input['display_style'] = isset( $this->pvc->options['display']['display_style'] ) && is_array( $this->pvc->options['display']['display_style'] )
366 ? wp_parse_args( $this->pvc->options['display']['display_style'], $data )
367 : $data;
368
369 return $input;
370 }
371
372 // any data?
373 if ( $input['display_style'] !== 'empty' && is_array( $input['display_style'] ) ) {
374 foreach ( $input['display_style'] as $value ) {
375 if ( array_key_exists( $value, $field['options'] ) )
376 $data[$value] = true;
377 }
378 }
379
380 $input['display_style'] = $data;
381
382 return $input;
383 }
384
385 /**
386 * Validate user type.
387 *
388 * @param array $input
389 * @param array $field
390 *
391 * @return array
392 */
393 public function validate_restrict_display_groups( $input, $field ) {
394 $groups = [];
395
396 if ( is_array( $input ) ) {
397 foreach ( $input as $group ) {
398 // sanitize value
399 $group = sanitize_key( $group );
400
401 if ( $group === 'robots' || $group === 'ai_bots' )
402 continue;
403
404 if ( isset( $field['options'][$group] ) )
405 $groups[] = $group;
406 }
407 }
408
409 return array_unique( $groups );
410 }
411
412 public function validate_restrict_display_roles( $input, $field ) {
413 $roles = [];
414
415 if ( is_array( $input ) ) {
416 foreach ( $input as $role ) {
417 // sanitize value
418 $role = sanitize_key( $role );
419
420 if ( isset( $field['options'][$role] ) )
421 $roles[] = $role;
422 }
423 }
424
425 return array_unique( $roles );
426 }
427
428 /**
429 * Section description: display targets.
430 *
431 * @return void
432 */
433 public function section_display_targets() {
434 echo '<p class="description">' . esc_html__( 'Choose where the counter is inserted and which content types it attaches to.', 'post-views-counter' ) . '</p>';
435 }
436
437 /**
438 * Section description: display audience.
439 *
440 * @return void
441 */
442 public function section_display_audience() {
443 echo '<p class="description">' . esc_html__( 'Control which visitor groups can see the counter. These rules apply on top of the display targets.', 'post-views-counter' ) . '</p>';
444 }
445
446 /**
447 * Section description: counter appearance.
448 *
449 * @return void
450 */
451 public function section_display_appearance() {
452 echo '<p class="description">' . esc_html__( 'Adjust the label, period, icon, and formatting used when the counter is rendered.', 'post-views-counter' ) . '</p>';
453 }
454
455 /**
456 * Section description: admin interface.
457 *
458 * @return void
459 */
460 public function section_display_admin() {
461 echo '<p class="description">' . esc_html__( 'Control how view counts are shown and managed in WordPress admin (columns, edit permissions, toolbar chart).', 'post-views-counter' ) . '</p>';
462 }
463
464 /**
465 * Mirror the saved menu position to legacy storage.
466 *
467 * @param mixed $old_value
468 * @param mixed $value
469 * @param string $option
470 * @return void
471 */
472 public function sync_menu_position_option( $old_value, $value, $option ) {
473 if ( self::$syncing_menu_position )
474 return;
475
476 self::$syncing_menu_position = true;
477 $this->mirror_menu_position_value( $value );
478 self::$syncing_menu_position = false;
479 }
480
481 /**
482 * Mirror the saved menu position when the option is added.
483 *
484 * @param string $option
485 * @param mixed $value
486 * @return void
487 */
488 public function sync_menu_position_option_on_add( $option, $value ) {
489 if ( self::$syncing_menu_position )
490 return;
491
492 self::$syncing_menu_position = true;
493 $this->mirror_menu_position_value( $value );
494 self::$syncing_menu_position = false;
495 }
496
497 /**
498 * Update the legacy menu position value stored under "Other" settings.
499 *
500 * @param mixed $value
501 * @return void
502 */
503 private function mirror_menu_position_value( $value ) {
504 if ( ! is_array( $value ) )
505 return;
506
507 $menu_position = isset( $value['menu_position'] ) && in_array( $value['menu_position'], [ 'top', 'sub' ], true ) ? $value['menu_position'] : 'top';
508 $other_options = get_option( 'post_views_counter_settings_other', [] );
509
510 if ( ! is_array( $other_options ) )
511 $other_options = [];
512
513 if ( ! isset( $other_options['menu_position'] ) || $other_options['menu_position'] !== $menu_position ) {
514 $other_options['menu_position'] = $menu_position;
515 update_option( 'post_views_counter_settings_other', $other_options );
516 }
517
518 $this->pvc->options['other']['menu_position'] = $menu_position;
519 }
520
521 /**
522 * Sync menu position from legacy writes to "Other" settings.
523 *
524 * @param mixed $value
525 * @param mixed $old_value
526 * @return mixed
527 */
528 public function sync_menu_position_from_other( $value, $old_value ) {
529 if ( self::$syncing_menu_position || ! is_array( $value ) || ! isset( $value['menu_position'] ) )
530 return $value;
531
532 $menu_position = in_array( $value['menu_position'], [ 'top', 'sub' ], true ) ? $value['menu_position'] : 'top';
533
534 self::$syncing_menu_position = true;
535
536 $display_options = get_option( 'post_views_counter_settings_display', [] );
537
538 if ( ! is_array( $display_options ) )
539 $display_options = [];
540
541 if ( ! isset( $display_options['menu_position'] ) || $display_options['menu_position'] !== $menu_position ) {
542 $display_options['menu_position'] = $menu_position;
543 update_option( 'post_views_counter_settings_display', $display_options );
544 }
545
546 $this->pvc->options['display']['menu_position'] = $menu_position;
547
548 self::$syncing_menu_position = false;
549
550 return $value;
551 }
552 }