PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.9.4
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.9.4
4.9.4 4.9.3 4.9.2 4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 All 202 releases
← All changes | includes/Core/Settings.php +2854 -1546 3.3.4 → 4.9.4 View file →
@@ -1,14 +1,23 @@
1 1 <?php
2 +namespace WPDeveloper\BetterDocs\Core;
2 3
3 -namespace WPDeveloper\BetterDocs\Core;
4 +if ( ! defined( 'ABSPATH' ) ) {
5 + exit;
6 +}
4 7
8 +
5 9 use WP_Error;
6 10 use WP_User;
7 11 use WPDeveloper\BetterDocs\Admin\Builder\GlobalFields;
8 12 use WPDeveloper\BetterDocs\Admin\Builder\Rules;
13 +use WPDeveloper\BetterDocs\AI\ModelRegistry;
14 +use WPDeveloper\BetterDocs\AI\ProviderFactory;
15 +use WPDeveloper\BetterDocs\REST\AIEdit;
16 +use WPDeveloper\BetterDocs\Utils\AIHelper;
9 17 use WPDeveloper\BetterDocs\Utils\Base;
10 18 use WPDeveloper\BetterDocs\Utils\Database;
19 +use WPDeveloper\BetterDocs\Utils\Helper;
11 20
12 21 class Settings extends Base {
13 22 public $base_key = 'betterdocs_settings';
14 23
@@ -17,11 +26,11 @@
17 26 * @var Database
18 27 */
19 28 protected $database;
20 29
21 - private $deprecated = [];
30 + private $deprecated = array();
22 31
23 - private $cannot_be_empty = [
32 + private $cannot_be_empty = array(
24 33 'breadcrumb_doc_title',
25 34 'docs_slug',
26 35 'category_slug',
27 36 'tag_slug',
@@ -26,31 +35,33 @@
26 35 'category_slug',
27 36 'tag_slug',
28 37 'permalink_structure',
29 38 'docs_page'
30 - ];
39 + );
31 40
32 41 public function __construct( Database $database ) {
33 42 $this->database = $database;
34 43 $this->deprecated = $this->deprecated_settings();
35 44
36 - add_filter( 'betterdocs_settings_tabs', [ $this, 'import_export_settings' ] );
45 + add_filter( 'betterdocs_settings_tabs', array( $this, 'import_export_settings' ) );
46 + add_filter( 'betterdocs_settings_tabs', array( $this, 'maybe_remove_git_tab' ), 20 );
37 47
38 - add_action( 'admin_enqueue_scripts', [ $this, 'enqueue' ] );
48 + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_old' ), 99 );
49 + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ), 99 );
39 50
40 - if ( isset( $_GET['page'] ) && $_GET['page'] === 'betterdocs-settings' && ! has_action( 'betterdocs_settings_header' ) ) {
41 - add_action( 'betterdocs_settings_header', [ $this, 'header' ] );
42 - }
51 + // if ( isset( $_GET['page'] ) && $_GET['page'] === 'betterdocs-settings' && ! has_action( 'betterdocs_settings_header' ) ) {
52 + // add_action( 'betterdocs_settings_header', [ $this, 'header' ] );
53 + // }
43 54
44 - add_action( 'wp_ajax_betterdocs_dark_mode', [ $this, 'dark_mode' ] );
45 - add_filter( 'betterdocs_settings_tab_advance', [ $this, 'hide_roles_management' ], 11, 1 );
46 - add_action( 'betterdocs::settings::saved', [ $this, 'fallback_slugs' ], 99, 3 );
55 + add_action( 'wp_ajax_betterdocs_dark_mode', array( $this, 'dark_mode' ) );
56 + add_filter( 'betterdocs_settings_tab_advance', array( $this, 'hide_roles_management' ), 11, 1 );
57 + add_action( 'betterdocs::settings::saved', array( $this, 'fallback_slugs' ), 99, 3 );
47 58 }
48 59
49 - public function fallback_slugs( $_saved, $_settings, $_old_settings = [] ) {
60 + public function fallback_slugs( $_saved, $_settings, $_old_settings = array() ) {
50 61 $_default = $this->get_default();
51 62 foreach ( $this->cannot_be_empty as $key ) {
52 - if ( $key === 'docs_page' && ! $_settings['builtin_doc_page'] && empty( $_settings[ $key ] ) ) {
63 + if ( 'docs_page' === $key && ! $_settings[ 'builtin_doc_page' ] && empty( $_settings[ $key ] ) ) {
53 64 $this->save( 'builtin_doc_page', true );
54 65 continue;
55 66 }
56 67
@@ -68,8 +79,31 @@
68 79 return esc_url( admin_url( 'admin.php?page=betterdocs-settings' ) );
69 80 }
70 81
71 82 /**
83 + * Settings keys holding secret API keys. These are masked before reaching
84 + * the browser, stripped for non-admins, and never persisted as their mask.
85 + *
86 + * Covers the AI Chatbot key plus every content-suite platform key. OpenAI's
87 + * is `ai_autowrite_api_key` (see ProviderFactory::key_field_for), hence the
88 + * dedupe.
89 + *
90 + * @return array<int,string>
91 + */
92 + public static function sensitive_api_key_fields() {
93 + $fields = array(
94 + ProviderFactory::OPENAI_KEY_FIELD,
95 + 'ai_chatbot_api_key',
96 + );
97 + foreach ( array_keys( ModelRegistry::platforms() ) as $platform ) {
98 + $fields[] = ProviderFactory::key_field_for( $platform );
99 + }
100 + // Add-ons (e.g. the AI Chatbot) register their own per-platform keys here
101 + // so they are masked in the browser and stripped for non-admins.
102 + return apply_filters( 'betterdocs_sensitive_api_key_fields', array_values( array_unique( $fields ) ) );
103 + }
104 +
105 + /**
72 106 * This method is responsible for enqueueing scripts in settings panel
73 107 *
74 108 * @param string $hook
75 109 *
@@ -76,19 +110,54 @@
76 110 * @return void
77 111 * @since 2.5.0
78 112 */
79 113 public function enqueue( $hook ) {
80 - if ( $hook !== 'betterdocs_page_betterdocs-settings' ) {
114 + if ( ! betterdocs()->is_betterdocs_screen( $hook ) ) {
81 115 return;
82 116 }
83 117
118 + wp_enqueue_media();
84 119 wp_enqueue_script( 'betterdocs-admin' );
85 - betterdocs()->assets->enqueue( 'betterdocs-settings', 'admin/css/settings.css' );
120 +
121 + $settings = GlobalFields::normalize( $this->settings_args() );
122 +
123 + // Mask sensitive API keys before they reach the browser. Non-admins still get them stripped entirely below.
124 + $sensitive_api_keys = self::sensitive_api_key_fields();
125 + foreach ( $sensitive_api_keys as $api_key_field ) {
126 + if ( ! empty( $settings[ 'values' ][ $api_key_field ] ) ) {
127 + $settings[ 'values' ][ $api_key_field ] = Helper::mask_api_key( $settings[ 'values' ][ $api_key_field ] );
128 + }
129 + }
130 +
131 + if ( ! current_user_can( 'edit_docs_settings' ) ) {
132 + foreach ( $sensitive_api_keys as $api_key_field ) {
133 + if ( isset( $settings[ 'values' ][ $api_key_field ] ) ) {
134 + unset( $settings[ 'values' ][ $api_key_field ] );
135 + }
136 + }
137 + }
138 +
139 + // Inject raw git settings to bypass get() fallback (e.g., '' -> 'docs')
140 + if ( isset( $settings[ 'values' ] ) ) {
141 + $settings[ 'values' ][ 'git_provider' ] = $this->get_raw_field( 'git_provider', 'github' );
142 + $settings[ 'values' ][ 'git_repository_url' ] = $this->get_raw_field( 'git_repository_url', '' );
143 + $settings[ 'values' ][ 'git_branch' ] = $this->get_raw_field( 'git_branch', '' );
144 + $settings[ 'values' ][ 'git_docs_directory' ] = $this->get_raw_field( 'git_docs_directory', '' );
145 + }
146 +
147 + betterdocs()->assets->localize( 'betterdocs-admin', 'betterdocsAdminSettings', $settings );
86 148 betterdocs()->assets->enqueue( 'betterdocs-icons', 'admin/btd-icon/style.css' );
87 - betterdocs()->assets->enqueue( 'betterdocs-settings', 'admin/js/settings.js' );
88 - betterdocs()->assets->localize( 'betterdocs-settings', 'betterdocsAdminSettings', GlobalFields::normalize( $this->settings_args() ) );
89 149 }
90 150
151 + public function enqueue_old( $hook ) {
152 + // FREE & Pro Version Compatibility Check
153 + if ( ! betterdocs()->is_betterdocs_screen( $hook ) ) {
154 + return;
155 + }
156 +
157 + $this->enqueue( 'betterdocs_page_betterdocs-settings' );
158 + }
159 +
91 160 /**
92 161 * This method is responsible for printing header in dashboard settings page.
93 162 *
94 163 * @param string $hook
@@ -96,9 +165,9 @@
96 165 * @return void
97 166 * @since 2.5.0
98 167 */
99 168 public function header( $hook ) {
100 - if ( $hook !== 'settings' ) {
169 + if ( 'settings' !== $hook ) {
101 170 return;
102 171 }
103 172
104 173 betterdocs()->views->get( 'admin/template-parts/settings-header' );
@@ -111,9 +180,9 @@
111 180 * @return array
112 181 * @since 2.5.0
113 182 */
114 183 public function deprecated_settings() {
115 - return [];
184 + return array();
116 185 }
117 186
118 187 /**
119 188 * Dynamic migration caller.
@@ -122,12 +191,12 @@
122 191 * @since 2.5.0
123 192 */
124 193 public function migration( $version ) {
125 194 if ( $version > 250 ) {
126 - for ( $v = 250; $v <= $version; $v++ ) {
195 + for ( $v = 250; $v <= $version; ++$v ) {
127 196 $_func = "v{$v}";
128 197 if ( method_exists( $this, $_func ) ) {
129 - call_user_func( [ $this, $_func ] );
198 + call_user_func( array( $this, $_func ) );
130 199 }
131 200 }
132 201 }
133 202 }
@@ -143,9 +212,9 @@
143 212 $this->save( 'terms_orderby', 'name' );
144 213 }
145 214
146 215 if ( $orderby = $this->get( 'alphabetically_order_post', false ) ) {
147 - if ( $orderby === '1' ) {
216 + if ( '1' === $orderby ) {
148 217 $this->save( 'alphabetically_order_post', 'title' );
149 218 }
150 219 }
151 220 }
@@ -157,80 +226,162 @@
157 226 * @since 1.0.0
158 227 *
159 228 */
160 229 public function get_default() {
161 - $_default = [
162 - 'multiple_kb' => '',
163 - 'builtin_doc_page' => true,
164 - 'breadcrumb_doc_title' => __( 'Docs', 'betterdocs' ),
165 - 'docs_slug' => 'docs',
166 - 'docs_page' => 0,
167 - 'category_slug' => 'docs-category',
168 - 'tag_slug' => 'docs-tag',
169 - 'permalink_structure' => 'docs/',
170 - 'enable_faq_schema' => false,
171 - 'live_search' => true,
172 - 'advance_search' => false,
173 - 'popular_keyword_limit' => 5,
174 - 'search_letter_limit' => 3,
175 - 'search_placeholder' => __( 'Search...', 'betterdocs' ),
176 - 'search_not_found_text' => __( 'Sorry, no docs were found.', 'betterdocs' ),
177 - 'search_result_image' => true,
178 - 'masonry_layout' => true,
179 - 'category_title_link' => false,
180 - 'terms_orderby' => 'betterdocs_order',
181 - 'alphabetically_order_term' => false,
182 - 'terms_order' => 'ASC',
183 - 'alphabetically_order_post' => 'betterdocs_order',
184 - 'docs_order' => 'ASC',
185 - 'nested_subcategory' => false,
186 - 'column_number' => 3,
187 - 'posts_number' => 10,
188 - 'post_count' => true,
189 - 'count_text' => __( 'docs', 'betterdocs' ),
190 - 'count_text_singular' => __( 'doc', 'betterdocs' ),
191 - 'exploremore_btn' => true,
192 - 'exploremore_btn_txt' => __( 'Explore More', 'betterdocs' ),
193 - 'doc_single' => 1,
194 - 'enable_toc' => true,
195 - 'toc_title' => __( 'Table of Contents', 'betterdocs' ),
196 - 'toc_hierarchy' => true,
197 - 'toc_list_number' => true,
198 - 'toc_dynamic_title' => false,
199 - 'enable_sticky_toc' => true,
200 - 'sticky_toc_offset' => 100,
201 - 'collapsible_toc_mobile' => false,
202 - 'supported_heading_tag' => [ '1', '2', '3', '4', '5', '6' ],
203 - 'enable_post_title' => true,
204 - 'title_link_ctc' => true,
205 - 'enable_breadcrumb' => true,
206 - 'breadcrumb_home_text' => __( 'Home', 'betterdocs' ),
207 - 'breadcrumb_home_url' => get_home_url(),
230 + $_default = array(
231 + 'multiple_kb' => '',
232 + 'enable_ai_sample_docs' => true,
233 + 'enable_export_faq' => true,
234 + 'builtin_doc_page' => true,
235 + 'breadcrumb_doc_title' => __( 'Docs', 'betterdocs' ),
236 + 'enable_category_hierarchy_slugs' => false,
237 + 'docs_slug' => 'docs',
238 + 'docs_page' => 0,
239 + 'category_slug' => 'docs-category',
240 + 'tag_slug' => 'docs-tag',
241 + 'permalink_structure' => 'docs/',
242 + 'enable_faq_schema' => false,
243 + 'live_search' => true,
244 + 'advance_search' => false,
245 + 'popular_keyword_limit' => 5,
246 + 'search_letter_limit' => 3,
247 + 'search_placeholder' => __( 'Search...', 'betterdocs' ),
248 + 'search_not_found_text' => __( 'Sorry, no docs were found.', 'betterdocs' ),
249 + 'search_result_image' => true,
250 + 'search_modal_search_type' => 'all',
251 + 'masonry_layout' => true,
252 + 'docs_list_icon' => array(),
253 + 'category_title_link' => false,
254 + 'terms_orderby' => 'betterdocs_order',
255 + 'alphabetically_order_term' => false,
256 + 'terms_order' => 'ASC',
257 + 'alphabetically_order_post' => 'betterdocs_order',
258 + 'docs_order' => 'ASC',
259 + 'nested_subcategory' => false,
260 + 'column_number' => 3,
261 + 'posts_number' => 10,
262 + 'post_count' => true,
263 + 'count_text' => __( 'Docs', 'betterdocs' ),
264 + 'count_text_singular' => __( 'Doc', 'betterdocs' ),
265 + 'exploremore_btn' => true,
266 + 'exploremore_btn_txt' => __( 'Explore More', 'betterdocs' ),
267 + 'doc_single' => 1,
268 + 'enable_toc' => true,
269 + 'toc_title' => __( 'Table of Contents', 'betterdocs' ),
270 + 'toc_hierarchy' => true,
271 + 'toc_list_number' => false,
272 + 'toc_dynamic_title' => false,
273 + 'enable_sticky_toc' => true,
274 + 'sticky_toc_offset' => 100,
275 + 'collapsible_toc_mobile' => false,
276 + 'supported_heading_tag' => array( '1', '2', '3', '4', '5', '6' ),
277 + 'enable_post_title' => true,
278 + 'title_link_ctc' => true,
279 + 'enable_breadcrumb' => true,
280 + 'breadcrumb_home_text' => __( 'Home', 'betterdocs' ),
281 + 'enable_breadcrumb_home_text' => true,
282 + 'breadcrumb_home_url' => get_home_url(),
208 283 'enable_breadcrumb_category' => true,
209 - 'enable_breadcrumb_title' => true,
210 - 'enable_sidebar_cat_list' => true,
211 - 'enable_print_icon' => true,
212 - 'enable_tags' => true,
213 - 'email_feedback' => true,
214 - 'feedback_link_text' => __( 'Still stuck? How can we help?', 'betterdocs' ),
215 - 'feedback_url' => '',
216 - 'feedback_form_title' => __( 'How can we help?', 'betterdocs' ),
217 - 'email_address' => get_option( 'admin_email' ),
218 - 'show_last_update_time' => true,
219 - 'enable_navigation' => true,
220 - 'enable_comment' => true,
221 - 'enable_credit' => true,
222 - 'enable_archive_sidebar' => true,
284 + 'enable_breadcrumb_title' => true,
285 + 'enable_sidebar_cat_list' => true,
286 + 'enable_print_icon' => true,
287 + 'print_enable_logo' => false,
288 + 'print_logo' => array(),
289 + 'print_enable_footer' => false,
290 + 'print_footer_text' => '',
291 + 'enable_tags' => true,
292 + 'email_feedback' => true,
293 + 'feedback_link_text' => __( 'Still stuck? How can we help?', 'betterdocs' ),
294 + 'reaction_feedback_text' => __( 'Thanks for your feedback', 'betterdocs' ),
295 + 'feedback_url' => '',
296 + 'feedback_form_title' => __( 'How can we help?', 'betterdocs' ),
297 + 'email_address' => get_option( 'admin_email' ),
298 + 'show_last_update_time' => true,
299 + 'enable_navigation' => true,
300 + 'enable_comment' => true,
301 + 'enable_credit' => false,
302 + 'enable_archive_sidebar' => true,
223 303 'archive_nested_subcategory' => true,
304 + 'archive_enable_pagination' => false,
305 + 'archive_lazy_load_descendants' => false,
224 306 'enable_content_restriction' => false,
225 - 'enable_reporting' => false,
226 - 'reporting_day' => 'monday',
227 - 'reporting_email' => get_option( 'admin_email' ),
228 - 'enable_write_with_ai' => true,
229 - 'enable_faq_write_with_ai' => true,
230 - 'ai_autowrite_api_key' => '',
231 - 'ai_autowrite_max_token' => 1500
232 - ];
307 + 'enable_reporting' => false,
308 + 'enable_sample_data' => false,
309 + 'reporting_day' => 'monday',
310 + 'reporting_email' => get_option( 'admin_email' ),
311 + 'enable_write_with_ai' => true,
312 + 'enable_faq_write_with_ai' => true,
313 + 'enable_glossaries_write_with_ai' => true,
314 + 'enable_docs_ai_suite' => true,
315 + 'write_with_ai_model' => 'gpt-4o-mini',
316 + 'ai_autowrite_api_key' => '',
317 + 'ai_autowrite_max_token' => 2500,
318 + 'write_with_ai_instructions' => array(
319 + array(
320 + 'id' => 'default',
321 + 'title' => __( 'Default/Core', 'betterdocs' ),
322 + 'content' => WriteWithAI::default_instruction_content()
323 + )
324 + ),
325 + 'ai_edit_actions' => AIEdit::default_actions(),
326 + 'enable_article_summary' => false,
327 + 'article_summary_model' => 'gpt-4o-mini',
328 + 'article_summary_max_token' => 1500,
329 + // Multi-platform AI (content suite). `ai_platform` selects the active
330 + // provider; `ai_model` is the single global model; keys are stored
331 + // per platform so switching never loses a saved key. OpenAI reuses
332 + // `ai_autowrite_api_key` above — it has always held an OpenAI key,
333 + // so nothing needs migrating.
334 + 'ai_platform' => 'openai',
335 + 'ai_model' => 'gpt-4o-mini',
336 + 'ai_api_key_gemini' => '',
337 + 'ai_api_key_claude' => '',
338 + 'ai_api_key_deepseek' => '',
339 + 'ai_api_key_openrouter' => '',
340 + 'enable_estimated_reading_time' => true,
341 + 'enable_encyclopedia' => false,
342 + 'enable_glossaries' => false,
343 + 'show_glossary_suggestions' => true,
344 + 'enable_ai_chatbot' => false,
345 + 'estimated_reading_time_title' => '',
346 + 'estimated_reading_time_text' => __( 'min read', 'betterdocs' ),
347 + 'singular_estimated_reading_time_text' => __( 'min read', 'betterdocs' ),
348 + 'betterdocs_access_control_repeater' => array(),
349 + 'internal_knowledge_base_type' => 'basic',
350 + 'betterdocs_access_control_repeater_kb' => array(),
351 + 'enable_git_integration' => false,
352 + 'enable_ai_actions' => true,
353 + 'enable_markdown_endpoint' => true,
354 + 'ai_actions_button_label' => __( 'Copy page', 'betterdocs' ),
355 + 'ai_actions_prompt_template' => __( 'Read from {URL} so I can ask questions about it.', 'betterdocs' ),
356 + 'ai_actions_copy_page' => true,
357 + 'ai_actions_view_markdown' => true,
358 + 'ai_actions_chatgpt' => true,
359 + 'ai_actions_claude' => true,
360 + 'ai_actions_gemini' => true,
361 + 'ai_actions_perplexity' => false,
362 + 'ai_actions_grok' => false,
363 + 'enable_listen' => true,
364 + 'listen_button_label' => __( 'Listen', 'betterdocs' ),
365 + 'listen_show_speed' => true,
366 + // Words a synthetic voice gets through in a minute at rate 1.
367 + // Deliberately lower than the 200 the reading-time pill assumes — that
368 + // number describes silent reading. Only the player's duration estimate
369 + // uses this; see Core\Listen::WORDS_PER_MINUTE.
370 + 'listen_words_per_minute' => 180,
371 + /**
372 + * MCP master switch. Off by default; the toggle lives on the
373 + * BetterDocs → MCP page, not in the settings tree, and writes
374 + * through POST betterdocs/v1/settings.
375 + *
376 + * The key has to be listed here or `get()` cannot see it at all:
377 + * it answers `$default` for anything absent from the defaults
378 + * array, whatever the stored option holds.
379 + *
380 + * @since 4.9.0
381 + */
382 + 'enable_mcp' => ''
383 + );
233 384
234 385 $_default = apply_filters( 'betterdocs_default_settings', $_default );
235 386 // $_default = apply_filters_deprecated(
236 387 // 'betterdocs_option_default_settings', [$_default], '2.5.0',
@@ -246,34 +397,98 @@
246 397 * @return array
247 398 * @since 2.5.0
248 399 */
249 400 public function get_pro_defaults() {
250 - return [];
401 + return array();
251 402 }
252 403
404 + public function is_elementor_pro() {
405 + return is_plugin_active( 'elementor-pro/elementor-pro.php' );
406 + }
407 +
253 408 /**
254 - * Get customizer links for docs page.
409 + * Get full site editor links for docs page.
255 410 *
256 411 * @return string
257 - * @since 1.0.0
412 + * @since 3.5.8
258 413 */
414 + public function gutenberg_link() {
415 + if ( betterdocs()->helper->current_theme_is_fse_theme() ) {
416 + return admin_url( 'site-editor.php?postType=wp_template&postId=betterdocs/betterdocs//archive-docs' );
417 + } else {
418 + return 'https://betterdocs.co/docs/betterdocs-provides-full-site-editor-support/';
419 + }
420 + }
421 +
422 + /**
423 + * Get elementor theme builder link for docs page.
424 + *
425 + * @return string
426 + * @since 3.5.8
427 + */
428 + public function elementor_link() {
429 + if ( $this->is_elementor_pro() ) {
430 + return admin_url( 'admin.php?page=elementor-app#/site-editor/templates/doc-archive' );
431 + } else {
432 + return 'https://betterdocs.co/docs/docs-page-with-elementor/';
433 + }
434 + }
435 +
259 436 public function customizer_link() {
260 - $query['autofocus[panel]'] = 'betterdocs_customize_options';
261 - $query['return'] = admin_url( 'edit.php?post_type=docs' );
262 - $builtin_doc_page = betterdocs()->settings->get( 'builtin_doc_page' );
263 - $docs_slug = betterdocs()->settings->get( 'docs_slug' );
264 - $docs_page = betterdocs()->settings->get( 'builtin_doc_page' );
437 + $query[ 'autofocus[panel]' ] = 'betterdocs_customize_options';
438 + $query[ 'return' ] = admin_url( 'edit.php?post_type=docs' );
439 + $builtin_doc_page = betterdocs()->settings->get( 'builtin_doc_page' );
440 + $docs_slug = betterdocs()->settings->get( 'docs_slug' );
441 + $docs_page = betterdocs()->settings->get( 'builtin_doc_page' );
265 442
266 - if ( $builtin_doc_page == 1 && $docs_slug ) {
267 - $query['url'] = site_url( '/' . $docs_slug );
268 - } elseif ( $builtin_doc_page != 1 && $docs_page ) {
269 - $post_info = get_post( $docs_page );
270 - $query['url'] = site_url( '/' . $post_info->post_name );
443 + if ( 1 == $builtin_doc_page && $docs_slug ) {
444 + $query[ 'url' ] = site_url( '/' . $docs_slug );
445 + } elseif ( 1 != $builtin_doc_page && $docs_page ) {
446 + $post_info = get_post( $docs_page );
447 + $query[ 'url' ] = site_url( '/' . $post_info->post_name );
271 448 }
272 449
273 450 return add_query_arg( $query, admin_url( 'customize.php' ) );
274 451 }
275 452
453 + public function design_tab() {
454 + $settings = array();
455 +
456 + $settings[ 'gutenberg_link' ] = array(
457 + 'name' => 'gutenberg_link',
458 + 'type' => 'action',
459 + 'action' => 'betterdocs_settings_gutenberg_link',
460 + 'button' => betterdocs()->helper->current_theme_is_fse_theme() ? __( 'Design with Gutenberg', 'betterdocs' ) : __( 'Learn More', 'betterdocs' ),
461 + 'url' => $this->gutenberg_link(),
462 + 'customizer_img' => betterdocs()->assets->icon( 'customizer/gutenberg-preview.png', true ),
463 + 'priority' => 1
464 + );
465 +
466 + $settings[ 'elementor_link' ] = array(
467 + 'name' => 'elementor_link',
468 + 'type' => 'action',
469 + 'action' => 'betterdocs_settings_elementor_link',
470 + 'button' => $this->is_elementor_pro() ? __( 'Design with Elementor', 'betterdocs' ) : __( 'Learn More', 'betterdocs' ),
471 + 'url' => $this->elementor_link(),
472 + 'customizer_img' => betterdocs()->assets->icon( 'customizer/elementor-preview.png', true ),
473 + 'priority' => 2
474 + );
475 +
476 + if ( ! betterdocs()->helper->current_theme_is_fse_theme() ) {
477 + $settings[ 'customizer_link' ] = array(
478 + 'name' => 'customizer_link',
479 + 'type' => 'action',
480 + 'action' => 'betterdocs_settings_customizer_link',
481 + 'button' => __( 'Customize in BetterDocs', 'betterdocs' ),
482 + 'url' => $this->customizer_link(),
483 + 'customizer_img' => betterdocs()->assets->icon( 'customizer/customizer-preview.png', true ),
484 + 'priority' => 3
485 + );
486 + }
487 +
488 + return $settings;
489 + }
490 +
276 491 /**
277 492 * Get All Roles
278 493 * dynamically
279 494 *
@@ -280,9 +495,9 @@
280 495 * @return array
281 496 */
282 497 public function get_roles() {
283 498 $roles = wp_roles()->role_names;
284 - unset( $roles['subscriber'] );
499 + unset( $roles[ 'subscriber' ] );
285 500
286 501 return $roles;
287 502 }
288 503
@@ -296,10 +511,11 @@
296 511 if ( ! check_ajax_referer( 'doc_cat_order_nonce', 'nonce', false ) ) {
297 512 wp_send_json_error();
298 513 }
299 514
300 - if ( isset( $_POST['mode'] ) ) {
301 - if ( $this->save( 'dark_mode', rest_sanitize_boolean( $_POST['mode'] ) ) ) {
515 + if ( isset( $_POST[ 'mode' ] ) ) {
516 + $mode = sanitize_text_field( wp_unslash( $_POST[ 'mode' ] ) );
517 + if ( $this->save( 'dark_mode', rest_sanitize_boolean( $mode ) ) ) {
302 518 wp_send_json_success();
303 519 }
304 520 }
305 521
@@ -308,9 +524,9 @@
308 524
309 525 public function get_normalized_value( $key, $value, $default = null ) {
310 526 $_origin_value = $_value = $value;
311 527
312 - if ( in_array( $_value, [ 'on', 'off', '1', 'false', 'true' ], true ) ) {
528 + if ( in_array( $_value, array( 'on', 'off', '1', 'false', 'true' ), true ) ) {
313 529 switch ( $_value ) {
314 530 case 'on':
315 531 case 'ON':
316 532 case '1':
@@ -330,14 +546,14 @@
330 546
331 547 return $_value;
332 548 }
333 549
334 - public function get_normalized_values( $values, $default_values = [] ) {
550 + public function get_normalized_values( $values, $default_values = array() ) {
335 551 if ( empty( $values ) ) {
336 - return [];
552 + return array();
337 553 }
338 554
339 - $_settings = [];
555 + $_settings = array();
340 556 foreach ( $values as $key => $value ) {
341 557 $_default_value = isset( $default_values[ $key ] ) ? $default_values[ $key ] : null;
342 558 $_settings[ $key ] = $this->get_normalized_value( $key, $value, $_default_value );
343 559 }
@@ -345,9 +561,9 @@
345 561 return $_settings;
346 562 }
347 563
348 564 public function get_all( $raw = false ) {
349 - $_default_settings = $raw ? [] : array_merge( $this->get_default(), $this->get_pro_defaults() );
565 + $_default_settings = $raw ? array() : array_merge( $this->get_default(), $this->get_pro_defaults() );
350 566 $_settings = $this->database->get( $this->base_key, $_default_settings );
351 567
352 568 return $this->get_normalized_values( $_settings, $_default_settings );
353 569 }
@@ -352,9 +568,9 @@
352 568 return $this->get_normalized_values( $_settings, $_default_settings );
353 569 }
354 570
355 571 public function type_validation( &$value, $defaultValue = null ) {
356 - if ( $defaultValue !== null ) {
572 + if ( null !== $defaultValue ) {
357 573 /**
358 574 * Check if value is not in same type
359 575 */
360 576 $_default_type = gettype( $defaultValue );
@@ -389,9 +605,9 @@
389 605 $_value = $default;
390 606 break;
391 607 // Check if it's a FREE Option and not in DB.
392 608 case ! isset( $_settings[ $key ] ) && isset( $_default_settings[ $key ] ):
393 - $_value = $default !== null ? $default : $_default_settings[ $key ];
609 + $_value = null !== $default ? $default : $_default_settings[ $key ];
394 610 break;
395 611 // Check if it's a FREE Option
396 612 case isset( $_settings[ $key ] ) && isset( $_default_settings[ $key ] ):
397 613 $_value = $_settings[ $key ];
@@ -400,11 +616,11 @@
400 616
401 617 $_value = $this->get_normalized_value( $key, $_value, isset( $_default_settings[ $key ] ) ? $_default_settings[ $key ] : null );
402 618
403 619 if ( gettype( $_value ) === 'string' ) {
404 - if ( empty( $_value ) && $default != null ) {
620 + if ( empty( $_value ) && null != $default ) {
405 621 $_value = $default;
406 - } elseif ( empty( $_value ) && $default === null && isset( $_default_settings[ $key ] ) ) {
622 + } elseif ( empty( $_value ) && null === $default && isset( $_default_settings[ $key ] ) ) {
407 623 $_value = $_default_settings[ $key ];
408 624 }
409 625 }
410 626
@@ -411,9 +627,9 @@
411 627 return $_value;
412 628 }
413 629
414 630 public function get_raw_field( $key, $default = null ) {
415 - $_settings = $this->database->get( $this->base_key, [] );
631 + $_settings = $this->database->get( $this->base_key, array() );
416 632
417 633 if ( isset( $_settings[ $key ] ) ) {
418 634 return $this->get_normalized_value( $key, $_settings[ $key ], $default );
419 635 }
@@ -421,9 +637,9 @@
421 637 return $default;
422 638 }
423 639
424 640 public function save( $key, $value ) {
425 - $_settings = $this->database->get( $this->base_key, [] );
641 + $_settings = $this->database->get( $this->base_key, array() );
426 642 $_settings[ $key ] = $value;
427 643
428 644 return $this->database->save( $this->base_key, $_settings );
429 645 }
@@ -433,20 +649,141 @@
433 649 if ( ! current_user_can( 'edit_docs_settings' ) ) {
434 650 return new WP_Error( 'unauthorized_action', __( 'You don\'t have any rights for saving settings.', 'betterdocs' ) );
435 651 }
436 652
653 + // The frontend sends the currently-active settings tab as a transport-only hint so
654 + // tab-scoped validation (the AI min-token floor below) only runs when that tab is being
655 + // saved. It must never be persisted into the settings option.
656 + $active_tab = '';
657 + if ( array_key_exists( '_active_tab', $settings ) ) {
658 + $active_tab = (string) $settings[ '_active_tab' ];
659 + unset( $settings[ '_active_tab' ] );
660 + }
661 +
662 + // Quickbuilder sends back the full UI-loaded payload. To avoid overwriting values that we
663 + // asynchronously updated in the DB via AJAX (like Git integration fields), we strictly remove them
664 + // from the incoming save payload so that the freshly loaded `$_old_settings` values persist.
665 + $exclude_ajax_keys = array( 'git_provider', 'git_repository_url', 'git_branch', 'git_docs_directory' );
666 + foreach ( $exclude_ajax_keys as $key ) {
667 + if ( array_key_exists( $key, $settings ) ) {
668 + unset( $settings[ $key ] );
669 + }
670 + if ( isset( $settings[ 'values' ] ) && is_array( $settings[ 'values' ] ) && array_key_exists( $key, $settings[ 'values' ] ) ) {
671 + unset( $settings[ 'values' ][ $key ] );
672 + }
673 + }
674 +
437 675 $_old_settings = $this->database->get( $this->base_key, $this->get_default() );
676 +
677 + // The frontend only ever sees masked API keys. A submitted value that still looks like a
678 + // mask (contains a run of asterisks — no real key does) means "unchanged": restore the
679 + // stored original so a mask string is never persisted. Guarding on the mask SHAPE rather
680 + // than strict equality with mask(stored) closes the corruption loop QA hit: once a mask
681 + // slips into storage, mask(mask) === mask, so an equality-only guard would faithfully
682 + // preserve the corrupted value forever (round-2 follow-up #1). When the stored value is
683 + // itself mask-shaped it is unrecoverable — clear it so the UI and the GeoIP/GA4 status
684 + // surfaces honestly report a missing key instead of failing downstream with 401s.
685 + $sensitive_api_keys = self::sensitive_api_key_fields();
686 + foreach ( $sensitive_api_keys as $api_key_field ) {
687 + if ( ! isset( $settings[ $api_key_field ] ) ) {
688 + continue;
689 + }
690 + $incoming = trim( (string) $settings[ $api_key_field ] );
691 + $stored = isset( $_old_settings[ $api_key_field ] ) ? (string) $_old_settings[ $api_key_field ] : '';
692 + $stored_is_mask = '' !== $stored && preg_match( '/\*{4,}/', $stored );
693 +
694 + if ( '' !== $incoming && preg_match( '/\*{4,}/', $incoming ) ) {
695 + $settings[ $api_key_field ] = $stored_is_mask ? '' : $stored;
696 + }
697 + }
698 +
699 + // Minimum-token policy: reject saves where a feature's max_token field is below the
700 + // per-model floor defined by AIHelper::get_min_tokens(). The model may be unchanged in
701 + // this submission, so fall back to the stored value when it isn't part of the payload.
702 + // Both token fields live under the AI Content Suite tab, so enforce the floor only when
703 + // that tab is the one being saved — saving any other settings page never trips it (e.g.
704 + // old users whose stored value predates the floor). When the active-tab hint is absent
705 + // (stale cached JS, the quick-setup wizard, or any programmatic caller) the loop is
706 + // skipped and the save is allowed through.
707 + $token_pairs = array(
708 + array(
709 + 'tab' => 'tab-betterdocs-ai',
710 + 'context' => 'write_with_ai',
711 + 'token_key' => 'ai_autowrite_max_token',
712 + 'model_key' => 'ai_model',
713 + 'label' => __( 'Write with AI', 'betterdocs' )
714 + ),
715 + array(
716 + 'tab' => 'tab-betterdocs-ai',
717 + 'context' => 'article_summary',
718 + 'token_key' => 'article_summary_max_token',
719 + 'model_key' => 'ai_model',
720 + 'label' => __( 'AI Doc Summarizer', 'betterdocs' )
721 + )
722 + );
723 + foreach ( $token_pairs as $pair ) {
724 + if ( $active_tab !== $pair[ 'tab' ] ) {
725 + continue;
726 + }
727 + if ( ! array_key_exists( $pair[ 'token_key' ], $settings ) ) {
728 + continue;
729 + }
730 + $incoming_tokens = (int) $settings[ $pair[ 'token_key' ] ];
731 + $incoming_model = isset( $settings[ $pair[ 'model_key' ] ] )
732 + ? $settings[ $pair[ 'model_key' ] ]
733 + : ( isset( $_old_settings[ $pair[ 'model_key' ] ] ) ? $_old_settings[ $pair[ 'model_key' ] ] : '' );
734 + $min = AIHelper::get_min_tokens( $pair[ 'context' ], $incoming_model );
735 + if ( $min > 0 && $incoming_tokens < $min ) {
736 + return new WP_Error(
737 + 'min_tokens_below_threshold',
738 + sprintf(
739 + /* translators: 1: feature label, 2: minimum tokens, 3: model id */
740 + __( '%1$s max tokens must be at least %2$d for %3$s.', 'betterdocs' ),
741 + $pair[ 'label' ],
742 + $min,
743 + $incoming_model
744 + )
745 + );
746 + }
747 + }
748 +
438 749 // @todo: sanitize the data before inject in DB.
439 750 $_normalized_settings = $this->get_normalized_values( $settings );
440 - if ( $existing_plugins && isset( $_normalized_settings['migration_step'] ) && $_normalized_settings['migration_step'] == true ) {
751 + if ( $existing_plugins && isset( $_normalized_settings[ 'migration_step' ] ) && true == $_normalized_settings[ 'migration_step' ] ) {
441 752 betterdocs()->kbmigration->migrate();
442 753 }
443 754 $_settings = wp_parse_args( $_normalized_settings, $_old_settings );
444 - $_saved = $this->database->save( $this->base_key, $_settings );
445 755
446 - do_action_ref_array( 'betterdocs::settings::saved', [ $_saved, $_settings, $_old_settings, &$this ] );
756 + // Detect whether this save actually changes the effective settings.
757 + //
758 + // The stored option and the submitted payload are normalized differently:
759 + // an optional field can be ABSENT from storage yet arrive as '' (e.g.
760 + // Feedback URL), and array fields can be stored empty ( [] ) while their
761 + // normalized/default form is non-empty (e.g. Instant Answer's
762 + // display_ia_texonomy defaults to ['all']). Comparing the raw arrays
763 + // ( $_settings != $_old_settings ) therefore reported a phantom change on
764 + // every save, leaving the tab perpetually "dirty" and always toasting
765 + // "Changes Saved Successfully." instead of "There are no changes to be
766 + // saved." — see WPDevelopers/betterdocs-pro#78.
767 + //
768 + // Compare like-for-like instead: fill defaults on both sides and run both
769 + // through the same normalization, so semantically-equal states (absent vs
770 + // '', [] vs ['all'], 'on' vs true) collapse to identical values and only a
771 + // real edit registers. This is also more reliable than update_option()'s
772 + // return, which is false whenever values serialize identically under object
773 + // caching or type coercion even when the user did change something (#49).
774 + $_defaults = array_merge( $this->get_default(), $this->get_pro_defaults() );
775 + $_old_normalized = $this->get_normalized_values( wp_parse_args( $_old_settings, $_defaults ), $_defaults );
776 + $_new_normalized = $this->get_normalized_values( wp_parse_args( $_settings, $_defaults ), $_defaults );
777 + $_has_changes = $_new_normalized != $_old_normalized;
447 778
448 - return $_saved;
779 + $_saved = $this->database->save( $this->base_key, $_settings );
780 +
781 + do_action_ref_array( 'betterdocs::settings::saved', array( $_saved, $_settings, $_old_settings, &$this ) );
782 +
783 + // The success / no-changes toast reflects whether the user made a real
784 + // change, not update_option()'s (unreliable) return value.
785 + return $_has_changes;
449 786 }
450 787
451 788 public function views( $hook ) {
452 789 return betterdocs()->views->get( 'admin/settings' );
@@ -458,19 +795,19 @@
458 795 return $this->database->save( $this->base_key, $_settings );
459 796 }
460 797
461 798 public function get_pages() {
462 - $_pages = betterdocs()->query->get_posts( [
463 - 'post_type' => 'page',
464 - 'numberposts' => -1,
465 - 'post_status' => 'publish',
799 + $_pages = betterdocs()->query->get_posts( array(
800 + 'post_type' => 'page',
801 + 'numberposts' => -1,
802 + 'post_status' => 'publish',
466 803 'posts_per_page' => -1
467 - ] );
804 + ) );
468 805
469 - $__pages = [];
806 + $__pages = array();
470 807
471 808 if ( ! empty( $_pages ) ) {
472 - $__pages[0] = __( 'Select a Page', 'betterdocs' );
809 + $__pages[ 0 ] = __( 'Select a Page', 'betterdocs' );
473 810 foreach ( $_pages->posts as $page ) {
474 811 $__pages[ $page->ID ] = esc_html( $page->post_title );
475 812 }
476 813 }
@@ -480,677 +817,836 @@
480 817
481 818 public function settings_args() {
482 819 $wp_roles = $this->normalize_options( $this->get_roles() );
483 820
484 - $settings = [
485 - 'id' => 'betterdocs_settings_metabox_wrapper',
486 - 'title' => __( 'betterdocs', 'betterdocs' ),
487 - 'object_types' => [ 'betterdocs' ],
488 - 'context' => 'normal',
489 - 'priority' => 'high',
490 - 'show_header' => false,
491 - 'tabnumber' => false,
821 + $roles_for_ikb = $this->normalize_options( array_merge( array( 'all' => __( 'All logged in users', 'betterdocs' ) ), wp_roles()->role_names ) );
822 +
823 + unset( $roles_for_ikb[ 'administrator' ] );
824 +
825 + $settings = array(
826 + 'id' => 'betterdocs_settings_metabox_wrapper',
827 + 'title' => __( 'betterdocs', 'betterdocs' ),
828 + 'object_types' => array( 'betterdocs' ),
829 + 'context' => 'normal',
830 + 'priority' => 'high',
831 + 'show_header' => false,
832 + 'tabnumber' => false,
492 833 'is_pro_active' => betterdocs()->is_pro_active(),
493 - 'logoURL' => betterdocs()->assets->icon( 'betterdocs-icon.svg', true ),
494 - 'layout' => 'vertical',
495 - 'config' => [
496 - 'active' => 'tab-general',
834 + 'logoURL' => betterdocs()->assets->icon( 'betterdocs-icon.svg', true ),
835 + 'layout' => 'vertical',
836 + 'config' => array(
837 + 'active' => 'tab-general',
497 838 'sidebar' => true,
498 - 'title' => false
499 - ],
500 - 'submit' => [
501 - 'show' => true,
502 - 'label' => __( 'Save', 'betterdocs' ),
839 + 'title' => false
840 + ),
841 + 'submit' => array(
842 + 'show' => true,
843 + 'label' => __( 'Save', 'betterdocs' ),
503 844 'loadingLabel' => __( 'Saving...', 'betterdocs' ),
504 - 'class' => 'save-settings',
505 - 'rules' => Rules::logicalRule( [
845 + 'class' => 'save-settings',
846 + 'rules' => Rules::logicalRule( array(
506 847 Rules::is( 'config.active', 'tab-design', true ),
507 848 Rules::is( 'config.active', 'tab-shortcodes', true ),
508 849 Rules::is( 'config.active', 'tab-instant-answer', true ),
509 850 Rules::is( 'config.active', 'tab-import-export', true ),
510 - Rules::is( 'config.active', 'tab-migration', true ),
511 - ], 'and' )
512 - ],
513 - 'values' => $this->get_all(),
514 - 'tabs' => apply_filters( 'betterdocs_settings_tabs', [
515 - 'tab-general' => apply_filters( 'betterdocs_settings_tab_general', [
516 - 'id' => 'tab-general',
517 - 'label' => __( 'General', 'betterdocs' ),
518 - 'classes' => 'tab-general',
851 + Rules::is( 'config.active', 'tab-migration', true )
852 + ), 'and' )
853 + ),
854 + 'values' => betterdocs()->is_pro_active() ? $this->get_all() : array_merge( $this->get_all(), $this->pro_settings_default_values() ),
855 + 'tabs' => apply_filters( 'betterdocs_settings_tabs', array(
856 + 'tab-general' => apply_filters( 'betterdocs_settings_tab_general', array(
857 + 'id' => 'tab-general',
858 + 'label' => __( 'General', 'betterdocs' ),
859 + 'classes' => 'tab-general',
519 860 'priority' => 10,
520 - 'fields' => [
521 - 'title-general' => [
522 - 'name' => 'title-general-tab',
523 - 'type' => 'section',
524 - 'label' => __( 'General Settings', 'betterdocs' ),
861 + 'fields' => array(
862 + 'title-general' => apply_filters( 'betterdocs_encyclopedia_settings', array(
863 + 'name' => 'title-general-tab',
864 + 'type' => 'section',
865 + 'label' => __( 'General Settings', 'betterdocs' ),
525 866 'priority' => 10,
526 - 'fields' => [
527 - 'multiple_kb' => apply_filters( 'betterdocs_multi_kb_settings', [
528 - 'name' => 'multiple_kb',
529 - 'type' => 'toggle',
530 - 'label' => __( 'Multiple Knowledge Base', 'betterdocs' ),
867 + 'fields' => array(
868 + 'multiple_kb' => apply_filters( 'betterdocs_multi_kb_settings', array(
869 + 'name' => 'multiple_kb',
870 + 'type' => 'toggle',
871 + 'label' => __( 'Multiple Knowledge Base', 'betterdocs' ),
531 872 'enable_disable_text_active' => true,
532 - 'default' => '',
533 - 'priority' => 1,
534 - 'is_pro' => true
535 - ] ),
536 - 'builtin_doc_page' => [
537 - 'name' => 'builtin_doc_page',
538 - 'type' => 'toggle',
539 - 'label' => __( 'Built-in Documentation Page', 'betterdocs' ),
873 + 'default' => '',
874 + 'priority' => 1,
875 + 'is_pro' => true
876 + ) ),
877 + 'builtin_doc_page' => array(
878 + 'name' => 'builtin_doc_page',
879 + 'type' => 'toggle',
880 + 'label' => __( 'Built-in Documentation Page', 'betterdocs' ),
540 881 'enable_disable_text_active' => true,
541 - 'default' => 1,
542 - 'priority' => 2,
543 - 'label_subtitle' => __( 'If you disable root slug for KB Archives, your individual knowledge base URL will be like this: https://example.com/knowledgebase-1', 'betterdocs' )
544 - ],
545 - 'breadcrumb_doc_title' => [
546 - 'name' => 'breadcrumb_doc_title',
547 - 'type' => 'text',
548 - 'label' => __( 'Documentation Page Title', 'betterdocs' ),
549 - 'default' => 'Docs',
550 - 'priority' => 3
551 - ],
552 - 'docs_slug' => [
553 - 'name' => 'docs_slug',
554 - 'type' => 'text',
555 - 'label' => __( 'BetterDocs Root Slug', 'betterdocs' ),
556 - 'default' => 'docs',
882 + 'default' => 1,
883 + 'priority' => 2
884 + ),
885 + 'enable_category_hierarchy_slugs' => array(
886 + 'name' => 'enable_category_hierarchy_slugs',
887 + 'type' => 'toggle',
888 + 'label' => __( 'Enable Category Hierarchy Slug', 'betterdocs' ),
889 + 'enable_disable_text_active' => true,
890 + 'default' => false,
891 + 'priority' => 3,
892 + 'label_subtitle' => __( "Shows Hierarchy Based Permalink Slugs For Doc Categories & Single Doc Page", 'betterdocs' )
893 + ),
894 + 'breadcrumb_doc_title' => array(
895 + 'name' => 'breadcrumb_doc_title',
896 + 'type' => 'text',
897 + 'label' => __( 'Documentation Page Title', 'betterdocs' ),
898 + 'default' => __( 'Docs', 'betterdocs' ),
557 899 'priority' => 4,
558 - 'rules' => Rules::is( 'builtin_doc_page', true )
559 - ],
560 - 'docs_page' => [
561 - 'name' => 'docs_page',
562 - 'label' => __( 'Docs Page', 'betterdocs' ),
563 - 'type' => 'select',
564 - 'default' => 0,
565 - 'priority' => 5,
566 - 'search' => true,
567 - 'options' => $this->normalize_options( $this->get_pages() ),
900 + 'rules' => Rules::is( 'builtin_doc_page', true )
901 + ),
902 + 'docs_slug' => array(
903 + 'name' => 'docs_slug',
904 + 'type' => 'text',
905 + 'label' => __( 'BetterDocs Root Slug', 'betterdocs' ),
906 + 'default' => 'docs',
907 + 'priority' => 5,
908 + 'rules' => Rules::is( 'builtin_doc_page', true )
909 + ),
910 + 'docs_page' => array(
911 + 'name' => 'docs_page',
912 + 'label' => __( 'Docs Page', 'betterdocs' ),
913 + 'type' => 'select',
914 + 'default' => 0,
915 + 'priority' => 6,
916 + 'search' => true,
917 + 'options' => $this->normalize_options( $this->get_pages() ),
568 918 'label_subtitle' => __( 'You will need to insert BetterDocs Shortcode inside the page. This page will be used as docs permalink.', 'betterdocs' ),
569 - 'rules' => Rules::is( 'builtin_doc_page', false )
570 - ],
571 - 'category_slug' => [
572 - 'name' => 'category_slug',
573 - 'type' => 'text',
574 - 'label' => __( 'Custom Category Slug', 'betterdocs' ),
575 - 'default' => 'docs-category',
576 - 'priority' => 6
577 - ],
578 - 'tag_slug' => [
579 - 'name' => 'tag_slug',
580 - 'type' => 'text',
581 - 'label' => __( 'Custom Tag Slug', 'betterdocs' ),
582 - 'default' => 'docs-tag',
919 + 'rules' => Rules::is( 'builtin_doc_page', false )
920 + ),
921 +
922 + 'category_slug' => array(
923 + 'name' => 'category_slug',
924 + 'type' => 'text',
925 + 'label' => __( 'Custom Category Slug', 'betterdocs' ),
926 + 'default' => 'docs-category',
583 927 'priority' => 7
584 - ],
585 - 'permalink_structure' => [
586 - 'name' => 'permalink_structure',
587 - 'type' => 'permalink_structure',
588 - 'label' => __( 'Single Docs Permalink', 'betterdocs' ),
589 - 'default' => PostType::permalink_structure(),
590 - 'priority' => 9,
591 - 'tags' => $this->normalize_options( [
592 - '%doc_category%' => '%doc_category%',
928 + ),
929 + 'tag_slug' => array(
930 + 'name' => 'tag_slug',
931 + 'type' => 'text',
932 + 'label' => __( 'Custom Tag Slug', 'betterdocs' ),
933 + 'default' => 'docs-tag',
934 + 'priority' => 8
935 + ),
936 + 'permalink_structure' => array(
937 + 'name' => 'permalink_structure',
938 + 'type' => 'permalink_structure',
939 + 'label' => __( 'Single Docs Permalink', 'betterdocs' ),
940 + 'default' => PostType::permalink_structure(),
941 + 'priority' => 9,
942 + 'tags' => $this->normalize_options( array(
943 + '%doc_category%' => '%doc_category%',
593 944 '%knowledge_base%' => '%knowledge_base%'
594 - ] ),
945 + ) ),
595 946 'label_subtitle' => __( 'Make sure to keep Docs Root Slug in the Single Docs Permalink. You are not able to keep it blank. You can use the available tags from below.', 'betterdocs' )
596 - ],
597 - 'enable_faq_schema' => [
598 - 'name' => 'enable_faq_schema',
599 - 'type' => 'toggle',
600 - 'label' => __( 'FAQ Schema', 'betterdocs' ),
947 + ),
948 + 'enable_glossaries' => array(
949 + 'name' => 'enable_glossaries',
950 + 'type' => 'toggle',
951 + 'label' => __( 'Show Glossary', 'betterdocs' ),
952 + 'label_subtitle' => __( 'Enable the glossary feature to allow users to look up definitions for terms used within your encyclopedia or glossaries themselves.', 'betterdocs' ),
601 953 'enable_disable_text_active' => true,
602 - 'default' => '',
603 - 'priority' => 10
604 - ],
605 - 'analytics_from' => [
606 - 'name' => 'analytics_from',
607 - 'type' => 'select',
608 - 'label' => __( 'Analytics From', 'betterdocs' ),
609 - 'options' => $this->normalize_options( [
610 - 'everyone' => __( 'Everyone', 'betterdocs' ),
611 - 'guests' => __( 'Guests Only', 'betterdocs' ),
954 + 'default' => false,
955 + 'priority' => 10,
956 + 'is_pro' => true
957 + ),
958 + 'enable_encyclopedia' => array(
959 + 'name' => 'enable_encyclopedia',
960 + 'type' => 'toggle',
961 + 'label' => __( 'Built-in Encyclopedia Page', 'betterdocs' ),
962 + 'enable_disable_text_active' => true,
963 + 'default' => false,
964 + 'priority' => 11,
965 + 'is_pro' => true
966 + ),
967 + 'enable_faq_schema' => array(
968 + 'name' => 'enable_faq_schema',
969 + 'type' => 'toggle',
970 + 'label' => __( 'FAQ Schema', 'betterdocs' ),
971 + 'enable_disable_text_active' => true,
972 + 'default' => '',
973 + 'priority' => 12
974 + ),
975 + 'analytics_from' => array(
976 + 'name' => 'analytics_from',
977 + 'type' => 'select',
978 + 'label' => __( 'Analytics From', 'betterdocs' ),
979 + 'options' => $this->normalize_options( array(
980 + 'everyone' => __( 'Everyone', 'betterdocs' ),
981 + 'guests' => __( 'Guests Only', 'betterdocs' ),
612 982 'registered_users' => __( 'Registered Users Only', 'betterdocs' )
613 - ] ),
614 - 'default' => 'everyone',
615 - 'priority' => 11,
616 - 'is_pro' => true
617 - ],
618 - 'exclude_bot_analytics' => [
619 - 'name' => 'exclude_bot_analytics',
620 - 'type' => 'toggle',
621 - 'label' => __( 'Exclude Bot Analytics', 'betterdocs' ),
983 + ) ),
984 + 'default' => 'everyone',
985 + 'priority' => 13,
986 + 'is_pro' => true
987 + ),
988 + 'unique_visitor_count' => array(
989 + 'name' => 'unique_visitor_count',
990 + 'type' => 'toggle',
991 + 'label' => __( 'Unique Visitor Count', 'betterdocs' ),
622 992 'enable_disable_text_active' => true,
623 - 'default' => true,
624 - 'priority' => 12,
625 - 'is_pro' => true
626 - ]
627 - ]
628 - ]
629 - ]
630 - ] ),
631 - 'tab-layout' => apply_filters( 'betterdocs_settings_tab_layout', [
632 - 'id' => 'tab-layout',
633 - 'label' => __( 'Layout', 'betterdocs' ),
634 - 'classes' => 'tab-layout',
993 + 'default' => false,
994 + 'priority' => 14,
995 + 'is_pro' => true
996 + ),
997 + 'exclude_bot_analytics' => array(
998 + 'name' => 'exclude_bot_analytics',
999 + 'type' => 'toggle',
1000 + 'label' => __( 'Exclude Bot Analytics', 'betterdocs' ),
1001 + 'enable_disable_text_active' => true,
1002 + 'default' => false,
1003 + 'priority' => 15,
1004 + 'is_pro' => true
1005 + )
1006 +
1007 + )
1008 + ) )
1009 + )
1010 + ) ),
1011 + 'tab-layout' => apply_filters( 'betterdocs_settings_tab_layout', array(
1012 + 'id' => 'tab-layout',
1013 + 'label' => __( 'Layout', 'betterdocs' ),
1014 + 'classes' => 'tab-layout',
635 1015 'priority' => 20,
636 - 'fields' => [
637 - 'title-layout' => [
638 - 'name' => 'title-layout-tab',
639 - 'type' => 'section',
640 - 'label' => __( 'Layout Settings', 'betterdocs' ),
1016 + 'fields' => array(
1017 + 'title-layout' => array(
1018 + 'name' => 'title-layout-tab',
1019 + 'type' => 'section',
1020 + 'label' => __( 'Layout Settings', 'betterdocs' ),
641 1021 'priority' => 20,
642 - 'fields' => [
643 - 'tab-sidebar-layout' => apply_filters( 'betterdocs_settings_tab_sidebar_layout', [
644 - 'id' => 'tab-sidebar-layout',
645 - 'name' => 'tab_sidebar_layout',
646 - 'label' => __( 'Layout Settings', 'betterdocs' ),
647 - 'classes' => 'tab-layout',
648 - 'type' => "tab",
649 - 'active' => "layout_documentation_page",
1022 + 'fields' => array(
1023 + 'tab-sidebar-layout' => apply_filters( 'betterdocs_settings_tab_sidebar_layout', array(
1024 + 'id' => 'tab-sidebar-layout',
1025 + 'name' => 'tab_sidebar_layout',
1026 + 'label' => __( 'Layout Settings', 'betterdocs' ),
1027 + 'classes' => 'tab-layout',
1028 + 'type' => 'tab',
1029 + 'active' => 'layout_documentation_page',
650 1030 'completionTrack' => true,
651 - 'sidebar' => false,
652 - 'save' => false,
653 - 'title' => false,
654 - 'config' => [
655 - 'active' => 'layout_documentation_page',
1031 + 'sidebar' => false,
1032 + 'save' => false,
1033 + 'title' => false,
1034 + 'config' => array(
1035 + 'active' => 'layout_documentation_page',
656 1036 'sidebar' => false,
657 - 'title' => false
658 - ],
659 - 'submit' => [
1037 + 'title' => false
1038 + ),
1039 + 'submit' => array(
660 1040 'show' => false
661 - ],
662 - 'step' => [
1041 + ),
1042 + 'step' => array(
663 1043 'show' => false
664 - ],
665 - 'priority' => 20,
666 - 'fields' => [
667 - 'layout_documentation_page' => [
668 - 'id' => 'layout_documentation_page',
669 - 'name' => 'layout_documentation_page',
670 - 'type' => 'section',
671 - 'label' => __( 'Documentation Page', 'betterdocs' ),
1044 + ),
1045 + 'priority' => 20,
1046 + 'fields' => array(
1047 + 'layout_documentation_page' => array(
1048 + 'id' => 'layout_documentation_page',
1049 + 'name' => 'layout_documentation_page',
1050 + 'type' => 'section',
1051 + 'label' => __( 'Documentation Page', 'betterdocs' ),
672 1052 'priority' => 1,
673 - 'fields' => [
674 - 'tab-nested-layout-1' => [
675 - 'id' => 'tab-nested-layout-1',
676 - 'name' => 'tab_nested_layout_1',
677 - 'label' => __( 'Documentation Page', 'betterdocs' ),
678 - 'classes' => 'tab-nested-layout',
679 - 'type' => "tab",
680 - 'active' => "layout_documentation_page_general",
1053 + 'fields' => array(
1054 + 'tab-nested-layout-1' => array(
1055 + 'id' => 'tab-nested-layout-1',
1056 + 'name' => 'tab_nested_layout_1',
1057 + 'label' => __( 'Documentation Page', 'betterdocs' ),
1058 + 'classes' => 'tab-nested-layout',
1059 + 'type' => 'tab',
1060 + 'active' => 'layout_documentation_page_general',
681 1061 'completionTrack' => true,
682 - 'sidebar' => false,
683 - 'save' => false,
684 - 'title' => false,
685 - 'config' => [
686 - 'active' => 'layout_documentation_page_general',
1062 + 'sidebar' => false,
1063 + 'save' => false,
1064 + 'title' => false,
1065 + 'config' => array(
1066 + 'active' => 'layout_documentation_page_general',
687 1067 'sidebar' => false,
688 - 'title' => false
689 - ],
690 - 'submit' => [
1068 + 'title' => false
1069 + ),
1070 + 'submit' => array(
691 1071 'show' => false
692 - ],
693 - 'step' => [
1072 + ),
1073 + 'step' => array(
694 1074 'show' => false
695 - ],
696 - 'priority' => 1,
697 - 'fields' => [
698 - 'layout_documentation_page_general' => [
699 - 'id' => 'layout_documentation_page_general',
700 - 'name' => 'layout_documentation_page_general',
701 - 'type' => 'section',
702 - 'label' => __( 'General', 'betterdocs' ),
1075 + ),
1076 + 'priority' => 1,
1077 + 'fields' => array(
1078 + 'layout_documentation_page_general' => array(
1079 + 'id' => 'layout_documentation_page_general',
1080 + 'name' => 'layout_documentation_page_general',
1081 + 'type' => 'section',
1082 + 'label' => __( 'General', 'betterdocs' ),
703 1083 'priority' => 1,
704 - 'fields' => [
705 - 'category_title_link' => [
706 - 'name' => 'category_title_link',
707 - 'type' => 'toggle',
708 - 'label' => __( 'Category Title Link', 'betterdocs' ),
709 - 'label_subtitle' => __( 'This setting is applicable for category grid layout', 'betterdocs' ),
1084 + 'fields' => array(
1085 + 'docs_list_icon' => array(
1086 + 'name' => 'docs_list_icon',
1087 + 'type' => 'media',
1088 + 'value' => '',
1089 + 'label' => __( 'Docs List Icon', 'betterdocs' ),
1090 + 'label_subtitle' => __( 'Upload your own preferred document list icon', 'betterdocs' ),
1091 + 'priority' => 0
1092 + ),
1093 + 'category_title_link' => array(
1094 + 'name' => 'category_title_link',
1095 + 'type' => 'toggle',
1096 + 'label' => __( 'Category Title Link', 'betterdocs' ),
1097 + 'label_subtitle' => __( 'This setting is applicable for category grid layout', 'betterdocs' ),
710 1098 'enable_disable_text_active' => true,
711 - 'default' => false,
712 - 'priority' => 0
713 - ],
714 - 'masonry_layout' => [
715 - 'name' => 'masonry_layout',
716 - 'type' => 'toggle',
717 - 'label' => __( 'Masonry', 'betterdocs' ),
1099 + 'default' => false,
1100 + 'priority' => 0
1101 + ),
1102 + 'masonry_layout' => array(
1103 + 'name' => 'masonry_layout',
1104 + 'type' => 'toggle',
1105 + 'label' => __( 'Masonry', 'betterdocs' ),
718 1106 'enable_disable_text_active' => true,
719 - 'default' => 1,
720 - 'priority' => 1
721 - ],
722 - 'nested_subcategory' => [
723 - 'name' => 'nested_subcategory',
724 - 'type' => 'toggle',
725 - 'label' => __( 'Nested Sub Category', 'betterdocs' ),
1107 + 'default' => 1,
1108 + 'priority' => 1
1109 + ),
1110 + 'archive_lazy_load_descendants' => array(
1111 + 'name' => 'archive_lazy_load_descendants',
1112 + 'type' => 'toggle',
1113 + 'label' => __( 'Lazy Load Sidebar Docs & Subcategories', 'betterdocs' ),
1114 + 'label_subtitle' => __( 'Applies to the Sidebar layout wherever it appears — single docs, category archives, and the Sidebar widget/block. Off by default: enable to render only the active category upfront and fetch the rest on click (or on scroll for the Memphis layout), cutting initial HTML size on large knowledge bases.', 'betterdocs' ),
726 1115 'enable_disable_text_active' => true,
727 - 'default' => '',
728 - 'priority' => 2
729 - ],
730 - 'column_number' => [
731 - 'name' => 'column_number',
732 - 'type' => 'number',
733 - 'label' => __( 'Number Of Columns', 'betterdocs' ),
734 - 'default' => 3,
1116 + 'default' => false,
1117 + 'priority' => 2
1118 + ),
1119 + 'nested_subcategory' => array(
1120 + 'name' => 'nested_subcategory',
1121 + 'type' => 'toggle',
1122 + 'label' => __( 'Nested Sub Category', 'betterdocs' ),
1123 + 'enable_disable_text_active' => true,
1124 + 'default' => '',
735 1125 'priority' => 3
736 - ],
737 - 'posts_number' => apply_filters( 'betterdocs_posts_number', [
738 - 'name' => 'posts_number',
739 - 'type' => 'number',
740 - 'label' => __( 'Number Of Docs', 'betterdocs' ),
1126 + ),
1127 + 'column_number' => array(
1128 + 'name' => 'column_number',
1129 + 'type' => 'number',
1130 + 'label' => __( 'Number Of Columns', 'betterdocs' ),
1131 + 'label_subtitle' => __( 'This setting is not applicable for sleek layout.', 'betterdocs' ),
1132 + 'default' => 3,
1133 + 'priority' => 4
1134 + ),
1135 + 'posts_number' => apply_filters( 'betterdocs_posts_number', array(
1136 + 'name' => 'posts_number',
1137 + 'type' => 'number',
1138 + 'label' => __( 'Number Of Docs', 'betterdocs' ),
741 1139 'label_subtitle' => __( 'This setting is not applicable for handbook layout.', 'betterdocs' ),
742 - 'default' => 10,
743 - 'priority' => 4
744 - ] ),
745 - 'post_count' => [
746 - 'name' => 'post_count',
747 - 'type' => 'toggle',
748 - 'label' => __( 'Doc Count', 'betterdocs' ),
1140 + 'default' => 10,
1141 + 'priority' => 5
1142 + ) ),
1143 + 'post_count' => array(
1144 + 'name' => 'post_count',
1145 + 'type' => 'toggle',
1146 + 'label' => __( 'Doc Count', 'betterdocs' ),
749 1147 'enable_disable_text_active' => true,
750 - 'default' => 1,
751 - 'priority' => 5
752 - ],
753 - 'count_text' => [
754 - 'name' => 'count_text',
755 - 'type' => 'text',
756 - 'label' => __( 'Count Text', 'betterdocs' ),
757 - 'default' => __( 'docs', 'betterdocs' ),
1148 + 'default' => 1,
758 1149 'priority' => 6
759 - ],
760 - 'count_text_singular' => [
761 - 'name' => 'count_text_singular',
762 - 'type' => 'text',
763 - 'label' => __( 'Count Text Singular', 'betterdocs' ),
764 - 'default' => __( 'doc', 'betterdocs' ),
1150 + ),
1151 + 'count_text' => array(
1152 + 'name' => 'count_text',
1153 + 'type' => 'text',
1154 + 'label' => __( 'Count Text', 'betterdocs' ),
1155 + 'default' => __( 'Docs', 'betterdocs' ),
765 1156 'priority' => 7
766 - ],
767 - 'exploremore_btn' => [
768 - 'name' => 'exploremore_btn',
769 - 'type' => 'toggle',
770 - 'label' => __( 'Explore More Button', 'betterdocs' ),
1157 + ),
1158 + 'count_text_singular' => array(
1159 + 'name' => 'count_text_singular',
1160 + 'type' => 'text',
1161 + 'label' => __( 'Count Text Singular', 'betterdocs' ),
1162 + 'default' => __( 'Doc', 'betterdocs' ),
1163 + 'priority' => 8
1164 + ),
1165 + 'exploremore_btn' => array(
1166 + 'name' => 'exploremore_btn',
1167 + 'type' => 'toggle',
1168 + 'label' => __( 'Explore More Button', 'betterdocs' ),
771 1169 'enable_disable_text_active' => true,
772 - 'default' => true,
773 - 'priority' => 8
774 - ],
775 - 'exploremore_btn_txt' => [
776 - 'name' => 'exploremore_btn_txt',
777 - 'type' => 'text',
778 - 'label' => __( 'Explore More Button Text', 'betterdocs' ),
779 - 'default' => __( 'Explore More', 'betterdocs' ),
780 - 'priority' => 9,
781 - 'rules' => Rules::is( 'exploremore_btn', true )
782 - ],
783 - 'betterdocs_popular_docs_text' => [
784 - 'name' => 'betterdocs_popular_docs_text',
785 - 'type' => 'text',
786 - 'label' => __( 'Popular Docs Text', 'betterdocs' ),
787 - 'default' => __( 'Popular Docs', 'betterdocs' ),
1170 + 'default' => true,
1171 + 'priority' => 9
1172 + ),
1173 + 'exploremore_btn_txt' => array(
1174 + 'name' => 'exploremore_btn_txt',
1175 + 'type' => 'text',
1176 + 'label' => __( 'Explore More Button Text', 'betterdocs' ),
1177 + 'default' => __( 'Explore More', 'betterdocs' ),
788 1178 'priority' => 10,
789 - "is_pro" => true
790 - ],
791 - 'betterdocs_popular_docs_number' => [
792 - 'name' => 'betterdocs_popular_docs_number',
793 - 'type' => 'number',
794 - 'label' => __( 'Popular Docs Number', 'betterdocs' ),
795 - 'default' => 10,
1179 + 'rules' => Rules::is( 'exploremore_btn', true )
1180 + ),
1181 + 'betterdocs_popular_docs_text' => array(
1182 + 'name' => 'betterdocs_popular_docs_text',
1183 + 'type' => 'text',
1184 + 'label' => __( 'Popular Docs Text', 'betterdocs' ),
1185 + 'default' => __( 'Popular Docs', 'betterdocs' ),
796 1186 'priority' => 11,
797 - "is_pro" => true
798 - ]
799 - ]
800 - ],
801 - 'layout_documentation_page_search' => [
802 - 'id' => 'layout_documentation_page_search',
803 - 'name' => 'layout_documentation_page_search',
804 - 'type' => 'section',
805 - 'label' => __( 'Search', 'betterdocs' ),
1187 + 'is_pro' => true
1188 + ),
1189 + 'betterdocs_popular_docs_number' => array(
1190 + 'name' => 'betterdocs_popular_docs_number',
1191 + 'type' => 'number',
1192 + 'label' => __( 'Popular Docs Number', 'betterdocs' ),
1193 + 'default' => 10,
1194 + 'priority' => 12,
1195 + 'is_pro' => true
1196 + )
1197 + )
1198 + ),
1199 + 'layout_documentation_page_search' => array(
1200 + 'id' => 'layout_documentation_page_search',
1201 + 'name' => 'layout_documentation_page_search',
1202 + 'type' => 'section',
1203 + 'label' => __( 'Search', 'betterdocs' ),
806 1204 'priority' => 2,
807 - 'fields' => [
808 - 'live_search' => [
809 - 'name' => 'live_search',
810 - 'type' => 'toggle',
811 - 'label' => __( 'Live Search', 'betterdocs' ),
1205 + 'fields' => array(
1206 + 'live_search' => array(
1207 + 'name' => 'live_search',
1208 + 'type' => 'toggle',
1209 + 'label' => __( 'Live Search', 'betterdocs' ),
812 1210 'enable_disable_text_active' => true,
813 - 'default' => 1,
814 - 'priority' => 1
815 - ],
816 - 'advance_search' => apply_filters( 'betterdocs_advance_search_settings', [
817 - 'name' => 'advance_search',
818 - 'type' => 'toggle',
819 - 'label' => __( 'Advanced Search', 'betterdocs' ),
1211 + 'default' => 1,
1212 + 'priority' => 1
1213 + ),
1214 + 'advance_search' => apply_filters( 'betterdocs_advance_search_settings', array(
1215 + 'name' => 'advance_search',
1216 + 'type' => 'toggle',
1217 + 'label' => __( 'Advanced Search', 'betterdocs' ),
820 1218 'enable_disable_text_active' => true,
821 - 'default' => '',
822 - 'priority' => 2,
823 - 'is_pro' => true
824 - ] ),
825 - 'child_category_exclude' => apply_filters( 'child_category_exclude', [
826 - 'name' => 'child_category_exclude',
827 - 'type' => 'toggle',
828 - 'label' => __( 'Category Search', 'betterdocs' ),
1219 + 'default' => '',
1220 + 'priority' => 2,
1221 + 'is_pro' => true
1222 + ) ),
1223 + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- legacy public filter name for category-exclude settings field, retained for back-compat.
1224 + 'child_category_exclude' => apply_filters( 'child_category_exclude', array(
1225 + 'name' => 'child_category_exclude',
1226 + 'type' => 'toggle',
1227 + 'label' => __( 'Exclude Child Terms In Category Search', 'betterdocs' ),
829 1228 'enable_disable_text_active' => true,
830 - 'default' => '',
831 - 'priority' => 3,
832 - 'is_pro' => true
833 - ] ),
834 - 'popular_keyword_limit' => apply_filters( 'betterdocs_popular_keyword_limit_settings', [
835 - 'name' => 'popular_keyword_limit',
836 - 'type' => 'number',
837 - 'label' => __( 'Minimum amount of Keywords Search', 'betterdocs' ),
838 - 'default' => 5,
1229 + 'default' => '',
1230 + 'priority' => 3,
1231 + 'is_pro' => true
1232 + ) ),
1233 + 'popular_keyword_limit' => apply_filters( 'betterdocs_popular_keyword_limit_settings', array(
1234 + 'name' => 'popular_keyword_limit',
1235 + 'type' => 'number',
1236 + 'label' => __( 'Minimum amount of Keywords Search', 'betterdocs' ),
1237 + 'default' => 5,
839 1238 'priority' => 4,
840 - 'is_pro' => true
841 - ] ),
842 - 'search_letter_limit' => [
843 - 'name' => 'search_letter_limit',
844 - 'type' => 'number',
845 - 'label' => __( 'Minimum Character Limit For Search Result', 'betterdocs' ),
1239 + 'is_pro' => true
1240 + ) ),
1241 + 'search_letter_limit' => array(
1242 + 'name' => 'search_letter_limit',
1243 + 'type' => 'number',
1244 + 'label' => __( 'Minimum Character Limit For Search Result', 'betterdocs' ),
846 1245 'priority' => 5,
847 - 'default' => 3
848 - ],
849 - 'search_placeholder' => [
850 - 'name' => 'search_placeholder',
851 - 'type' => 'text',
852 - 'label' => __( 'Search Placeholder', 'betterdocs' ),
853 - 'default' => __( 'Search..', 'betterdocs' ),
1246 + 'default' => 3
1247 + ),
1248 + 'search_placeholder' => array(
1249 + 'name' => 'search_placeholder',
1250 + 'type' => 'text',
1251 + 'label' => __( 'Search Placeholder', 'betterdocs' ),
1252 + 'default' => __( 'Search..', 'betterdocs' ),
854 1253 'priority' => 6
855 - ],
856 - 'search_button_text' => apply_filters( 'betterdocs_search_button_text', [
857 - 'name' => 'search_button_text',
858 - 'type' => 'text',
859 - 'label' => __( 'Search Button Text', 'betterdocs' ),
1254 + ),
1255 + 'search_button_text' => apply_filters( 'betterdocs_search_button_text', array(
1256 + 'name' => 'search_button_text',
1257 + 'type' => 'text',
1258 + 'label' => __( 'Search Button Text', 'betterdocs' ),
860 1259 'priority' => 7,
861 - 'default' => __( 'Search', 'betterdocs' ),
862 - 'is_pro' => true
863 - ] ),
864 - 'search_not_found_text' => [
865 - 'name' => 'search_not_found_text',
866 - 'type' => 'text',
867 - 'label' => __( 'Search Not Found Text', 'betterdocs' ),
868 - 'default' => 'Sorry, no docs were found.',
1260 + 'default' => __( 'Search', 'betterdocs' )
1261 + ) ),
1262 + 'search_not_found_text' => array(
1263 + 'name' => 'search_not_found_text',
1264 + 'type' => 'text',
1265 + 'label' => __( 'Search Not Found Text', 'betterdocs' ),
1266 + 'default' => 'Sorry, no docs were found.',
869 1267 'priority' => 8
870 - ],
871 - 'search_result_image' => [
872 - 'name' => 'search_result_image',
873 - 'type' => 'toggle',
874 - 'label' => __( 'Search Result Image', 'betterdocs' ),
1268 + ),
1269 + 'search_result_image' => array(
1270 + 'name' => 'search_result_image',
1271 + 'type' => 'toggle',
1272 + 'label' => __( 'Search Result Image', 'betterdocs' ),
875 1273 'enable_disable_text_active' => true,
876 - 'default' => 1,
877 - 'priority' => 9
878 - ],
879 - 'kb_based_search' => apply_filters( 'betterdocs_kb_based_search_settings', [
880 - 'name' => 'kb_based_search',
881 - 'type' => 'toggle',
882 - 'label' => __( 'KB Based Search', 'betterdocs' ),
1274 + 'default' => 1,
1275 + 'priority' => 9
1276 + ),
1277 + 'kb_based_search' => apply_filters( 'betterdocs_kb_based_search_settings', array(
1278 + 'name' => 'kb_based_search',
1279 + 'type' => 'toggle',
1280 + 'label' => __( 'KB Based Search', 'betterdocs' ),
883 1281 'enable_disable_text_active' => true,
884 - 'default' => '',
885 - 'priority' => 10,
886 - 'is_pro' => true,
887 - 'rules' => Rules::is( 'multiple_kb', true )
888 - ] )
889 - ]
890 - ],
891 - 'layout_documentation_page_order_by' => [
892 - 'id' => 'layout_documentation_page_order_by',
893 - 'name' => 'layout_documentation_page_order_by',
894 - 'type' => 'section',
895 - 'label' => __( 'Order By', 'betterdocs' ),
1282 + 'default' => '',
1283 + 'priority' => 10,
1284 + 'is_pro' => true,
1285 + 'rules' => Rules::is( 'multiple_kb', true )
1286 + ) ),
1287 + 'search_modal_search_type' => array(
1288 + 'name' => 'search_modal_search_type',
1289 + 'type' => 'select',
1290 + 'label' => __( 'Search Modal Source', 'betterdocs' ),
1291 + 'label_subtitle' => __( 'Choose the content type to be shown in the search modal. <br> <b>Note:</b> This is only applicable on Modal Search.', 'betterdocs' ),
1292 + 'default' => 'all',
1293 + 'options' => $this->normalize_options( array(
1294 + 'all' => __( 'Both (Docs + FAQs)', 'betterdocs' ),
1295 + 'docs' => __( 'Docs only', 'betterdocs' ),
1296 + 'faq' => __( 'FAQs only', 'betterdocs' )
1297 + ) ),
1298 + 'priority' => 11
1299 + )
1300 + )
1301 + ),
1302 + 'layout_documentation_page_order_by' => array(
1303 + 'id' => 'layout_documentation_page_order_by',
1304 + 'name' => 'layout_documentation_page_order_by',
1305 + 'type' => 'section',
1306 + 'label' => __( 'Order By', 'betterdocs' ),
896 1307 'priority' => 3,
897 - 'fields' => [
898 - 'terms_orderby' => [
899 - 'name' => 'terms_orderby',
900 - 'type' => 'select',
901 - 'label' => __( 'Terms Order By', 'betterdocs' ),
902 - 'default' => 'betterdocs_order',
903 - 'options' => $this->normalize_options( apply_filters( 'betterdocs_terms_orderby_options', [
904 - 'none' => __( 'No order', 'betterdocs' ),
905 - 'name' => __( 'Name', 'betterdocs' ),
906 - 'slug' => __( 'Slug', 'betterdocs' ),
907 - 'term_group' => __( 'Term Group', 'betterdocs' ),
908 - 'term_id' => __( 'Term ID', 'betterdocs' ),
909 - 'id' => __( 'ID', 'betterdocs' ),
910 - 'description' => __( 'Description', 'betterdocs' ),
911 - 'parent' => __( 'Parent', 'betterdocs' ),
1308 + 'fields' => array(
1309 + 'terms_orderby' => array(
1310 + 'name' => 'terms_orderby',
1311 + 'type' => 'select',
1312 + 'label' => __( 'Terms Order By', 'betterdocs' ),
1313 + 'default' => 'betterdocs_order',
1314 + 'options' => $this->normalize_options( apply_filters( 'betterdocs_terms_orderby_options', array(
1315 + 'none' => __( 'No order', 'betterdocs' ),
1316 + 'name' => __( 'Name', 'betterdocs' ),
1317 + 'slug' => __( 'Slug', 'betterdocs' ),
1318 + 'term_group' => __( 'Term Group', 'betterdocs' ),
1319 + 'term_id' => __( 'Term ID', 'betterdocs' ),
1320 + 'id' => __( 'ID', 'betterdocs' ),
1321 + 'description' => __( 'Description', 'betterdocs' ),
1322 + 'parent' => __( 'Parent', 'betterdocs' ),
912 1323 'betterdocs_order' => __( 'BetterDocs Order', 'betterdocs' )
913 - ] ) ),
1324 + ) ) ),
914 1325 'priority' => 1
915 - ],
916 - 'terms_order' => [
917 - 'name' => 'terms_order',
918 - 'type' => 'select',
919 - 'label' => __( 'Terms Order', 'betterdocs' ),
920 - 'default' => 'ASC',
921 - 'options' => $this->normalize_options( [
922 - 'ASC' => 'Ascending',
1326 + ),
1327 + 'terms_order' => array(
1328 + 'name' => 'terms_order',
1329 + 'type' => 'select',
1330 + 'label' => __( 'Terms Order', 'betterdocs' ),
1331 + 'default' => 'ASC',
1332 + 'options' => $this->normalize_options( array(
1333 + 'ASC' => 'Ascending',
923 1334 'DESC' => 'Descending'
924 - ] ),
925 - 'priority' => 3
926 - ],
927 - 'alphabetically_order_post' => [
928 - 'name' => 'alphabetically_order_post',
929 - 'type' => 'select',
930 - 'label' => __( 'Docs Order By', 'betterdocs' ),
931 - 'default' => 'betterdocs_order',
932 - 'options' => $this->normalize_options( [
933 - 'none' => __( 'No order', 'betterdocs' ),
934 - 'ID' => __( 'Docs ID', 'betterdocs' ),
935 - 'author' => __( 'Docs Author', 'betterdocs' ),
936 - 'title' => __( 'Title', 'betterdocs' ),
937 - 'date' => __( 'Date', 'betterdocs' ),
938 - 'modified' => __( 'Last Modified Date', 'betterdocs' ),
939 - 'parent' => __( 'Parent Id', 'betterdocs' ),
940 - 'rand' => __( 'Random', 'betterdocs' ),
941 - 'comment_count' => __( 'Comment Count', 'betterdocs' ),
942 - 'menu_order' => __( 'Menu Order', 'betterdocs' ),
1335 + ) ),
1336 + 'priority' => 3,
1337 + 'rules' => Rules::includes( 'terms_orderby', 'betterdocs_order', true )
1338 + ),
1339 + 'alphabetically_order_post' => array(
1340 + 'name' => 'alphabetically_order_post',
1341 + 'type' => 'select',
1342 + 'label' => __( 'Docs Order By', 'betterdocs' ),
1343 + 'default' => 'betterdocs_order',
1344 + 'options' => $this->normalize_options( array(
1345 + 'none' => __( 'No order', 'betterdocs' ),
1346 + 'ID' => __( 'Docs ID', 'betterdocs' ),
1347 + 'author' => __( 'Docs Author', 'betterdocs' ),
1348 + 'title' => __( 'Title', 'betterdocs' ),
1349 + 'date' => __( 'Date', 'betterdocs' ),
1350 + 'modified' => __( 'Last Modified Date', 'betterdocs' ),
1351 + 'parent' => __( 'Parent Id', 'betterdocs' ),
1352 + 'rand' => __( 'Random', 'betterdocs' ),
1353 + 'comment_count' => __( 'Comment Count', 'betterdocs' ),
1354 + 'menu_order' => __( 'Menu Order', 'betterdocs' ),
943 1355 'betterdocs_order' => __( 'BetterDocs Order', 'betterdocs' )
944 - ] ),
1356 + ) ),
945 1357 'priority' => 4
946 - ],
947 - 'docs_order' => [
948 - 'name' => 'docs_order',
949 - 'type' => 'select',
950 - 'label' => __( 'Docs Order', 'betterdocs' ),
951 - 'default' => 'ASC',
952 - 'options' => $this->normalize_options( [
953 - 'ASC' => 'Ascending',
1358 + ),
1359 + 'docs_order' => array(
1360 + 'name' => 'docs_order',
1361 + 'type' => 'select',
1362 + 'label' => __( 'Docs Order', 'betterdocs' ),
1363 + 'default' => 'ASC',
1364 + 'options' => $this->normalize_options( array(
1365 + 'ASC' => 'Ascending',
954 1366 'DESC' => 'Descending'
955 - ] ),
956 - 'priority' => 5
957 - ]
958 - ]
959 - ]
960 - ]
961 - ]
962 - ]
963 - ],
964 - 'layout_single_doc' => [
965 - 'id' => 'layout_single_doc',
966 - 'name' => 'layout_single_doc',
967 - 'type' => 'section',
968 - 'label' => __( 'Single Doc', 'betterdocs' ),
1367 + ) ),
1368 + 'priority' => 5,
1369 + 'rules' => Rules::includes( 'alphabetically_order_post', 'betterdocs_order', true )
1370 + )
1371 + )
1372 + )
1373 + )
1374 + )
1375 + )
1376 + ),
1377 + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- legacy public filter name for single-doc setting section, retained for back-compat.
1378 + 'layout_single_doc' => apply_filters( 'single_doc_setting_section', array(
1379 + 'id' => 'layout_single_doc',
1380 + 'name' => 'layout_single_doc',
1381 + 'type' => 'section',
1382 + 'label' => __( 'Single Doc', 'betterdocs' ),
969 1383 'priority' => 2,
970 - 'fields' => [
971 - 'tab-nested-layout-2' => [
972 - 'id' => 'tab-nested-layout-2',
973 - 'name' => 'tab_nested_layout_2',
974 - 'label' => __( 'Single Doc', 'betterdocs' ),
975 - 'classes' => 'tab-nested-layout',
976 - 'type' => "tab",
977 - 'active' => "layout_single_doc_general",
1384 + 'fields' => array(
1385 + 'tab-nested-layout-2' => array(
1386 + 'id' => 'tab-nested-layout-2',
1387 + 'name' => 'tab_nested_layout_2',
1388 + 'label' => __( 'Single Doc', 'betterdocs' ),
1389 + 'classes' => 'tab-nested-layout',
1390 + 'type' => 'tab',
1391 + 'active' => 'layout_single_doc_general',
978 1392 'completionTrack' => true,
979 - 'sidebar' => false,
980 - 'save' => false,
981 - 'title' => false,
982 - 'config' => [
983 - 'active' => 'layout_single_doc_general',
1393 + 'sidebar' => false,
1394 + 'save' => false,
1395 + 'title' => false,
1396 + 'config' => array(
1397 + 'active' => 'layout_single_doc_general',
984 1398 'sidebar' => false,
985 - 'title' => false
986 - ],
987 - 'submit' => [
1399 + 'title' => false
1400 + ),
1401 + 'submit' => array(
988 1402 'show' => false
989 - ],
990 - 'step' => [
1403 + ),
1404 + 'step' => array(
991 1405 'show' => false
992 - ],
993 - 'priority' => 20,
994 - 'fields' => [
995 - 'layout_single_doc_general' => [
996 - 'id' => 'layout_single_doc_general',
997 - 'name' => 'layout_single_doc_general',
998 - 'type' => 'section',
999 - 'label' => __( 'General', 'betterdocs' ),
1406 + ),
1407 + 'priority' => 20,
1408 + 'fields' => array(
1409 + 'layout_single_doc_general' => array(
1410 + 'id' => 'layout_single_doc_general',
1411 + 'name' => 'layout_single_doc_general',
1412 + 'type' => 'section',
1413 + 'label' => __( 'General', 'betterdocs' ),
1000 1414 'priority' => 5,
1001 - 'fields' => [
1002 - 'enable_post_title' => [
1003 - 'name' => 'enable_post_title',
1004 - 'type' => 'toggle',
1005 - 'label' => __( 'Doc Title', 'betterdocs' ),
1415 + 'fields' => array(
1416 + 'enable_post_title' => array(
1417 + 'name' => 'enable_post_title',
1418 + 'type' => 'toggle',
1419 + 'label' => __( 'Doc Title', 'betterdocs' ),
1006 1420 'enable_disable_text_active' => true,
1007 - 'default' => 1,
1008 - 'priority' => 1
1009 - ],
1010 - 'enable_sidebar_cat_list' => [
1011 - 'name' => 'enable_sidebar_cat_list',
1012 - 'type' => 'toggle',
1013 - 'label' => __( 'Sidebar Category List', 'betterdocs' ),
1421 + 'default' => 1,
1422 + 'priority' => 1
1423 + ),
1424 + 'enable_sidebar_cat_list' => array(
1425 + 'name' => 'enable_sidebar_cat_list',
1426 + 'type' => 'toggle',
1427 + 'label' => __( 'Sidebar Category List', 'betterdocs' ),
1014 1428 'enable_disable_text_active' => true,
1015 - 'default' => 1,
1016 - 'priority' => 2
1017 - ],
1018 - 'enable_print_icon' => [
1019 - 'name' => 'enable_print_icon',
1020 - 'type' => 'toggle',
1021 - 'label' => __( 'Print Icon', 'betterdocs' ),
1429 + 'default' => 1,
1430 + 'priority' => 2
1431 + ),
1432 + 'enable_print_icon' => array(
1433 + 'name' => 'enable_print_icon',
1434 + 'type' => 'toggle',
1435 + 'label' => __( 'Print Icon', 'betterdocs' ),
1022 1436 'enable_disable_text_active' => true,
1023 - 'default' => 1,
1024 - 'priority' => 3
1025 - ],
1026 - 'enable_tags' => [
1027 - 'name' => 'enable_tags',
1028 - 'type' => 'toggle',
1029 - 'label' => __( 'Tags', 'betterdocs' ),
1437 + 'default' => 1,
1438 + 'priority' => 3
1439 + ),
1440 + 'print_enable_logo' => array(
1441 + 'name' => 'print_enable_logo',
1442 + 'type' => 'toggle',
1443 + 'label' => __( 'Logo on Printed Doc', 'betterdocs' ),
1444 + 'label_subtitle' => __( 'Show a logo at the top of the printed / PDF page', 'betterdocs' ),
1030 1445 'enable_disable_text_active' => true,
1031 - 'default' => 1,
1032 - 'priority' => 4
1033 - ],
1034 - 'show_last_update_time' => [
1035 - 'name' => 'show_last_update_time',
1036 - 'type' => 'toggle',
1037 - 'label' => __( 'Last Update Time', 'betterdocs' ),
1446 + 'default' => 0,
1447 + 'priority' => 4
1448 + ),
1449 + 'print_logo' => array(
1450 + 'name' => 'print_logo',
1451 + 'type' => 'media',
1452 + 'value' => '',
1453 + 'label' => __( 'Print Logo', 'betterdocs' ),
1454 + 'label_subtitle' => __( 'Leave empty to use your site logo, or the site icon when no site logo is set', 'betterdocs' ),
1455 + 'priority' => 5,
1456 + 'rules' => Rules::is( 'print_enable_logo', true )
1457 + ),
1458 + 'print_enable_footer' => array(
1459 + 'name' => 'print_enable_footer',
1460 + 'type' => 'toggle',
1461 + 'label' => __( 'Footer on Printed Doc', 'betterdocs' ),
1462 + 'label_subtitle' => __( 'Show a footer on every page of the printed / PDF document', 'betterdocs' ),
1038 1463 'enable_disable_text_active' => true,
1039 - 'default' => 1,
1040 - 'priority' => 5
1041 - ],
1042 - 'enable_navigation' => [
1043 - 'name' => 'enable_navigation',
1044 - 'type' => 'toggle',
1045 - 'label' => __( 'Navigation', 'betterdocs' ),
1464 + 'default' => 0,
1465 + 'priority' => 6
1466 + ),
1467 + 'print_footer_text' => array(
1468 + 'name' => 'print_footer_text',
1469 + 'type' => 'textarea',
1470 + 'label' => __( 'Print Footer Text', 'betterdocs' ),
1471 + 'label_subtitle' => __( 'Leave empty to use the site name and current year', 'betterdocs' ),
1472 + 'default' => '',
1473 + 'priority' => 7,
1474 + 'rules' => Rules::is( 'print_enable_footer', true )
1475 + ),
1476 + 'enable_tags' => array(
1477 + 'name' => 'enable_tags',
1478 + 'type' => 'toggle',
1479 + 'label' => __( 'Tags', 'betterdocs' ),
1046 1480 'enable_disable_text_active' => true,
1047 - 'default' => 1,
1048 - 'priority' => 6
1049 - ],
1050 - 'enable_comment' => [
1051 - 'name' => 'enable_comment',
1052 - 'type' => 'toggle',
1053 - 'label' => __( 'Comment', 'betterdocs' ),
1481 + 'default' => 1,
1482 + 'priority' => 8
1483 + ),
1484 + 'show_last_update_time' => array(
1485 + 'name' => 'show_last_update_time',
1486 + 'type' => 'toggle',
1487 + 'label' => __( 'Last Update Time', 'betterdocs' ),
1054 1488 'enable_disable_text_active' => true,
1055 - 'default' => '',
1056 - 'priority' => 7
1057 - ],
1058 - 'enable_credit' => [
1059 - 'name' => 'enable_credit',
1060 - 'type' => 'toggle',
1061 - 'label' => __( 'Credit', 'betterdocs' ),
1489 + 'default' => 1,
1490 + 'priority' => 9
1491 + ),
1492 + 'enable_navigation' => array(
1493 + 'name' => 'enable_navigation',
1494 + 'type' => 'toggle',
1495 + 'label' => __( 'Navigation', 'betterdocs' ),
1062 1496 'enable_disable_text_active' => true,
1063 - 'default' => 1,
1064 - 'priority' => 8
1065 - ]
1066 - ]
1067 - ],
1068 - 'layout_single_doc_TOC' => [
1069 - 'id' => 'layout_single_doc_TOC',
1070 - 'name' => 'layout_single_doc_TOC',
1071 - 'type' => 'section',
1072 - 'label' => __( 'TOC', 'betterdocs' ),
1497 + 'default' => 1,
1498 + 'priority' => 10
1499 + ),
1500 + 'enable_comment' => array(
1501 + 'name' => 'enable_comment',
1502 + 'type' => 'toggle',
1503 + 'label' => __( 'Comment', 'betterdocs' ),
1504 + 'enable_disable_text_active' => true,
1505 + 'default' => '',
1506 + 'priority' => 11
1507 + ),
1508 + 'enable_credit' => array(
1509 + 'name' => 'enable_credit',
1510 + 'type' => 'toggle',
1511 + 'label' => __( 'Show Powered by BetterDocs', 'betterdocs' ),
1512 + 'enable_disable_text_active' => true,
1513 + 'default' => '',
1514 + 'priority' => 12
1515 + ),
1516 + 'reaction_feedback_text' => array(
1517 + 'name' => 'reaction_feedback_text',
1518 + 'type' => 'text',
1519 + 'label' => __( 'Reaction Feedback Text', 'betterdocs' ),
1520 + 'default' => __( 'Thanks for your feedback.', 'betterdocs' ),
1521 + 'priority' => 13
1522 + ),
1523 + 'enable_estimated_reading_time' => array(
1524 + 'name' => 'enable_estimated_reading_time',
1525 + 'type' => 'toggle',
1526 + 'label' => __( 'Estimated Reading Time', 'betterdocs' ),
1527 + 'enable_disable_text_active' => true,
1528 + 'default' => 0,
1529 + 'priority' => 14
1530 + ),
1531 + 'estimated_reading_time_title' => array(
1532 + 'name' => 'estimated_reading_time_title',
1533 + 'type' => 'text',
1534 + 'label' => __( 'Estimated Reading Time Title', 'betterdocs' ),
1535 + 'default' => '',
1536 + 'priority' => 15,
1537 + 'rules' => Rules::is( 'enable_estimated_reading_time', true )
1538 + ),
1539 + 'estimated_reading_time_text' => array(
1540 + 'name' => 'estimated_reading_time_text',
1541 + 'type' => 'text',
1542 + 'label' => __( 'Estimated Reading Time Text', 'betterdocs' ),
1543 + 'default' => __( 'min read', 'betterdocs' ),
1544 + 'priority' => 16,
1545 + 'rules' => Rules::is( 'enable_estimated_reading_time', true )
1546 + ),
1547 + 'singular_estimated_reading_time_text' => array(
1548 + 'name' => 'singular_estimated_reading_time_text',
1549 + 'type' => 'text',
1550 + 'label' => __( 'Estimated Reading Time Text Singular', 'betterdocs' ),
1551 + 'default' => __( 'min read', 'betterdocs' ),
1552 + 'priority' => 17,
1553 + 'rules' => Rules::is( 'enable_estimated_reading_time', true )
1554 + )
1555 + )
1556 + ),
1557 + 'layout_single_doc_TOC' => array(
1558 + 'id' => 'layout_single_doc_TOC',
1559 + 'name' => 'layout_single_doc_TOC',
1560 + 'type' => 'section',
1561 + 'label' => __( 'TOC', 'betterdocs' ),
1073 1562 'priority' => 5,
1074 - 'fields' => [
1075 - 'enable_toc' => [
1076 - 'name' => 'enable_toc',
1077 - 'type' => 'toggle',
1078 - 'label' => __( 'Table of Contents', 'betterdocs' ),
1563 + 'fields' => array(
1564 + 'enable_toc' => array(
1565 + 'name' => 'enable_toc',
1566 + 'type' => 'toggle',
1567 + 'label' => __( 'Table of Contents', 'betterdocs' ),
1079 1568 'enable_disable_text_active' => true,
1080 - 'default' => 1,
1081 - 'priority' => 1
1082 - ],
1083 - 'toc_title' => [
1084 - 'name' => 'toc_title',
1085 - 'type' => 'text',
1086 - 'label' => __( 'TOC Title', 'betterdocs' ),
1087 - 'default' => __( 'Table of Contents', 'betterdocs' ),
1569 + 'default' => 1,
1570 + 'priority' => 1
1571 + ),
1572 + 'toc_title' => array(
1573 + 'name' => 'toc_title',
1574 + 'type' => 'text',
1575 + 'label' => __( 'TOC Title', 'betterdocs' ),
1576 + 'default' => __( 'Table of Contents', 'betterdocs' ),
1088 1577 'priority' => 2,
1089 - 'rules' => Rules::is( 'enable_toc', true )
1578 + 'rules' => Rules::is( 'enable_toc', true )
1090 1579
1091 - ],
1092 - 'toc_hierarchy' => [
1093 - 'name' => 'toc_hierarchy',
1094 - 'type' => 'toggle',
1095 - 'label' => __( 'TOC Hierarchy', 'betterdocs' ),
1580 + ),
1581 + 'toc_hierarchy' => array(
1582 + 'name' => 'toc_hierarchy',
1583 + 'type' => 'toggle',
1584 + 'label' => __( 'TOC Hierarchy', 'betterdocs' ),
1096 1585 'enable_disable_text_active' => true,
1097 - 'default' => 1,
1098 - 'priority' => 3,
1099 - 'rules' => Rules::is( 'enable_toc', true )
1100 - ],
1101 - 'toc_list_number' => [
1102 - 'name' => 'toc_list_number',
1103 - 'type' => 'toggle',
1104 - 'label' => __( 'TOC List Number', 'betterdocs' ),
1586 + 'default' => 1,
1587 + 'priority' => 3,
1588 + 'rules' => Rules::is( 'enable_toc', true )
1589 + ),
1590 + 'toc_list_number' => array(
1591 + 'name' => 'toc_list_number',
1592 + 'type' => 'toggle',
1593 + 'label' => __( 'TOC List Number', 'betterdocs' ),
1105 1594 'enable_disable_text_active' => true,
1106 - 'default' => 1,
1107 - 'priority' => 4,
1108 - 'rules' => Rules::is( 'enable_toc', true )
1109 - ],
1110 - 'toc_dynamic_title' => [
1111 - 'name' => 'toc_dynamic_title',
1112 - 'type' => 'toggle',
1113 - 'label' => __( 'Show TOC Title in Anchor Links', 'betterdocs' ),
1595 + 'default' => 1,
1596 + 'priority' => 4,
1597 + 'rules' => Rules::is( 'enable_toc', true )
1598 + ),
1599 + 'toc_dynamic_title' => array(
1600 + 'name' => 'toc_dynamic_title',
1601 + 'type' => 'toggle',
1602 + 'label' => __( 'Show TOC Title in Anchor Links', 'betterdocs' ),
1114 1603 'enable_disable_text_active' => true,
1115 - 'default' => 0,
1116 - 'priority' => 5,
1117 - 'rules' => Rules::is( 'enable_toc', true )
1118 - ],
1119 - 'enable_sticky_toc' => [
1120 - 'name' => 'enable_sticky_toc',
1121 - 'type' => 'toggle',
1122 - 'label' => __( 'Sticky TOC', 'betterdocs' ),
1604 + 'default' => 0,
1605 + 'priority' => 5,
1606 + 'rules' => Rules::is( 'enable_toc', true )
1607 + ),
1608 + 'enable_sticky_toc' => array(
1609 + 'name' => 'enable_sticky_toc',
1610 + 'type' => 'toggle',
1611 + 'label' => __( 'Sticky TOC', 'betterdocs' ),
1123 1612 'enable_disable_text_active' => true,
1124 - 'default' => 1,
1125 - 'priority' => 6,
1126 - 'rules' => Rules::is( 'enable_toc', true )
1127 - ],
1128 - 'collapsible_toc_mobile' => [
1129 - 'name' => 'collapsible_toc_mobile',
1130 - 'type' => 'toggle',
1131 - 'label' => __( 'Collapsible TOC on small devices', 'betterdocs' ),
1613 + 'default' => 1,
1614 + 'priority' => 6,
1615 + 'rules' => Rules::is( 'enable_toc', true )
1616 + ),
1617 + 'collapsible_toc_mobile' => array(
1618 + 'name' => 'collapsible_toc_mobile',
1619 + 'type' => 'toggle',
1620 + 'label' => __( 'Collapsible TOC on small devices', 'betterdocs' ),
1132 1621 'enable_disable_text_active' => true,
1133 - 'default' => '',
1134 - 'priority' => 7,
1135 - 'rules' => Rules::is( 'enable_toc', true )
1136 - ],
1137 - 'title_link_ctc' => [
1138 - 'name' => 'title_link_ctc',
1139 - 'type' => 'toggle',
1140 - 'label' => __( 'Title Link Copy To Clipboard', 'betterdocs' ),
1622 + 'default' => '',
1623 + 'priority' => 7,
1624 + 'rules' => Rules::is( 'enable_toc', true )
1625 + ),
1626 + 'title_link_ctc' => array(
1627 + 'name' => 'title_link_ctc',
1628 + 'type' => 'toggle',
1629 + 'label' => __( 'Title Link Copy To Clipboard', 'betterdocs' ),
1141 1630 'enable_disable_text_active' => true,
1142 - 'default' => 1,
1143 - 'priority' => 8
1144 - ],
1145 - 'supported_heading_tag' => [
1146 - 'name' => 'supported_heading_tag',
1147 - 'label' => __( 'TOC Supported Heading Tag', 'betterdocs' ),
1148 - 'type' => 'checkbox-select',
1631 + 'default' => 1,
1632 + 'priority' => 8
1633 + ),
1634 + 'supported_heading_tag' => array(
1635 + 'name' => 'supported_heading_tag',
1636 + 'label' => __( 'TOC Supported Heading Tag', 'betterdocs' ),
1637 + 'type' => 'checkbox-select',
1149 1638 'multiple' => true,
1150 1639 'priority' => 10,
1151 - 'default' => [ '1', '2', '3', '4', '5', '6' ],
1152 - 'options' => $this->normalize_options( [
1640 + 'default' => array(
1641 + '1',
1642 + '2',
1643 + '3',
1644 + '4',
1645 + '5',
1646 + '6'
1647 + ),
1648 + 'options' => $this->normalize_options( array(
1153 1649 '1' => 'H1',
1154 1650 '2' => 'H2',
1155 1651 '3' => 'H3',
1156 1652 '4' => 'H4',
@@ -1155,927 +1651,1706 @@
1155 1651 '3' => 'H3',
1156 1652 '4' => 'H4',
1157 1653 '5' => 'H5',
1158 1654 '6' => 'H6'
1159 - ] ),
1655 + ) ),
1160 1656 'priority' => 9,
1161 - 'rules' => Rules::is( 'enable_toc', true )
1162 - ],
1163 - 'sticky_toc_offset' => [
1164 - 'name' => 'sticky_toc_offset',
1165 - 'type' => 'number',
1166 - 'label' => __( 'Content Offset', 'betterdocs' ),
1167 - 'default' => 100,
1168 - 'priority' => 10,
1657 + 'rules' => Rules::is( 'enable_toc', true )
1658 + ),
1659 + 'sticky_toc_offset' => array(
1660 + 'name' => 'sticky_toc_offset',
1661 + 'type' => 'number',
1662 + 'label' => __( 'Content Offset', 'betterdocs' ),
1663 + 'default' => 100,
1664 + 'priority' => 10,
1169 1665 'label_subtitle' => __( 'content offset from top on scroll.', 'betterdocs' ),
1170 - 'rules' => Rules::is( 'enable_toc', true )
1171 - ]
1172 - ]
1173 - ],
1174 - 'layout_single_doc_breadcrumb' => [
1175 - 'id' => 'layout_single_doc_breadcrumb',
1176 - 'name' => 'layout_single_doc_breadcrumb',
1177 - 'type' => 'section',
1178 - 'label' => __( 'Breadcrumb', 'betterdocs' ),
1666 + 'rules' => Rules::is( 'enable_toc', true )
1667 + )
1668 + )
1669 + ),
1670 + 'layout_single_doc_breadcrumb' => array(
1671 + 'id' => 'layout_single_doc_breadcrumb',
1672 + 'name' => 'layout_single_doc_breadcrumb',
1673 + 'type' => 'section',
1674 + 'label' => __( 'Breadcrumb', 'betterdocs' ),
1179 1675 'priority' => 5,
1180 - 'fields' => [
1181 - 'enable_breadcrumb' => [
1182 - 'name' => 'enable_breadcrumb',
1183 - 'type' => 'toggle',
1184 - 'label' => __( 'Breadcrumb', 'betterdocs' ),
1676 + 'fields' => array(
1677 + 'enable_breadcrumb' => array(
1678 + 'name' => 'enable_breadcrumb',
1679 + 'type' => 'toggle',
1680 + 'label' => __( 'Breadcrumb', 'betterdocs' ),
1185 1681 'enable_disable_text_active' => true,
1186 - 'default' => 1,
1187 - 'priority' => 1
1188 - ],
1189 - 'breadcrumb_home_text' => [
1190 - 'name' => 'breadcrumb_home_text',
1191 - 'type' => 'text',
1192 - 'label' => __( 'Breadcrumb Home Text', 'betterdocs' ),
1193 - 'default' => __( 'Home', 'betterdocs' ),
1682 + 'default' => 1,
1683 + 'priority' => 1
1684 + ),
1685 + 'enable_breadcrumb_home_text' => array(
1686 + 'name' => 'enable_breadcrumb_home_text',
1687 + 'type' => 'toggle',
1688 + 'label' => __( 'Enable Breadcrumb Home Text', 'betterdocs' ),
1689 + 'enable_disable_text_active' => true,
1690 + 'default' => true,
1194 1691 'priority' => 2,
1195 - 'rules' => Rules::is( 'enable_breadcrumb', true )
1196 - ],
1197 - 'breadcrumb_home_url' => [
1198 - 'name' => 'breadcrumb_home_url',
1199 - 'type' => 'text',
1200 - 'label' => __( 'Breadcrumb Home URL', 'betterdocs' ),
1692 + 'rules' => Rules::is( 'enable_breadcrumb', true )
1693 + ),
1694 + 'breadcrumb_home_text' => array(
1695 + 'name' => 'breadcrumb_home_text',
1696 + 'type' => 'text',
1697 + 'label' => __( 'Breadcrumb Home Text', 'betterdocs' ),
1698 + 'default' => __( 'Home', 'betterdocs' ),
1201 1699 'priority' => 3,
1202 - 'default' => get_home_url(),
1203 - 'rules' => Rules::is( 'enable_breadcrumb', true )
1204 - ],
1205 - 'enable_breadcrumb_category' => [
1206 - 'name' => 'enable_breadcrumb_category',
1207 - 'type' => 'toggle',
1208 - 'label' => __( 'Category on Breadcrumb', 'betterdocs' ),
1700 + 'rules' => Rules::logicalRule(
1701 + array(
1702 + Rules::is( 'enable_breadcrumb', true ),
1703 + Rules::is( 'enable_breadcrumb_home_text', true )
1704 + ),
1705 + 'and'
1706 + )
1707 + ),
1708 + 'breadcrumb_home_url' => array(
1709 + 'name' => 'breadcrumb_home_url',
1710 + 'type' => 'text',
1711 + 'label' => __( 'Breadcrumb Home URL', 'betterdocs' ),
1712 + 'priority' => 4,
1713 + 'default' => get_home_url(),
1714 + 'rules' => Rules::is( 'enable_breadcrumb', true )
1715 + ),
1716 + 'enable_breadcrumb_category' => array(
1717 + 'name' => 'enable_breadcrumb_category',
1718 + 'type' => 'toggle',
1719 + 'label' => __( 'Category on Breadcrumb', 'betterdocs' ),
1209 1720 'enable_disable_text_active' => true,
1210 - 'default' => 1,
1211 - 'priority' => 4,
1212 - 'rules' => Rules::is( 'enable_breadcrumb', true )
1213 - ],
1214 - 'enable_breadcrumb_title' => [
1215 - 'name' => 'enable_breadcrumb_title',
1216 - 'type' => 'toggle',
1217 - 'label' => __( 'Title on Breadcrumb', 'betterdocs' ),
1721 + 'default' => 1,
1722 + 'priority' => 5,
1723 + 'rules' => Rules::is( 'enable_breadcrumb', true )
1724 + ),
1725 + 'enable_breadcrumb_title' => array(
1726 + 'name' => 'enable_breadcrumb_title',
1727 + 'type' => 'toggle',
1728 + 'label' => __( 'Title on Breadcrumb', 'betterdocs' ),
1218 1729 'enable_disable_text_active' => true,
1219 - 'default' => 1,
1220 - 'priority' => 5,
1221 - 'rules' => Rules::is( 'enable_breadcrumb', true )
1222 - ]
1223 - ]
1224 - ],
1225 - 'layout_single_doc_email_feedback' => [
1226 - 'id' => 'layout_single_doc_email_feedback',
1227 - 'name' => 'layout_single_doc_email_feedback',
1228 - 'type' => 'section',
1229 - 'label' => __( 'Email Feedback', 'betterdocs' ),
1730 + 'default' => 1,
1731 + 'priority' => 6,
1732 + 'rules' => Rules::is( 'enable_breadcrumb', true )
1733 + )
1734 + )
1735 + ),
1736 + 'layout_single_doc_email_feedback' => array(
1737 + 'id' => 'layout_single_doc_email_feedback',
1738 + 'name' => 'layout_single_doc_email_feedback',
1739 + 'type' => 'section',
1740 + 'label' => __( 'Email Feedback', 'betterdocs' ),
1230 1741 'priority' => 5,
1231 - 'fields' => [
1232 - 'email_feedback' => [
1233 - 'name' => 'email_feedback',
1234 - 'type' => 'toggle',
1235 - 'label' => __( 'Email Feedback', 'betterdocs' ),
1742 + 'fields' => array(
1743 + 'email_feedback' => array(
1744 + 'name' => 'email_feedback',
1745 + 'type' => 'toggle',
1746 + 'label' => __( 'Email Feedback', 'betterdocs' ),
1236 1747 'enable_disable_text_active' => true,
1237 - 'default' => 1,
1238 - 'priority' => 1
1239 - ],
1240 - 'feedback_link_text' => [
1241 - 'name' => 'feedback_link_text',
1242 - 'type' => 'text',
1243 - 'label' => __( 'Feedback Link Text', 'betterdocs' ),
1244 - 'default' => __( 'Still stuck? How can we help?', 'betterdocs' ),
1748 + 'default' => 1,
1749 + 'priority' => 1
1750 + ),
1751 + 'feedback_link_text' => array(
1752 + 'name' => 'feedback_link_text',
1753 + 'type' => 'text',
1754 + 'label' => __( 'Feedback Link Text', 'betterdocs' ),
1755 + 'default' => __( 'Still stuck? How can we help?', 'betterdocs' ),
1245 1756 'priority' => 2,
1246 - 'rules' => Rules::is( 'email_feedback', true )
1247 - ],
1248 - 'feedback_form_title' => [
1249 - 'name' => 'feedback_form_title',
1250 - 'type' => 'text',
1251 - 'label' => __( 'Feedback Form Title', 'betterdocs' ),
1252 - 'default' => __( 'Still stuck? How can we help?', 'betterdocs' ),
1757 + 'rules' => Rules::is( 'email_feedback', true )
1758 + ),
1759 + 'feedback_form_title' => array(
1760 + 'name' => 'feedback_form_title',
1761 + 'type' => 'text',
1762 + 'label' => __( 'Feedback Form Title', 'betterdocs' ),
1763 + 'default' => __( 'Still stuck? How can we help?', 'betterdocs' ),
1253 1764 'priority' => 3,
1254 - 'rules' => Rules::is( 'email_feedback', true )
1255 - ],
1256 - 'email_address' => [
1257 - 'name' => 'email_address',
1258 - 'type' => 'text',
1259 - 'label' => __( 'Email Address', 'betterdocs' ),
1260 - 'default' => get_option( 'admin_email' ),
1261 - 'priority' => 4,
1765 + 'rules' => Rules::is( 'email_feedback', true )
1766 + ),
1767 + 'email_address' => array(
1768 + 'name' => 'email_address',
1769 + 'type' => 'text',
1770 + 'label' => __( 'Email Address', 'betterdocs' ),
1771 + 'default' => get_option( 'admin_email' ),
1772 + 'priority' => 4,
1262 1773 'label_subtitle' => __( 'The email address where the Feedback form will be sent', 'betterdocs' ),
1263 - 'rules' => Rules::is( 'email_feedback', true )
1264 - ],
1265 - 'feedback_url' => [
1266 - 'name' => 'feedback_url',
1267 - 'type' => 'text',
1268 - 'label' => __( 'Feedback URL', 'betterdocs' ),
1269 - 'default' => '',
1774 + 'rules' => Rules::is( 'email_feedback', true )
1775 + ),
1776 + 'feedback_url' => array(
1777 + 'name' => 'feedback_url',
1778 + 'type' => 'text',
1779 + 'label' => __( 'Feedback URL', 'betterdocs' ),
1780 + 'default' => '',
1270 1781 'priority' => 5,
1271 - 'rules' => Rules::is( 'email_feedback', true )
1272 - ]
1273 - ]
1274 - ]
1275 - ]
1276 - ]
1277 - ]
1278 - ],
1279 - 'layout_archive_page' => [
1280 - 'id' => 'layout_archive_page',
1281 - 'name' => 'layout_archive_page',
1282 - 'type' => 'section',
1283 - 'label' => __( 'Archive Page', 'betterdocs' ),
1782 + 'rules' => Rules::is( 'email_feedback', true )
1783 + )
1784 + )
1785 + ),
1786 + array(
1787 + 'id' => 'layout_single_doc_attachments',
1788 + 'name' => 'layout_single_doc_attachments',
1789 + 'type' => 'section',
1790 + 'label' => __( 'Attachments', 'betterdocs' ),
1791 + 'priority' => 6,
1792 + 'fields' => apply_filters( 'betterdocs_single_doc_attachments', array(
1793 + 'show_attachment' => array(
1794 + 'name' => 'show_attachment',
1795 + 'type' => 'toggle',
1796 + 'is_pro' => true,
1797 + 'priority' => 1,
1798 + 'label' => __( 'Show Attachment', 'betterdocs' ),
1799 + 'enable_disable_text_active' => true,
1800 + 'default' => false
1801 + )
1802 + ) )
1803 + ),
1804 + array(
1805 + 'id' => 'layout_single_doc_related_docs',
1806 + 'name' => 'layout_single_doc_related_docs',
1807 + 'type' => 'section',
1808 + 'label' => __( 'Related Docs', 'betterdocs' ),
1809 + 'priority' => 7,
1810 + 'fields' => apply_filters( 'betterdocs_single_doc_related_docs', array(
1811 + 'show_related_docs' => array(
1812 + 'name' => 'show_related_docs',
1813 + 'type' => 'toggle',
1814 + 'is_pro' => true,
1815 + 'priority' => 1,
1816 + 'label' => __( 'Show Related Docs', 'betterdocs' ),
1817 + 'enable_disable_text_active' => true,
1818 + 'default' => false
1819 + )
1820 + ) )
1821 + ),
1822 + 'layout_single_doc_ai_actions' => array(
1823 + 'id' => 'layout_single_doc_ai_actions',
1824 + 'name' => 'layout_single_doc_ai_actions',
1825 + 'type' => 'section',
1826 + 'label' => __( 'AI Actions', 'betterdocs' ),
1827 + 'priority' => 8,
1828 + 'fields' => apply_filters( 'betterdocs_single_doc_ai_actions', array(
1829 + 'enable_ai_actions' => array(
1830 + 'name' => 'enable_ai_actions',
1831 + 'type' => 'toggle',
1832 + 'priority' => 1,
1833 + 'label' => __( 'Enable AI Actions', 'betterdocs' ),
1834 + 'label_subtitle' => __( 'Show a "Copy page" button beside the doc title so readers can copy the page as Markdown or open it in an AI assistant.', 'betterdocs' ),
1835 + 'enable_disable_text_active' => true,
1836 + 'default' => true
1837 + ),
1838 + 'enable_markdown_endpoint' => array(
1839 + 'name' => 'enable_markdown_endpoint',
1840 + 'type' => 'toggle',
1841 + 'priority' => 2,
1842 + 'label' => __( 'Serve Docs as Markdown', 'betterdocs' ),
1843 + // Plain text, not `<doc-url>.md`: the subtitle is rendered as HTML, so an
1844 + // angle-bracketed placeholder is swallowed as an unknown tag and the
1845 + // sentence read "Publish every doc at .md".
1846 + 'label_subtitle' => __( 'Publish every doc as Markdown at its address plus .md (for example /docs/getting-started.md), so AI assistants can read a clean copy. The Listen player uses it too. Required by "Copy page", "View as Markdown", and the Claude and Google AI Studio actions.', 'betterdocs' ),
1847 + 'enable_disable_text_active' => true,
1848 + 'default' => true
1849 + ),
1850 + // AI Actions and the Markdown endpoint are deliberately independent: the
1851 + // `.md` copies also serve AI assistants directly and the Listen player.
1852 + // So switching AI Actions off leaves Markdown on — say so where the
1853 + // admin is looking, rather than leaving a lone "Enabled" toggle under a
1854 + // feature that reads as switched off.
1855 + 'ai_actions_markdown_notice' => array(
1856 + 'name' => 'ai_actions_markdown_notice',
1857 + 'type' => 'html',
1858 + 'priority' => 3,
1859 + 'html' => sprintf(
1860 + '<div class="betterdocs-ai-actions-markdown-notice" style="margin:8px 0 0;padding:12px 16px;background:#f0f6ff;border-left:4px solid #5a6bff;border-radius:4px;font-size:13px;color:#202223;line-height:1.5;">%s</div>',
1861 + esc_html__( 'AI Actions is off, but your docs are still published as Markdown (.md) for AI assistants and the Listen player. Turn off "Serve Docs as Markdown" above if you don\'t want that.', 'betterdocs' )
1862 + ),
1863 + 'rules' => Rules::logicalRule( array(
1864 + Rules::is( 'enable_ai_actions', false ),
1865 + Rules::is( 'enable_markdown_endpoint', true )
1866 + ), 'and' )
1867 + ),
1868 + 'ai_actions_button_label' => array(
1869 + 'name' => 'ai_actions_button_label',
1870 + 'type' => 'text',
1871 + 'priority' => 4,
1872 + 'label' => __( 'Button Label', 'betterdocs' ),
1873 + 'default' => __( 'Copy page', 'betterdocs' ),
1874 + 'rules' => Rules::is( 'enable_ai_actions', true )
1875 + ),
1876 + 'ai_actions_prompt_template' => array(
1877 + 'name' => 'ai_actions_prompt_template',
1878 + 'type' => 'text',
1879 + 'priority' => 5,
1880 + 'label' => __( 'AI Prompt Template', 'betterdocs' ),
1881 + 'label_subtitle' => __( 'Sent to the AI assistant when a reader opens this doc there. Use {URL} for the doc address.', 'betterdocs' ),
1882 + 'default' => __( 'Read from {URL} so I can ask questions about it.', 'betterdocs' ),
1883 + 'rules' => Rules::is( 'enable_ai_actions', true )
1884 + ),
1885 + 'ai_actions_copy_page' => array(
1886 + 'name' => 'ai_actions_copy_page',
1887 + 'type' => 'toggle',
1888 + 'priority' => 6,
1889 + 'label' => __( 'Copy Page', 'betterdocs' ),
1890 + 'enable_disable_text_active' => true,
1891 + 'default' => true,
1892 + 'rules' => Rules::logicalRule( array(
1893 + Rules::is( 'enable_ai_actions', true ),
1894 + Rules::is( 'enable_markdown_endpoint', true )
1895 + ), 'and' )
1896 + ),
1897 + 'ai_actions_view_markdown' => array(
1898 + 'name' => 'ai_actions_view_markdown',
1899 + 'type' => 'toggle',
1900 + 'priority' => 7,
1901 + 'label' => __( 'View as Markdown', 'betterdocs' ),
1902 + 'enable_disable_text_active' => true,
1903 + 'default' => true,
1904 + 'rules' => Rules::logicalRule( array(
1905 + Rules::is( 'enable_ai_actions', true ),
1906 + Rules::is( 'enable_markdown_endpoint', true )
1907 + ), 'and' )
1908 + ),
1909 + 'ai_actions_chatgpt' => array(
1910 + 'name' => 'ai_actions_chatgpt',
1911 + 'type' => 'toggle',
1912 + 'priority' => 8,
1913 + 'label' => __( 'Open in ChatGPT', 'betterdocs' ),
1914 + 'enable_disable_text_active' => true,
1915 + 'default' => true,
1916 + 'rules' => Rules::is( 'enable_ai_actions', true )
1917 + ),
1918 + 'ai_actions_claude' => array(
1919 + 'name' => 'ai_actions_claude',
1920 + 'type' => 'toggle',
1921 + 'priority' => 9,
1922 + 'label' => __( 'Open in Claude', 'betterdocs' ),
1923 + 'enable_disable_text_active' => true,
1924 + 'default' => true,
1925 + 'rules' => Rules::logicalRule( array(
1926 + Rules::is( 'enable_ai_actions', true ),
1927 + Rules::is( 'enable_markdown_endpoint', true )
1928 + ), 'and' )
1929 + ),
1930 + 'ai_actions_gemini' => array(
1931 + 'name' => 'ai_actions_gemini',
1932 + 'type' => 'toggle',
1933 + 'priority' => 10,
1934 + 'label' => __( 'Open in Google AI Studio', 'betterdocs' ),
1935 + 'label_subtitle' => __( 'Gemini has no way to receive a prompt from a link, so this opens Google AI Studio instead. A Google account is required.', 'betterdocs' ),
1936 + 'enable_disable_text_active' => true,
1937 + 'default' => true,
1938 + 'rules' => Rules::logicalRule( array(
1939 + Rules::is( 'enable_ai_actions', true ),
1940 + Rules::is( 'enable_markdown_endpoint', true )
1941 + ), 'and' )
1942 + ),
1943 + 'ai_actions_perplexity' => array(
1944 + 'name' => 'ai_actions_perplexity',
1945 + 'type' => 'toggle',
1946 + 'priority' => 11,
1947 + 'label' => __( 'Open in Perplexity', 'betterdocs' ),
1948 + 'enable_disable_text_active' => true,
1949 + 'default' => false,
1950 + 'rules' => Rules::logicalRule( array(
1951 + Rules::is( 'enable_ai_actions', true ),
1952 + Rules::is( 'enable_markdown_endpoint', true )
1953 + ), 'and' )
1954 + ),
1955 + 'ai_actions_grok' => array(
1956 + 'name' => 'ai_actions_grok',
1957 + 'type' => 'toggle',
1958 + 'priority' => 12,
1959 + 'label' => __( 'Open in Grok', 'betterdocs' ),
1960 + 'enable_disable_text_active' => true,
1961 + 'default' => false,
1962 + 'rules' => Rules::logicalRule( array(
1963 + Rules::is( 'enable_ai_actions', true ),
1964 + Rules::is( 'enable_markdown_endpoint', true )
1965 + ), 'and' )
1966 + )
1967 + ) )
1968 + ),
1969 + 'layout_single_doc_listen' => array(
1970 + 'id' => 'layout_single_doc_listen',
1971 + 'name' => 'layout_single_doc_listen',
1972 + 'type' => 'section',
1973 + 'label' => __( 'Listen', 'betterdocs' ),
1974 + 'priority' => 9,
1975 + 'fields' => apply_filters( 'betterdocs_single_doc_listen', array(
1976 + 'enable_listen' => array(
1977 + 'name' => 'enable_listen',
1978 + 'type' => 'toggle',
1979 + 'priority' => 1,
1980 + 'label' => __( 'Enable Listen', 'betterdocs' ),
1981 + 'label_subtitle' => __( 'Show a "Listen" button beside the reading time. Pressed, it turns into a small audio player that reads the doc aloud using the visitor\'s browser — no audio files and no third-party service.', 'betterdocs' ),
1982 + 'enable_disable_text_active' => true,
1983 + 'default' => true
1984 + ),
1985 + 'listen_button_label' => array(
1986 + 'name' => 'listen_button_label',
1987 + 'type' => 'text',
1988 + 'priority' => 2,
1989 + 'label' => __( 'Button Label', 'betterdocs' ),
1990 + 'default' => __( 'Listen', 'betterdocs' ),
1991 + 'rules' => Rules::is( 'enable_listen', true )
1992 + ),
1993 + 'listen_show_speed' => array(
1994 + 'name' => 'listen_show_speed',
1995 + 'type' => 'toggle',
1996 + 'priority' => 3,
1997 + 'label' => __( 'Speed Control', 'betterdocs' ),
1998 + 'label_subtitle' => __( 'Let readers cycle the playback speed between 0.75× and 2×.', 'betterdocs' ),
1999 + 'enable_disable_text_active' => true,
2000 + 'default' => true,
2001 + 'rules' => Rules::is( 'enable_listen', true )
2002 + ),
2003 + 'listen_words_per_minute' => array(
2004 + 'name' => 'listen_words_per_minute',
2005 + 'type' => 'number',
2006 + 'priority' => 4,
2007 + 'label' => __( 'Words Per Minute', 'betterdocs' ),
2008 + 'label_subtitle' => __( 'Used to estimate the total playing time the player shows. Browser voices read at roughly 180 words a minute at normal speed; raise this if the countdown finishes early.', 'betterdocs' ),
2009 + 'default' => 180,
2010 + 'min' => 60,
2011 + 'max' => 400,
2012 + 'rules' => Rules::is( 'enable_listen', true )
2013 + )
2014 + ) )
2015 + )
2016 + )
2017 + )
2018 + )
2019 + ) ),
2020 + 'layout_archive_page' => array(
2021 + 'id' => 'layout_archive_page',
2022 + 'name' => 'layout_archive_page',
2023 + 'type' => 'section',
2024 + 'label' => __( 'Archive Page', 'betterdocs' ),
1284 2025 'priority' => 3,
1285 - 'fields' => [
1286 - 'enable_archive_sidebar' => [
1287 - 'name' => 'enable_archive_sidebar',
1288 - 'type' => 'toggle',
1289 - 'label' => __( 'Sidebar Category List', 'betterdocs' ),
2026 + 'fields' => array(
2027 + 'enable_archive_sidebar' => array(
2028 + 'name' => 'enable_archive_sidebar',
2029 + 'type' => 'toggle',
2030 + 'label' => __( 'Sidebar Category List', 'betterdocs' ),
1290 2031 'enable_disable_text_active' => true,
1291 - 'default' => 1,
1292 - 'priority' => 31
1293 - ],
1294 - 'archive_nested_subcategory' => [
1295 - 'name' => 'archive_nested_subcategory',
1296 - 'type' => 'toggle',
1297 - 'label' => __( 'Nested Subcategory', 'betterdocs' ),
2032 + 'default' => 1,
2033 + 'priority' => 31
2034 + ),
2035 + 'archive_nested_subcategory' => array(
2036 + 'name' => 'archive_nested_subcategory',
2037 + 'type' => 'toggle',
2038 + 'label' => __( 'Nested Subcategory', 'betterdocs' ),
1298 2039 'enable_disable_text_active' => true,
1299 - 'default' => 1,
1300 - 'priority' => 32
1301 - ]
1302 - ]
1303 - ]
1304 - ]
1305 - ] )
1306 - ]
1307 - ]
1308 - ]
1309 - ] ),
1310 - 'tab-design' => apply_filters( 'betterdocs_settings_tab_design', [
1311 - 'id' => 'tab-design',
1312 - 'label' => __( 'Design', 'betterdocs' ),
2040 + 'default' => 1,
2041 + 'priority' => 32
2042 + ),
2043 + 'archive_enable_pagination' => array(
2044 + 'name' => 'archive_enable_pagination',
2045 + 'type' => 'toggle',
2046 + 'label' => __( 'Enable Pagination', 'betterdocs' ),
2047 + 'enable_disable_text_active' => true,
2048 + 'default' => false,
2049 + 'priority' => 33
2050 + )
2051 + )
2052 + )
2053 + )
2054 + ) )
2055 + )
2056 + )
2057 + )
2058 + ) ),
2059 + 'tab-design' => apply_filters( 'betterdocs_settings_tab_design', array(
2060 + 'id' => 'tab-design',
2061 + 'label' => __( 'Design', 'betterdocs' ),
1313 2062 'priority' => 30,
1314 - 'fields' => [
1315 - 'title-design' => [
1316 - 'name' => 'title-design-tab',
1317 - 'type' => 'section',
1318 - 'label' => __( 'Design', 'betterdocs' ),
2063 + 'fields' => array(
2064 + 'title-design' => array(
2065 + 'name' => 'title-design-tab',
2066 + 'type' => 'section',
2067 + 'label' => __( 'Design', 'betterdocs' ),
1319 2068 'priority' => 30,
1320 - 'fields' => [
1321 - 'customizer_link' => [
1322 - 'name' => 'customizer_link',
1323 - 'type' => 'action',
1324 - 'action' => 'betterdocs_settings_customizer_link',
1325 - 'label' => __( 'Customize BetterDocs', 'betterdocs' ),
1326 - 'url' => $this->customizer_link(),
1327 - 'customizer_img' => betterdocs()->assets->icon( 'customizer/betterdocs-customize.png', true ),
1328 - 'priority' => 1
1329 - ]
1330 - ]
1331 - ]
1332 - ]
1333 - ] ),
1334 - 'tab-shortcodes' => apply_filters( 'betterdocs_settings_tab_shortcodes', [
1335 - 'label' => __( 'Shortcodes', 'betterdocs' ),
1336 - 'id' => 'tab-shortcodes',
1337 - 'classes' => 'tab-shortcodes',
2069 + 'fields' => $this->design_tab()
2070 + )
2071 + )
2072 + ) ),
2073 + 'tab-shortcodes' => apply_filters( 'betterdocs_settings_tab_shortcodes', array(
2074 + 'label' => __( 'Shortcodes', 'betterdocs' ),
2075 + 'id' => 'tab-shortcodes',
2076 + 'classes' => 'tab-shortcodes',
1338 2077 'priority' => 40,
1339 - 'fields' => [
1340 - 'title-shortcodes' => [
1341 - 'name' => 'title-shortcodes-tab',
1342 - 'type' => 'section',
1343 - 'label' => __( 'Shortcodes', 'betterdocs' ),
1344 - 'priority' => 40,
1345 - 'searchable' => true,
1346 - 'searchPlaceholder' => __( 'Search for shortcode', 'betterdocs' ),
2078 + 'fields' => array(
2079 + 'title-shortcodes' => array(
2080 + 'name' => 'title-shortcodes-tab',
2081 + 'type' => 'section',
2082 + 'label' => __( 'Shortcodes', 'betterdocs' ),
2083 + 'priority' => 40,
2084 + 'searchable' => true,
2085 + 'searchPlaceholder' => __( 'Search for shortcode', 'betterdocs' ),
1347 2086 'searchNotFoundMessage' => '<img src="' . betterdocs()->assets->icon( 'not-found.svg', true ) . '"/><p>' . __( 'No Shortcodes Found with these keywords', 'betterdocs' ) . '</p>',
1348 - 'fields' => apply_filters( 'betterdocs_shortcode_fields', [
1349 - 'search_form' => [
1350 - 'name' => 'search_form',
1351 - 'type' => 'copy-to-clipboard',
1352 - 'label' => __( 'Search Form', 'betterdocs' ),
1353 - 'default' => '[betterdocs_search_form]',
1354 - 'readOnly' => true,
1355 - 'priority' => 1,
1356 - 'description' => __( '[betterdocs_search_form placeholder="Search..." heading="Heading" subheading="Subheading" category_search="true" search_button="true" popular_search="true"]', 'betterdocs' ),
1357 - 'descriptionLabel' => __( 'Example with parameters:', 'betterdocs' ),
2087 + 'fields' => apply_filters( 'betterdocs_shortcode_fields', array(
2088 + 'search_form' => array(
2089 + 'name' => 'search_form',
2090 + 'type' => 'copy-to-clipboard',
2091 + 'label' => __( 'Search Form', 'betterdocs' ),
2092 + 'default' => '[betterdocs_search_form]',
2093 + 'readOnly' => true,
2094 + 'priority' => 1,
2095 + 'description' => __( '[betterdocs_search_form placeholder="Search..." heading="Heading" subheading="Subheading" category_search="true" search_button="true" popular_search="true"]', 'betterdocs' ),
2096 + 'descriptionLabel' => __( 'Example with parameters:', 'betterdocs' ),
1358 2097 'descriptionCopyable' => true
1359 - ],
1360 - 'feedback_form' => [
1361 - 'name' => 'feedback_form',
1362 - 'type' => 'copy-to-clipboard',
1363 - 'label' => __( 'Feedback Form', 'betterdocs' ),
1364 - 'default' => '[betterdocs_feedback_form]',
1365 - 'readOnly' => true,
1366 - 'priority' => 2,
1367 - 'description' => __( '[betterdocs_feedback_form button_text="Send"]', 'betterdocs' ),
1368 - 'descriptionLabel' => __( 'Example with parameters:', 'betterdocs' ),
2098 + ),
2099 + 'feedback_form' => array(
2100 + 'name' => 'feedback_form',
2101 + 'type' => 'copy-to-clipboard',
2102 + 'label' => __( 'Feedback Form', 'betterdocs' ),
2103 + 'default' => '[betterdocs_feedback_form]',
2104 + 'readOnly' => true,
2105 + 'priority' => 2,
2106 + 'description' => __( '[betterdocs_feedback_form button_text="Send"]', 'betterdocs' ),
2107 + 'descriptionLabel' => __( 'Example with parameters:', 'betterdocs' ),
1369 2108 'descriptionCopyable' => true
1370 - ],
1371 - 'category_grid' => [
1372 - 'name' => 'category_grid',
1373 - 'type' => 'copy-to-clipboard',
1374 - 'label' => __( 'Category Grid- Layout 1', 'betterdocs' ),
1375 - 'default' => '[betterdocs_category_grid]',
1376 - 'readOnly' => true,
1377 - 'priority' => 3,
1378 - 'description' => __( '[betterdocs_category_grid post_counter="true" show_icon="true" masonry="true" column="3" posts_per_page="5" nested_subcategory="true" terms="term_ID, term_ID" terms_orderby="" terms_order="" multiple_knowledge_base="" kb_slug="" title_tag="h2" orderby="" order="" ]', 'betterdocs' ),
1379 - 'descriptionLabel' => __( 'Example with parameters:', 'betterdocs' ),
2109 + ),
2110 + 'category_grid' => array(
2111 + 'name' => 'category_grid',
2112 + 'type' => 'copy-to-clipboard',
2113 + 'label' => __( 'Category Grid- Layout 1', 'betterdocs' ),
2114 + 'default' => '[betterdocs_category_grid]',
2115 + 'readOnly' => true,
2116 + 'priority' => 3,
2117 + 'description' => __( '[betterdocs_category_grid show_count="true" show_icon="true" masonry="true" column="3" posts_per_page="5" nested_subcategory="true" terms="term_ID, term_ID" terms_orderby="" terms_order="" multiple_knowledge_base="" kb_slug="" title_tag="h2" orderby="" order="" ]', 'betterdocs' ),
2118 + 'descriptionLabel' => __( 'Example with parameters:', 'betterdocs' ),
1380 2119 'descriptionCopyable' => true
1381 - ],
1382 - 'category_box' => [
1383 - 'name' => 'category_box',
1384 - 'type' => 'copy-to-clipboard',
1385 - 'label' => __( 'Category Box- Layout 2', 'betterdocs' ),
1386 - 'default' => '[betterdocs_category_box]',
1387 - 'readOnly' => true,
1388 - 'priority' => 4,
1389 - 'description' => __( '[betterdocs_category_box orderby="" column="" nested_subcategory="" terms="" terms_orderby="" show_icon="" kb_slug="" title_tag="h2" multiple_knowledge_base="false" border_bottom="false"]', 'betterdocs' ),
1390 - 'descriptionLabel' => __( 'Example with parameters:', 'betterdocs' ),
2120 + ),
2121 + 'category_box' => array(
2122 + 'name' => 'category_box',
2123 + 'type' => 'copy-to-clipboard',
2124 + 'label' => __( 'Category Box- Layout 2', 'betterdocs' ),
2125 + 'default' => '[betterdocs_category_box]',
2126 + 'readOnly' => true,
2127 + 'priority' => 4,
2128 + 'description' => __( '[betterdocs_category_box orderby="" column="" nested_subcategory="" terms="" terms_orderby="" show_icon="" kb_slug="" title_tag="h2" multiple_knowledge_base="false" border_bottom="false"]', 'betterdocs' ),
2129 + 'descriptionLabel' => __( 'Example with parameters:', 'betterdocs' ),
1391 2130 'descriptionCopyable' => true
1392 - ],
1393 - 'category_list' => [
1394 - 'name' => 'category_list',
1395 - 'type' => 'copy-to-clipboard',
1396 - 'label' => __( 'Category List', 'betterdocs' ),
1397 - 'default' => '[betterdocs_category_list]',
1398 - 'readOnly' => true,
1399 - 'priority' => 5,
1400 - 'description' => __( '[betterdocs_category_list orderby="" order="" posts_per_page="" nested_subcategory="" terms="" terms_orderby="" terms_order="" kb_slug="" multiple_knowledge_base="false" title_tag="h2"]', 'betterdocs' ),
1401 - 'descriptionLabel' => __( 'Example with parameters:', 'betterdocs' ),
2131 + ),
2132 + 'category_list' => array(
2133 + 'name' => 'category_list',
2134 + 'type' => 'copy-to-clipboard',
2135 + 'label' => __( 'Category List', 'betterdocs' ),
2136 + 'default' => '[betterdocs_category_list]',
2137 + 'readOnly' => true,
2138 + 'priority' => 5,
2139 + 'description' => __( '[betterdocs_category_list orderby="" order="" posts_per_page="" nested_subcategory="" terms="" terms_orderby="" terms_order="" kb_slug="" multiple_knowledge_base="false" title_tag="h2"]', 'betterdocs' ),
2140 + 'descriptionLabel' => __( 'Example with parameters:', 'betterdocs' ),
1402 2141 'descriptionCopyable' => true
1403 - ],
1404 - 'faq_modern_layout' => [
1405 - 'name' => 'faq_modern_layout',
1406 - 'type' => 'copy-to-clipboard',
1407 - 'label' => __( 'FAQ Layout - 1', 'betterdocs' ),
1408 - 'default' => '[betterdocs_faq_list_modern]',
1409 - 'readOnly' => true,
1410 - 'priority' => 13,
1411 - 'description' => __( '[betterdocs_faq_list_modern groups="group_id" class="" group_exclude="group_id" faq_heading="Frequently Asked Questions"]', 'betterdocs' ),
1412 - 'descriptionLabel' => __( 'Example with parameters:', 'betterdocs' ),
2142 + ),
2143 + 'faq_modern_layout' => array(
2144 + 'name' => 'faq_modern_layout',
2145 + 'type' => 'copy-to-clipboard',
2146 + 'label' => __( 'FAQ Layout - 1', 'betterdocs' ),
2147 + 'default' => '[betterdocs_faq_list_modern]',
2148 + 'readOnly' => true,
2149 + 'priority' => 13,
2150 + 'description' => __( '[betterdocs_faq_list_modern groups="group_id" class="" group_exclude="group_id" faq_heading="Frequently Asked Questions"]', 'betterdocs' ),
2151 + 'descriptionLabel' => __( 'Example with parameters:', 'betterdocs' ),
1413 2152 'descriptionCopyable' => true
1414 - ],
1415 - 'faq_classic_layout' => [
1416 - 'name' => 'faq_classic_layout',
1417 - 'type' => 'copy-to-clipboard',
1418 - 'label' => __( 'FAQ Layout - 2', 'betterdocs' ),
1419 - 'default' => '[betterdocs_faq_list_classic]',
1420 - 'readOnly' => true,
1421 - 'priority' => 14,
1422 - 'description' => __( '[betterdocs_faq_list_classic groups="group_id" class="" group_exclude="group_id" faq_heading="Frequently Asked Questions"]', 'betterdocs' ),
1423 - 'descriptionLabel' => __( 'Example with parameters:', 'betterdocs' ),
2153 + ),
2154 + 'faq_classic_layout' => array(
2155 + 'name' => 'faq_classic_layout',
2156 + 'type' => 'copy-to-clipboard',
2157 + 'label' => __( 'FAQ Layout - 2', 'betterdocs' ),
2158 + 'default' => '[betterdocs_faq_list_classic]',
2159 + 'readOnly' => true,
2160 + 'priority' => 14,
2161 + 'description' => __( '[betterdocs_faq_list_classic groups="group_id" class="" group_exclude="group_id" faq_heading="Frequently Asked Questions"]', 'betterdocs' ),
2162 + 'descriptionLabel' => __( 'Example with parameters:', 'betterdocs' ),
1424 2163 'descriptionCopyable' => true
1425 - ]
1426 - ] )
1427 - ]
1428 - ]
1429 - ] ),
1430 - 'tab-advance-settings' => apply_filters( 'betterdocs_settings_tab_advance', [
1431 - 'id' => 'tab-advance-settings',
1432 - 'label' => __( 'Advanced Settings', 'betterdocs' ),
2164 + ),
2165 + 'betterdocs_faq_list_layout_3' => array(
2166 + 'name' => 'betterdocs_faq_list_layout_3',
2167 + 'type' => 'copy-to-clipboard',
2168 + 'label' => __( 'FAQ Layout - 3', 'betterdocs' ),
2169 + 'default' => '[betterdocs_faq_list_layout_3 class="faq-doc betterdocs-faq-layout-3"]',
2170 + 'readOnly' => true,
2171 + 'priority' => 15,
2172 + 'description' => __( '[betterdocs_faq_list_layout_3 class="faq-doc betterdocs-faq-layout-3" groups="group_id" class="" group_exclude="group_id" faq_heading="Frequently Asked Questions"]', 'betterdocs' ),
2173 + 'descriptionLabel' => __( 'Example with parameters:', 'betterdocs' ),
2174 + 'descriptionCopyable' => true
2175 + ),
2176 + 'betterdocs_faq_tab' => array(
2177 + 'name' => 'betterdocs_faq_tab',
2178 + 'type' => 'copy-to-clipboard',
2179 + 'label' => __( 'FAQ Layout - 4', 'betterdocs' ),
2180 + 'default' => '[betterdocs_faq_tab class="faq-doc betterdocs-faq-layout-4"]',
2181 + 'readOnly' => true,
2182 + 'priority' => 16,
2183 + 'description' => __( '[betterdocs_faq_tab class="faq-doc betterdocs-faq-layout-4" groups="group_id" group_exclude="group_id" faq_heading="Frequently Asked Questions"]', 'betterdocs' ),
2184 + 'descriptionLabel' => __( 'Example with parameters:', 'betterdocs' ),
2185 + 'descriptionCopyable' => true
2186 + )
2187 + ) )
2188 + )
2189 + )
2190 + ) ),
2191 + 'tab-advance-settings' => apply_filters( 'betterdocs_settings_tab_advance', array(
2192 + 'id' => 'tab-advance-settings',
2193 + 'label' => __( 'Access & Restrictions', 'betterdocs' ),
2194 + 'classes' => 'tab-layout',
1433 2195 'priority' => 50,
1434 - 'fields' => [
1435 - 'title-advance-settings' => [
1436 - 'name' => 'title-advance-settings-tab',
1437 - 'type' => 'section',
1438 - 'label' => __( 'Advanced Settings', 'betterdocs' ),
2196 + 'fields' => array(
2197 + 'title_advance_settings' => array(
2198 + 'name' => 'title-advance-settings-tab',
2199 + 'type' => 'section',
2200 + 'label' => __( 'Access & Restrictions', 'betterdocs' ),
1439 2201 'priority' => 50,
1440 - 'fields' => apply_filters( 'betterdocs_internal_kb_fields', [
1441 - 'article_roles' => [
1442 - 'name' => 'article_roles',
1443 - 'type' => 'checkbox-select',
1444 - 'label' => __( 'Who Can Write Docs?', 'betterdocs' ),
1445 - 'priority' => 1,
1446 - 'multiple' => true,
1447 - 'search' => true,
1448 - 'is_pro' => true,
1449 - 'default' => [ 'administrator' ],
1450 - 'options' => $wp_roles
1451 - ],
1452 - 'settings_roles' => [
1453 - 'name' => 'settings_roles',
1454 - 'type' => 'checkbox-select',
1455 - 'label' => __( 'Who Can Edit Settings?', 'betterdocs' ),
1456 - 'priority' => 2,
1457 - 'multiple' => true,
1458 - 'is_pro' => true,
1459 - 'search' => true,
1460 - 'default' => [ 'administrator' ],
1461 - 'options' => $wp_roles
1462 - ],
1463 - 'analytics_roles' => [
1464 - 'name' => 'analytics_roles',
1465 - 'type' => 'checkbox-select',
1466 - 'label' => __( 'Who Can Check Analytics?', 'betterdocs' ),
1467 - 'priority' => 3,
1468 - 'multiple' => true,
1469 - 'is_pro' => true,
1470 - 'search' => true,
1471 - 'default' => [ 'administrator' ],
1472 - 'options' => $wp_roles
1473 - ],
1474 - 'enable_content_restriction' => [
1475 - 'name' => 'enable_content_restriction',
1476 - 'type' => 'toggle',
1477 - 'is_pro' => true,
1478 - 'priority' => 4,
1479 - 'label' => __( 'Internal Knowledge Base', 'betterdocs' ),
1480 - 'enable_disable_text_active' => true,
1481 - 'default' => [ 'all' ]
1482 - ],
1483 - 'content_visibility' => [
1484 - 'name' => 'content_visibility',
1485 - 'type' => 'checkbox-select',
1486 - 'label' => __( 'Restrict Access to', 'betterdocs' ),
1487 - 'label_subtitle' => __( 'Only selected User Roles will be able to view your Knowledge Base', 'betterdocs' ),
1488 - 'is_pro' => true,
1489 - 'priority' => 5,
1490 - 'multiple' => true,
1491 - 'search' => true,
1492 - 'default' => [ 'all' ],
1493 - 'placeholder' => __( 'Select any', 'betterdocs' ),
1494 - 'options' => $this->normalize_options( array_merge( [
1495 - 'all' => __( 'All logged in users', 'betterdocs' )
1496 - ], wp_roles()->role_names ) ),
1497 - 'rules' => Rules::is( 'enable_content_restriction', true ),
1498 - 'filterValue' => 'all'
1499 - ],
1500 - 'restrict_template' => [
1501 - 'name' => 'restrict_template',
1502 - 'type' => 'checkbox-select',
1503 - 'label' => __( 'Restriction on Docs', 'betterdocs' ),
1504 - 'label_subtitle' => __( 'Selected Docs pages will be restricted', 'betterdocs' ),
1505 - 'is_pro' => true,
1506 - 'priority' => 6,
1507 - 'multiple' => true,
1508 - 'search' => true,
1509 - 'default' => [ 'all' ],
1510 - 'placeholder' => __( 'Select any', 'betterdocs' ),
1511 - 'options' => $this->get_texanomy(),
1512 - 'rules' => Rules::is( 'enable_content_restriction', true ),
1513 - 'filterValue' => 'all'
1514 - ],
1515 - 'restrict_category' => [
1516 - 'name' => 'restrict_category',
1517 - 'type' => 'checkbox-select',
1518 - 'label' => __( 'Restriction on Docs Categories', 'betterdocs' ),
1519 - 'label_subtitle' => __( 'Selected Docs categories will be restricted', 'betterdocs' ),
1520 - 'is_pro' => true,
1521 - 'priority' => 7,
1522 - 'multiple' => true,
1523 - 'search' => true,
1524 - 'default' => [ 'all' ],
1525 - 'placeholder' => __( 'Select any', 'betterdocs' ),
1526 - 'options' => $this->get_terms( 'doc_category' ),
1527 - 'rules' => Rules::is( 'enable_content_restriction', true ),
1528 - 'filterValue' => 'all'
1529 - ],
1530 - 'restricted_redirect_url' => [
1531 - 'name' => 'restricted_redirect_url',
1532 - 'type' => 'text',
1533 - 'label' => __( 'Redirect URL', 'betterdocs' ),
1534 - 'label_subtitle' => __( 'Set a custom URL to redirect users without permissions when they try to access internal knowledge base. By default, restricted content will redirect to the "404 not found" page', 'betterdocs' ),
1535 - 'default' => '',
1536 - 'placeholder' => 'https://',
1537 - 'is_pro' => true,
1538 - 'priority' => 9,
1539 - 'rules' => Rules::is( 'enable_content_restriction', true )
1540 - ]
1541 - ] )
1542 - ]
1543 - ]
1544 - ] ),
1545 - 'tab-email-reporting' => apply_filters( 'betterdocs_settings_tab_email_reporting', [
1546 - 'id' => 'tab-email-reporting',
1547 - 'label' => __( 'Email Reporting', 'betterdocs' ),
2202 + 'fields' => array(
2203 + 'tab-advanced-settings' => array(
2204 + 'id' => 'tab-advanced-settings',
2205 + 'name' => 'tab-advanced-settings',
2206 + 'label' => __( 'Access & Restrictions', 'betterdocs' ),
2207 + 'classes' => 'tab-layout',
2208 + 'type' => 'tab',
2209 + 'active' => 'global_role_management',
2210 + 'completionTrack' => true,
2211 + 'sidebar' => false,
2212 + 'save' => false,
2213 + 'title' => false,
2214 + 'config' => array(
2215 + 'active' => '',
2216 + 'sidebar' => false,
2217 + 'title' => false
2218 + ),
2219 + 'submit' => array(
2220 + 'show' => false
2221 + ),
2222 + 'step' => array(
2223 + 'show' => false
2224 + ),
2225 + 'priority' => 50,
2226 + 'fields' => array(
2227 + 'global_role_management' => array(
2228 + 'id' => 'global_role_management',
2229 + 'name' => 'global_role_management',
2230 + 'type' => 'section',
2231 + 'label' => __( 'Global Role Management', 'betterdocs' ),
2232 + 'priority' => 1,
2233 + 'fields' => array(
2234 + 'article_roles' => array(
2235 + 'name' => 'article_roles',
2236 + 'type' => 'checkbox-select',
2237 + 'label' => __( 'Who Can Write Docs?', 'betterdocs' ),
2238 + 'priority' => 1,
2239 + 'multiple' => true,
2240 + 'search' => true,
2241 + 'is_pro' => true,
2242 + 'default' => array( 'administrator' ),
2243 + 'options' => $wp_roles
2244 + ),
2245 + 'settings_roles' => array(
2246 + 'name' => 'settings_roles',
2247 + 'type' => 'checkbox-select',
2248 + 'label' => __( 'Who Can Edit Settings?', 'betterdocs' ),
2249 + 'priority' => 2,
2250 + 'multiple' => true,
2251 + 'is_pro' => true,
2252 + 'search' => true,
2253 + 'default' => array( 'administrator' ),
2254 + 'options' => $wp_roles
2255 + ),
2256 + 'analytics_roles' => array(
2257 + 'name' => 'analytics_roles',
2258 + 'type' => 'checkbox-select',
2259 + 'label' => __( 'Who Can Check Analytics?', 'betterdocs' ),
2260 + 'priority' => 3,
2261 + 'multiple' => true,
2262 + 'is_pro' => true,
2263 + 'search' => true,
2264 + 'default' => array( 'administrator' ),
2265 + 'options' => $wp_roles
2266 + ),
2267 + 'faq_roles' => array(
2268 + 'name' => 'faq_roles',
2269 + 'type' => 'checkbox-select',
2270 + 'label' => __( 'Who Can Check FAQ Builder?', 'betterdocs' ),
2271 + 'priority' => 4,
2272 + 'multiple' => true,
2273 + 'is_pro' => true,
2274 + 'search' => true,
2275 + 'default' => array( 'administrator' ),
2276 + 'options' => $wp_roles
2277 + )
2278 +
2279 + )
2280 + ),
2281 + 'internal_knowledge_base' => array(
2282 + 'id' => 'internal_knowledge_base',
2283 + 'name' => 'internal_knowledge_base',
2284 + 'type' => 'section',
2285 + 'label' => __( 'Internal Knowledge Base', 'betterdocs' ),
2286 + 'priority' => 1,
2287 + 'fields' => apply_filters( 'betterdocs_settings_content_restriction_fields', array(
2288 + 'enable_content_restriction' => array(
2289 + 'name' => 'enable_content_restriction',
2290 + 'type' => 'toggle',
2291 + 'is_pro' => true,
2292 + 'priority' => 5,
2293 + 'label' => __( 'Internal Knowledge Base', 'betterdocs' ),
2294 + 'enable_disable_text_active' => true,
2295 + 'default' => array( 'all' )
2296 + ),
2297 + 'internal_knowledge_base_type' => array(
2298 + 'name' => 'internal_knowledge_base_type',
2299 + 'type' => 'radio-card',
2300 + 'label' => __( 'Choose a Rule Type', 'betterdocs' ),
2301 + 'label_subtitle' => __( 'Choose a rule type: apply access globally (Basic), or configure detailed restrictions (Advanced) for docs, categories, and KBs.', 'betterdocs' ),
2302 + 'priority' => 6,
2303 + 'multiple' => true,
2304 + 'search' => true,
2305 + 'default' => array( 'all' ),
2306 + 'placeholder' => __( 'Select any', 'betterdocs' ),
2307 + 'options' => array(
2308 + array(
2309 + 'label' => 'Basic',
2310 + 'value' => 'basic'
2311 + ),
2312 + array(
2313 + 'label' => 'Advanced',
2314 + 'value' => 'advanced'
2315 + )
2316 + ),
2317 + 'filterValue' => 'all',
2318 + 'rules' => Rules::is( 'enable_content_restriction', true )
2319 + ),
2320 + 'content_visibility' => array(
2321 + 'name' => 'content_visibility',
2322 + 'type' => 'checkbox-select',
2323 + 'label' => __( 'Restrict Access to', 'betterdocs' ),
2324 + 'label_subtitle' => __( 'Only selected User Roles will be able to view your Knowledge Base', 'betterdocs' ),
2325 + 'is_pro' => true,
2326 + 'priority' => 7,
2327 + 'multiple' => true,
2328 + 'search' => true,
2329 + 'default' => array( 'all' ),
2330 + 'placeholder' => __( 'Select any', 'betterdocs' ),
2331 + 'options' => $roles_for_ikb,
2332 + 'rules' => Rules::logicalRule(
2333 + array(
2334 + Rules::is( 'enable_content_restriction', true ),
2335 + Rules::is( 'internal_knowledge_base_type', 'basic' )
2336 + ),
2337 + 'and'
2338 + ),
2339 + 'filterValue' => 'all'
2340 + ),
2341 + 'restrict_template' => array(
2342 + 'name' => 'restrict_template',
2343 + 'type' => 'checkbox-select',
2344 + 'label' => __( 'Restriction on Docs', 'betterdocs' ),
2345 + 'label_subtitle' => __( 'Selected Docs pages will be restricted', 'betterdocs' ),
2346 + 'is_pro' => true,
2347 + 'priority' => 8,
2348 + 'multiple' => true,
2349 + 'search' => true,
2350 + 'default' => array( 'all' ),
2351 + 'placeholder' => __( 'Select any', 'betterdocs' ),
2352 + 'options' => $this->get_texanomy(),
2353 + 'rules' => Rules::logicalRule(
2354 + array(
2355 + Rules::is( 'enable_content_restriction', true ),
2356 + Rules::is( 'internal_knowledge_base_type', 'basic' )
2357 + ),
2358 + 'and'
2359 + ),
2360 + 'filterValue' => 'all'
2361 + ),
2362 + 'restrict_category' => array(
2363 + 'name' => 'restrict_category',
2364 + 'type' => 'checkbox-select',
2365 + 'label' => __( 'Restriction on Docs Categories', 'betterdocs' ),
2366 + 'label_subtitle' => __( 'Selected Docs categories will be restricted', 'betterdocs' ),
2367 + 'is_pro' => true,
2368 + 'priority' => 9,
2369 + 'multiple' => true,
2370 + 'search' => true,
2371 + 'default' => array( 'all' ),
2372 + 'placeholder' => __( 'Select any', 'betterdocs' ),
2373 + 'options' => $this->get_terms( 'doc_category' ),
2374 + 'rules' => Rules::logicalRule(
2375 + array(
2376 + Rules::is( 'enable_content_restriction', true ),
2377 + Rules::is( 'internal_knowledge_base_type', 'basic' )
2378 + ),
2379 + 'and'
2380 + ),
2381 + 'filterValue' => 'all'
2382 + ),
2383 + 'restricted_redirect_url' => array(
2384 + 'name' => 'restricted_redirect_url',
2385 + 'type' => 'text',
2386 + 'label' => __( 'Redirect URL', 'betterdocs' ),
2387 + 'label_subtitle' => __( 'Set a custom URL to redirect users without permissions when they try to access internal knowledge base. By default, restricted content will redirect to the "404 not found" page', 'betterdocs' ),
2388 + 'default' => '',
2389 + 'placeholder' => 'https://',
2390 + 'is_pro' => true,
2391 + 'priority' => 20,
2392 + 'rules' => Rules::logicalRule(
2393 + array(
2394 + Rules::is( 'enable_content_restriction', true )
2395 + ),
2396 + 'and'
2397 + )
2398 + )
2399 + ) )
2400 + )
2401 + )
2402 + )
2403 + )
2404 + )
2405 + )
2406 + ) ),
2407 + 'tab-email-reporting' => apply_filters( 'betterdocs_settings_tab_email_reporting', array(
2408 + 'id' => 'tab-email-reporting',
2409 + 'label' => __( 'Email Reporting', 'betterdocs' ),
1548 2410 'priority' => 60,
1549 - 'fields' => [
1550 - 'title-email-reporting' => [
1551 - 'name' => 'title-email-reporting-tab',
1552 - 'type' => 'section',
1553 - 'label' => __( 'Email Reporting', 'betterdocs' ),
2411 + 'fields' => array(
2412 + 'title-email-reporting' => array(
2413 + 'name' => 'title-email-reporting-tab',
2414 + 'type' => 'section',
2415 + 'label' => __( 'Email Reporting', 'betterdocs' ),
1554 2416 'priority' => 60,
1555 - 'fields' => [
1556 - 'enable_reporting' => [
1557 - 'name' => 'enable_reporting',
1558 - 'label' => __( 'Email Reporting', 'betterdocs' ),
2417 + 'fields' => array(
2418 + 'enable_reporting' => array(
2419 + 'name' => 'enable_reporting',
2420 + 'label' => __( 'Email Reporting', 'betterdocs' ),
1559 2421 'enable_disable_text_active' => true,
1560 - 'type' => 'toggle',
1561 - 'priority' => 1,
1562 - 'default' => 0
1563 - ],
1564 - 'reporting_frequency' => apply_filters( 'betterdocs_reporting_frequency_settings', [
1565 - 'name' => 'reporting_frequency',
1566 - 'type' => 'select',
1567 - 'label' => __( 'Reporting Frequency', 'betterdocs' ),
1568 - 'default' => 'betterdocs_weekly',
2422 + 'type' => 'toggle',
2423 + 'priority' => 1,
2424 + 'default' => 0
2425 + ),
2426 + 'reporting_frequency' => apply_filters( 'betterdocs_reporting_frequency_settings', array(
2427 + 'name' => 'reporting_frequency',
2428 + 'type' => 'select',
2429 + 'label' => __( 'Reporting Frequency', 'betterdocs' ),
2430 + 'default' => 'betterdocs_weekly',
1569 2431 'priority' => 2,
1570 - 'is_pro' => true,
1571 - 'options' => $this->normalize_options( [
1572 - 'betterdocs_daily' => __( 'Once Daily', 'betterdocs' ),
1573 - 'betterdocs_weekly' => __( 'Once Weekly', 'betterdocs' ),
2432 + 'is_pro' => true,
2433 + 'options' => $this->normalize_options( array(
2434 + 'betterdocs_daily' => __( 'Once Daily', 'betterdocs' ),
2435 + 'betterdocs_weekly' => __( 'Once Weekly', 'betterdocs' ),
1574 2436 'betterdocs_monthly' => __( 'Once Monthly', 'betterdocs' )
1575 - ] ),
1576 - 'rules' => Rules::is( 'enable_reporting', true )
1577 - ] ),
1578 - 'reporting_day' => [
1579 - 'name' => 'reporting_day',
1580 - 'type' => 'select',
1581 - 'label' => __( 'Reporting Day', 'betterdocs' ),
1582 - 'default' => 'monday',
1583 - 'rules' => Rules::logicalRule( [
2437 + ) ),
2438 + 'rules' => Rules::is( 'enable_reporting', true )
2439 + ) ),
2440 + 'reporting_day' => array(
2441 + 'name' => 'reporting_day',
2442 + 'type' => 'select',
2443 + 'label' => __( 'Reporting Day', 'betterdocs' ),
2444 + 'default' => 'monday',
2445 + 'rules' => Rules::logicalRule( array(
1584 2446 Rules::is( 'enable_reporting', true ),
1585 2447 Rules::is( 'reporting_frequency', 'betterdocs_weekly' )
1586 - ], 'and' ),
1587 - 'priority' => 3,
1588 - 'options' => $this->normalize_options( [
1589 - 'sunday' => __( 'Sunday', 'betterdocs' ),
1590 - 'monday' => __( 'Monday', 'betterdocs' ),
1591 - 'tuesday' => __( 'Tuesday', 'betterdocs' ),
2448 + ), 'and' ),
2449 + 'priority' => 3,
2450 + 'options' => $this->normalize_options( array(
2451 + 'sunday' => __( 'Sunday', 'betterdocs' ),
2452 + 'monday' => __( 'Monday', 'betterdocs' ),
2453 + 'tuesday' => __( 'Tuesday', 'betterdocs' ),
1592 2454 'wednesday' => __( 'Wednesday', 'betterdocs' ),
1593 - 'thursday' => __( 'Thursday', 'betterdocs' ),
1594 - 'friday' => __( 'Friday', 'betterdocs' ),
1595 - 'saturday' => __( 'Saturday', 'betterdocs' )
1596 - ] ),
2455 + 'thursday' => __( 'Thursday', 'betterdocs' ),
2456 + 'friday' => __( 'Friday', 'betterdocs' ),
2457 + 'saturday' => __( 'Saturday', 'betterdocs' )
2458 + ) ),
1597 2459 'label_subtitle' => __( 'This is only applicable for the “Weekly” report', 'betterdocs' )
1598 - ],
1599 - 'select_reporting_data' => apply_filters( 'betterdocs_select_reporting_data_settings', [
1600 - 'name' => 'select_reporting_data',
1601 - 'type' => 'checkbox-select',
1602 - 'label' => __( 'Select Reporting Data', 'betterdocs' ),
2460 + ),
2461 + 'select_reporting_data' => apply_filters( 'betterdocs_select_reporting_data_settings', array(
2462 + 'name' => 'select_reporting_data',
2463 + 'type' => 'checkbox-select',
2464 + 'label' => __( 'Select Reporting Data', 'betterdocs' ),
1603 2465 'priority' => 4,
1604 2466 'multiple' => true,
1605 - 'options' => $this->normalize_options( [
1606 - 'overview' => 'Overview',
1607 - 'top-docs' => 'Top Docs',
2467 + 'options' => $this->normalize_options( array(
2468 + 'overview' => 'Overview',
2469 + 'top-docs' => 'Top Docs',
1608 2470 'most-search' => 'Most Searched Keywords'
1609 - ] ),
1610 - 'default' => [ 'overview', 'top-docs', 'most-search' ],
1611 - 'is_pro' => true,
1612 - 'rules' => Rules::is( 'enable_reporting', true )
1613 - ] ),
1614 - 'reporting_email' => [
1615 - 'name' => 'reporting_email',
1616 - 'type' => 'text',
1617 - 'label' => __( 'Reporting Email', 'betterdocs' ),
1618 - 'default' => get_option( 'admin_email' ),
2471 + ) ),
2472 + 'default' => array( 'overview', 'top-docs', 'most-search' ),
2473 + 'is_pro' => true,
2474 + 'rules' => Rules::is( 'enable_reporting', true )
2475 + ) ),
2476 + 'reporting_email' => array(
2477 + 'name' => 'reporting_email',
2478 + 'type' => 'text',
2479 + 'label' => __( 'Reporting Email', 'betterdocs' ),
2480 + 'default' => get_option( 'admin_email' ),
1619 2481 'priority' => 5,
1620 - 'rules' => Rules::is( 'enable_reporting', true )
1621 - ],
1622 - 'reporting_subject' => apply_filters( 'betterdocs_reporting_subject_settings', [
1623 - 'name' => 'reporting_subject',
1624 - 'type' => 'textarea',
1625 - 'label' => __( 'Reporting Email Subject', 'betterdocs' ),
1626 - 'default' => wp_sprintf( __( 'Your Documentation Performance of %s Website', 'betterdocs' ), get_bloginfo( 'name' ) ),
2482 + 'rules' => Rules::is( 'enable_reporting', true )
2483 + ),
2484 + 'reporting_subject' => apply_filters( 'betterdocs_reporting_subject_settings', array(
2485 + 'name' => 'reporting_subject',
2486 + 'type' => 'textarea',
2487 + 'label' => __( 'Reporting Email Subject', 'betterdocs' ),
2488 + 'default' => wp_sprintf( // Translators: %s is replaced with the website name.
2489 + __( 'Your Documentation Performance of %s Website', 'betterdocs' ), get_bloginfo( 'name' ) ),
1627 2490 'priority' => 6,
1628 - 'is_pro' => true,
1629 - 'rules' => Rules::is( 'enable_reporting', true )
1630 - ] ),
1631 - 'test_report' => [
1632 - 'name' => 'test_report',
1633 - 'label' => __( 'Reporting Test', 'betterdocs' ),
1634 - 'text' => __( 'Test Report', 'betterdocs' ),
1635 - 'type' => 'button',
2491 + 'is_pro' => true,
2492 + 'rules' => Rules::is( 'enable_reporting', true )
2493 + ) ),
2494 + 'test_report' => array(
2495 + 'name' => 'test_report',
2496 + 'label' => __( 'Reporting Test', 'betterdocs' ),
2497 + 'text' => __( 'Test Report', 'betterdocs' ),
2498 + 'type' => 'button',
1636 2499 'priority' => 7,
1637 - 'rules' => Rules::is( 'enable_reporting', true ),
1638 - 'ajax' => [
1639 - 'on' => 'click',
1640 - 'api' => '/betterdocs/v1/reporting-test',
1641 - 'data' => [
1642 - 'enable_reporting' => '@enable_reporting',
2500 + 'rules' => Rules::is( 'enable_reporting', true ),
2501 + 'ajax' => array(
2502 + 'on' => 'click',
2503 + 'api' => '/betterdocs/v1/reporting-test',
2504 + 'data' => array(
2505 + 'enable_reporting' => '@enable_reporting',
1643 2506 'select_reporting_data' => '@select_reporting_data',
1644 - 'reporting_subject' => '@reporting_subject',
1645 - 'reporting_email' => '@reporting_email',
1646 - 'reporting_day' => '@reporting_day',
1647 - 'reporting_frequency' => '@reporting_frequency'
1648 - ],
1649 - 'swal' => [
1650 - 'text' => __( 'Successfully Sent a Test Report in Your Email.', 'betterdocs' ),
1651 - 'icon' => 'success',
2507 + 'reporting_subject' => '@reporting_subject',
2508 + 'reporting_email' => '@reporting_email',
2509 + 'reporting_day' => '@reporting_day',
2510 + 'reporting_frequency' => '@reporting_frequency'
2511 + ),
2512 + 'swal' => array(
2513 + 'text' => __( 'Successfully Sent a Test Report in Your Email.', 'betterdocs' ),
2514 + 'icon' => 'success',
1652 2515 'autoClose' => 2000
1653 - ]
1654 - ]
1655 - ]
1656 - ]
1657 - ]
1658 - ]
1659 - ] ),
1660 - 'tab-instant-answer' => apply_filters( 'betterdocs_settings_tab_instant_answer', [
1661 - 'id' => 'tab-instant-answer',
1662 - 'name' => 'tab-instant-answer',
1663 - 'type' => 'section',
1664 - 'label' => __( 'Instant Answer', 'betterdocs' ),
1665 - 'save' => false,
2516 + )
2517 + )
2518 + )
2519 + )
2520 + )
2521 + )
2522 + ) ),
2523 + 'tab-git-sync' => apply_filters( 'betterdocs_settings_tab_github_integration', array(
2524 + 'id' => 'tab-git-sync',
2525 + 'label' => __( 'Git Sync', 'betterdocs' ),
2526 + 'priority' => 60,
2527 + 'fields' => array(
2528 + 'title-git-sync' => array(
2529 + 'name' => 'title-git-sync-tab',
2530 + 'type' => 'section',
2531 + 'label' => __( 'Git Sync Settings', 'betterdocs' ),
2532 + 'priority' => 60,
2533 + 'fields' => array(
2534 + 'enable_git_integration' => array(
2535 + 'name' => 'enable_git_integration',
2536 + 'type' => 'toggle',
2537 + 'label' => __( 'Enable Git Sync', 'betterdocs' ),
2538 + 'enable_disable_text_active' => true,
2539 + 'default' => false,
2540 + 'priority' => 1,
2541 + 'is_pro' => true,
2542 + 'label_subtitle' => __( 'Enable bidirectional synchronization between BetterDocs and Git repositories', 'betterdocs' )
2543 + )
2544 + )
2545 + )
2546 + )
2547 + ) ),
2548 + 'tab-instant-answer' => apply_filters( 'betterdocs_settings_tab_instant_answer', array(
2549 + 'id' => 'tab-instant-answer',
2550 + 'name' => 'tab-instant-answer',
2551 + 'type' => 'section',
2552 + 'label' => __( 'Instant Answer', 'betterdocs' ),
2553 + 'save' => false,
1666 2554 'priority' => 70,
1667 - 'fields' => [
1668 - 'title-instant-answer' => [
1669 - 'name' => 'title-instant-answer-tab',
1670 - 'type' => 'section',
1671 - 'label' => __( 'Instant Answer', 'betterdocs' ),
1672 - 'priority' => 80,
1673 - 'save' => false,
2555 + 'fields' => array(
2556 + 'title-instant-answer' => array(
2557 + 'name' => 'title-instant-answer-tab',
2558 + 'type' => 'section',
2559 + 'label' => __( 'Instant Answer', 'betterdocs' ),
2560 + 'priority' => 80,
2561 + 'save' => false,
1674 2562 'showSubmit' => false,
1675 - 'fields' => apply_filters( 'betterdocs_instant_answer_fields', [
1676 - 'enable_disable_wrapper' => [
1677 - 'name' => 'enable_disable_wrapper',
1678 - 'type' => 'section',
2563 + 'fields' => apply_filters( 'betterdocs_instant_answer_fields', array(
2564 + 'enable_disable_wrapper' => array(
2565 + 'name' => 'enable_disable_wrapper',
2566 + 'type' => 'section',
1679 2567 'priority' => 0,
1680 - 'save' => false,
1681 - 'fields' => [
1682 - 'enable_disable' => [
1683 - 'name' => 'enable_disable',
1684 - 'type' => 'toggle',
1685 - 'priority' => 100,
1686 - 'description' => __( 'Enable Instant Answer', 'betterdocs' ),
2568 + 'save' => false,
2569 + 'fields' => array(
2570 + 'enable_disable' => array(
2571 + 'name' => 'enable_disable',
2572 + 'type' => 'toggle',
2573 + 'priority' => 100,
2574 + 'description' => __( 'Enable Instant Answer', 'betterdocs' ),
1687 2575 'enable_disable_text_active' => false,
1688 - 'default' => true,
1689 - 'is_pro' => true
1690 - ]
1691 - ]
1692 - ]
1693 - ] )
1694 - ]
1695 - ]
1696 - ] ),
1697 - 'tab-ai-autowrite' => [
1698 - 'id' => 'tab-ai-autowrite',
1699 - 'name' => 'tab-ai-autowrite',
1700 - 'type' => 'section',
1701 - 'label' => __( 'Write with AI', 'betterdocs' ),
2576 + 'default' => false,
2577 + 'is_pro' => true
2578 + )
2579 + )
2580 + )
2581 + ) )
2582 + )
2583 + )
2584 + ) ),
2585 + 'tab-betterdocs-ai' => array(
2586 + 'id' => 'tab-betterdocs-ai',
2587 + 'name' => 'tab-betterdocs-ai',
2588 + 'type' => 'section',
2589 + 'label' => __( 'AI Content Suite', 'betterdocs' ),
2590 + 'priority' => 74,
2591 + 'fields' => array(
2592 + 'sections-betterdocs-ai' => array(
2593 + 'name' => 'sections-betterdocs-ai',
2594 + 'type' => 'section',
2595 + 'label' => __( 'AI Content Suite', 'betterdocs' ),
2596 + 'priority' => 10,
2597 + 'fields' => array(
2598 + 'all-betterdocs-ai' => array(
2599 + 'id' => 'all-tab-betterdocs-ai',
2600 + 'name' => 'all-tab-betterdocs-ai',
2601 + 'label' => __( 'AI Content Suite Settings', 'betterdocs' ),
2602 + 'classes' => 'tab-layout',
2603 + 'type' => 'tab',
2604 + 'active' => 'open-ai-settings',
2605 + 'completionTrack' => true,
2606 + 'sidebar' => false,
2607 + 'save' => false,
2608 + 'title' => false,
2609 + 'config' => array(
2610 + 'active' => 'open-ai-settings',
2611 + 'sidebar' => false,
2612 + 'title' => false
2613 + ),
2614 + 'submit' => array(
2615 + 'show' => false
2616 + ),
2617 + 'step' => array(
2618 + 'show' => false
2619 + ),
2620 + 'priority' => 20,
2621 + 'fields' => apply_filters(
2622 + 'betterdocs_migration_tab_sections',
2623 + array(
2624 + 'open-ai-settings' => array(
2625 + 'id' => 'open-ai-settings',
2626 + 'name' => 'open-ai-settings',
2627 + 'type' => 'section',
2628 + 'label' => __( 'AI Platform & API', 'betterdocs' ),
2629 + 'priority' => 1,
2630 + 'fields' => array(
2631 + 'ai_platform' => array(
2632 + 'name' => 'ai_platform',
2633 + 'type' => 'select',
2634 + 'label' => __( 'AI Platform', 'betterdocs' ),
2635 + 'label_subtitle' => __( 'Choose which AI platform powers Write with AI, AI Edit, the Doc Summarizer and Quality Score. The model list and API key field below adapt to your choice.', 'betterdocs' ),
2636 + 'priority' => 1,
2637 + 'multiple' => false,
2638 + 'default' => 'openai',
2639 + // DeepSeek and OpenRouter are temporarily hidden from the
2640 + // dropdown. Filter the options here, NOT ModelRegistry::platforms() —
2641 + // sensitive_api_key_fields() loops the registry to mask each
2642 + // platform's key field, so trimming the registry would silently
2643 + // un-mask those keys. Re-enable later by dropping the array_diff_key.
2644 + 'options' => GlobalFields::normalize_fields(
2645 + array_diff_key( ModelRegistry::platforms(), array_flip( array( 'deepseek', 'openrouter' ) ) )
2646 + )
2647 + ),
2648 + // OpenAI's key field keeps its original name so installs
2649 + // that already saved a Write with AI key keep it.
2650 + 'ai_autowrite_api_key' => array(
2651 + 'name' => 'ai_autowrite_api_key',
2652 + 'type' => 'text',
2653 + 'label' => __( 'OpenAI API Key', 'betterdocs' ),
2654 + 'label_subtitle' => sprintf( /* translators: %s: documentation URL */ __( 'Check out this <a target="_blank" href="%s">documentation</a> to generate your OpenAI API key.', 'betterdocs' ), esc_url( 'https://betterdocs.co/docs/write-with-ai/' ) ),
2655 + 'default' => '',
2656 + 'priority' => 2,
2657 + 'rules' => Rules::is( 'ai_platform', 'openai' )
2658 + ),
2659 + 'ai_api_key_gemini' => array(
2660 + 'name' => 'ai_api_key_gemini',
2661 + 'type' => 'text',
2662 + 'label' => __( 'Google Gemini API Key', 'betterdocs' ),
2663 + 'label_subtitle' => sprintf( /* translators: %s: Google AI Studio URL */ __( 'Generate a key from <a target="_blank" href="%s">Google AI Studio</a>.', 'betterdocs' ), esc_url( 'https://aistudio.google.com/app/apikey' ) ),
2664 + 'default' => '',
2665 + 'priority' => 2,
2666 + 'rules' => Rules::is( 'ai_platform', 'gemini' )
2667 + ),
2668 + 'ai_api_key_claude' => array(
2669 + 'name' => 'ai_api_key_claude',
2670 + 'type' => 'text',
2671 + 'label' => __( 'Anthropic Claude API Key', 'betterdocs' ),
2672 + 'label_subtitle' => sprintf( /* translators: %s: Anthropic Console URL */ __( 'Generate a key from the <a target="_blank" href="%s">Anthropic Console</a>.', 'betterdocs' ), esc_url( 'https://console.anthropic.com/settings/keys' ) ),
2673 + 'default' => '',
2674 + 'priority' => 2,
2675 + 'rules' => Rules::is( 'ai_platform', 'claude' )
2676 + ),
2677 + 'ai_api_key_deepseek' => array(
2678 + 'name' => 'ai_api_key_deepseek',
2679 + 'type' => 'text',
2680 + 'label' => __( 'DeepSeek API Key', 'betterdocs' ),
2681 + 'label_subtitle' => sprintf( /* translators: %s: DeepSeek platform URL */ __( 'Generate a key from the <a target="_blank" href="%s">DeepSeek platform</a>.', 'betterdocs' ), esc_url( 'https://platform.deepseek.com/api_keys' ) ),
2682 + 'default' => '',
2683 + 'priority' => 2,
2684 + 'rules' => Rules::is( 'ai_platform', 'deepseek' )
2685 + ),
2686 + 'ai_api_key_openrouter' => array(
2687 + 'name' => 'ai_api_key_openrouter',
2688 + 'type' => 'text',
2689 + 'label' => __( 'OpenRouter API Key', 'betterdocs' ),
2690 + 'label_subtitle' => sprintf( /* translators: %s: OpenRouter keys URL */ __( 'Generate a key from <a target="_blank" href="%s">OpenRouter</a>.', 'betterdocs' ), esc_url( 'https://openrouter.ai/keys' ) ),
2691 + 'default' => '',
2692 + 'priority' => 2,
2693 + 'rules' => Rules::is( 'ai_platform', 'openrouter' )
2694 + ),
2695 + 'ai_model' => array(
2696 + 'name' => 'ai_model',
2697 + 'type' => 'platform_model_select',
2698 + 'label' => __( 'Model', 'betterdocs' ),
2699 + 'label_subtitle' => __( 'Available models depend on the selected platform.', 'betterdocs' ),
2700 + 'priority' => 10,
2701 + 'default' => 'gpt-4o-mini',
2702 + 'catalogue' => ModelRegistry::catalogue(),
2703 + 'defaults' => ModelRegistry::defaults()
2704 + )
2705 + )
2706 + ),
2707 + 'write-with-ai' => array(
2708 + 'id' => 'write-with-ai',
2709 + 'name' => 'write-with-ai',
2710 + 'type' => 'section',
2711 + 'label' => __( 'Write with AI', 'betterdocs' ),
2712 + 'priority' => 5,
2713 + 'fields' => array(
2714 + 'write-with-ai-subtabs' => array(
2715 + 'id' => 'write-with-ai-subtabs',
2716 + 'name' => 'write_with_ai_subtabs',
2717 + 'label' => __( 'Write with AI', 'betterdocs' ),
2718 + 'classes' => 'tab-nested-layout',
2719 + 'type' => 'tab',
2720 + 'active' => 'wwa-configuration',
2721 + 'completionTrack' => true,
2722 + 'sidebar' => false,
2723 + 'save' => false,
2724 + 'title' => false,
2725 + 'config' => array(
2726 + 'active' => 'wwa-configuration',
2727 + 'sidebar' => false,
2728 + 'title' => false
2729 + ),
2730 + 'submit' => array(
2731 + 'show' => false
2732 + ),
2733 + 'step' => array(
2734 + 'show' => false
2735 + ),
2736 + 'priority' => 5,
2737 + 'fields' => array(
2738 + 'wwa-configuration' => array(
2739 + 'id' => 'wwa-configuration',
2740 + 'name' => 'wwa-configuration',
2741 + 'type' => 'section',
2742 + 'label' => __( 'Configuration', 'betterdocs' ),
2743 + 'priority' => 1,
2744 + 'fields' => array(
2745 + 'enable_write_with_ai' => array(
2746 + 'name' => 'enable_write_with_ai',
2747 + 'type' => 'toggle',
2748 + 'priority' => 0,
2749 + 'label' => __( 'Write Docs with AI', 'betterdocs' ),
2750 + 'label_subtitle' => __( 'Generate AI based Documentation in your Gutenberg Editor', 'betterdocs' ),
2751 + 'enable_disable_text_active' => true,
2752 + 'default' => true
2753 + ),
2754 + 'enable_faq_write_with_ai' => array(
2755 + 'name' => 'enable_faq_write_with_ai',
2756 + 'type' => 'toggle',
2757 + 'priority' => 5,
2758 + 'label' => __( 'Write FAQ with AI', 'betterdocs' ),
2759 + 'label_subtitle' => __( 'Generate AI based FAQ in your Editor', 'betterdocs' ),
2760 + 'enable_disable_text_active' => true,
2761 + 'default' => true
2762 + ),
2763 + 'enable_glossaries_write_with_ai' => array(
2764 + 'name' => 'enable_glossaries_write_with_ai',
2765 + 'type' => 'toggle',
2766 + 'priority' => 6,
2767 + 'label' => __( 'Write Glossaries with AI', 'betterdocs' ),
2768 + 'label_subtitle' => __( 'Generate AI based Glossary definitions from the Glossaries admin page', 'betterdocs' ),
2769 + 'enable_disable_text_active' => true,
2770 + 'default' => true,
2771 + 'is_pro' => true
2772 + ),
2773 + 'enable_docs_ai_suite' => array(
2774 + 'name' => 'enable_docs_ai_suite',
2775 + 'type' => 'toggle',
2776 + 'priority' => 7,
2777 + 'label' => __( 'Enhance Docs with AI', 'betterdocs' ),
2778 + 'label_subtitle' => __( 'Add BetterDocs AI actions for suggesting categories, tags and excerpts inside the native Docs editor panels.', 'betterdocs' ),
2779 + 'enable_disable_text_active' => true,
2780 + 'default' => true
2781 + ),
2782 + 'ai_autowrite_max_token' => array(
2783 + 'name' => 'ai_autowrite_max_token',
2784 + 'type' => 'min_token_number',
2785 + 'label' => __( 'Set Max Tokens', 'betterdocs' ),
2786 + 'label_subtitle' => sprintf( // translators: %s is a link to more information about token limits.
2787 + __( 'Documentation will be generated based on the Token Limits you have set. For more information on Token Limits, you can check out this <a target="_blank" href="%s">link</a>.', 'betterdocs' ), esc_url( 'https://platform.openai.com/account/limits' ) ),
2788 + 'default' => 2500,
2789 + 'priority' => 10,
2790 + 'model_field' => 'ai_model',
2791 + 'context' => 'write_with_ai',
2792 + 'min_token_map' => AIHelper::get_min_tokens_map( 'write_with_ai' ),
2793 + 'classes' => 'wprf-type-text'
2794 + )
2795 + )
2796 + ),
2797 + 'wwa-personalize' => array(
2798 + 'id' => 'wwa-personalize',
2799 + 'name' => 'wwa-personalize',
2800 + 'type' => 'section',
2801 + 'label' => __( 'Write AI Personalize', 'betterdocs' ),
2802 + 'priority' => 5,
2803 + 'fields' => array(
2804 + 'write_with_ai_instructions' => array(
2805 + 'name' => 'write_with_ai_instructions',
2806 + 'type' => 'wwa_instructions',
2807 + 'label' => __( 'Instructions', 'betterdocs' ),
2808 + 'label_subtitle' => __( 'Add reusable instruction sets to steer how BetterDocs AI writes. The "Default/Core" set is always applied; extra sets can be picked in the Write with AI popup.', 'betterdocs' ),
2809 + 'priority' => 1,
2810 + 'default' => array(
2811 + array(
2812 + 'id' => 'default',
2813 + 'title' => __( 'Default/Core', 'betterdocs' ),
2814 + 'content' => WriteWithAI::default_instruction_content()
2815 + )
2816 + )
2817 + )
2818 + )
2819 + ),
2820 + 'edit-ai-personalize' => array(
2821 + 'id' => 'edit-ai-personalize',
2822 + 'name' => 'edit-ai-personalize',
2823 + 'type' => 'section',
2824 + 'label' => __( 'Edit AI Personalize', 'betterdocs' ),
2825 + 'priority' => 7,
2826 + 'fields' => array(
2827 + 'ai_edit_actions' => array(
2828 + 'name' => 'ai_edit_actions',
2829 + 'type' => 'ai_edit_actions',
2830 + 'label' => __( 'Actions', 'betterdocs' ),
2831 + 'label_subtitle' => __( 'Choose which Edit with AI actions appear in the editor. Toggle actions on or off, edit each action\'s instruction, or add your own custom actions. All predefined actions are enabled by default.', 'betterdocs' ),
2832 + 'priority' => 1,
2833 + 'default' => AIEdit::default_actions()
2834 + )
2835 + )
2836 + )
2837 + )
2838 + )
2839 + )
2840 + ),
2841 + 'article-summary' => array(
2842 + 'id' => 'article-summary',
2843 + 'name' => 'article-summary',
2844 + 'type' => 'section',
2845 + 'label' => __( 'AI Doc Summarizer', 'betterdocs' ),
2846 + 'priority' => 10,
2847 + 'fields' => array(
2848 + 'enable_article_summary' => array(
2849 + 'name' => 'enable_article_summary',
2850 + 'type' => 'toggle',
2851 + 'priority' => 1,
2852 + 'label' => __( 'AI Powered Doc Summarizer', 'betterdocs' ),
2853 + 'label_subtitle' => __( 'Enable AI-powered article summaries on single doc pages. Requires OpenAI API key.', 'betterdocs' ),
2854 + 'enable_disable_text_active' => true,
2855 + 'default' => false
2856 + ),
2857 + 'article_summary_max_token' => array(
2858 + 'name' => 'article_summary_max_token',
2859 + 'type' => 'min_token_number',
2860 + 'label' => __( 'Set Max Tokens', 'betterdocs' ),
2861 + 'label_subtitle' => sprintf( // translators: %s is a link to more information about token limits.
2862 + __( 'Single Doc summarizer will be generated based on the token limits you have set. For more information on Token Limits, you can check out this <a target="_blank" href="%s">link</a>.', 'betterdocs' ), esc_url( 'https://platform.openai.com/account/limits' ) ),
2863 + 'default' => 1500,
2864 + 'priority' => 5,
2865 + 'model_field' => 'ai_model',
2866 + 'context' => 'article_summary',
2867 + 'min_token_map' => AIHelper::get_min_tokens_map( 'article_summary' ),
2868 + 'classes' => 'wprf-type-text'
2869 + )
2870 + )
2871 + )
2872 + )
2873 + )
2874 + )
2875 + )
2876 + )
2877 + )
2878 + ),
2879 + 'tab-ai-chatbot' => apply_filters( 'betterdocs_settings_tab_ai_chatbot', array(
2880 + 'id' => 'tab-ai-chatbot',
2881 + 'name' => 'tab-ai-chatbot',
2882 + 'type' => 'section',
2883 + 'label' => __( 'AI Chatbot', 'betterdocs' ),
2884 + 'submit' => array(
2885 + 'show' => false
2886 + ),
2887 + 'save' => false,
1702 2888 'priority' => 75,
1703 - 'fields' => [
1704 - 'title-ai-autowrite' => apply_filters( 'betterdocs_settings_ai_autowrite_fields', [
1705 - 'name' => 'title-ai-autowrite-tab',
1706 - 'type' => 'section',
1707 - 'label' => __( 'Write with AI', 'betterdocs' ),
1708 - 'priority' => 60,
1709 - 'fields' => [
1710 - 'enable_write_with_ai' => [
1711 - 'name' => 'enable_write_with_ai',
1712 - 'type' => 'toggle',
1713 - 'priority' => 0,
1714 - 'label' => __( 'Write Docs with AI', 'betterdocs' ),
1715 - 'label_subtitle' => __( 'Generate AI based Documentation in your Gutenberg Editor', 'betterdocs' ),
1716 - 'enable_disable_text_active' => true,
1717 - 'default' => true
1718 - ],
1719 - 'enable_faq_write_with_ai' => [
1720 - 'name' => 'enable_faq_write_with_ai',
1721 - 'type' => 'toggle',
1722 - 'priority' => 5,
1723 - 'label' => __( 'Write FAQ with AI', 'betterdocs' ),
1724 - 'label_subtitle' => __( 'Generate AI based FAQ in your Editor', 'betterdocs' ),
1725 - 'enable_disable_text_active' => true,
1726 - 'default' => true
1727 - ],
1728 - 'ai_autowrite_api_key' => [
1729 - 'name' => 'ai_autowrite_api_key',
1730 - 'type' => 'text',
1731 - 'label' => __( 'API Key', 'betterdocs' ),
1732 - 'label_subtitle' => __( 'Check out this <a target="_blank" href="' . esc_url( 'https://betterdocs.co/docs/write-with-ai/' ) . '">documentation</a> to find out to generate your OpenAI API Key', 'betterdocs' ),
1733 - 'default' => '',
1734 - 'priority' => 10,
1735 - ],
1736 - 'ai_autowrite_max_token' => [
1737 - 'name' => 'ai_autowrite_max_token',
1738 - 'type' => 'number',
1739 - 'label' => __( 'Set Max Tokens', 'betterdocs' ),
1740 - 'label_subtitle' => __( 'Documentation will be generated based on the Token Limits you have set. For more information on Token Limits, you can check out this <a target="_blank" href="' . esc_url( 'https://platform.openai.com/account/limits' ) . '">link</a>.', 'betterdocs' ),
1741 - 'default' => 1500,
1742 - 'priority' => 15
1743 - ]
1744 - ]
1745 - ] )
1746 - ]
1747 - ]
1748 - ] )
1749 - ];
2889 + 'fields' => array(
2890 + 'title-ai-chatbot-tab' => array(
2891 + 'name' => 'title-ai-chatbot-tab',
2892 + 'type' => 'section',
2893 + 'label' => __( 'AI Chatbot', 'betterdocs' ),
2894 + 'priority' => 80,
2895 + 'submit' => array(
2896 + 'show' => false
2897 + ),
2898 + 'save' => false,
2899 + 'fields' => apply_filters( 'betterdocs_ai_chatbot_fields', array(
2900 + 'ai_chatbot_fields' => array(
2901 + 'name' => 'ai_chatbot_fields',
2902 + 'type' => 'section',
2903 + 'priority' => 0,
2904 + 'fields' => array(
2905 + 'enable_ai_chatbot' => array(
2906 + 'name' => 'enable_ai_chatbot',
2907 + 'label' => __( 'AI Chatbot', 'betterdocs' ),
2908 + 'description' => __( 'Enable AI Chatbot', 'betterdocs' ),
2909 + 'type' => 'toggle',
2910 + 'priority' => 5,
2911 + 'default' => 0,
2912 + 'is_pro' => true,
2913 + 'is_license_active' => false,
2914 + 'disabled' => ! betterdocs()->is_pro_active() || ! defined( 'BETTERDOCS_CHATBOT_FILE' )
2915 + ),
2916 + 'instant_answer_warning' => array(
2917 + 'name' => 'instant_answer_warning',
2918 + 'type' => 'html',
2919 + 'priority' => 6,
2920 + 'html' => sprintf(
2921 + '<div class="betterdocs-ia-warning" style="margin:8px 0 0;padding:12px 16px;background:#fffaeb;border-left:4px solid #fdb022;border-radius:4px;display:flex;align-items:flex-start;gap:10px;"><span style="font-size:18px;line-height:1;flex-shrink:0;color:#b54708;">&#9888;</span><div style="font-size:13px;color:#202223;line-height:1.5;">%1$s<br><a href="?page=betterdocs-settings&amp;tab=tab-instant-answer" style="display:inline-block;margin-top:6px;color:#5a6bff;text-decoration:none;font-weight:500;">%2$s &rarr;</a></div></div>',
2922 + esc_html__( 'Instant Answer is currently disabled. The AI Chatbot won\'t appear on your site until Instant Answer is enabled.', 'betterdocs' ),
2923 + esc_html__( 'Enable Instant Answer', 'betterdocs' )
2924 + ),
2925 + 'rules' => Rules::logicalRule( array(
2926 + Rules::is( 'enable_ai_chatbot', true ),
2927 + Rules::is( 'enable_disable', false ),
2928 + ), 'and' ),
2929 + )
2930 + )
2931 + )
2932 + ) )
2933 + )
2934 + )
2935 + ) )
2936 + ) ),
2937 + 'TAB_AI_CHATBOT' => get_option( 'enable_ai_chatbot' ),
2938 + 'CHATBOT_LICENSE' => get_option( 'betterdocs_chatbot_software__license_status' ),
2939 + 'PRO_ACTIVE' => is_plugin_active( 'betterdocs-pro/betterdocs-pro.php' ),
2940 + 'PRO_LICENSE' => get_option( 'betterdocs_pro_software__license_status' )
2941 + );
1750 2942
2943 + $settings = array_merge( $settings, $this->chatbot_active_localize() );
2944 +
1751 2945 return apply_filters( 'betterdocs_settings_args', $settings );
1752 2946 }
1753 2947
2948 + /**
2949 + * @return array
2950 + */
2951 + public function chatbot_active_localize() {
2952 + $chatbot_active = is_plugin_active( 'betterdocs-ai-chatbot/betterdocs-ai-chatbot.php' );
2953 + $chatbot_license_valid = get_option( 'betterdocs_chatbot_software__license_status' ) === 'valid';
2954 + $chatbot_enabled = $this->get( 'enable_ai_chatbot', false );
2955 +
2956 + // AI Search Suggestions are enabled if all conditions are met
2957 + $ai_search_suggestions_enabled = betterdocs()->helper->is_ai_chatbot_enabled();
2958 +
2959 + return array(
2960 + 'CHATBOT_ACTIVE' => $chatbot_active,
2961 + 'CHATBOT_LICENSE_VALID' => $chatbot_license_valid,
2962 + 'CHATBOT_ENABLED' => $chatbot_enabled,
2963 + 'AI_SEARCH_SUGGESTIONS_ENABLED' => $ai_search_suggestions_enabled
2964 + );
2965 + }
2966 +
2967 + /**
2968 + * Call This Function As Helper, When Pro Is Deactivated, To Be Used As Settings Default Values, When Betterdocs Pro Is Deactivated
2969 + *
2970 + * @return array
2971 + */
2972 + public function pro_settings_default_values() {
2973 + return array(
2974 + 'multiple_kb' => false,
2975 + 'enable_glossaries' => false,
2976 + 'enable_encyclopedia' => false,
2977 + 'analytics_from' => false,
2978 + 'unique_visitor_count' => false,
2979 + 'exclude_bot_analytics' => false,
2980 + 'show_attachment' => false,
2981 + 'show_related_docs' => false,
2982 + 'advance_search' => false,
2983 + 'child_category_exclude' => false,
2984 + 'kb_based_search' => false,
2985 + 'enable_disable' => false,
2986 + 'enable_content_restriction' => false
2987 + );
2988 + }
2989 +
1754 2990 public function import_export_settings( $settings ) {
1755 2991 if ( ! current_user_can( 'import' ) ) {
1756 2992 return $settings;
1757 2993 }
1758 2994
1759 - $settings['tab-import-export'] = apply_filters( 'betterdocs_settings_tab_import_export', [
1760 - 'id' => 'tab-import-export',
1761 - 'name' => 'tab-import-export',
1762 - 'classes' => 'tab-import-export',
1763 - 'label' => __( 'Import / Export', 'betterdocs' ),
2995 + $settings[ 'tab-import-export' ] = apply_filters( 'betterdocs_settings_tab_import_export', array(
2996 + 'id' => 'tab-import-export',
2997 + 'name' => 'tab-import-export',
2998 + 'classes' => 'tab-import-export',
2999 + 'label' => __( 'Import / Export', 'betterdocs' ),
1764 3000 'priority' => 80,
1765 - 'fields' => [
1766 - 'sections-import-export' => [
1767 - 'name' => 'sections-import-export',
1768 - 'type' => 'section',
1769 - 'label' => __( 'Import / Export', 'betterdocs' ),
3001 + 'fields' => array(
3002 + 'sections-import-export' => array(
3003 + 'name' => 'sections-import-export',
3004 + 'type' => 'section',
3005 + 'label' => __( 'Import / Export', 'betterdocs' ),
1770 3006 'priority' => 30,
1771 - 'fields' => [
1772 - 'all-tab-import-export' => [
1773 - 'id' => 'all-tab-import-export',
1774 - 'name' => 'all-tab-import-export',
1775 - 'label' => __( 'Import Export Settings', 'betterdocs' ),
1776 - 'classes' => 'tab-layout',
1777 - 'type' => "tab",
1778 - 'active' => "import",
3007 + 'fields' => array(
3008 + 'all-tab-import-export' => array(
3009 + 'id' => 'all-tab-import-export',
3010 + 'name' => 'all-tab-import-export',
3011 + 'label' => __( 'Import Export Settings', 'betterdocs' ),
3012 + 'classes' => 'tab-layout',
3013 + 'type' => 'tab',
3014 + 'active' => 'import',
1779 3015 'completionTrack' => true,
1780 - 'sidebar' => false,
1781 - 'save' => false,
1782 - 'title' => false,
1783 - 'config' => [
1784 - 'active' => 'import',
3016 + 'sidebar' => false,
3017 + 'save' => false,
3018 + 'title' => false,
3019 + 'config' => array(
3020 + 'active' => 'import',
1785 3021 'sidebar' => false,
1786 - 'title' => false
1787 - ],
1788 - 'submit' => [
3022 + 'title' => false
3023 + ),
3024 + 'submit' => array(
1789 3025 'show' => false
1790 - ],
1791 - 'step' => [
3026 + ),
3027 + 'step' => array(
1792 3028 'show' => false
1793 - ],
1794 - 'priority' => 20,
1795 - 'fields' => [
1796 - 'import' => [
1797 - 'id' => 'import',
1798 - 'name' => 'import',
1799 - 'type' => 'section',
1800 - 'label' => __( 'Import', 'betterdocs' ),
3029 + ),
3030 + 'priority' => 20,
3031 + 'fields' => array(
3032 + 'import' => array(
3033 + 'id' => 'import',
3034 + 'name' => 'import',
3035 + 'type' => 'section',
3036 + 'label' => __( 'Import', 'betterdocs' ),
1801 3037 'priority' => 1,
1802 - 'fields' => [
1803 - 'import_tab_nested' => [
1804 - 'id' => 'import_tab_nested',
1805 - 'name' => 'import_tab_nested',
1806 - 'label' => __( 'Import', 'betterdocs' ),
1807 - 'classes' => 'tab-nested-layout',
1808 - 'type' => "tab",
1809 - 'active' => "import_docs_nested",
3038 + 'fields' => array(
3039 + 'import_tab_nested' => array(
3040 + 'id' => 'import_tab_nested',
3041 + 'name' => 'import_tab_nested',
3042 + 'label' => __( 'Import', 'betterdocs' ),
3043 + 'classes' => 'tab-nested-layout',
3044 + 'type' => 'tab',
3045 + 'active' => 'import_docs_nested',
1810 3046 'completionTrack' => true,
1811 - 'sidebar' => false,
1812 - 'save' => false,
1813 - 'title' => false,
1814 - 'config' => [
1815 - 'active' => 'import_docs_nested',
3047 + 'sidebar' => false,
3048 + 'save' => false,
3049 + 'title' => false,
3050 + 'config' => array(
3051 + 'active' => 'import_docs_nested',
1816 3052 'sidebar' => false,
1817 - 'title' => false
1818 - ],
1819 - 'submit' => [
3053 + 'title' => false
3054 + ),
3055 + 'submit' => array(
1820 3056 'show' => false
1821 - ],
1822 - 'step' => [
3057 + ),
3058 + 'step' => array(
1823 3059 'show' => false
1824 - ],
1825 - 'priority' => 1,
1826 - 'fields' => [
1827 - 'import_docs_nested' => [
1828 - 'id' => 'import_docs_nested',
1829 - 'name' => 'import_docs_nested',
1830 - 'type' => 'section',
1831 - 'label' => __( 'Import Docs', 'betterdocs' ),
3060 + ),
3061 + 'priority' => 1,
3062 + 'fields' => array(
3063 + 'import_docs_nested' => array(
3064 + 'id' => 'import_docs_nested',
3065 + 'name' => 'import_docs_nested',
3066 + 'type' => 'section',
3067 + 'label' => __( 'Import Docs', 'betterdocs' ),
1832 3068 'priority' => 1,
1833 - 'fields' => [
1834 - 'import_docs' => [
1835 - 'name' => 'import_docs',
1836 - 'type' => 'importerupload',
1837 - 'label' => __( 'Import Docs', 'betterdocs' ),
1838 - 'label_subtitle' => wp_sprintf( __( 'To import your Docs, please upload the .xml / .csv file here. <a href="%1$s">Download sample csv file</a>', 'betterdocs' ), betterdocs()->assets->icon( 'BetterDocs-sample-data.csv', true ) ),
1839 - 'text' => [
1840 - 'normal' => __( 'Proceed', 'betterdocs' ),
1841 - 'saved' => __( 'Proceed', 'betterdocs' ),
1842 - 'loading' => __( 'Importing...', 'betterdocs' ),
1843 - 'exists_notice' => __( 'It seems like documentations with same slugs already exist on your website. What would you like to do?', 'betterdocs' ),
1844 - ],
1845 - 'ajax' => [
1846 - 'on' => 'click',
1847 - 'api' => '/betterdocs/v1/import-docs',
1848 - 'swal' => [
1849 - 'text' => __( 'Import completed successfully.', 'betterdocs' ),
1850 - 'icon' => 'success',
3069 + 'fields' => array(
3070 + 'import_docs' => array(
3071 + 'name' => 'import_docs',
3072 + 'type' => 'importerupload',
3073 + 'label' => __( 'Import Docs', 'betterdocs' ),
3074 + 'label_subtitle' => wp_sprintf( // Translators: %1$s is a link to download a sample CSV file.
3075 + __( 'To import your Docs, please upload the .xml / .csv file here. <a href="%1$s">Download sample csv file</a>', 'betterdocs' ), betterdocs()->assets->icon( 'BetterDocs-sample-data.csv', true ) ),
3076 + 'text' => array(
3077 + 'normal' => __( 'Proceed', 'betterdocs' ),
3078 + 'saved' => __( 'Proceed', 'betterdocs' ),
3079 + 'loading' => __( 'Importing...', 'betterdocs' ),
3080 + 'exists_notice' => __( 'It seems like documentations with same slugs already exist on your website. What would you like to do?', 'betterdocs' )
3081 + ),
3082 + 'ajax' => array(
3083 + 'on' => 'click',
3084 + 'api' => '/betterdocs/v1/import-docs',
3085 + 'swal' => array(
3086 + 'text' => __( 'Import completed successfully.', 'betterdocs' ),
3087 + 'icon' => 'success',
1851 3088 'autoClose' => 2000
1852 - ]
1853 - ],
1854 - 'file_type' => '.xml, .csv',
1855 - 'priority' => 1
1856 - ]
1857 - ]
1858 - ],
3089 + )
3090 + ),
3091 + 'file_type' => '.xml, .csv',
3092 + 'priority' => 1
3093 + )
3094 + )
3095 + ),
1859 3096
1860 - 'import_settings_nested' => [
1861 - 'id' => 'import_settings_nested',
1862 - 'name' => 'import_settings_nested',
1863 - 'type' => 'section',
1864 - 'label' => __( 'Import Settings', 'betterdocs' ),
3097 + 'import_settings_nested' => array(
3098 + 'id' => 'import_settings_nested',
3099 + 'name' => 'import_settings_nested',
3100 + 'type' => 'section',
3101 + 'label' => __( 'Import Settings', 'betterdocs' ),
1865 3102 'priority' => 1,
1866 - 'fields' => [
1867 - 'settings_importer' => [
1868 - 'name' => 'settings_importer',
1869 - 'type' => 'settingsuploader',
1870 - 'label' => __( 'Import Settings', 'notificationx' ),
3103 + 'fields' => array(
3104 + 'settings_importer' => array(
3105 + 'name' => 'settings_importer',
3106 + 'type' => 'settingsuploader',
3107 + 'label' => __( 'Import Settings', 'betterdocs' ),
1871 3108 'label_subtitle' => __( 'To import BetterDocs Settings, please upload BetterDocs settings you have exported from another website in .json format', 'betterdocs' ),
1872 - 'reset' => __( 'Change', 'notificationx' ),
1873 - 'priority' => 1
1874 - ],
1875 - 'import_settings' => [
1876 - 'name' => 'import_settings',
1877 - 'type' => 'button',
1878 - 'rules' => Rules::is( 'settings_importer', null, true ),
1879 - 'text' => [
1880 - 'normal' => __( 'Proceed', 'betterdocs' ),
1881 - 'saved' => __( 'Proceed', 'betterdocs' ),
3109 + 'reset' => __( 'Change', 'betterdocs' ),
3110 + 'priority' => 1
3111 + ),
3112 + 'import_settings' => array(
3113 + 'name' => 'import_settings',
3114 + 'type' => 'button',
3115 + 'rules' => Rules::is( 'settings_importer', null, true ),
3116 + 'text' => array(
3117 + 'normal' => __( 'Proceed', 'betterdocs' ),
3118 + 'saved' => __( 'Proceed', 'betterdocs' ),
1882 3119 'loading' => __( 'Importing...', 'betterdocs' )
1883 - ],
1884 - 'ajax' => [
1885 - 'on' => 'click',
1886 - 'api' => '/betterdocs/v1/import-settings',
1887 - 'data' => [
3120 + ),
3121 + 'ajax' => array(
3122 + 'on' => 'click',
3123 + 'api' => '/betterdocs/v1/import-settings',
3124 + 'data' => array(
1888 3125 'settings' => '@settings_importer'
1889 - ],
1890 - 'swal' => [
1891 - 'text' => __( 'Import completed successfully.', 'betterdocs' ),
1892 - 'icon' => 'success',
3126 + ),
3127 + 'swal' => array(
3128 + 'text' => __( 'Import completed successfully.', 'betterdocs' ),
3129 + 'icon' => 'success',
1893 3130 'autoClose' => 1000
1894 - ],
3131 + ),
1895 3132 'reload' => true
1896 - ],
3133 + ),
1897 3134 'priority' => 2
1898 - ]
1899 - ]
1900 - ]
1901 - ]
1902 - ]
1903 - ]
1904 - ],
1905 - 'export' => [
1906 - 'id' => 'export',
1907 - 'name' => 'export',
1908 - 'type' => 'section',
1909 - 'label' => __( 'Export', 'betterdocs' ),
3135 + )
3136 + )
3137 + )
3138 + )
3139 + )
3140 + )
3141 + ),
3142 + 'export' => array(
3143 + 'id' => 'export',
3144 + 'name' => 'export',
3145 + 'type' => 'section',
3146 + 'label' => __( 'Export', 'betterdocs' ),
1910 3147 'priority' => 1,
1911 - 'fields' => [
1912 - 'export_tab_nested' => [
1913 - 'id' => 'export_tab_nested',
1914 - 'name' => 'export_tab_nested',
1915 - 'label' => __( 'Export', 'betterdocs' ),
1916 - 'classes' => 'tab-nested-layout',
1917 - 'type' => "tab",
1918 - 'active' => "export_docs_nested",
3148 + 'fields' => array(
3149 + 'export_tab_nested' => array(
3150 + 'id' => 'export_tab_nested',
3151 + 'name' => 'export_tab_nested',
3152 + 'label' => __( 'Export', 'betterdocs' ),
3153 + 'classes' => 'tab-nested-layout',
3154 + 'type' => 'tab',
3155 + 'active' => 'export_docs_nested',
1919 3156 'completionTrack' => true,
1920 - 'sidebar' => false,
1921 - 'save' => false,
1922 - 'title' => false,
1923 - 'config' => [
1924 - 'active' => 'export_docs_nested',
3157 + 'sidebar' => false,
3158 + 'save' => false,
3159 + 'title' => false,
3160 + 'config' => array(
3161 + 'active' => 'export_docs_nested',
1925 3162 'sidebar' => false,
1926 - 'title' => false
1927 - ],
1928 - 'submit' => [
3163 + 'title' => false
3164 + ),
3165 + 'submit' => array(
1929 3166 'show' => false
1930 - ],
1931 - 'step' => [
3167 + ),
3168 + 'step' => array(
1932 3169 'show' => false
1933 - ],
1934 - 'priority' => 1,
1935 - 'fields' => [
1936 - 'export_docs_nested' => [
1937 - 'id' => 'export_docs_nested',
1938 - 'name' => 'export_docs_nested',
1939 - 'type' => 'section',
1940 - 'label' => __( 'Export Docs', 'betterdocs' ),
3170 + ),
3171 + 'priority' => 1,
3172 + 'fields' => array(
3173 + 'export_docs_nested' => array(
3174 + 'id' => 'export_docs_nested',
3175 + 'name' => 'export_docs_nested',
3176 + 'type' => 'section',
3177 + 'label' => __( 'Export Docs', 'betterdocs' ),
1941 3178 'priority' => 1,
1942 - 'fields' => apply_filters( 'betterdocs_export_fields', [
1943 - 'export_type' => [
1944 - 'name' => 'export_type',
1945 - 'label' => __( 'Select Docs Type', 'betterdocs' ),
3179 + 'fields' => apply_filters( 'betterdocs_export_fields', array(
3180 + 'export_type' => array(
3181 + 'name' => 'export_type',
3182 + 'label' => __( 'Select Docs Type', 'betterdocs' ),
1946 3183 'label_subtitle' => __( 'Choose an export type: All Docs, a specific Knowledge Base, or a Doc Category', 'betterdocs' ),
1947 - 'type' => 'select',
1948 - 'default' => 'docs',
1949 - 'priority' => 3,
1950 - 'search' => true,
1951 - 'options' => $this->normalize_options( apply_filters( 'betterdocs_export_type_options', [
1952 - 'docs' => __( 'Docs', 'betterdocs' ),
1953 - 'doc_category' => __( 'Docs Category', 'betterdocs' )
1954 - ] ) )
1955 - ],
1956 - 'export_docs' => [
1957 - 'name' => 'export_docs',
1958 - 'type' => 'checkbox-select',
1959 - 'label' => __( 'Select Docs', 'betterdocs' ),
3184 + 'type' => 'select',
3185 + 'default' => 'docs',
3186 + 'priority' => 3,
3187 + 'search' => true,
3188 + 'options' => $this->normalize_options( apply_filters( 'betterdocs_export_type_options', array(
3189 + 'docs' => __( 'Docs', 'betterdocs' ),
3190 + 'doc_category' => __( 'Docs Category', 'betterdocs' ),
3191 + 'glossaries' => __( 'Glossaries', 'betterdocs' )
3192 + ) ) )
3193 + ),
3194 + 'export_docs' => array(
3195 + 'name' => 'export_docs',
3196 + 'type' => 'checkbox-select',
3197 + 'label' => __( 'Select Docs', 'betterdocs' ),
1960 3198 'label_subtitle' => __( 'Selected docs will be included in the export.', 'betterdocs' ),
1961 - 'priority' => 4,
1962 - 'multiple' => true,
1963 - 'search' => true,
1964 - 'default' => [ 'all' ],
1965 - 'placeholder' => __( 'Select any', 'betterdocs' ),
1966 - 'options' => array_merge( [
1967 - [
3199 + 'priority' => 4,
3200 + 'multiple' => true,
3201 + 'search' => true,
3202 + 'default' => array( 'all' ),
3203 + 'placeholder' => __( 'Select any', 'betterdocs' ),
3204 + 'options' => array_merge( array(
3205 + array(
1968 3206 'value' => 'all',
1969 3207 'label' => 'All'
1970 - ]
1971 - ], $this->docs() ),
1972 - 'filterValue' => 'all',
1973 - 'rules' => Rules::is( 'export_type', 'docs' )
1974 - ],
1975 - 'export_categories' => [
1976 - 'name' => 'export_categories',
1977 - 'type' => 'checkbox-select',
1978 - 'label' => __( 'Select Categories', 'betterdocs' ),
3208 + )
3209 + ), $this->docs() ),
3210 + 'filterValue' => 'all',
3211 + 'rules' => Rules::is( 'export_type', 'docs' )
3212 + ),
3213 + 'export_categories' => array(
3214 + 'name' => 'export_categories',
3215 + 'type' => 'checkbox-select',
3216 + 'label' => __( 'Select Categories', 'betterdocs' ),
1979 3217 'label_subtitle' => __( 'Selected categories and its docs will be included in the export.', 'betterdocs' ),
1980 - 'priority' => 6,
1981 - 'multiple' => true,
1982 - 'search' => true,
1983 - 'default' => [ 'all' ],
1984 - 'placeholder' => __( 'Select any', 'betterdocs' ),
1985 - 'options' => $this->get_terms( 'doc_category' ),
1986 - 'filterValue' => 'all',
1987 - 'rules' => Rules::is( 'export_type', 'doc_category' )
1988 - ],
1989 - 'file_type' => [
1990 - 'name' => 'file_type',
1991 - 'label' => __( 'Select File Type', 'betterdocs' ),
3218 + 'priority' => 6,
3219 + 'multiple' => true,
3220 + 'search' => true,
3221 + 'default' => array( 'all' ),
3222 + 'placeholder' => __( 'Select any', 'betterdocs' ),
3223 + 'options' => $this->get_terms( 'doc_category', false ),
3224 + 'filterValue' => 'all',
3225 + 'rules' => Rules::is( 'export_type', 'doc_category' )
3226 + ),
3227 + 'export_glossaries' => array(
3228 + 'name' => 'export_glossaries',
3229 + 'type' => 'checkbox-select',
3230 + 'label' => __( 'Select Glossaries', 'betterdocs' ),
3231 + 'label_subtitle' => __( 'Selected glossary terms will be exported.', 'betterdocs' ),
3232 + 'priority' => 7,
3233 + 'multiple' => true,
3234 + 'search' => true,
3235 + 'default' => array( 'all' ),
3236 + 'placeholder' => __( 'Select any', 'betterdocs' ),
3237 + 'options' => $this->get_terms( 'glossaries' ),
3238 + 'filterValue' => 'all',
3239 + 'rules' => Rules::is( 'export_type', 'glossaries' )
3240 + ),
3241 + 'file_type' => array(
3242 + 'name' => 'file_type',
3243 + 'label' => __( 'Select File Type', 'betterdocs' ),
1992 3244 'label_subtitle' => __( 'Choose a file type', 'betterdocs' ),
1993 - 'type' => 'select',
1994 - 'default' => 'xml',
1995 - 'priority' => 7,
1996 - 'search' => true,
1997 - 'options' => $this->normalize_options( apply_filters( 'betterdocs_export_file_type_options', [
3245 + 'type' => 'select',
3246 + 'default' => 'xml',
3247 + 'priority' => 8,
3248 + 'search' => true,
3249 + 'options' => $this->normalize_options( apply_filters( 'betterdocs_export_file_type_options', array(
1998 3250 'xml' => __( '.xml', 'betterdocs' ),
1999 3251 'csv' => __( '.csv', 'betterdocs' )
2000 - ] ) )
2001 - ],
2002 - 'export_docs_btn' => [
2003 - 'name' => 'export_docs_btn',
2004 - 'text' => [
2005 - 'normal' => __( 'Proceed', 'betterdocs' ),
2006 - 'saved' => __( 'Proceed', 'betterdocs' ),
3252 + ) ) )
3253 + ),
3254 + 'enable_export_faq' => array(
3255 + 'name' => 'enable_export_faq',
3256 + 'type' => 'toggle',
3257 + 'priority' => 9,
3258 + 'label' => __( 'Export FAQ', 'betterdocs' ),
3259 + 'label_subtitle' => __( 'Export FAQ Related Terms & Posts', 'betterdocs' ),
3260 + 'enable_disable_text_active' => true,
3261 + 'default' => true,
3262 + 'rules' => Rules::is( 'export_type', 'glossaries', true )
3263 + ),
3264 + 'export_docs_btn' => array(
3265 + 'name' => 'export_docs_btn',
3266 + 'text' => array(
3267 + 'normal' => __( 'Proceed', 'betterdocs' ),
3268 + 'saved' => __( 'Proceed', 'betterdocs' ),
2007 3269 'loading' => __( 'Exporting...', 'betterdocs' )
2008 - ],
2009 - 'type' => 'button',
2010 - 'priority' => 8,
2011 - 'ajax' => [
2012 - 'on' => 'click',
2013 - 'api' => '/betterdocs/v1/export-docs',
2014 - 'data' => [
2015 - 'export_type' => '@export_type',
2016 - 'export_docs' => '@export_docs',
2017 - 'export_kbs' => '@export_kbs',
3270 + ),
3271 + 'type' => 'button',
3272 + 'priority' => 10,
3273 + 'ajax' => array(
3274 + 'on' => 'click',
3275 + 'api' => '/betterdocs/v1/export-docs',
3276 + 'data' => array(
3277 + 'export_type' => '@export_type',
3278 + 'export_docs' => '@export_docs',
3279 + 'export_kbs' => '@export_kbs',
2018 3280 'export_categories' => '@export_categories',
2019 - 'file_type' => '@file_type'
2020 - ],
2021 - 'swal' => [
2022 - 'text' => __( 'Exported Successfully.', 'betterdocs' ),
2023 - 'icon' => 'success',
3281 + 'export_glossaries' => '@export_glossaries',
3282 + 'file_type' => '@file_type',
3283 + 'enable_export_faq' => '@enable_export_faq'
3284 + ),
3285 + 'swal' => array(
3286 + 'text' => __( 'Exported Successfully.', 'betterdocs' ),
3287 + 'icon' => 'success',
2024 3288 'autoClose' => 2000
2025 - ]
2026 - ]
2027 - ]
2028 - ] )
2029 - ],
3289 + )
3290 + )
3291 + )
3292 + ) )
3293 + ),
2030 3294
2031 - 'export_settings_nested' => [
2032 - 'id' => 'export_settings_nested',
2033 - 'name' => 'export_settings_nested',
2034 - 'type' => 'section',
2035 - 'label' => __( 'Export Settings', 'betterdocs' ),
3295 + 'export_settings_nested' => array(
3296 + 'id' => 'export_settings_nested',
3297 + 'name' => 'export_settings_nested',
3298 + 'type' => 'section',
3299 + 'label' => __( 'Export Settings', 'betterdocs' ),
2036 3300 'priority' => 1,
2037 - 'fields' => [
2038 - 'export_settings' => [
2039 - 'name' => 'export_settings',
2040 - 'label' => __( 'Export Settings', 'betterdocs' ),
3301 + 'fields' => array(
3302 + 'export_settings' => array(
3303 + 'name' => 'export_settings',
3304 + 'label' => __( 'Export Settings', 'betterdocs' ),
2041 3305 'label_subtitle' => __( 'Simply click on “Export Settings” button to download your BetterDocs settings in .json format', 'betterdocs' ),
2042 - 'text' => [
2043 - 'normal' => __( 'Export Settings', 'betterdocs' ),
2044 - 'saved' => __( 'Export Settings', 'betterdocs' ),
3306 + 'text' => array(
3307 + 'normal' => __( 'Export Settings', 'betterdocs' ),
3308 + 'saved' => __( 'Export Settings', 'betterdocs' ),
2045 3309 'loading' => __( 'Exporting...', 'betterdocs' )
2046 - ],
2047 - 'type' => 'button',
2048 - 'priority' => 8,
2049 - 'ajax' => [
2050 - 'on' => 'click',
2051 - 'api' => '/betterdocs/v1/export-settings',
2052 - 'data' => [
3310 + ),
3311 + 'type' => 'button',
3312 + 'priority' => 8,
3313 + 'ajax' => array(
3314 + 'on' => 'click',
3315 + 'api' => '/betterdocs/v1/export-settings',
3316 + 'data' => array(
2053 3317 'betterdocs_settings' => get_option( 'betterdocs_settings' )
2054 - ],
2055 - 'swal' => [
2056 - 'text' => __( 'File downloaded successfully.', 'betterdocs' ),
2057 - 'icon' => 'success',
3318 + ),
3319 + 'swal' => array(
3320 + 'text' => __( 'File downloaded successfully.', 'betterdocs' ),
3321 + 'icon' => 'success',
2058 3322 'autoClose' => 2000
2059 - ]
2060 - ]
2061 - ]
2062 - ]
2063 - ]
2064 - ]
2065 - ]
2066 - ]
2067 - ]
2068 - ]
2069 - ]
2070 - ]
2071 - ]
2072 - ]
2073 - ] );
3323 + )
3324 + )
3325 + )
3326 + )
3327 + )
3328 + )
3329 + )
3330 + )
3331 + )
3332 + )
3333 + )
3334 + )
3335 + )
3336 + )
3337 + ) );
2074 3338
2075 3339 return $settings;
2076 3340 }
2077 3341
3342 + public function maybe_remove_git_tab( $tabs ) {
3343 + $pro_active = is_plugin_active( 'betterdocs-pro/betterdocs-pro.php' );
3344 + $pro_has_git = apply_filters( 'betterdocs_pro_has_git_integration', false );
3345 +
3346 + if ( $pro_active && ! $pro_has_git ) {
3347 + unset( $tabs[ 'tab-git-sync' ] );
3348 + }
3349 +
3350 + return $tabs;
3351 + }
3352 +
2078 3353 public function normalize_options( $options ) {
2079 3354 return GlobalFields::normalize_fields( $options );
2080 3355 }
2081 3356
@@ -2085,20 +3360,20 @@
2085 3360 if ( $docs_tax ) {
2086 3361 return $docs_tax;
2087 3362 }
2088 3363
2089 - $taxonomies = get_taxonomies( [
2090 - 'object_type' => [ 'docs' ]
2091 - ], 'objects' );
3364 + $taxonomies = get_taxonomies( array(
3365 + 'object_type' => array( 'docs' )
3366 + ), 'objects' );
2092 3367
2093 - $docs_tax = [
2094 - 'all' => 'All Docs Archive',
3368 + $docs_tax = array(
3369 + 'all' => 'All Docs Archive',
2095 3370 'docs' => 'Docs Page'
2096 - ];
3371 + );
2097 3372 foreach ( $taxonomies as $key => $value ) {
2098 3373 $docs_tax[ $key ] = $value->label;
2099 3374 }
2100 - unset( $docs_tax['doc_tag'] );
3375 + unset( $docs_tax[ 'doc_tag' ] );
2101 3376
2102 3377 $docs_tax = $this->normalize_options( $docs_tax );
2103 3378 if ( count( $docs_tax ) > 2 ) {
2104 3379 $this->database->set_cache( 'betterdocs::settings::taxonomies', $docs_tax );
@@ -2106,9 +3381,9 @@
2106 3381
2107 3382 return $docs_tax;
2108 3383 }
2109 3384
2110 - public function get_terms( $taxonomy ) {
3385 + public function get_terms( $taxonomy, $hide_empty = true ) {
2111 3386 $_cache_key = 'betterdocs::settings::terms::' . trim( $taxonomy );
2112 3387 $docs_tax = $this->database->get_cache( $_cache_key );
2113 3388
2114 3389 if ( $docs_tax ) {
@@ -2114,16 +3389,16 @@
2114 3389 if ( $docs_tax ) {
2115 3390 return $docs_tax;
2116 3391 }
2117 3392
2118 - $get_terms = get_terms( [
2119 - 'taxonomy' => $taxonomy,
2120 - 'hide_empty' => false
2121 - ] );
3393 + $get_terms = get_terms( array(
3394 + 'taxonomy' => $taxonomy,
3395 + 'hide_empty' => $hide_empty
3396 + ) );
2122 3397
2123 - $terms = [
3398 + $terms = array(
2124 3399 'all' => 'All'
2125 - ];
3400 + );
2126 3401
2127 3402 if ( ! empty( $get_terms ) && ! is_wp_error( $get_terms ) ) {
2128 3403 foreach ( $get_terms as $value ) {
2129 3404 if ( isset( $value->slug ) && isset( $value->name ) ) {
@@ -2139,8 +3414,40 @@
2139 3414
2140 3415 return $terms;
2141 3416 }
2142 3417
3418 + public function get_terms_with_ids( $taxonomy ) {
3419 + $_cache_key = 'betterdocs::settings::terms::ids' . trim( $taxonomy );
3420 + $docs_tax = $this->database->get_cache( $_cache_key );
3421 +
3422 + if ( $docs_tax ) {
3423 + return $docs_tax;
3424 + }
3425 +
3426 + $get_terms = get_terms( array(
3427 + 'taxonomy' => $taxonomy,
3428 + 'hide_empty' => false,
3429 + 'suppress_filter' => true
3430 + ) );
3431 +
3432 + $terms = array();
3433 +
3434 + if ( ! empty( $get_terms ) && ! is_wp_error( $get_terms ) ) {
3435 + foreach ( $get_terms as $value ) {
3436 + if ( isset( $value->term_id ) && isset( $value->name ) ) {
3437 + $terms[ $value->term_id ] = $value->name;
3438 + }
3439 + }
3440 + }
3441 +
3442 + $terms = $this->normalize_options( $terms );
3443 + if ( count( $terms ) > 1 ) {
3444 + $this->database->set_cache( $_cache_key, $terms );
3445 + }
3446 +
3447 + return $terms;
3448 + }
3449 +
2143 3450 /**
2144 3451 * Get all docs
2145 3452 */
2146 3453 public function docs() {
@@ -2149,15 +3456,15 @@
2149 3456 if ( $docs ) {
2150 3457 return $docs;
2151 3458 }
2152 3459
2153 - $docs = [];
3460 + $docs = array();
2154 3461
2155 - $_docs = get_posts( [
2156 - 'post_type' => 'docs',
2157 - 'numberposts' => -1,
3462 + $_docs = get_posts( array(
3463 + 'post_type' => 'docs',
3464 + 'numberposts' => -1,
2158 3465 'posts_per_page' => -1
2159 - ] );
3466 + ) );
2160 3467
2161 3468 if ( ! empty( $_docs ) ) {
2162 3469 foreach ( $_docs as $doc ) {
2163 3470 $docs[ $doc->ID ] = betterdocs()->template_helper->kses( $doc->post_title );
@@ -2168,15 +3475,16 @@
2168 3475
2169 3476 return $docs;
2170 3477 }
2171 3478
2172 - public function hide_roles_management( $tabData = [] ) {
3479 + public function hide_roles_management( $tabData = array() ) {
2173 3480 global $current_user;
2174 3481
2175 3482 if ( $current_user instanceof WP_User && ! in_array( 'administrator', $current_user->roles ) ) {
2176 - unset( $tabData['fields']['title-advance-settings']['fields']['article_roles'] );
2177 - unset( $tabData['fields']['title-advance-settings']['fields']['settings_roles'] );
2178 - unset( $tabData['fields']['title-advance-settings']['fields']['analytics_roles'] );
3483 + unset( $tabData[ 'fields' ][ 'title-advance-settings' ][ 'fields' ][ 'article_roles' ] );
3484 + unset( $tabData[ 'fields' ][ 'title-advance-settings' ][ 'fields' ][ 'settings_roles' ] );
3485 + unset( $tabData[ 'fields' ][ 'title-advance-settings' ][ 'fields' ][ 'analytics_roles' ] );
3486 + unset( $tabData[ 'fields' ][ 'title-advance-settings' ][ 'fields' ][ 'faq_roles' ] );
2179 3487 }
2180 3488
2181 3489 return $tabData;
2182 3490 }