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