PluginProbe
WebberZone Top 10 — Popular Posts / 4.5.2
WebberZone Top 10 — Popular Posts v4.5.2
4.5.2 4.5.1 4.5.0 4.4.3 4.4.2 4.4.1 4.4.0 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 trunk 1.0 1.0.1 1.1 1.2 1.3 1.4 1.4.1 1.5 1.5.1 1.5.2 1.5.3 1.6 All 118 releases
top-10 / includes / admin / class-settings.php

class-settings.php in WebberZone Top 10 — Popular Posts 4.5.2, at includes/admin/class-settings.php

2,205 lines 86.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Settings class.
4 *
5 * @package WebberZone\Top_Ten\Admin
6 */
7
8 namespace WebberZone\Top_Ten\Admin;
9
10 use WebberZone\Top_Ten\Admin\Settings\Settings_API;
11 use WebberZone\Top_Ten\Admin\Settings\Settings_Sanitize;
12 use WebberZone\Top_Ten\Frontend\Display;
13 use WebberZone\Top_Ten\Frontend\Media_Handler;
14 use WebberZone\Top_Ten\Util\Helpers;
15 use WebberZone\Top_Ten\Util\Hook_Registry;
16
17 // If this file is called directly, abort.
18 if ( ! defined( 'WPINC' ) ) {
19 die;
20 }
21
22 /**
23 * Class to register the settings.
24 *
25 * @since 3.3.0
26 */
27 class Settings {
28
29
30 /**
31 * Settings API.
32 *
33 * @since 3.3.0
34 *
35 * @var Settings_API Settings API.
36 */
37 public $settings_api;
38
39 /**
40 * Statistics table.
41 *
42 * @since 3.3.0
43 *
44 * @var object Statistics table.
45 */
46 public $statistics;
47
48 /**
49 * Prefix which is used for creating the unique filters and actions.
50 *
51 * @since 3.3.0
52 *
53 * @var string Prefix.
54 */
55 public static $prefix = 'tptn';
56
57 /**
58 * Settings Key.
59 *
60 * @since 3.3.0
61 *
62 * @var string Settings Key.
63 */
64 public $settings_key = 'tptn_settings';
65
66 /**
67 * The slug name to refer to this menu by (should be unique for this menu).
68 *
69 * @since 3.3.0
70 *
71 * @var string Menu slug.
72 */
73 public $menu_slug = 'tptn_options_page';
74
75 /**
76 * Main constructor class.
77 *
78 * @since 3.3.0
79 */
80 public function __construct() {
81 Hook_Registry::add_action( 'admin_menu', array( $this, 'initialise_settings' ) );
82 Hook_Registry::add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 11, 2 );
83 Hook_Registry::add_filter( 'plugin_action_links_' . plugin_basename( TOP_TEN_PLUGIN_FILE ), array( $this, 'plugin_actions_links' ) );
84 Hook_Registry::add_filter( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ), 99 );
85 Hook_Registry::add_filter( self::$prefix . '_settings_sanitize', array( $this, 'change_settings_on_save' ), 99 );
86 Hook_Registry::add_filter( self::$prefix . '_after_setting_output', array( $this, 'display_admin_thumbnail' ), 10, 2 );
87 Hook_Registry::add_filter( self::$prefix . '_setting_field_description', array( $this, 'reset_default_thumb_setting' ), 10, 2 );
88 Hook_Registry::add_filter( self::$prefix . '_settings_page_header', array( $this, 'settings_page_header' ) );
89 Hook_Registry::add_filter( self::$prefix . '_after_setting_output', array( $this, 'after_setting_output' ), 10, 2 );
90 Hook_Registry::add_action( self::$prefix . '_settings_form_buttons', array( $this, 'add_wizard_button' ) );
91
92 Hook_Registry::add_action( 'wp_ajax_nopriv_' . self::$prefix . '_taxonomy_search_tom_select', array( __CLASS__, 'taxonomy_search_tom_select' ) );
93 Hook_Registry::add_action( 'wp_ajax_' . self::$prefix . '_taxonomy_search_tom_select', array( __CLASS__, 'taxonomy_search_tom_select' ) );
94 }
95
96 /**
97 * Initialise the settings API.
98 *
99 * @since 3.3.0
100 */
101 public function initialise_settings() {
102 $props = array(
103 'default_tab' => 'features',
104 'help_sidebar' => $this->get_help_sidebar(),
105 'help_tabs' => $this->get_help_tabs(),
106 'admin_footer_text' => $this->get_admin_footer_text(),
107 'menus' => $this->get_menus(),
108 'version' => TOP_TEN_VERSION,
109 );
110
111 $args = array(
112 'props' => $props,
113 'translation_strings' => $this->get_translation_strings(),
114 'settings_sections' => $this->get_settings_sections(),
115 'registered_settings' => $this->get_registered_settings(),
116 'upgraded_settings' => array(),
117 );
118
119 $this->settings_api = new Settings_API( $this->settings_key, self::$prefix, $args );
120 }
121
122 /**
123 * Array containing the settings' sections.
124 *
125 * @since 1.8.0
126 *
127 * @return array Settings array
128 */
129 public function get_translation_strings() {
130 $strings = array(
131 'page_header' => esc_html__( 'Top 10 Settings', 'top-10' ),
132 'reset_message' => esc_html__( 'Settings have been reset to their default values. Reload this page to view the updated settings.', 'top-10' ),
133 'success_message' => esc_html__( 'Settings updated.', 'top-10' ),
134 'save_changes' => esc_html__( 'Save Changes', 'top-10' ),
135 'reset_settings' => esc_html__( 'Reset all settings', 'top-10' ),
136 'reset_button_confirm' => esc_html__( 'Do you really want to reset all these settings to their default values?', 'top-10' ),
137 'modified_field' => esc_html__( 'Modified from default setting', 'top-10' ),
138 'modified_legend' => esc_html__( 'Setting modified from its default value', 'top-10' ),
139 'default_label' => esc_html__( 'Default', 'top-10' ),
140 'default_none' => esc_html__( 'None', 'top-10' ),
141 'repeater_move_up' => esc_html__( 'Move item up', 'top-10' ),
142 'repeater_move_down' => esc_html__( 'Move item down', 'top-10' ),
143 'repeater_remove_item' => esc_html__( 'Remove item', 'top-10' ),
144 );
145
146 /**
147 * Filter the array containing the settings' sections.
148 *
149 * @since 1.8.0
150 *
151 * @param array $strings Translation strings.
152 */
153 return apply_filters( self::$prefix . '_translation_strings', $strings );
154 }
155
156 /**
157 * Get the admin menus.
158 *
159 * @return array Admin menus.
160 */
161 public function get_menus() {
162 $menus = array();
163
164 // Settings menu.
165 $menus[] = array(
166 'settings_page' => true,
167 'type' => 'submenu',
168 'parent_slug' => 'tptn_dashboard',
169 'page_title' => esc_html__( 'Top 10 Settings', 'top-10' ),
170 'menu_title' => esc_html__( 'Settings', 'top-10' ),
171 'menu_slug' => $this->menu_slug,
172 );
173
174 return $menus;
175 }
176
177 /**
178 * Array containing the settings' sections.
179 *
180 * @since 3.3.0
181 *
182 * @return array Settings array
183 */
184 public static function get_settings_sections() {
185 $settings_sections = array(
186 'features' => __( 'Features', 'top-10' ),
187 'general' => __( 'General', 'top-10' ),
188 'counter' => __( 'Counter/Tracker', 'top-10' ),
189 'list' => __( 'Posts list', 'top-10' ),
190 'thumbnail' => __( 'Thumbnail', 'top-10' ),
191 'styles' => __( 'Styles', 'top-10' ),
192 'maintenance' => __( 'Maintenance', 'top-10' ),
193 'feed' => __( 'Feed', 'top-10' ),
194 );
195
196 /**
197 * Filter the array containing the settings' sections.
198 *
199 * @since 1.2.0
200 *
201 * @param array $settings_sections Settings array
202 */
203 return apply_filters( self::$prefix . '_settings_sections', $settings_sections );
204 }
205
206
207 /**
208 * Raw defaults for every registered setting, keyed by option ID.
209 *
210 * Must exactly match what `tptn_settings_defaults()` computes from
211 * {@see self::get_registered_settings()}, but without building the full
212 * (translated) field definitions. Values are pre-normalized: checkboxes are
213 * `1`/`0`, not `true`/`false`. Computed defaults (e.g. `thumb_default`) are
214 * represented as `''` here since their real value cannot be known statically.
215 *
216 * @since 4.4.2
217 *
218 * @return array<string, mixed> Default value for every option ID.
219 */
220 public static function get_defaults() {
221 return array(
222 'features_header' => '',
223 'features_display_header' => '',
224 'features_performance_header' => '',
225 'enable_blocks' => 1,
226 'enable_legacy_widgets' => 1,
227 'enable_rest_api' => 1,
228 'enable_query_block' => 1,
229 'enable_featured_image_block' => 1,
230 'enable_popular_posts_pro_block' => 1,
231 'enable_page_builders' => 1,
232 'enable_popular_authors' => 1,
233 'features_tracking_header' => '',
234 'enable_feed' => 1,
235 'enable_fast_tracker' => 1,
236 'enable_sitewide_tracking' => 1,
237 'features_data_header' => '',
238 'enable_daily_table_rollup' => 1,
239 'features_admin_header' => '',
240 'features_api_header' => '',
241 'enable_pro_dashboard_widgets' => 1,
242 'enable_lazy_load' => 1,
243 'cache' => 1,
244 'cache_time' => HOUR_IN_SECONDS,
245 'lazy_load' => 0,
246 'uninstall_clean_options' => 1,
247 'uninstall_clean_tables' => 0,
248 'show_credit' => 0,
249 'admin_header' => '',
250 'show_metabox' => 1,
251 'show_metabox_admins' => 0,
252 'pv_in_admin' => 1,
253 'admin_column_post_types' => 'post,page',
254 'show_count_non_admins' => 1,
255 'show_dashboard_to_roles' => 'administrator',
256 'show_admin_bar' => 1,
257 'query_optimization' => '',
258 'max_execution_time' => 3000,
259 'counter_header' => '',
260 'add_to' => 'single,page',
261 'count_disp_form' => 'Visited %totalcount% times, %dailycount% visit(s) today',
262 'count_disp_form_zero' => 'No visits yet',
263 'number_format_count' => 1,
264 'number_format_style' => 'full',
265 'daily_midnight' => 1,
266 'range_desc' => '',
267 'daily_range' => '1',
268 'hour_range' => '0',
269 'dynamic_post_count' => 0,
270 'exclude_on_post_ids' => '',
271 'tracker_header' => '',
272 'trackers' => 'overall,daily',
273 'tracker_type' => 'query_based',
274 'tracking_method' => 'funnel',
275 'tracker_all_pages' => 0,
276 'track_sitewide' => 0,
277 'track_feed_views' => 0,
278 'track_users' => 'authors,editors,admins',
279 'logged_in' => 1,
280 'no_bots' => 0,
281 'debug_mode' => 0,
282 'use_global_settings' => 0,
283 'limit' => '10',
284 'how_old' => '0',
285 'post_types' => 'post',
286 'exclusion_header' => '',
287 'exclude_front' => 0,
288 'exclude_current_post' => 0,
289 'exclude_post_ids' => '',
290 'exclude_cat_slugs' => '',
291 'exclude_categories' => '',
292 'exclude_terms_include_parents' => 'none',
293 'exclude_on_cat_slugs' => '',
294 'customize_output_header' => '',
295 'title' => '<h3>Popular posts:</h3>',
296 'title_daily' => '<h3>Currently trending:</h3>',
297 'blank_output' => 'blank',
298 'blank_output_text' => 'No top posts yet',
299 'show_excerpt' => 0,
300 'excerpt_length' => '10',
301 'show_date' => 0,
302 'show_author' => 0,
303 'disp_list_count' => 0,
304 'show_ratings' => '',
305 'title_length' => '60',
306 'link_new_window' => 0,
307 'link_nofollow' => 0,
308 'html_wrapper_header' => '',
309 'before_list' => '<ul>',
310 'after_list' => '</ul>',
311 'before_list_item' => '<li>',
312 'after_list_item' => '</li>',
313 'post_thumb_op' => 'text_only',
314 'thumb_size' => 'tptn_thumbnail',
315 'thumb_width' => '250',
316 'thumb_height' => '250',
317 'thumb_crop' => 1,
318 'thumb_create_sizes' => 1,
319 'thumb_html' => 'html',
320 'thumb_meta' => 'post-image',
321 'scan_images' => 1,
322 'thumb_default_show' => 1,
323 'thumb_default' => '',
324 'tptn_styles' => 'no_style',
325 'custom_css' => '',
326 'cron_on' => 0,
327 'maintenance_days' => 0,
328 'log_retention_days' => 0,
329 'cron_range_desc' => '',
330 'cron_hour' => '0',
331 'cron_min' => '0',
332 'cron_recurrence' => 'weekly',
333 'feed_permalink_overall' => 'popular-posts',
334 'feed_permalink_daily' => 'popular-posts-daily',
335 'feed_limit' => '10',
336 'feed_daily_range' => '1',
337 'feed_category_slugs' => '',
338 'wzpa_number' => 10,
339 'wzpa_daily_range' => 1,
340 'wzpa_hour_range' => 0,
341 'wzpa_optioncount' => 0,
342 'wzpa_show_postcount' => 0,
343 'wzpa_show_fullname' => 0,
344 'wzpa_show_avatar' => 0,
345 'wzpa_exclude_admin' => 0,
346 'wzpa_post_type' => 'post',
347 'wzpa_cache' => 1,
348 'wzpa_styles_desc' => '',
349 'wzpa_styles' => 'no_style',
350 'wzpa_html_wrapper_header' => '',
351 'wzpa_before_list' => '<ul>',
352 'wzpa_after_list' => '</ul>',
353 'wzpa_before_list_item' => '<li>',
354 'wzpa_after_list_item' => '</li>',
355 );
356 }
357
358 /**
359 * Retrieve the array of plugin settings
360 *
361 * @since 3.3.0
362 *
363 * @return array Settings array
364 */
365 public static function get_registered_settings() {
366 $settings = array();
367 $sections = self::get_settings_sections();
368
369 foreach ( $sections as $section => $value ) {
370 $method_name = 'settings_' . $section;
371 if ( method_exists( __CLASS__, $method_name ) ) {
372 $settings[ $section ] = self::$method_name();
373 }
374 }
375
376 /**
377 * Filters the settings array
378 *
379 * @since 1.2.0
380 *
381 * @param array $tptn_setings Settings array
382 */
383 return apply_filters( self::$prefix . '_registered_settings', $settings );
384 }
385
386 /**
387 * Retrieve the array of General settings
388 *
389 * @since 3.3.0
390 *
391 * @return array General settings array
392 */
393 public static function settings_general() {
394 $settings = array(
395 'cache' => array(
396 'id' => 'cache',
397 'name' => esc_html__( 'Enable cache', 'top-10' ),
398 'desc' => esc_html__( 'If activated, Top 10 will use the Transients API to cache the popular posts output for the time specified below.', 'top-10' ),
399 'type' => 'checkbox',
400 'default' => true,
401 ),
402 'cache_time' => array(
403 'id' => 'cache_time',
404 'name' => esc_html__( 'Time to cache', 'top-10' ),
405 'desc' => esc_html__( 'Enter the number of seconds to cache the output.', 'top-10' ),
406 'type' => 'text',
407 'default' => HOUR_IN_SECONDS,
408 ),
409 'lazy_load' => array(
410 'id' => 'lazy_load',
411 'name' => esc_html__( 'Lazy load popular posts', 'top-10' ),
412 'desc' => esc_html__( 'Load popular posts using JavaScript when the list is about to enter the viewport. This speeds up initial page loads and lets full-page caches serve fresh lists. Search engines may not index links loaded this way. Applies to content, shortcodes, widgets and the Popular Posts block. Use lazy_load="0" in the shortcode or block attributes to disable it per instance. Not applied on feeds or AMP pages.', 'top-10' ),
413 'type' => 'checkbox',
414 'default' => false,
415 'pro' => true,
416 ),
417 'uninstall_clean_options' => array(
418 'id' => 'uninstall_clean_options',
419 'name' => esc_html__( 'Delete options on uninstall', 'top-10' ),
420 'desc' => esc_html__( 'If this is checked, all settings related to Top 10 are removed from the database if you choose to uninstall/delete the plugin.', 'top-10' ),
421 'type' => 'checkbox',
422 'default' => true,
423 ),
424 'uninstall_clean_tables' => array(
425 'id' => 'uninstall_clean_tables',
426 'name' => esc_html__( 'Delete counter data on uninstall', 'top-10' ),
427 'desc' => esc_html__( 'If this is checked, the tables containing the counter statistics are removed from the database if you choose to uninstall/delete the plugin. Keep this unchecked if you choose to reinstall the plugin and do not want to lose your counter data.', 'top-10' ),
428 'type' => 'checkbox',
429 'default' => false,
430 ),
431 'show_credit' => array(
432 'id' => 'show_credit',
433 'name' => esc_html__( 'Link to Top 10 plugin page', 'top-10' ),
434 'desc' => esc_html__( 'A no-follow link to the plugin homepage will be added as the last item of the popular posts.', 'top-10' ),
435 'type' => 'checkbox',
436 'default' => false,
437 ),
438 'admin_header' => array(
439 'id' => 'admin_header',
440 'name' => '<h3>' . esc_html__( 'Admin settings', 'top-10' ) . '</h3>',
441 'desc' => '',
442 'type' => 'header',
443 ),
444 'show_metabox' => array(
445 'id' => 'show_metabox',
446 'name' => esc_html__( 'Show metabox', 'top-10' ),
447 'desc' => esc_html__( 'This will add the Top 10 metabox on Edit Posts or Add New Posts screens. Also applies to Pages and Custom Post Types.', 'top-10' ),
448 'type' => 'checkbox',
449 'default' => true,
450 ),
451 'show_metabox_admins' => array(
452 'id' => 'show_metabox_admins',
453 'name' => esc_html__( 'Limit meta box to Admins', 'top-10' ),
454 'desc' => esc_html__( 'If selected, the meta box will be hidden from anyone who is not an Admin. By default, Contributors and above will be able to see the meta box. Applies only if the above option is selected.', 'top-10' ),
455 'type' => 'checkbox',
456 'default' => false,
457 ),
458 'pv_in_admin' => array(
459 'id' => 'pv_in_admin',
460 'name' => esc_html__( 'Display admin columns', 'top-10' ),
461 /* translators: %s: Custom period label (e.g. Daily, Custom (7 days)). */
462 'desc' => sprintf( esc_html__( 'Adds three columns called Total Views, %s Views and Views. You can selectively disable these by pulling down the Screen Options from the top right of the respective screens.', 'top-10' ), Helpers::get_daily_range_label() ),
463 'type' => 'checkbox',
464 'default' => true,
465 ),
466 'admin_column_post_types' => array(
467 'id' => 'admin_column_post_types',
468 'name' => esc_html__( 'Display columns on post types', 'top-10' ),
469 'desc' => esc_html__( 'Select which post types to display the admin columns. Unselect the above option if you would like to disable the columns.', 'top-10' ),
470 'type' => 'posttypes',
471 'default' => 'post,page',
472 'pro' => true,
473 ),
474 'show_count_non_admins' => array(
475 'id' => 'show_count_non_admins',
476 'name' => esc_html__( 'Show views to non-admins', 'top-10' ),
477 'desc' => esc_html__( "If you disable this then non-admins won't see the above columns or view the independent pages with the top posts.", 'top-10' ),
478 'type' => 'checkbox',
479 'default' => true,
480 ),
481 'show_dashboard_to_roles' => array(
482 'id' => 'show_dashboard_to_roles',
483 'name' => esc_html__( 'Also show dashboard to', 'top-10' ),
484 'desc' => esc_html__( 'Choose the user roles that should have access to the Top 10 dashboard, which showcases popular posts over time. These roles are linked to specific capabilities, and selecting a lower role will automatically grant access to higher roles.', 'top-10' ),
485 'type' => 'multicheck',
486 'default' => 'administrator',
487 'options' => self::get_user_roles( array( 'administrator' ) ),
488 'pro' => true,
489 ),
490 'show_admin_bar' => array(
491 'id' => 'show_admin_bar',
492 'name' => esc_html__( 'Show Admin Bar menu', 'top-10' ),
493 'desc' => esc_html__( 'Display the Top 10 menu in the WordPress admin bar with quick access to popular posts stats and tools.', 'top-10' ),
494 'type' => 'checkbox',
495 'default' => true,
496 'pro' => true,
497 ),
498 'query_optimization' => array(
499 'id' => 'query_optimization',
500 'name' => '<h3>' . esc_html__( 'Query Optimization', 'top-10' ) . '</h3>',
501 'desc' => esc_html__( 'Settings for optimizing database queries', 'top-10' ),
502 'type' => 'header',
503 ),
504 'max_execution_time' => array(
505 'id' => 'max_execution_time',
506 'name' => esc_html__( 'Max Execution Time', 'top-10' ),
507 'desc' => esc_html__( 'Maximum execution time for MySQL queries in milliseconds. Set to 0 to disable. Default is 3000 (3 seconds).', 'top-10' ),
508 'type' => 'number',
509 'default' => 3000,
510 'min' => 0,
511 'step' => 100,
512 'pro' => true,
513 ),
514 );
515
516 /**
517 * Filters the General settings array
518 *
519 * @since 3.3.0
520 *
521 * @param array $settings General settings array
522 */
523 return apply_filters( self::$prefix . '_settings_general', $settings );
524 }
525
526
527 /**
528 * Retrieve the array of Counter settings
529 *
530 * @since 3.3.0
531 *
532 * @return array Counter settings array
533 */
534 public static function settings_counter() {
535 $settings = array(
536 'counter_header' => array(
537 'id' => 'counter_header',
538 'name' => '<h3>' . esc_html__( 'Counter settings', 'top-10' ) . '</h3>',
539 'desc' => '',
540 'type' => 'header',
541 ),
542 'add_to' => array(
543 'id' => 'add_to',
544 'name' => esc_html__( 'Display number of views on', 'top-10' ) . ':',
545 /* translators: 1: Code. */
546 'desc' => sprintf( esc_html__( 'If you choose to disable this, please add the following code to your template file where you want it displayed: %1$s', 'top-10' ), "<code>&lt;?php if ( function_exists( 'echo_tptn_post_count' ) ) { echo_tptn_post_count(); } ?&gt;</code>" ),
547 'type' => 'multicheck',
548 'default' => 'single,page',
549 'options' => array(
550 'single' => esc_html__( 'Posts', 'top-10' ),
551 'page' => esc_html__( 'Pages', 'top-10' ),
552 'home' => esc_html__( 'Home page', 'top-10' ),
553 'feed' => esc_html__( 'Feeds', 'top-10' ),
554 'category_archives' => esc_html__( 'Category archives', 'top-10' ),
555 'tag_archives' => esc_html__( 'Tag archives', 'top-10' ),
556 'other_archives' => esc_html__( 'Other archives', 'top-10' ),
557 ),
558 ),
559 'count_disp_form' => array(
560 'id' => 'count_disp_form',
561 'name' => esc_html__( 'Format to display the post views', 'top-10' ),
562 /* translators: 1: Opening a tag, 2: Closing a tag, 3: Opening code tage, 4. Closing code tag. */
563 'desc' => sprintf( esc_html__( 'Use %1$s to display the total count, %2$s for daily count and %3$s for overall counts across all posts. Default display is %4$s', 'top-10' ), '<code>%totalcount%</code>', '<code>%dailycount%</code>', '<code>%overallcount%</code>', '<code>Visited %totalcount% times, %dailycount% visit(s) today</code>' ),
564 'type' => 'textarea',
565 'default' => 'Visited %totalcount% times, %dailycount% visit(s) today',
566 ),
567 'count_disp_form_zero' => array(
568 'id' => 'count_disp_form_zero',
569 'name' => esc_html__( 'No visits text', 'top-10' ),
570 'desc' => esc_html__( "This text is displayed when there are no hits for the post and it isn't a single page. For example, if you display post views on the Homepage or Archives, this text will be used. To override this, simply enter the same text as the above option.", 'top-10' ),
571 'type' => 'textarea',
572 'default' => 'No visits yet',
573 ),
574 'number_format_count' => array(
575 'id' => 'number_format_count',
576 'name' => esc_html__( 'Number format post count', 'top-10' ),
577 'desc' => esc_html__( 'Activating this option will convert the post counts into a number format based on the locale', 'top-10' ),
578 'type' => 'checkbox',
579 'default' => true,
580 ),
581 'number_format_style' => array(
582 'id' => 'number_format_style',
583 'name' => esc_html__( 'Number format style', 'top-10' ),
584 'desc' => esc_html__( 'Select Abbreviated to display large view counts in a compact form, e.g. 1.2k or 3.4M, wherever counts are displayed. Full displays the complete number.', 'top-10' ),
585 'type' => 'select',
586 'default' => 'full',
587 'options' => array(
588 'full' => esc_html__( 'Full', 'top-10' ),
589 'abbreviated' => esc_html__( 'Abbreviated (1.2k, 3.4M)', 'top-10' ),
590 ),
591 ),
592 'daily_midnight' => array(
593 'id' => 'daily_midnight',
594 'name' => esc_html__( 'Start daily counts at midnight', 'top-10' ),
595 'desc' => esc_html__( 'The daily counter displays visits starting at midnight. This option is enabled by default, similar to most standard counters. If you disable this option, you can use the hourly setting in the next option.', 'top-10' ),
596 'type' => 'checkbox',
597 'default' => true,
598 ),
599 'range_desc' => array(
600 'id' => 'range_desc',
601 'name' => esc_html__( 'Default custom period range', 'top-10' ),
602 'desc' => esc_html__( 'The following two options let you set the default range for the custom period. This can be overridden in the widget settings.', 'top-10' ),
603 'type' => 'descriptive_text',
604 ),
605 'daily_range' => array(
606 'id' => 'daily_range',
607 'name' => esc_html__( 'Day(s)', 'top-10' ),
608 'desc' => '',
609 'type' => 'number',
610 'default' => '1',
611 'min' => '0',
612 'size' => 'small',
613 ),
614 'hour_range' => array(
615 'id' => 'hour_range',
616 'name' => esc_html__( 'Hour(s)', 'top-10' ),
617 'desc' => '',
618 'type' => 'number',
619 'default' => '0',
620 'min' => '0',
621 'max' => '23',
622 'size' => 'small',
623 ),
624 'dynamic_post_count' => array(
625 'id' => 'dynamic_post_count',
626 'name' => esc_html__( 'Always display latest post count', 'top-10' ),
627 'desc' => esc_html__( 'This option uses JavaScript and will increase your page load time. Turn this off if you are not using caching plugins or are OK with displaying older cached counts.', 'top-10' ),
628 'type' => 'checkbox',
629 'default' => false,
630 ),
631 'exclude_on_post_ids' => array(
632 'id' => 'exclude_on_post_ids',
633 'name' => esc_html__( 'Exclude display on these post IDs', 'top-10' ),
634 'desc' => esc_html__( 'Comma-separated list of post or page IDs to exclude displaying the top posts on. e.g. 188,320,500', 'top-10' ),
635 'type' => 'numbercsv',
636 'default' => '',
637 ),
638 'tracker_header' => array(
639 'id' => 'tracker_header',
640 'name' => '<h3>' . esc_html__( 'Tracker settings', 'top-10' ) . '</h3>',
641 'desc' => '',
642 'type' => 'header',
643 ),
644 'trackers' => array(
645 'id' => 'trackers',
646 'name' => esc_html__( 'Enable trackers', 'top-10' ),
647 /* translators: 1: Code. */
648 'desc' => esc_html__( 'Top 10 tracks hits in two tables in the database. The overall table only tracks the total hits per post. The daily table tracks hits per post on an hourly basis.', 'top-10' ),
649 'type' => 'multicheck',
650 'default' => 'overall,daily',
651 'options' => array(
652 'overall' => esc_html__( 'Overall', 'top-10' ),
653 'daily' => esc_html__( 'Daily range', 'top-10' ),
654 ),
655 ),
656 'tracker_type' => array(
657 'id' => 'tracker_type',
658 'name' => esc_html__( 'Tracker type', 'top-10' ),
659 'desc' => '',
660 'type' => 'radiodesc',
661 'default' => 'query_based',
662 'options' => self::get_tracker_types(),
663 ),
664 'tracking_method' => array(
665 'id' => 'tracking_method',
666 'name' => esc_html__( 'Tracking method', 'top-10' ),
667 'desc' => esc_html__( 'Funnel tracking buffers views in a staging table that is merged into the count tables by a background job every few minutes and is recommended for most sites. Switch to Legacy tracking if view counts are not updating on your site, e.g. when WP-Cron is disabled or unreliable. Legacy tracking does not populate the visits log table.', 'top-10' ),
668 'type' => 'radiodesc',
669 'default' => 'funnel',
670 'options' => self::get_tracking_methods(),
671 ),
672 'tracker_all_pages' => array(
673 'id' => 'tracker_all_pages',
674 'name' => esc_html__( 'Load tracker on all pages', 'top-10' ),
675 'desc' => esc_html__( 'This will load the tracker js on all pages. Helpful if you are running minification/concatenation plugins.', 'top-10' ),
676 'type' => 'checkbox',
677 'default' => false,
678 ),
679 'track_sitewide' => array(
680 'id' => 'track_sitewide',
681 'name' => esc_html__( 'Track site-wide views', 'top-10' ),
682 'desc' => esc_html__( 'Track views for the front page, posts page, archives, and search results in addition to individual posts and pages. Site-wide contexts use fixed reserved IDs in the shared Top 10 tables: front page = PHP_INT_MAX; home page = PHP_INT_MAX - 1; search = PHP_INT_MAX - 2; category = PHP_INT_MAX - 4; tag = PHP_INT_MAX - 5; taxonomy = PHP_INT_MAX - 6; author = PHP_INT_MAX - 7; post type archive = PHP_INT_MAX - 8; date archive = PHP_INT_MAX - 9; archive = PHP_INT_MAX - 10; other = PHP_INT_MAX - 11. These IDs are the same on every site and counts remain separate by site (blog ID).', 'top-10' ),
683 'type' => 'checkbox',
684 'default' => false,
685 'pro' => true,
686 ),
687 'track_feed_views' => array(
688 'id' => 'track_feed_views',
689 'name' => esc_html__( 'Track feed views', 'top-10' ),
690 'desc' => esc_html__( 'Count post views from RSS/Atom feed readers via a tracking pixel. Views are added to the post\'s regular view count. Note: some feed readers block remote images by default; views are only counted when the reader loads images.', 'top-10' ),
691 'type' => 'checkbox',
692 'default' => false,
693 'pro' => true,
694 ),
695 'track_users' => array(
696 'id' => 'track_users',
697 'name' => esc_html__( 'Track user groups', 'top-10' ) . ':',
698 'desc' => esc_html__( 'Uncheck above to disable tracking if the current user falls into any one of these groups.', 'top-10' ),
699 'type' => 'multicheck',
700 'default' => 'authors,editors,admins',
701 'options' => array(
702 'authors' => esc_html__( 'Authors', 'top-10' ),
703 'editors' => esc_html__( 'Editors', 'top-10' ),
704 'admins' => esc_html__( 'Admins', 'top-10' ),
705 ),
706 ),
707 'logged_in' => array(
708 'id' => 'logged_in',
709 'name' => esc_html__( 'Track logged-in users', 'top-10' ),
710 'desc' => esc_html__( 'Uncheck to stop tracking logged in users. Only logged out visitors will be tracked if this is disabled. Unchecking this will override the above setting.', 'top-10' ),
711 'type' => 'checkbox',
712 'default' => true,
713 ),
714 'no_bots' => array(
715 'id' => 'no_bots',
716 'name' => esc_html__( 'Do not track bots', 'top-10' ),
717 'desc' => esc_html__( 'Enable this if you want Top 10 to attempt to stop tracking bots. The plugin includes a comprehensive set of known bot user agents but in some cases this might not be enough to stop tracking bots.', 'top-10' ),
718 'type' => 'checkbox',
719 'default' => false,
720 ),
721 'debug_mode' => array(
722 'id' => 'debug_mode',
723 'name' => esc_html__( 'Debug mode', 'top-10' ),
724 'desc' => esc_html__( 'Setting this to true will force the tracker to display an output in the browser. This is useful if you are having issues and are seeking support.', 'top-10' ),
725 'type' => 'checkbox',
726 'default' => false,
727 ),
728 );
729
730 /**
731 * Filters the Counter settings array
732 *
733 * @since 3.3.0
734 *
735 * @param array $settings Counter settings array
736 */
737 return apply_filters( self::$prefix . '_settings_counter', $settings );
738 }
739
740
741 /**
742 * Retrieve the array of List settings
743 *
744 * @since 3.3.0
745 *
746 * @return array List settings array
747 */
748 public static function settings_list() {
749 $settings = array(
750 'use_global_settings' => array(
751 'id' => 'use_global_settings',
752 'name' => esc_html__( 'Use global settings in block', 'top-10' ),
753 'desc' => esc_html__( 'If activated, the settings from this page are automatically inserted in the Popular Posts block. This also applies to existing blocks which do not have any attributes set if the post is edited.', 'top-10' ),
754 'type' => 'checkbox',
755 'default' => false,
756 'pro' => true,
757 ),
758 'limit' => array(
759 'id' => 'limit',
760 'name' => esc_html__( 'Number of posts to display', 'top-10' ),
761 'desc' => esc_html__( 'Maximum number of posts that will be displayed in the list. This option is used if you do not specify the number of posts in the widget or shortcodes', 'top-10' ),
762 'type' => 'number',
763 'default' => '10',
764 'size' => 'small',
765 ),
766 'how_old' => array(
767 'id' => 'how_old',
768 'name' => esc_html__( 'Published age of posts', 'top-10' ),
769 'desc' => esc_html__( 'This options allows you to only show posts that have been published within the above day range. Applies to both overall posts and daily posts lists. e.g. 365 days will only show posts published in the last year in the popular posts lists. Enter 0 for no restriction.', 'top-10' ),
770 'type' => 'number',
771 'default' => '0',
772 'size' => 'small',
773 ),
774 'post_types' => array(
775 'id' => 'post_types',
776 'name' => esc_html__( 'Post types to include', 'top-10' ),
777 'desc' => esc_html__( 'At least one option should be selected above. Select which post types you want to include in the list of posts. This field can be overridden using a comma separated list of post types when using the manual display.', 'top-10' ),
778 'type' => 'posttypes',
779 'default' => 'post',
780 ),
781 'exclusion_header' => array(
782 'id' => 'exclusion_header',
783 'name' => '<h3>' . esc_html__( 'Exclusion settings', 'top-10' ) . '</h3>',
784 'desc' => '',
785 'type' => 'header',
786 ),
787 'exclude_front' => array(
788 'id' => 'exclude_front',
789 'name' => esc_html__( 'Exclude Front page and Posts page', 'top-10' ),
790 'desc' => esc_html__( 'If you have designated specific pages for your Front page and Posts page via Settings > Reading, they will be tracked like any other page. Enable this option to exclude them from appearing in the popular posts lists. Note that tracking will still occur.', 'top-10' ),
791 'type' => 'checkbox',
792 'default' => false,
793 ),
794 'exclude_current_post' => array(
795 'id' => 'exclude_current_post',
796 'name' => esc_html__( 'Exclude current post', 'top-10' ),
797 'desc' => esc_html__( 'Enabling this will exclude the current post being browsed from being displayed in the popular posts list.', 'top-10' ),
798 'type' => 'checkbox',
799 'default' => false,
800 ),
801 'exclude_post_ids' => array(
802 'id' => 'exclude_post_ids',
803 'name' => esc_html__( 'Post/page IDs to exclude', 'top-10' ),
804 'desc' => esc_html__( 'Comma-separated list of post or page IDs to exclude from the list. e.g. 188,320,500', 'top-10' ),
805 'type' => 'numbercsv',
806 'default' => '',
807 'size' => 'large',
808 ),
809 'exclude_cat_slugs' => array(
810 'id' => 'exclude_cat_slugs',
811 'name' => esc_html__( 'Exclude Categories', 'top-10' ),
812 'desc' => esc_html__( 'Comma separated list of category slugs. The field above has an autocomplete so simply start typing in the starting letters and it will prompt you with options. Does not support custom taxonomies.', 'top-10' ),
813 'type' => 'csv',
814 'default' => '',
815 'size' => 'large',
816 'field_class' => 'ts_autocomplete',
817 'field_attributes' => self::get_taxonomy_search_field_attributes( 'category' ),
818 ),
819 'exclude_categories' => array(
820 'id' => 'exclude_categories',
821 'name' => esc_html__( 'Exclude category IDs', 'top-10' ),
822 'desc' => esc_html__( 'This is a readonly field that is automatically populated based on the above input when the settings are saved. These might differ from the IDs visible in the Categories page which use the term_id. Top 10 uses the term_taxonomy_id which is unique to this taxonomy.', 'top-10' ),
823 'type' => 'text',
824 'default' => '',
825 'size' => 'large',
826 'readonly' => true,
827 ),
828 'exclude_terms_include_parents' => array(
829 'id' => 'exclude_terms_include_parents',
830 'name' => esc_html__( 'Include parent categories', 'top-10' ),
831 'desc' => esc_html__( 'Exclude popular posts from parent categories or all ancestors for nested categories.', 'top-10' ),
832 'type' => 'radio',
833 'default' => 'none',
834 'options' => array(
835 'none' => esc_html__( 'None', 'top-10' ),
836 'parent' => esc_html__( 'Only parent categories', 'top-10' ),
837 'all' => esc_html__( 'All ancestors', 'top-10' ),
838 ),
839 'pro' => true,
840 ),
841 'exclude_on_cat_slugs' => array(
842 'id' => 'exclude_on_cat_slugs',
843 'name' => esc_html__( 'Exclude on Categories', 'top-10' ),
844 'desc' => esc_html__( 'Comma separated list of category slugs. The field above has an autocomplete so simply start typing in the starting letters and it will prompt you with options. Does not support custom taxonomies.', 'top-10' ),
845 'type' => 'csv',
846 'default' => '',
847 'size' => 'large',
848 'field_class' => 'ts_autocomplete',
849 'field_attributes' => self::get_taxonomy_search_field_attributes( 'category' ),
850 ),
851 'customize_output_header' => array(
852 'id' => 'customize_output_header',
853 'name' => '<h3>' . esc_html__( 'Customize the output', 'top-10' ) . '</h3>',
854 'desc' => '',
855 'type' => 'header',
856 ),
857 'title' => array(
858 'id' => 'title',
859 'name' => esc_html__( 'Heading of posts', 'top-10' ),
860 'desc' => esc_html__( 'Displayed before the list of the posts as a the master heading', 'top-10' ),
861 'type' => 'text',
862 'default' => '<h3>' . esc_html__( 'Popular posts:', 'top-10' ) . '</h3>',
863 'size' => 'large',
864 ),
865 'title_daily' => array(
866 'id' => 'title_daily',
867 'name' => esc_html__( 'Heading of posts for daily/custom period lists', 'top-10' ),
868 'desc' => esc_html__( 'Displayed before the list of the posts as a the master heading', 'top-10' ),
869 'type' => 'text',
870 'default' => '<h3>' . esc_html__( 'Currently trending:', 'top-10' ) . '</h3>',
871 'size' => 'large',
872 ),
873 'blank_output' => array(
874 'id' => 'blank_output',
875 'name' => esc_html__( 'Show when no posts are found', 'top-10' ),
876 /* translators: 1: Code. */
877 'desc' => '',
878 'type' => 'radio',
879 'default' => 'blank',
880 'options' => array(
881 'blank' => esc_html__( 'Blank output', 'top-10' ),
882 'custom_text' => esc_html__( 'Display custom text', 'top-10' ),
883 ),
884 ),
885 'blank_output_text' => array(
886 'id' => 'blank_output_text',
887 'name' => esc_html__( 'Custom text', 'top-10' ),
888 'desc' => esc_html__( 'Enter the custom text that will be displayed if the second option is selected above', 'top-10' ),
889 'type' => 'textarea',
890 'default' => esc_html__( 'No top posts yet', 'top-10' ),
891 ),
892 'show_excerpt' => array(
893 'id' => 'show_excerpt',
894 'name' => esc_html__( 'Show post excerpt', 'top-10' ),
895 'desc' => '',
896 'type' => 'checkbox',
897 'default' => false,
898 ),
899 'excerpt_length' => array(
900 'id' => 'excerpt_length',
901 'name' => esc_html__( 'Length of excerpt (in words)', 'top-10' ),
902 'desc' => '',
903 'type' => 'number',
904 'default' => '10',
905 'size' => 'small',
906 ),
907 'show_date' => array(
908 'id' => 'show_date',
909 'name' => esc_html__( 'Show date', 'top-10' ),
910 'desc' => '',
911 'type' => 'checkbox',
912 'default' => false,
913 ),
914 'show_author' => array(
915 'id' => 'show_author',
916 'name' => esc_html__( 'Show author', 'top-10' ),
917 'desc' => '',
918 'type' => 'checkbox',
919 'default' => false,
920 ),
921 'disp_list_count' => array(
922 'id' => 'disp_list_count',
923 'name' => esc_html__( 'Show number of views', 'top-10' ),
924 'desc' => '',
925 'type' => 'checkbox',
926 'default' => false,
927 ),
928 'show_ratings' => array(
929 'id' => 'show_ratings',
930 'name' => esc_html__( 'Show WP-PostRatings rating', 'top-10' ),
931 'desc' => esc_html__( 'Display the rating from the WP-PostRatings plugin with each post in the list. This option only takes effect when the WP-PostRatings plugin is active. The Star rating output, including the text shown alongside the stars, comes from the "Ratings Voted Text" template which you can edit under WP-PostRatings » Settings » Templates.', 'top-10' ),
932 'type' => 'select',
933 'default' => '',
934 'options' => array(
935 '' => esc_html__( 'Do not display', 'top-10' ),
936 'stars' => esc_html__( 'Star rating', 'top-10' ),
937 'score' => esc_html__( 'Average score, e.g. 4.25', 'top-10' ),
938 ),
939 ),
940 'title_length' => array(
941 'id' => 'title_length',
942 'name' => esc_html__( 'Limit post title length (in characters)', 'top-10' ),
943 'desc' => '',
944 'type' => 'number',
945 'default' => '60',
946 'size' => 'small',
947 ),
948 'link_new_window' => array(
949 'id' => 'link_new_window',
950 'name' => esc_html__( 'Open links in new window', 'top-10' ),
951 'desc' => '',
952 'type' => 'checkbox',
953 'default' => false,
954 ),
955 'link_nofollow' => array(
956 'id' => 'link_nofollow',
957 'name' => esc_html__( 'Add nofollow to links', 'top-10' ),
958 'desc' => '',
959 'type' => 'checkbox',
960 'default' => false,
961 ),
962 'html_wrapper_header' => array(
963 'id' => 'html_wrapper_header',
964 'name' => '<h3>' . esc_html__( 'HTML to display', 'top-10' ) . '</h3>',
965 'desc' => '',
966 'type' => 'header',
967 ),
968 'before_list' => array(
969 'id' => 'before_list',
970 'name' => esc_html__( 'Before the list of posts', 'top-10' ),
971 'desc' => '',
972 'type' => 'text',
973 'default' => '<ul>',
974 'size' => 'large',
975 ),
976 'after_list' => array(
977 'id' => 'after_list',
978 'name' => esc_html__( 'After the list of posts', 'top-10' ),
979 'desc' => '',
980 'type' => 'text',
981 'default' => '</ul>',
982 'size' => 'large',
983 ),
984 'before_list_item' => array(
985 'id' => 'before_list_item',
986 'name' => esc_html__( 'Before each list item', 'top-10' ),
987 'desc' => '',
988 'type' => 'text',
989 'default' => '<li>',
990 'size' => 'large',
991 ),
992 'after_list_item' => array(
993 'id' => 'after_list_item',
994 'name' => esc_html__( 'After each list item', 'top-10' ),
995 'desc' => '',
996 'type' => 'text',
997 'default' => '</li>',
998 'size' => 'large',
999 ),
1000 );
1001
1002 /**
1003 * Filters the List settings array
1004 *
1005 * @since 3.3.0
1006 *
1007 * @param array $settings List settings array
1008 */
1009 return apply_filters( self::$prefix . '_settings_list', $settings );
1010 }
1011
1012
1013 /**
1014 * Retrieve the array of Thumbnail settings
1015 *
1016 * @since 3.3.0
1017 *
1018 * @return array Thumbnail settings array
1019 */
1020 public static function settings_thumbnail() {
1021 $settings = array(
1022 'post_thumb_op' => array(
1023 'id' => 'post_thumb_op',
1024 'name' => esc_html__( 'Location of the post thumbnail', 'top-10' ),
1025 'desc' => '',
1026 'type' => 'radio',
1027 'default' => 'text_only',
1028 'options' => array(
1029 'inline' => esc_html__( 'Display thumbnails inline with posts, before title', 'top-10' ),
1030 'after' => esc_html__( 'Display thumbnails inline with posts, after title', 'top-10' ),
1031 'thumbs_only' => esc_html__( 'Display only thumbnails, no text', 'top-10' ),
1032 'text_only' => esc_html__( 'Do not display thumbnails, only text', 'top-10' ),
1033 ),
1034 ),
1035 'thumb_size' => array(
1036 'id' => 'thumb_size',
1037 'name' => esc_html__( 'Thumbnail size', 'top-10' ),
1038 'desc' => esc_html__( 'You can choose from existing image sizes above or create a custom size (tptn_thumbnail). If you select a custom size, enter the width, height, and crop settings below. For best results, use a cropped image. Note that changing the width and/or height below will not automatically resize existing images. You will need to regenerate the images using a plugin or WP CLI: wp media regenerate.', 'top-10' ),
1039 'type' => 'thumbsizes',
1040 'default' => 'tptn_thumbnail',
1041 'options' => Media_Handler::get_all_image_sizes(),
1042 ),
1043 'thumb_width' => array(
1044 'id' => 'thumb_width',
1045 'name' => esc_html__( 'Thumbnail width', 'top-10' ),
1046 'desc' => '',
1047 'type' => 'number',
1048 'default' => '250',
1049 'size' => 'small',
1050 ),
1051 'thumb_height' => array(
1052 'id' => 'thumb_height',
1053 'name' => esc_html__( 'Thumbnail height', 'top-10' ),
1054 'desc' => '',
1055 'type' => 'number',
1056 'default' => '250',
1057 'size' => 'small',
1058 ),
1059 'thumb_crop' => array(
1060 'id' => 'thumb_crop',
1061 'name' => esc_html__( 'Hard crop thumbnails', 'top-10' ),
1062 'desc' => esc_html__( 'Check this box to hard crop the thumbnails. i.e. force the width and height above vs. maintaining proportions.', 'top-10' ),
1063 'type' => 'checkbox',
1064 'default' => true,
1065 ),
1066 'thumb_create_sizes' => array(
1067 'id' => 'thumb_create_sizes',
1068 'name' => esc_html__( 'Generate thumbnail sizes', 'top-10' ),
1069 'desc' => esc_html__( 'If you select this option and tptn_thumbnail is chosen above, the plugin will register the image size with WordPress to create new thumbnails. Note that this does not update old images, as explained above.', 'top-10' ),
1070 'type' => 'checkbox',
1071 'default' => true,
1072 ),
1073 'thumb_html' => array(
1074 'id' => 'thumb_html',
1075 'name' => esc_html__( 'Thumbnail size attributes', 'top-10' ),
1076 'desc' => '',
1077 'type' => 'radio',
1078 'default' => 'html',
1079 'options' => array(
1080 /* translators: %s: Code. */
1081 'css' => sprintf( esc_html__( 'Use CSS to set the width and height: e.g. %s', 'top-10' ), '<code>style="max-width:250px;max-height:250px"</code>' ),
1082 /* translators: %s: Code. */
1083 'html' => sprintf( esc_html__( 'Use HTML attributes to set the width and height: e.g. %s', 'top-10' ), '<code>width="250" height="250"</code>' ),
1084 'none' => esc_html__( 'No width or height set. You will need to use external styles to force any width or height of your choice.', 'top-10' ),
1085 ),
1086 ),
1087 'thumb_meta' => array(
1088 'id' => 'thumb_meta',
1089 'name' => esc_html__( 'Thumbnail meta field name', 'top-10' ),
1090 'desc' => esc_html__( 'The value of this field should contain the URL of the image and can be set in the metabox in the Edit Post screen', 'top-10' ),
1091 'type' => 'text',
1092 'default' => 'post-image',
1093 ),
1094 'scan_images' => array(
1095 'id' => 'scan_images',
1096 'name' => esc_html__( 'Get first image', 'top-10' ),
1097 'desc' => esc_html__( 'If enabled, the plugin will fetch the first image in the post content. Note that this might slow down your page loading time if the first image in the posts is large in file size.', 'top-10' ),
1098 'type' => 'checkbox',
1099 'default' => true,
1100 ),
1101 'thumb_default_show' => array(
1102 'id' => 'thumb_default_show',
1103 'name' => esc_html__( 'Use default thumbnail', 'top-10' ),
1104 'desc' => esc_html__( 'Check this box to show the default thumbnail from the next option if no thumbnail is found from the post.', 'top-10' ),
1105 'type' => 'checkbox',
1106 'default' => true,
1107 ),
1108 'thumb_default' => array(
1109 'id' => 'thumb_default',
1110 'name' => esc_html__( 'Default thumbnail', 'top-10' ),
1111 'desc' => esc_html__( 'Enter the full URL of the image that you wish to display if no thumbnail is found. This image will be displayed below.', 'top-10' ),
1112 'type' => 'file',
1113 'default' => Display::get_default_thumbnail(),
1114 'size' => 'large',
1115 'modified_indicator' => false,
1116 ),
1117 );
1118
1119 /**
1120 * Filters the Thumbnail settings array
1121 *
1122 * @since 3.3.0
1123 *
1124 * @param array $settings Thumbnail settings array
1125 */
1126 return apply_filters( self::$prefix . '_settings_thumbnail', $settings );
1127 }
1128
1129
1130 /**
1131 * Retrieve the array of Styles settings
1132 *
1133 * @since 3.3.0
1134 *
1135 * @return array Styles settings array
1136 */
1137 public static function settings_styles() {
1138 $settings = array(
1139 'tptn_styles' => array(
1140 'id' => 'tptn_styles',
1141 'name' => esc_html__( 'Popular posts style', 'top-10' ),
1142 'desc' => '',
1143 'type' => 'select',
1144 'default' => 'no_style',
1145 'options' => wp_list_pluck( self::get_styles(), 'name', 'id' ),
1146 ),
1147 'custom_css' => array(
1148 'id' => 'custom_css',
1149 'name' => esc_html__( 'Custom CSS', 'top-10' ),
1150 'desc' => sprintf(
1151 /* translators: 1: Opening a tag, 2: Closing a tag, 3: Opening code tage, 4. Closing code tag. */
1152 esc_html__( 'Do not include %3$sstyle%4$s tags. Check out %1$sthis article%2$s for available CSS classes to style.', 'top-10' ),
1153 '<a href="' . esc_url( 'https://webberzone.com/support/knowledgebase/using-and-customising-top-10/' ) . '" target="_blank">',
1154 '</a>',
1155 '<code>',
1156 '</code>'
1157 ),
1158 'type' => 'css',
1159 'default' => '',
1160 'field_class' => 'codemirror_css',
1161 ),
1162 );
1163
1164 /**
1165 * Filters the Styles settings array
1166 *
1167 * @since 3.3.0
1168 *
1169 * @param array $settings Styles settings array
1170 */
1171 return apply_filters( self::$prefix . '_settings_styles', $settings );
1172 }
1173
1174
1175 /**
1176 * Retrieve the array of Maintenance settings
1177 *
1178 * @since 3.3.0
1179 *
1180 * @return array Maintenance settings array
1181 */
1182 public static function settings_maintenance() {
1183 $settings = array(
1184 'cron_on' => array(
1185 'id' => 'cron_on',
1186 'name' => esc_html__( 'Enable scheduled maintenance', 'top-10' ),
1187 'desc' => sprintf(
1188 /* translators: 1: Constant holding number of days data is stored. */
1189 esc_html__( 'Regularly cleaning the database can enhance performance, especially for high-traffic blogs. Enabling maintenance will automatically delete entries older than %s days from the daily tables.', 'top-10' ),
1190 /** This filter is documented in includes/admin/class-cron.php */
1191 '<strong>' . (int) apply_filters( 'tptn_maintenance_days', TOP_TEN_STORE_DATA ) . '</strong>'
1192 ),
1193 'type' => 'checkbox',
1194 'default' => false,
1195 ),
1196 'maintenance_days' => array(
1197 'id' => 'maintenance_days',
1198 'name' => esc_html__( 'Daily table retention period', 'top-10' ),
1199 'desc' => sprintf(
1200 /* translators: 1: Constant holding number of days data is stored. */
1201 esc_html__( 'Enter the number of days to retain data in the daily tables before scheduled maintenance removes older entries. Enter 0 to use the default value of %s days.', 'top-10' ),
1202 '<strong>' . TOP_TEN_STORE_DATA . '</strong>'
1203 ),
1204 'type' => 'number',
1205 'default' => 0,
1206 'min' => 0,
1207 'size' => 'small',
1208 'pro' => true,
1209 ),
1210 'log_retention_days' => array(
1211 'id' => 'log_retention_days',
1212 'name' => esc_html__( 'Visits log retention period', 'top-10' ),
1213 'desc' => sprintf(
1214 /* translators: 1: Default number of days for visits log retention. */
1215 esc_html__( 'Enter the number of days to retain raw visit rows in the visits log table. The log stores one row per visit and grows faster than the daily table, so a shorter window is recommended. Enter 0 to use the default value of %s days.', 'top-10' ),
1216 '<strong>' . TOP_TEN_LOG_STORE_DATA . '</strong>'
1217 ),
1218 'type' => 'number',
1219 'default' => 0,
1220 'min' => 0,
1221 'size' => 'small',
1222 'pro' => true,
1223 ),
1224 'cron_range_desc' => array(
1225 'id' => 'cron_range_desc',
1226 'name' => esc_html__( 'Time to run maintenance', 'top-10' ),
1227 'desc' => esc_html__( 'The next two options allow you to set the time to run the cron.', 'top-10' ),
1228 'type' => 'descriptive_text',
1229 ),
1230 'cron_hour' => array(
1231 'id' => 'cron_hour',
1232 'name' => esc_html__( 'Hour', 'top-10' ),
1233 'desc' => '',
1234 'type' => 'number',
1235 'default' => '0',
1236 'min' => '0',
1237 'max' => '23',
1238 'size' => 'small',
1239 ),
1240 'cron_min' => array(
1241 'id' => 'cron_min',
1242 'name' => esc_html__( 'Minute', 'top-10' ),
1243 'desc' => '',
1244 'type' => 'number',
1245 'default' => '0',
1246 'min' => '0',
1247 'max' => '59',
1248 'size' => 'small',
1249 ),
1250 'cron_recurrence' => array(
1251 'id' => 'cron_recurrence',
1252 'name' => esc_html__( 'Run maintenance', 'top-10' ),
1253 'desc' => '',
1254 'type' => 'radio',
1255 'default' => 'weekly',
1256 'options' => array(
1257 'daily' => esc_html__( 'Daily', 'top-10' ),
1258 'weekly' => esc_html__( 'Weekly', 'top-10' ),
1259 'fortnightly' => esc_html__( 'Fortnightly', 'top-10' ),
1260 'monthly' => esc_html__( 'Monthly', 'top-10' ),
1261 ),
1262 ),
1263 );
1264
1265 /**
1266 * Filters the Maintenance settings array
1267 *
1268 * @since 3.3.0
1269 *
1270 * @param array $settings Maintenance settings array
1271 */
1272 return apply_filters( self::$prefix . '_settings_maintenance', $settings );
1273 }
1274
1275
1276 /**
1277 * Retrieve the array of Feed settings
1278 *
1279 * @since 2.8.0
1280 *
1281 * @return array Feed settings array
1282 */
1283 public static function settings_feed() {
1284 $settings = array(
1285 'feed_permalink_overall' => array(
1286 'id' => 'feed_permalink_overall',
1287 'name' => esc_html__( 'Permalink - Overall', 'top-10' ),
1288 /* translators: 1: Opening link tag, 2: Closing link tag. */
1289 'desc' => sprintf( esc_html__( 'This will set the path of the custom feed generated by the plugin for overall popular posts. You might need to %1$srefresh your permalinks%2$s when changing this option.', 'top-10' ), '<a href="' . admin_url( 'options-permalink.php' ) . '" target="_blank">', '</a>' ),
1290 'type' => 'text',
1291 'default' => 'popular-posts',
1292 'size' => 'large',
1293 ),
1294 'feed_permalink_daily' => array(
1295 'id' => 'feed_permalink_daily',
1296 /* translators: %s: Custom period label (e.g. Daily, Custom (7 days)). */
1297 'name' => sprintf( esc_html__( 'Permalink - %s', 'top-10' ), Helpers::get_daily_range_label( (int) \tptn_get_option( 'feed_daily_range', 1 ) ) ),
1298 /* translators: 1: Opening link tag, 2: Closing link tag. */
1299 'desc' => sprintf( esc_html__( 'This will set the path of the custom feed generated by the plugin for daily/custom period popular posts. You might need to %1$srefresh your permalinks%2$s when changing this option.', 'top-10' ), '<a href="' . admin_url( 'options-permalink.php' ) . '" target="_blank">', '</a>' ),
1300 'type' => 'text',
1301 'default' => 'popular-posts-daily',
1302 'size' => 'large',
1303 ),
1304 'feed_limit' => array(
1305 'id' => 'feed_limit',
1306 'name' => esc_html__( 'Number of posts to display', 'top-10' ),
1307 'desc' => esc_html__( 'Maximum number of posts that will be displayed in the custom feed.', 'top-10' ),
1308 'type' => 'number',
1309 'default' => '10',
1310 'size' => 'small',
1311 ),
1312 'feed_daily_range' => array(
1313 'id' => 'feed_daily_range',
1314 'name' => esc_html__( 'Custom period in day(s)', 'top-10' ),
1315 'desc' => '',
1316 'type' => 'number',
1317 'default' => '1',
1318 'min' => '0',
1319 'size' => 'small',
1320 ),
1321 'feed_category_slugs' => array(
1322 'id' => 'feed_category_slugs',
1323 'name' => esc_html__( 'Filter Categories', 'top-10' ),
1324 'desc' => esc_html__( 'Comma separated list of category slugs to include in the feed. The field has an autocomplete so simply start typing the starting letters and it will prompt you with options. Leave blank to include all categories.', 'top-10' ),
1325 'type' => 'csv',
1326 'default' => '',
1327 'size' => 'large',
1328 'field_class' => 'ts_autocomplete',
1329 'field_attributes' => self::get_taxonomy_search_field_attributes( 'category' ),
1330 'pro' => true,
1331 ),
1332 );
1333
1334 /**
1335 * Filters the Feed settings array
1336 *
1337 * @since 2.8.0
1338 *
1339 * @param array $settings Feed settings array
1340 */
1341 return apply_filters( self::$prefix . '_settings_feed', $settings );
1342 }
1343
1344 /**
1345 * Retrieve the array of Features settings
1346 *
1347 * All features are enabled by default. Disabling a feature stops its
1348 * classes from being loaded on any request.
1349 *
1350 * @since 4.4.0
1351 *
1352 * @return array Features settings array
1353 */
1354 public static function settings_features() {
1355 $settings = array(
1356 'features_header' => array(
1357 'id' => 'features_header',
1358 'name' => '<h3>' . esc_html__( 'Features', 'top-10' ) . '</h3>',
1359 'desc' => esc_html__( 'Turn off any features you do not use and the plugin will not load their code. All features are enabled by default. Blocks that are disabled will render as empty on the front end and show an unavailable notice in the block editor.', 'top-10' ),
1360 'type' => 'header',
1361 ),
1362 'features_display_header' => array(
1363 'id' => 'features_display_header',
1364 'name' => '<h3>' . esc_html__( 'Content and display', 'top-10' ) . '</h3>',
1365 'desc' => esc_html__( 'Control the blocks, widgets, page builders, and author tools registered by Top 10.', 'top-10' ),
1366 'type' => 'header',
1367 ),
1368 'enable_blocks' => array(
1369 'id' => 'enable_blocks',
1370 'name' => esc_html__( 'Popular Posts and Post Count blocks', 'top-10' ),
1371 'desc' => esc_html__( 'Registers the free Popular Posts and Post Count blocks for the block editor.', 'top-10' ),
1372 'type' => 'checkbox',
1373 'default' => 1,
1374 ),
1375 'enable_legacy_widgets' => array(
1376 'id' => 'enable_legacy_widgets',
1377 'name' => esc_html__( 'Legacy widgets', 'top-10' ),
1378 'desc' => esc_html__( 'Registers the classic Popular Posts and Views Count widgets. Disable this if you use blocks instead of classic widgets.', 'top-10' ),
1379 'type' => 'checkbox',
1380 'default' => 1,
1381 ),
1382 'enable_query_block' => array(
1383 'id' => 'enable_query_block',
1384 'name' => esc_html__( 'Query block', 'top-10' ),
1385 'desc' => esc_html__( 'Registers the Top 10 Query block and the pre-built block patterns.', 'top-10' ),
1386 'type' => 'checkbox',
1387 'default' => 1,
1388 'pro' => true,
1389 ),
1390 'enable_featured_image_block' => array(
1391 'id' => 'enable_featured_image_block',
1392 'name' => esc_html__( 'Featured Image block', 'top-10' ),
1393 'desc' => esc_html__( 'Extends the core Featured Image block with Top 10 options.', 'top-10' ),
1394 'type' => 'checkbox',
1395 'default' => 1,
1396 'pro' => true,
1397 ),
1398 'enable_popular_posts_pro_block' => array(
1399 'id' => 'enable_popular_posts_pro_block',
1400 'name' => esc_html__( 'Popular Posts Pro block', 'top-10' ),
1401 'desc' => esc_html__( 'Registers the Popular Posts Pro block for the block editor.', 'top-10' ),
1402 'type' => 'checkbox',
1403 'default' => 1,
1404 'pro' => true,
1405 ),
1406 'enable_page_builders' => array(
1407 'id' => 'enable_page_builders',
1408 'name' => esc_html__( 'Page builder integrations', 'top-10' ),
1409 'desc' => esc_html__( 'Registers the Popular Posts elements for Elementor, Bricks Builder, and WPBakery Page Builder.', 'top-10' ),
1410 'type' => 'checkbox',
1411 'default' => 1,
1412 'pro' => true,
1413 ),
1414 'enable_popular_authors' => array(
1415 'id' => 'enable_popular_authors',
1416 'name' => esc_html__( 'Popular Authors', 'top-10' ),
1417 'desc' => esc_html__( 'Enables the Popular Authors blocks, shortcodes, widgets and settings.', 'top-10' ),
1418 'type' => 'checkbox',
1419 'default' => 1,
1420 'pro' => true,
1421 ),
1422 'features_performance_header' => array(
1423 'id' => 'features_performance_header',
1424 'name' => '<h3>' . esc_html__( 'Performance', 'top-10' ) . '</h3>',
1425 'desc' => esc_html__( 'Control optional output performance modules.', 'top-10' ),
1426 'type' => 'header',
1427 ),
1428 'enable_lazy_load' => array(
1429 'id' => 'enable_lazy_load',
1430 'name' => esc_html__( 'Lazy-load module', 'top-10' ),
1431 'desc' => esc_html__( 'Loads the lazy-loading module and its REST endpoint. Disable this to remove lazy-loading support, including per-shortcode and per-block lazy_load overrides. Requires REST API endpoints to be enabled.', 'top-10' ),
1432 'type' => 'checkbox',
1433 'default' => 1,
1434 'pro' => true,
1435 ),
1436 'features_tracking_header' => array(
1437 'id' => 'features_tracking_header',
1438 'name' => '<h3>' . esc_html__( 'Tracking and feeds', 'top-10' ) . '</h3>',
1439 'desc' => esc_html__( 'Control how Top 10 records views and provides popular posts feeds.', 'top-10' ),
1440 'type' => 'header',
1441 ),
1442 'enable_feed' => array(
1443 'id' => 'enable_feed',
1444 'name' => esc_html__( 'Popular posts feeds', 'top-10' ),
1445 'desc' => esc_html__( 'Adds custom RSS feeds for overall and daily popular posts. The feed settings are on the Feed tab.', 'top-10' ),
1446 'type' => 'checkbox',
1447 'default' => 1,
1448 ),
1449 'enable_fast_tracker' => array(
1450 'id' => 'enable_fast_tracker',
1451 'name' => esc_html__( 'Fast and High-traffic trackers', 'top-10' ),
1452 'desc' => esc_html__( 'Adds the Fast tracker and High-traffic tracker options to the Tracker type setting. If this is disabled while one of these trackers is in use, the tracker type will be reset to the default.', 'top-10' ),
1453 'type' => 'checkbox',
1454 'default' => 1,
1455 'pro' => true,
1456 ),
1457 'enable_sitewide_tracking' => array(
1458 'id' => 'enable_sitewide_tracking',
1459 'name' => esc_html__( 'Site-wide tracking', 'top-10' ),
1460 'desc' => esc_html__( 'Enables the site-wide tracking feature. When enabled, turn on Track site-wide views under Counter/Tracker to count front pages, posts pages, archives, and searches.', 'top-10' ),
1461 'type' => 'checkbox',
1462 'default' => 1,
1463 'pro' => true,
1464 ),
1465 'features_data_header' => array(
1466 'id' => 'features_data_header',
1467 'name' => '<h3>' . esc_html__( 'Data and maintenance', 'top-10' ) . '</h3>',
1468 'desc' => esc_html__( 'Control tools that manage and reduce stored view data.', 'top-10' ),
1469 'type' => 'header',
1470 ),
1471 'enable_daily_table_rollup' => array(
1472 'id' => 'enable_daily_table_rollup',
1473 'name' => esc_html__( 'Daily table size reduction', 'top-10' ),
1474 'desc' => esc_html__( 'Enables the Reduce Daily Table Size tool and the wp top10 db rollup command for combining older hourly records.', 'top-10' ),
1475 'type' => 'checkbox',
1476 'default' => 1,
1477 'pro' => true,
1478 ),
1479 'features_admin_header' => array(
1480 'id' => 'features_admin_header',
1481 'name' => '<h3>' . esc_html__( 'Administration', 'top-10' ) . '</h3>',
1482 'desc' => esc_html__( 'Control additional Top 10 administration features.', 'top-10' ),
1483 'type' => 'header',
1484 ),
1485 'enable_pro_dashboard_widgets' => array(
1486 'id' => 'enable_pro_dashboard_widgets',
1487 'name' => esc_html__( 'Pro dashboard widgets', 'top-10' ),
1488 'desc' => esc_html__( 'Adds the enhanced Top 10 Pro widgets to the WordPress dashboard.', 'top-10' ),
1489 'type' => 'checkbox',
1490 'default' => 1,
1491 'pro' => true,
1492 ),
1493 'features_api_header' => array(
1494 'id' => 'features_api_header',
1495 'name' => '<h3>' . esc_html__( 'API integrations', 'top-10' ) . '</h3>',
1496 'desc' => esc_html__( 'Control the Top 10 REST API endpoints used by integrations, tracking, blocks, and lazy loading.', 'top-10' ),
1497 'type' => 'header',
1498 ),
1499 'enable_rest_api' => array(
1500 'id' => 'enable_rest_api',
1501 'name' => esc_html__( 'REST API endpoints', 'top-10' ),
1502 'desc' => esc_html__( 'Registers the top-10/v1 endpoints for popular posts, tracking, counters, blocks, and lazy loading. Keep enabled if your tracker type is REST-based or if your integrations or blocks use these endpoints.', 'top-10' ),
1503 'type' => 'checkbox',
1504 'default' => 1,
1505 ),
1506 );
1507
1508 /**
1509 * Filters the Features settings array
1510 *
1511 * @since 4.4.0
1512 *
1513 * @param array $settings Features settings array
1514 */
1515 return apply_filters( self::$prefix . '_settings_features', $settings );
1516 }
1517
1518 /**
1519 * Get the various styles.
1520 *
1521 * @since 2.5.0
1522 * @return array Style options.
1523 */
1524 public static function get_styles() {
1525 $styles = array(
1526 array(
1527 'id' => 'no_style',
1528 'name' => esc_html__( 'No styles', 'top-10' ),
1529 'description' => esc_html__( 'Select this option if you plan to add your own styles', 'top-10' ) . '<br />',
1530 ),
1531 array(
1532 'id' => 'text_only',
1533 'name' => esc_html__( 'Text only', 'top-10' ),
1534 'description' => esc_html__( 'Disable thumbnails and no longer include the default style sheet included in the plugin', 'top-10' ) . '<br />',
1535 ),
1536 array(
1537 'id' => 'left_thumbs',
1538 'name' => esc_html__( 'Left thumbnails', 'top-10' ),
1539 'description' => esc_html__( 'Enabling this option will set the post thumbnail to be before text. Disabling this option will not revert any settings.', 'top-10' ),
1540 ),
1541 );
1542
1543 /**
1544 * Filter the array containing the types of styles to add your own.
1545 *
1546 * @since 2.5.0
1547 *
1548 * @param array $styles Different styles.
1549 */
1550 return apply_filters( self::$prefix . '_get_styles', $styles );
1551 }
1552
1553 /**
1554 * Get User Roles.
1555 *
1556 * @since 4.0.0
1557 *
1558 * @param array $remove_roles Roles to remove.
1559 * @return array User roles in the format 'role' => 'name'.
1560 */
1561 public static function get_user_roles( $remove_roles = array() ) {
1562 // Get the global $wp_roles object using the wp_roles() function.
1563 $wp_roles = wp_roles();
1564
1565 // Initialize the array to store roles in the desired format.
1566 $roles_array = array();
1567
1568 if ( ! empty( $wp_roles->roles ) ) {
1569 // Loop through all roles and store them in 'role' => 'name' format.
1570 foreach ( $wp_roles->roles as $role_key => $role_details ) {
1571 if ( in_array( $role_key, $remove_roles, true ) ) {
1572 continue;
1573 }
1574 $roles_array[ $role_key ] = esc_html( $role_details['name'] );
1575 }
1576 } else {
1577 // Fallback to default WordPress roles.
1578 $default_roles = array(
1579 'administrator' => esc_html__( 'Administrator' ),
1580 'editor' => esc_html__( 'Editor' ),
1581 'author' => esc_html__( 'Author' ),
1582 'contributor' => esc_html__( 'Contributor' ),
1583 'subscriber' => esc_html__( 'Subscriber' ),
1584 );
1585
1586 foreach ( $default_roles as $role_key => $role_name ) {
1587 if ( ! in_array( $role_key, $remove_roles, true ) ) {
1588 $roles_array[ $role_key ] = $role_name;
1589 }
1590 }
1591 }
1592
1593 return $roles_array;
1594 }
1595
1596 /**
1597 * Adding WordPress plugin action links.
1598 *
1599 * @since 3.3.0
1600 *
1601 * @param array $links Array of links.
1602 * @return array
1603 */
1604 public function plugin_actions_links( $links ) {
1605
1606 return array_merge(
1607 array(
1608 'settings' => '<a href="' . admin_url( 'admin.php?page=' . $this->menu_slug ) . '">' . esc_html__( 'Settings', 'top-10' ) . '</a>',
1609 ),
1610 $links
1611 );
1612 }
1613
1614 /**
1615 * Add meta links on Plugins page.
1616 *
1617 * @since 3.3.0
1618 *
1619 * @param array $links Array of Links.
1620 * @param string $file Current file.
1621 * @return array
1622 */
1623 public function plugin_row_meta( $links, $file ) {
1624
1625 if ( false !== strpos( $file, 'top-10.php' ) ) {
1626 $new_links = array(
1627 'support' => '<a href = "https://wordpress.org/support/plugin/top-10">' . esc_html__( 'Support', 'top-10' ) . '</a>',
1628 'donate' => '<a href = "https://wzn.io/donate-wz">' . esc_html__( 'Donate', 'top-10' ) . '</a>',
1629 'contribute' => '<a href = "https://github.com/WebberZone/top-10">' . esc_html__( 'Contribute', 'top-10' ) . '</a>',
1630 );
1631
1632 $links = array_merge( $links, $new_links );
1633 }
1634 return $links;
1635 }
1636
1637 /**
1638 * Get the help sidebar content to display on the plugin settings page.
1639 *
1640 * @since 1.8.0
1641 */
1642 public function get_help_sidebar() {
1643 $help_sidebar =
1644 /* translators: 1: Plugin support site link. */
1645 '<p>' . sprintf( __( 'For more information or how to get support visit the <a href="%s">support site</a>.', 'top-10' ), esc_url( 'https://webberzone.com/support/' ) ) . '</p>' .
1646 /* translators: 1: WordPress.org support forums link. */
1647 '<p>' . sprintf( __( 'Support queries should be posted in the <a href="%s">WordPress.org support forums</a>.', 'top-10' ), esc_url( 'https://wordpress.org/support/plugin/top-10' ) ) . '</p>' .
1648 '<p>' . sprintf(
1649 /* translators: 1: Github issues link, 2: Github plugin page link. */
1650 __( '<a href="%1$s">Post an issue</a> on <a href="%2$s">GitHub</a> (bug reports only).', 'top-10' ),
1651 esc_url( 'https://github.com/ajaydsouza/top-10/issues' ),
1652 esc_url( 'https://github.com/ajaydsouza/top-10' )
1653 ) . '</p>';
1654
1655 /**
1656 * Filter to modify the help sidebar content.
1657 *
1658 * @since 1.8.0
1659 *
1660 * @param string $help_sidebar Help sidebar content.
1661 */
1662 return apply_filters( self::$prefix . '_settings_help', $help_sidebar );
1663 }
1664
1665 /**
1666 * Get the help tabs to display on the plugin settings page.
1667 *
1668 * @since 1.8.0
1669 */
1670 public function get_help_tabs() {
1671 $help_tabs = array(
1672 array(
1673 'id' => 'tptn-settings-general-help',
1674 'title' => esc_html__( 'General', 'top-10' ),
1675 'content' =>
1676 '<p><strong>' . esc_html__( 'This tab provides global settings for how Top 10 works across your site.', 'top-10' ) . '</strong></p>' .
1677 '<p>' . esc_html__( 'Configure caching, uninstall behaviour, admin columns, the dashboard, and other high-level options. You must click the Save Changes button at the bottom of the screen for new settings to take effect.', 'top-10' ) . '</p>',
1678 ),
1679 array(
1680 'id' => 'tptn-settings-counter-help',
1681 'title' => esc_html__( 'Counter / Tracker', 'top-10' ),
1682 'content' =>
1683 '<p><strong>' . esc_html__( 'This tab controls how Top 10 tracks and displays view counts.', 'top-10' ) . '</strong></p>' .
1684 '<p>' . esc_html__( 'Choose where to display view counts, how they are formatted, which visits are tracked, and how the tracker works (REST API, query variables, or Ajax).', 'top-10' ) . '</p>',
1685 ),
1686 array(
1687 'id' => 'tptn-settings-list-help',
1688 'title' => esc_html__( 'Posts list', 'top-10' ),
1689 'content' =>
1690 '<p><strong>' . esc_html__( 'This tab controls the popular posts list output.', 'top-10' ) . '</strong></p>' .
1691 '<p>' . esc_html__( 'Configure the number of posts, age of posts, post types, exclusions, and what information is shown (title, date, author, views, excerpts, and HTML wrappers).', 'top-10' ) . '</p>',
1692 ),
1693 array(
1694 'id' => 'tptn-settings-thumbnail-help',
1695 'title' => esc_html__( 'Thumbnail', 'top-10' ),
1696 'content' =>
1697 '<p><strong>' . esc_html__( 'This tab manages thumbnail settings for the popular posts list.', 'top-10' ) . '</strong></p>' .
1698 '<p>' . esc_html__( 'Choose whether thumbnails are displayed, select the image size, configure custom dimensions, cropping, the default thumbnail, and fallback behaviour when no thumbnail is found.', 'top-10' ) . '</p>',
1699 ),
1700 array(
1701 'id' => 'tptn-settings-styles-help',
1702 'title' => esc_html__( 'Styles', 'top-10' ),
1703 'content' =>
1704 '<p><strong>' . esc_html__( 'This tab controls how the popular posts list is styled.', 'top-10' ) . '</strong></p>' .
1705 '<p>' . esc_html__( 'Select a built-in style or disable styles if you want to fully control the look using your own CSS.', 'top-10' ) . '</p>',
1706 ),
1707 array(
1708 'id' => 'tptn-settings-maintenance-help',
1709 'title' => esc_html__( 'Maintenance', 'top-10' ),
1710 'content' =>
1711 '<p><strong>' . esc_html__( 'This tab handles tools and maintenance-related options.', 'top-10' ) . '</strong></p>' .
1712 '<p>' . esc_html__( 'Use this screen to reset settings, clear cached popular posts, and manage database-related options such as pruning or rebuilding counts.', 'top-10' ) . '</p>',
1713 ),
1714 array(
1715 'id' => 'tptn-settings-feed-help',
1716 'title' => esc_html__( 'Feed', 'top-10' ),
1717 'content' =>
1718 '<p><strong>' . esc_html__( 'This tab controls how Top 10 content appears in your site feed.', 'top-10' ) . '</strong></p>' .
1719 '<p>' . esc_html__( 'Configure copyright text and additional HTML that is added before or after the content in your feeds.', 'top-10' ) . '</p>',
1720 ),
1721 );
1722
1723 /**
1724 * Filter to add more help tabs.
1725 *
1726 * @since 1.8.0
1727 *
1728 * @param array $help_tabs Associative array of help tabs.
1729 */
1730 return apply_filters( self::$prefix . '_settings_help', $help_tabs );
1731 }
1732
1733 /**
1734 * Function returns the different types of trackers.
1735 *
1736 * @since 3.3.0
1737 * @return array Tracker types.
1738 */
1739 public static function get_tracker_types() {
1740
1741 $trackers = array(
1742 array(
1743 'id' => 'rest_based',
1744 'name' => __( 'REST API based', 'top-10' ),
1745 'description' => __( 'Uses the REST API to record visits', 'top-10' ),
1746 ),
1747 array(
1748 'id' => 'query_based',
1749 'name' => __( 'Query variable based', 'top-10' ),
1750 'description' => __( 'Uses query variables to record visits', 'top-10' ),
1751 ),
1752 array(
1753 'id' => 'ajaxurl',
1754 'name' => __( 'Ajaxurl based', 'top-10' ),
1755 'description' => __( 'Uses admin-ajax.php which is inbuilt within WordPress to process the tracker', 'top-10' ),
1756 ),
1757 );
1758
1759 /**
1760 * Filter the array containing the types of trackers to add your own.
1761 *
1762 * @since 2.4.0
1763 *
1764 * @param array $trackers Different trackers.
1765 */
1766 return apply_filters( self::$prefix . '_get_tracker_types', $trackers );
1767 }
1768
1769 /**
1770 * Function returns the different tracking methods.
1771 *
1772 * @since 4.3.3
1773 * @return array Tracking methods.
1774 */
1775 public static function get_tracking_methods() {
1776
1777 $methods = array(
1778 array(
1779 'id' => 'funnel',
1780 'name' => __( 'Funnel tracking', 'top-10' ),
1781 'description' => __( 'Views are buffered and merged into the count tables every few minutes (default)', 'top-10' ),
1782 ),
1783 array(
1784 'id' => 'legacy',
1785 'name' => __( 'Legacy tracking', 'top-10' ),
1786 'description' => __( 'Views are written directly to the count tables on every visit (behaviour of versions before 4.3)', 'top-10' ),
1787 ),
1788 );
1789
1790 /**
1791 * Filter the array containing the tracking methods.
1792 *
1793 * @since 4.3.3
1794 *
1795 * @param array $methods Tracking methods.
1796 */
1797 return apply_filters( self::$prefix . '_get_tracking_methods', $methods );
1798 }
1799
1800
1801
1802
1803 /**
1804 * Add footer text on the plugin page.
1805 *
1806 * @since 2.0.0
1807 */
1808 public static function get_admin_footer_text() {
1809 return sprintf(
1810 /* translators: 1: Opening achor tag with Plugin page link, 2: Closing anchor tag, 3: Opening anchor tag with review link. */
1811 __( 'Thank you for using %1$sWebberZone Top 10%2$s! Please %3$srate us%2$s on WordPress.org', 'top-10' ),
1812 '<a href="https://webberzone.com/plugins/top-10/" target="_blank">',
1813 '</a>',
1814 '<a href="https://wordpress.org/support/plugin/top-10/reviews/#new-post" target="_blank">'
1815 );
1816 }
1817
1818 /**
1819 * Enqueue scripts and styles.
1820 *
1821 * @since 3.3.0
1822 *
1823 * @param string $hook Current hook.
1824 */
1825 public function admin_enqueue_scripts( $hook ) {
1826
1827 if ( ! isset( $this->settings_api->settings_page ) || $this->settings_api->settings_page !== $hook ) {
1828 return;
1829 }
1830
1831 wp_enqueue_script( 'top-ten-admin-js' );
1832 wp_enqueue_style( 'top-ten-admin-css' );
1833 wp_enqueue_style( 'wp-spinner' );
1834 wp_localize_script(
1835 'top-ten-admin-js',
1836 'tptn_admin',
1837 array(
1838 'thumb_default' => Display::get_default_thumbnail(),
1839 )
1840 );
1841 wp_localize_script(
1842 'top-ten-admin-js',
1843 'top_ten_admin_data',
1844 array(
1845 'security' => wp_create_nonce( 'tptn-admin' ),
1846 'strings' => array(
1847 'confirm_message' => esc_html__( 'Are you sure you want to clear the cache?', 'top-10' ),
1848 'clearing_text' => esc_html__( 'Clearing...', 'top-10' ),
1849 'success_message' => esc_html__( 'Cache cleared successfully!', 'top-10' ),
1850 'fail_message' => esc_html__( 'Failed to clear cache. Please try again.', 'top-10' ),
1851 'request_fail_message' => esc_html__( 'Request failed: ', 'top-10' ),
1852 'left_thumbs_message' => esc_html__( 'Note: This setting cannot be changed as the Popular posts style is set to Left thumbnails. You can change the style in the Styles tab.', 'top-10' ),
1853 'grid_thumbs_message' => esc_html__( 'Note: This setting cannot be changed as the Popular posts style is set to Grid thumbnails. You can change the style in the Styles tab.', 'top-10' ),
1854 'text_only_message' => esc_html__( 'Note: This setting cannot be changed as the Popular posts style is set to Text only. You can change the style in the Styles tab.', 'top-10' ),
1855 ),
1856 )
1857 );
1858 }
1859
1860 /**
1861 * Modify settings when they are being saved.
1862 *
1863 * @since 3.3.0
1864 *
1865 * @param array $settings Settings array.
1866 * @return array Sanitized settings array.
1867 */
1868 public function change_settings_on_save( $settings ) {
1869
1870 Settings_Sanitize::sanitize_tax_slugs( $settings, 'exclude_cat_slugs', 'exclude_categories' );
1871 Settings_Sanitize::sanitize_tax_slugs( $settings, 'exclude_on_cat_slugs', 'exclude_on_categories' );
1872 Settings_Sanitize::sanitize_tax_slugs( $settings, 'feed_category_slugs', 'feed_categories' );
1873
1874 // Save cron settings.
1875 $settings['cron_hour'] = min( 23, absint( $settings['cron_hour'] ) );
1876 $settings['cron_min'] = min( 59, absint( $settings['cron_min'] ) );
1877
1878 if ( ! empty( $settings['cron_on'] ) ) {
1879 \WebberZone\Top_Ten\Admin\Cron::enable_run( $settings['cron_hour'], $settings['cron_min'], $settings['cron_recurrence'] );
1880 } else {
1881 \WebberZone\Top_Ten\Admin\Cron::disable_run();
1882 }
1883
1884 // Force thumb_width and thumb_height if either are zero.
1885 if ( empty( $settings['thumb_width'] ) || empty( $settings['thumb_height'] ) ) {
1886 list( $settings['thumb_width'], $settings['thumb_height'] ) = Media_Handler::get_thumb_size( $settings['thumb_size'] );
1887 }
1888
1889 // Overwrite settings based on selected style; guard against missing keys on reset.
1890 $style = $settings['tptn_styles'] ?? '';
1891
1892 $inline_thumb_styles = array(
1893 'left_thumbs' => esc_html__( 'Note: Thumbnail location can only be Inline, After, or Thumbnails only when the Popular posts style is set to Left thumbnails. You can change the style in the Styles tab.', 'top-10' ),
1894 'grid_thumbs' => esc_html__( 'Note: Thumbnail location can only be Inline, After, or Thumbnails only when the Popular posts style is set to Grid thumbnails. You can change the style in the Styles tab.', 'top-10' ),
1895 );
1896
1897 if ( array_key_exists( $style, $inline_thumb_styles ) ) {
1898 $post_thumb_op = $settings['post_thumb_op'] ?? '';
1899 if ( 'inline' !== $post_thumb_op && 'after' !== $post_thumb_op && 'thumbs_only' !== $post_thumb_op ) {
1900 $settings['post_thumb_op'] = 'inline';
1901 }
1902
1903 add_settings_error(
1904 self::$prefix . '-notices',
1905 '',
1906 $inline_thumb_styles[ $style ],
1907 'warning'
1908 );
1909 }
1910 // Overwrite settings if text_only style is selected.
1911 if ( 'text_only' === $style ) {
1912 $settings['post_thumb_op'] = 'text_only';
1913
1914 add_settings_error(
1915 self::$prefix . '-notices',
1916 '',
1917 esc_html__( 'Note: Thumbnail location set to Text only as the Popular posts style is set to Text only. You can change the style in the Styles tab.', 'top-10' ),
1918 'warning'
1919 );
1920 }
1921
1922 // If the fast/high-traffic trackers are disabled, reset the tracker type to the default.
1923 if ( isset( $settings['enable_fast_tracker'] ) && empty( $settings['enable_fast_tracker'] ) && isset( $settings['tracker_type'] ) && in_array( $settings['tracker_type'], array( 'fast_tracker', 'high_traffic_tracker' ), true ) ) {
1924 $settings['tracker_type'] = 'query_based';
1925
1926 add_settings_error(
1927 self::$prefix . '-notices',
1928 '',
1929 esc_html__( 'Note: Tracker type has been reset to the default as the Fast and High-traffic trackers feature is disabled.', 'top-10' ),
1930 'warning'
1931 );
1932 }
1933
1934 // Delete the cache.
1935 \WebberZone\Top_Ten\Util\Cache::delete();
1936
1937 return $settings;
1938 }
1939
1940 /**
1941 * Display the default thumbnail below the setting.
1942 *
1943 * @since 3.3.0
1944 *
1945 * @param string $html Current HTML.
1946 * @param array $args Argument array of the setting.
1947 * @return string
1948 */
1949 public function display_admin_thumbnail( $html, $args ) {
1950
1951 $thumb_default = \tptn_get_option( 'thumb_default' );
1952
1953 if ( 'thumb_default' === $args['id'] && '' !== $thumb_default ) {
1954 $html .= '<br />';
1955 $html .= sprintf( '<img src="%1$s" style="max-width:200px" title="%2$s" alt="%2$s" />', esc_attr( $thumb_default ), esc_html__( 'Default thumbnail', 'top-10' ) );
1956 }
1957
1958 return $html;
1959 }
1960
1961 /**
1962 * Display the default thumbnail below the setting.
1963 *
1964 * @since 3.3.0
1965 *
1966 * @param string $html Current HTML.
1967 * @param array $args Argument array of the setting.
1968 * @return string
1969 */
1970 public function reset_default_thumb_setting( $html, $args ) {
1971
1972 $thumb_default = \tptn_get_option( 'thumb_default' );
1973
1974 if ( 'thumb_default' === $args['id'] && Display::get_default_thumbnail() !== $thumb_default ) {
1975 $html = '<span class="dashicons dashicons-undo reset-default-thumb" style="cursor: pointer;" title="' . __( 'Reset' ) . '"></span> <br />' . $html;
1976 }
1977
1978 return $html;
1979 }
1980
1981 /**
1982 * Add a link to the Tools page from the settings page.
1983 *
1984 * @since 3.5.0
1985 */
1986 public static function settings_page_header() {
1987 global $tptn_freemius;
1988 ?>
1989 <p>
1990 <?php if ( ! $tptn_freemius->is_paying() ) { ?>
1991 <a class="tptn_button tptn_button_gold" href="<?php echo esc_url( $tptn_freemius->get_upgrade_url() ); ?>">
1992 <?php esc_html_e( 'Upgrade to Pro', 'top-10' ); ?>
1993 </a>
1994 <?php } ?>
1995 </p>
1996
1997 <?php
1998 }
1999
2000 /**
2001 * Updated the settings fields to display a pro version link.
2002 *
2003 * @param string $output Settings field HTML.
2004 * @param array $args Settings field arguments.
2005 * @return string Updated HTML.
2006 */
2007 public static function after_setting_output( $output, $args ) {
2008 if ( isset( $args['pro'] ) && $args['pro'] ) {
2009 $output .= sprintf(
2010 '<a class="tptn_button tptn_button_gold" target="_blank" href="%s" title="%s">%s</a>',
2011 esc_url( \WebberZone\Top_Ten\tptn_freemius()->get_upgrade_url() ),
2012 esc_attr__( 'Upgrade to Pro', 'top-10' ),
2013 esc_html__( 'Upgrade to Pro', 'top-10' )
2014 );
2015 }
2016
2017 if ( isset( $args['id'] ) && 'tptn_styles' === $args['id'] ) {
2018 $post_thumb_op = \tptn_get_option( 'post_thumb_op' );
2019 $tptn_style = \tptn_get_option( 'tptn_styles' );
2020
2021 if ( 'text_only' === $post_thumb_op && 'text_only' !== $tptn_style ) {
2022 $output .= sprintf(
2023 '<p class="description" style="color:#9B0800;">%s</p>',
2024 esc_html__( 'Note: Thumbnail location is set to "Do not display thumbnails, only text". This may override the selected style.', 'top-10' )
2025 );
2026 }
2027 }
2028
2029 return $output;
2030 }
2031
2032 /**
2033 * Add a button to the settings page to start the settings wizard.
2034 *
2035 * @since 4.2.0
2036 */
2037 public function add_wizard_button() {
2038 printf(
2039 '<br /><a aria-label="%s" class="button button-secondary" href="%s" title="%s" style="margin-top: 10px;">%s</a>',
2040 esc_attr__( 'Start Settings Wizard', 'top-10' ),
2041 esc_url( admin_url( 'admin.php?page=tptn_wizard' ) ),
2042 esc_attr__( 'Start Settings Wizard', 'top-10' ),
2043 esc_html__( 'Start Settings Wizard', 'top-10' )
2044 );
2045 }
2046
2047 /**
2048 * Handle Tom Select taxonomy search AJAX requests.
2049 *
2050 * @since 4.2.0
2051 *
2052 * @return void
2053 */
2054 public static function taxonomy_search_tom_select() {
2055 // Verify nonce.
2056 if ( ! isset( $_REQUEST['nonce'] ) ) {
2057 wp_send_json_error( array( 'message' => 'Missing nonce' ) );
2058 }
2059
2060 $nonce_valid = wp_verify_nonce( sanitize_key( $_REQUEST['nonce'] ), self::$prefix . '_taxonomy_search_tom_select' );
2061
2062 if ( ! $nonce_valid ) {
2063 wp_send_json_error(
2064 array(
2065 'message' => 'Invalid nonce',
2066 'received_nonce' => sanitize_key( $_REQUEST['nonce'] ),
2067 'expected_action' => self::$prefix . '_taxonomy_search_tom_select',
2068 )
2069 );
2070 }
2071
2072 if ( ! isset( $_REQUEST['endpoint'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
2073 wp_send_json_error( 'Missing endpoint' );
2074 }
2075
2076 $endpoint = sanitize_key( $_REQUEST['endpoint'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
2077
2078 $search_term = isset( $_REQUEST['q'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['q'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
2079
2080 $comma = _x( ',', 'tag delimiter', 'top-10' );
2081 if ( ',' !== $comma ) {
2082 $search_term = str_replace( $comma, ',', $search_term );
2083 }
2084 if ( false !== strpos( $search_term, ',' ) ) {
2085 $search_term = explode( ',', $search_term );
2086 $search_term = $search_term[ count( $search_term ) - 1 ];
2087 }
2088 $search_term = trim( $search_term, " \t\n\r\0\x0B" );
2089
2090 if ( 'public_taxonomies' === $endpoint ) {
2091 $taxonomies = (array) get_taxonomies( array( 'public' => true ), 'objects' );
2092 $taxonomy = array();
2093 $tax = null;
2094
2095 foreach ( $taxonomies as $taxonomy_name => $taxonomy_object ) {
2096 if ( empty( $taxonomy_object->cap->assign_terms ) ) {
2097 continue;
2098 }
2099
2100 if ( ! current_user_can( $taxonomy_object->cap->assign_terms ) ) {
2101 continue;
2102 }
2103
2104 $taxonomy[] = $taxonomy_object->name;
2105 }
2106
2107 if ( empty( $taxonomy ) ) {
2108 wp_send_json_success( array() );
2109 }
2110
2111 $tax = get_taxonomy( $taxonomy[0] );
2112 } else {
2113 $taxonomy = $endpoint;
2114 $tax = get_taxonomy( $taxonomy );
2115
2116 if ( ! $tax ) {
2117 wp_send_json_error( 'Invalid taxonomy' );
2118 }
2119
2120 if ( ! current_user_can( $tax->cap->assign_terms ) ) {
2121 wp_send_json_error( 'Insufficient permissions' );
2122 }
2123 }
2124
2125 /**
2126 * This filter has been defined in /wp-admin/includes/ajax-actions.php
2127 */
2128 $term_search_min_chars = (int) apply_filters( 'term_search_min_chars', 2, $tax, $search_term );
2129
2130 /*
2131 * Require $term_search_min_chars chars for matching (default: 2)
2132 * ensure it's a non-negative, non-zero integer.
2133 */
2134 if ( ( 0 === $term_search_min_chars ) || ( strlen( $search_term ) < $term_search_min_chars ) ) {
2135 wp_send_json_success( array() );
2136 }
2137
2138 $terms = get_terms(
2139 array(
2140 'taxonomy' => $taxonomy,
2141 'name__like' => $search_term,
2142 'hide_empty' => false,
2143 )
2144 );
2145
2146 $results = array();
2147 foreach ( (array) $terms as $term ) {
2148 $formatted_string = "{$term->name} ({$term->taxonomy}:{$term->term_taxonomy_id})";
2149 $results[] = array(
2150 'value' => $formatted_string,
2151 'text' => $term->name,
2152 );
2153 }
2154
2155 wp_send_json_success( $results );
2156 }
2157
2158 /**
2159 * Get field attributes for Tom Select taxonomy search fields.
2160 *
2161 * @since 4.2.0
2162 *
2163 * @param string $taxonomy The taxonomy to search.
2164 * @param array $ts_config Optional Tom Select configuration.
2165 * @return array Field attributes array.
2166 */
2167 private static function get_taxonomy_search_field_attributes( $taxonomy, $ts_config = array() ) {
2168 $attributes = array(
2169 'data-wp-prefix' => strtoupper( (string) self::$prefix ),
2170 'data-wp-action' => self::$prefix . '_taxonomy_search_tom_select',
2171 'data-wp-nonce' => wp_create_nonce( self::$prefix . '_taxonomy_search_tom_select' ),
2172 'data-wp-endpoint' => $taxonomy,
2173 );
2174
2175 if ( ! empty( $ts_config ) ) {
2176 $attributes['data-ts-config'] = wp_json_encode( $ts_config );
2177 }
2178
2179 return $attributes;
2180 }
2181
2182 /**
2183 * Get field attributes for Tom Select meta key search fields.
2184 *
2185 * @since 4.2.0
2186 *
2187 * @param array $ts_config Optional Tom Select configuration.
2188 * @return array Field attributes array.
2189 */
2190 private static function get_meta_keys_search_field_attributes( $ts_config = array() ) {
2191 $attributes = array(
2192 'data-wp-prefix' => strtoupper( (string) self::$prefix ),
2193 'data-wp-action' => self::$prefix . '_taxonomy_search_tom_select',
2194 'data-wp-nonce' => wp_create_nonce( self::$prefix . '_taxonomy_search_tom_select' ),
2195 'data-wp-endpoint' => 'meta_keys',
2196 );
2197
2198 if ( ! empty( $ts_config ) ) {
2199 $attributes['data-ts-config'] = wp_json_encode( $ts_config );
2200 }
2201
2202 return $attributes;
2203 }
2204 }
2205