PluginProbe ʕ •ᴥ•ʔ
Post Views Counter / 1.7.6
Post Views Counter v1.7.6
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 4 months ago class-columns-modal.php 4 months ago class-columns.php 4 months ago class-counter.php 4 months ago class-crawler-detect.php 4 months ago class-cron.php 4 months ago class-dashboard.php 4 months ago class-frontend.php 4 months ago class-functions.php 4 months ago class-import.php 4 months ago class-integration-gutenberg.php 4 months ago class-integrations.php 4 months ago class-query.php 4 months ago class-settings-api.php 4 months ago class-settings-display.php 4 months ago class-settings-general.php 4 months ago class-settings-integrations.php 4 months ago class-settings-other.php 4 months ago class-settings-reports.php 4 months ago class-settings.php 4 months ago class-toolbar.php 4 months ago class-traffic-signals.php 4 months ago class-update.php 4 months ago class-widgets.php 4 months ago functions.php 4 months ago
class-settings-display.php
544 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 // any data?
365 if ( ! empty( $input['display_style'] && $input['display_style'] !== 'empty' && is_array( $input['display_style'] ) ) ) {
366 foreach ( $input['display_style'] as $value ) {
367 if ( array_key_exists( $value, $field['options'] ) )
368 $data[$value] = true;
369 }
370 }
371
372 $input['display_style'] = $data;
373
374 return $input;
375 }
376
377 /**
378 * Validate user type.
379 *
380 * @param array $input
381 * @param array $field
382 *
383 * @return array
384 */
385 public function validate_restrict_display_groups( $input, $field ) {
386 $groups = [];
387
388 if ( is_array( $input ) ) {
389 foreach ( $input as $group ) {
390 // sanitize value
391 $group = sanitize_key( $group );
392
393 if ( $group === 'robots' || $group === 'ai_bots' )
394 continue;
395
396 if ( isset( $field['options'][$group] ) )
397 $groups[] = $group;
398 }
399 }
400
401 return array_unique( $groups );
402 }
403
404 public function validate_restrict_display_roles( $input, $field ) {
405 $roles = [];
406
407 if ( is_array( $input ) ) {
408 foreach ( $input as $role ) {
409 // sanitize value
410 $role = sanitize_key( $role );
411
412 if ( isset( $field['options'][$role] ) )
413 $roles[] = $role;
414 }
415 }
416
417 return array_unique( $roles );
418 }
419
420 /**
421 * Section description: display targets.
422 *
423 * @return void
424 */
425 public function section_display_targets() {
426 echo '<p class="description">' . esc_html__( 'Choose where the counter is inserted and which content types it attaches to.', 'post-views-counter' ) . '</p>';
427 }
428
429 /**
430 * Section description: display audience.
431 *
432 * @return void
433 */
434 public function section_display_audience() {
435 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>';
436 }
437
438 /**
439 * Section description: counter appearance.
440 *
441 * @return void
442 */
443 public function section_display_appearance() {
444 echo '<p class="description">' . esc_html__( 'Adjust the label, period, icon, and formatting used when the counter is rendered.', 'post-views-counter' ) . '</p>';
445 }
446
447 /**
448 * Section description: admin interface.
449 *
450 * @return void
451 */
452 public function section_display_admin() {
453 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>';
454 }
455
456 /**
457 * Mirror the saved menu position to legacy storage.
458 *
459 * @param mixed $old_value
460 * @param mixed $value
461 * @param string $option
462 * @return void
463 */
464 public function sync_menu_position_option( $old_value, $value, $option ) {
465 if ( self::$syncing_menu_position )
466 return;
467
468 self::$syncing_menu_position = true;
469 $this->mirror_menu_position_value( $value );
470 self::$syncing_menu_position = false;
471 }
472
473 /**
474 * Mirror the saved menu position when the option is added.
475 *
476 * @param string $option
477 * @param mixed $value
478 * @return void
479 */
480 public function sync_menu_position_option_on_add( $option, $value ) {
481 if ( self::$syncing_menu_position )
482 return;
483
484 self::$syncing_menu_position = true;
485 $this->mirror_menu_position_value( $value );
486 self::$syncing_menu_position = false;
487 }
488
489 /**
490 * Update the legacy menu position value stored under "Other" settings.
491 *
492 * @param mixed $value
493 * @return void
494 */
495 private function mirror_menu_position_value( $value ) {
496 if ( ! is_array( $value ) )
497 return;
498
499 $menu_position = isset( $value['menu_position'] ) && in_array( $value['menu_position'], [ 'top', 'sub' ], true ) ? $value['menu_position'] : 'top';
500 $other_options = get_option( 'post_views_counter_settings_other', [] );
501
502 if ( ! is_array( $other_options ) )
503 $other_options = [];
504
505 if ( ! isset( $other_options['menu_position'] ) || $other_options['menu_position'] !== $menu_position ) {
506 $other_options['menu_position'] = $menu_position;
507 update_option( 'post_views_counter_settings_other', $other_options );
508 }
509
510 $this->pvc->options['other']['menu_position'] = $menu_position;
511 }
512
513 /**
514 * Sync menu position from legacy writes to "Other" settings.
515 *
516 * @param mixed $value
517 * @param mixed $old_value
518 * @return mixed
519 */
520 public function sync_menu_position_from_other( $value, $old_value ) {
521 if ( self::$syncing_menu_position || ! is_array( $value ) || ! isset( $value['menu_position'] ) )
522 return $value;
523
524 $menu_position = in_array( $value['menu_position'], [ 'top', 'sub' ], true ) ? $value['menu_position'] : 'top';
525
526 self::$syncing_menu_position = true;
527
528 $display_options = get_option( 'post_views_counter_settings_display', [] );
529
530 if ( ! is_array( $display_options ) )
531 $display_options = [];
532
533 if ( ! isset( $display_options['menu_position'] ) || $display_options['menu_position'] !== $menu_position ) {
534 $display_options['menu_position'] = $menu_position;
535 update_option( 'post_views_counter_settings_display', $display_options );
536 }
537
538 $this->pvc->options['display']['menu_position'] = $menu_position;
539
540 self::$syncing_menu_position = false;
541
542 return $value;
543 }
544 }