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 +2638 -1597 3.4.04.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 +
9 +use WP_Error;
5 10 use WP_User;
6 -use WP_Error;
11 +use WPDeveloper\BetterDocs\Admin\Builder\GlobalFields;
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;
7 17 use WPDeveloper\BetterDocs\Utils\Base;
8 18 use WPDeveloper\BetterDocs\Utils\Database;
9 -use WPDeveloper\BetterDocs\Admin\Builder\Rules;
10 -use WPDeveloper\BetterDocs\Admin\Builder\GlobalFields;
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,37 +35,39 @@
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
57 - if ( empty( $_settings[$key] ) ) {
58 - $this->save( $key, $_default[$key] );
68 + if ( empty( $_settings[ $key ] ) ) {
69 + $this->save( $key, $_default[ $key ] );
59 70 }
60 71 }
61 72 }
62 73
@@ -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,81 +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 - 'enable_sample_data' => false,
227 - 'reporting_day' => 'monday',
228 - 'reporting_email' => get_option( 'admin_email' ),
229 - 'enable_write_with_ai' => true,
230 - 'enable_faq_write_with_ai' => true,
231 - 'ai_autowrite_api_key' => '',
232 - 'ai_autowrite_max_token' => 1500
233 - ];
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 + );
234 365
235 366 $_default = apply_filters( 'betterdocs_default_settings', $_default );
236 367 // $_default = apply_filters_deprecated(
237 368 // 'betterdocs_option_default_settings', [$_default], '2.5.0',
@@ -247,34 +378,98 @@
247 378 * @return array
248 379 * @since 2.5.0
249 380 */
250 381 public function get_pro_defaults() {
251 - return [];
382 + return array();
252 383 }
253 384
385 + public function is_elementor_pro() {
386 + return is_plugin_active( 'elementor-pro/elementor-pro.php' );
387 + }
388 +
254 389 /**
255 - * Get customizer links for docs page.
390 + * Get full site editor links for docs page.
256 391 *
257 392 * @return string
258 - * @since 1.0.0
393 + * @since 3.5.8
259 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 +
260 417 public function customizer_link() {
261 - $query['autofocus[panel]'] = 'betterdocs_customize_options';
262 - $query['return'] = admin_url( 'edit.php?post_type=docs' );
263 - $builtin_doc_page = betterdocs()->settings->get( 'builtin_doc_page' );
264 - $docs_slug = betterdocs()->settings->get( 'docs_slug' );
265 - $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' );
266 423
267 - if ( $builtin_doc_page == 1 && $docs_slug ) {
268 - $query['url'] = site_url( '/' . $docs_slug );
269 - } elseif ( $builtin_doc_page != 1 && $docs_page ) {
270 - $post_info = get_post( $docs_page );
271 - $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 );
272 429 }
273 430
274 431 return add_query_arg( $query, admin_url( 'customize.php' ) );
275 432 }
276 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 +
277 472 /**
278 473 * Get All Roles
279 474 * dynamically
280 475 *
@@ -281,9 +476,9 @@
281 476 * @return array
282 477 */
283 478 public function get_roles() {
284 479 $roles = wp_roles()->role_names;
285 - unset( $roles['subscriber'] );
480 + unset( $roles[ 'subscriber' ] );
286 481
287 482 return $roles;
288 483 }
289 484
@@ -297,10 +492,11 @@
297 492 if ( ! check_ajax_referer( 'doc_cat_order_nonce', 'nonce', false ) ) {
298 493 wp_send_json_error();
299 494 }
300 495
301 - if ( isset( $_POST['mode'] ) ) {
302 - 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 ) ) ) {
303 499 wp_send_json_success();
304 500 }
305 501 }
306 502
@@ -309,9 +505,9 @@
309 505
310 506 public function get_normalized_value( $key, $value, $default = null ) {
311 507 $_origin_value = $_value = $value;
312 508
313 - if ( in_array( $_value, ['on', 'off', '1', 'false', 'true'], true ) ) {
509 + if ( in_array( $_value, array( 'on', 'off', '1', 'false', 'true' ), true ) ) {
314 510 switch ( $_value ) {
315 511 case 'on':
316 512 case 'ON':
317 513 case '1':
@@ -331,17 +527,17 @@
331 527
332 528 return $_value;
333 529 }
334 530
335 - public function get_normalized_values( $values, $default_values = [] ) {
531 + public function get_normalized_values( $values, $default_values = array() ) {
336 532 if ( empty( $values ) ) {
337 - return [];
533 + return array();
338 534 }
339 535
340 - $_settings = [];
536 + $_settings = array();
341 537 foreach ( $values as $key => $value ) {
342 - $_default_value = isset( $default_values[$key] ) ? $default_values[$key] : null;
343 - $_settings[$key] = $this->get_normalized_value( $key, $value, $_default_value );
538 + $_default_value = isset( $default_values[ $key ] ) ? $default_values[ $key ] : null;
539 + $_settings[ $key ] = $this->get_normalized_value( $key, $value, $_default_value );
344 540 }
345 541
346 542 return $_settings;
347 543 }
@@ -346,9 +542,9 @@
346 542 return $_settings;
347 543 }
348 544
349 545 public function get_all( $raw = false ) {
350 - $_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() );
351 547 $_settings = $this->database->get( $this->base_key, $_default_settings );
352 548
353 549 return $this->get_normalized_values( $_settings, $_default_settings );
354 550 }
@@ -353,9 +549,9 @@
353 549 return $this->get_normalized_values( $_settings, $_default_settings );
354 550 }
355 551
356 552 public function type_validation( &$value, $defaultValue = null ) {
357 - if ( $defaultValue !== null ) {
553 + if ( null !== $defaultValue ) {
358 554 /**
359 555 * Check if value is not in same type
360 556 */
361 557 $_default_type = gettype( $defaultValue );
@@ -385,28 +581,28 @@
385 581
386 582 $_value = $default;
387 583 switch ( true ) {
388 584 // Check if it's a PRO Option
389 - case ! isset( $_default_settings[$key] ):
585 + case ! isset( $_default_settings[ $key ] ):
390 586 $_value = $default;
391 587 break;
392 588 // Check if it's a FREE Option and not in DB.
393 - case ! isset( $_settings[$key] ) && isset( $_default_settings[$key] ):
394 - $_value = $default !== null ? $default : $_default_settings[$key];
589 + case ! isset( $_settings[ $key ] ) && isset( $_default_settings[ $key ] ):
590 + $_value = null !== $default ? $default : $_default_settings[ $key ];
395 591 break;
396 592 // Check if it's a FREE Option
397 - case isset( $_settings[$key] ) && isset( $_default_settings[$key] ):
398 - $_value = $_settings[$key];
593 + case isset( $_settings[ $key ] ) && isset( $_default_settings[ $key ] ):
594 + $_value = $_settings[ $key ];
399 595 break;
400 596 }
401 597
402 - $_value = $this->get_normalized_value( $key, $_value, isset( $_default_settings[$key] ) ? $_default_settings[$key] : null );
598 + $_value = $this->get_normalized_value( $key, $_value, isset( $_default_settings[ $key ] ) ? $_default_settings[ $key ] : null );
403 599
404 600 if ( gettype( $_value ) === 'string' ) {
405 - if ( empty( $_value ) && $default != null ) {
601 + if ( empty( $_value ) && null != $default ) {
406 602 $_value = $default;
407 - } elseif ( empty( $_value ) && $default === null && isset( $_default_settings[$key] ) ) {
408 - $_value = $_default_settings[$key];
603 + } elseif ( empty( $_value ) && null === $default && isset( $_default_settings[ $key ] ) ) {
604 + $_value = $_default_settings[ $key ];
409 605 }
410 606 }
411 607
412 608 return $_value;
@@ -412,12 +608,12 @@
412 608 return $_value;
413 609 }
414 610
415 611 public function get_raw_field( $key, $default = null ) {
416 - $_settings = $this->database->get( $this->base_key, [] );
612 + $_settings = $this->database->get( $this->base_key, array() );
417 613
418 - if ( isset( $_settings[$key] ) ) {
419 - return $this->get_normalized_value( $key, $_settings[$key], $default );
614 + if ( isset( $_settings[ $key ] ) ) {
615 + return $this->get_normalized_value( $key, $_settings[ $key ], $default );
420 616 }
421 617
422 618 return $default;
423 619 }
@@ -422,10 +618,10 @@
422 618 return $default;
423 619 }
424 620
425 621 public function save( $key, $value ) {
426 - $_settings = $this->database->get( $this->base_key, [] );
427 - $_settings[$key] = $value;
622 + $_settings = $this->database->get( $this->base_key, array() );
623 + $_settings[ $key ] = $value;
428 624
429 625 return $this->database->save( $this->base_key, $_settings );
430 626 }
431 627
@@ -434,20 +630,124 @@
434 630 if ( ! current_user_can( 'edit_docs_settings' ) ) {
435 631 return new WP_Error( 'unauthorized_action', __( 'You don\'t have any rights for saving settings.', 'betterdocs' ) );
436 632 }
437 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 +
438 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 +
439 730 // @todo: sanitize the data before inject in DB.
440 731 $_normalized_settings = $this->get_normalized_values( $settings );
441 - 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' ] ) {
442 733 betterdocs()->kbmigration->migrate();
443 734 }
444 735 $_settings = wp_parse_args( $_normalized_settings, $_old_settings );
445 - $_saved = $this->database->save( $this->base_key, $_settings );
446 736
447 - 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;
448 741
449 - 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;
450 750 }
451 751
452 752 public function views( $hook ) {
453 753 return betterdocs()->views->get( 'admin/settings' );
@@ -459,21 +759,21 @@
459 759 return $this->database->save( $this->base_key, $_settings );
460 760 }
461 761
462 762 public function get_pages() {
463 - $_pages = betterdocs()->query->get_posts( [
464 - 'post_type' => 'page',
465 - 'numberposts' => -1,
466 - 'post_status' => 'publish',
763 + $_pages = betterdocs()->query->get_posts( array(
764 + 'post_type' => 'page',
765 + 'numberposts' => -1,
766 + 'post_status' => 'publish',
467 767 'posts_per_page' => -1
468 - ] );
768 + ) );
469 769
470 - $__pages = [];
770 + $__pages = array();
471 771
472 772 if ( ! empty( $_pages ) ) {
473 - $__pages[0] = __( 'Select a Page', 'betterdocs' );
773 + $__pages[ 0 ] = __( 'Select a Page', 'betterdocs' );
474 774 foreach ( $_pages->posts as $page ) {
475 - $__pages[$page->ID] = esc_html( $page->post_title );
775 + $__pages[ $page->ID ] = esc_html( $page->post_title );
476 776 }
477 777 }
478 778
479 779 return $__pages;
@@ -481,677 +781,836 @@
481 781
482 782 public function settings_args() {
483 783 $wp_roles = $this->normalize_options( $this->get_roles() );
484 784
485 - $settings = [
486 - 'id' => 'betterdocs_settings_metabox_wrapper',
487 - 'title' => __( 'betterdocs', 'betterdocs' ),
488 - 'object_types' => ['betterdocs'],
489 - 'context' => 'normal',
490 - 'priority' => 'high',
491 - 'show_header' => false,
492 - '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,
493 797 'is_pro_active' => betterdocs()->is_pro_active(),
494 - 'logoURL' => betterdocs()->assets->icon( 'betterdocs-icon.svg', true ),
495 - 'layout' => 'vertical',
496 - 'config' => [
497 - 'active' => 'tab-general',
798 + 'logoURL' => betterdocs()->assets->icon( 'betterdocs-icon.svg', true ),
799 + 'layout' => 'vertical',
800 + 'config' => array(
801 + 'active' => 'tab-general',
498 802 'sidebar' => true,
499 - 'title' => false
500 - ],
501 - 'submit' => [
502 - 'show' => true,
503 - 'label' => __( 'Save', 'betterdocs' ),
803 + 'title' => false
804 + ),
805 + 'submit' => array(
806 + 'show' => true,
807 + 'label' => __( 'Save', 'betterdocs' ),
504 808 'loadingLabel' => __( 'Saving...', 'betterdocs' ),
505 - 'class' => 'save-settings',
506 - 'rules' => Rules::logicalRule( [
809 + 'class' => 'save-settings',
810 + 'rules' => Rules::logicalRule( array(
507 811 Rules::is( 'config.active', 'tab-design', true ),
508 812 Rules::is( 'config.active', 'tab-shortcodes', true ),
509 813 Rules::is( 'config.active', 'tab-instant-answer', true ),
510 814 Rules::is( 'config.active', 'tab-import-export', true ),
511 815 Rules::is( 'config.active', 'tab-migration', true )
512 - ], 'and' )
513 - ],
514 - 'values' => $this->get_all(),
515 - 'tabs' => apply_filters( 'betterdocs_settings_tabs', [
516 - 'tab-general' => apply_filters( 'betterdocs_settings_tab_general', [
517 - 'id' => 'tab-general',
518 - 'label' => __( 'General', 'betterdocs' ),
519 - 'classes' => 'tab-general',
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',
520 824 'priority' => 10,
521 - 'fields' => [
522 - 'title-general' => [
523 - 'name' => 'title-general-tab',
524 - 'type' => 'section',
525 - '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' ),
526 830 'priority' => 10,
527 - 'fields' => [
528 - 'multiple_kb' => apply_filters( 'betterdocs_multi_kb_settings', [
529 - 'name' => 'multiple_kb',
530 - 'type' => 'toggle',
531 - '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' ),
532 836 'enable_disable_text_active' => true,
533 - 'default' => '',
534 - 'priority' => 1,
535 - 'is_pro' => true
536 - ] ),
537 - 'builtin_doc_page' => [
538 - 'name' => 'builtin_doc_page',
539 - 'type' => 'toggle',
540 - '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' ),
541 845 'enable_disable_text_active' => true,
542 - 'default' => 1,
543 - 'priority' => 2,
544 - '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' )
545 - ],
546 - 'breadcrumb_doc_title' => [
547 - 'name' => 'breadcrumb_doc_title',
548 - 'type' => 'text',
549 - 'label' => __( 'Documentation Page Title', 'betterdocs' ),
550 - 'default' => 'Docs',
551 - 'priority' => 3
552 - ],
553 - 'docs_slug' => [
554 - 'name' => 'docs_slug',
555 - 'type' => 'text',
556 - 'label' => __( 'BetterDocs Root Slug', 'betterdocs' ),
557 - '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' ),
558 863 'priority' => 4,
559 - 'rules' => Rules::is( 'builtin_doc_page', true )
560 - ],
561 - 'docs_page' => [
562 - 'name' => 'docs_page',
563 - 'label' => __( 'Docs Page', 'betterdocs' ),
564 - 'type' => 'select',
565 - 'default' => 0,
566 - 'priority' => 5,
567 - 'search' => true,
568 - '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() ),
569 882 'label_subtitle' => __( 'You will need to insert BetterDocs Shortcode inside the page. This page will be used as docs permalink.', 'betterdocs' ),
570 - 'rules' => Rules::is( 'builtin_doc_page', false )
571 - ],
572 - 'category_slug' => [
573 - 'name' => 'category_slug',
574 - 'type' => 'text',
575 - 'label' => __( 'Custom Category Slug', 'betterdocs' ),
576 - 'default' => 'docs-category',
577 - 'priority' => 6
578 - ],
579 - 'tag_slug' => [
580 - 'name' => 'tag_slug',
581 - 'type' => 'text',
582 - 'label' => __( 'Custom Tag Slug', 'betterdocs' ),
583 - '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',
584 891 'priority' => 7
585 - ],
586 - 'permalink_structure' => [
587 - 'name' => 'permalink_structure',
588 - 'type' => 'permalink_structure',
589 - 'label' => __( 'Single Docs Permalink', 'betterdocs' ),
590 - 'default' => PostType::permalink_structure(),
591 - 'priority' => 9,
592 - 'tags' => $this->normalize_options( [
593 - '%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%',
594 908 '%knowledge_base%' => '%knowledge_base%'
595 - ] ),
909 + ) ),
596 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' )
597 - ],
598 - 'enable_faq_schema' => [
599 - 'name' => 'enable_faq_schema',
600 - 'type' => 'toggle',
601 - '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' ),
602 917 'enable_disable_text_active' => true,
603 - 'default' => '',
604 - 'priority' => 10
605 - ],
606 - 'analytics_from' => [
607 - 'name' => 'analytics_from',
608 - 'type' => 'select',
609 - 'label' => __( 'Analytics From', 'betterdocs' ),
610 - 'options' => $this->normalize_options( [
611 - 'everyone' => __( 'Everyone', 'betterdocs' ),
612 - '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' ),
613 946 'registered_users' => __( 'Registered Users Only', 'betterdocs' )
614 - ] ),
615 - 'default' => 'everyone',
616 - 'priority' => 11,
617 - 'is_pro' => true
618 - ],
619 - 'exclude_bot_analytics' => [
620 - 'name' => 'exclude_bot_analytics',
621 - 'type' => 'toggle',
622 - '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' ),
623 956 'enable_disable_text_active' => true,
624 - 'default' => true,
625 - 'priority' => 12,
626 - 'is_pro' => true
627 - ]
628 - ]
629 - ]
630 - ]
631 - ] ),
632 - 'tab-layout' => apply_filters( 'betterdocs_settings_tab_layout', [
633 - 'id' => 'tab-layout',
634 - 'label' => __( 'Layout', 'betterdocs' ),
635 - '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',
636 979 'priority' => 20,
637 - 'fields' => [
638 - 'title-layout' => [
639 - 'name' => 'title-layout-tab',
640 - 'type' => 'section',
641 - 'label' => __( 'Layout Settings', 'betterdocs' ),
980 + 'fields' => array(
981 + 'title-layout' => array(
982 + 'name' => 'title-layout-tab',
983 + 'type' => 'section',
984 + 'label' => __( 'Layout Settings', 'betterdocs' ),
642 985 'priority' => 20,
643 - 'fields' => [
644 - 'tab-sidebar-layout' => apply_filters( 'betterdocs_settings_tab_sidebar_layout', [
645 - 'id' => 'tab-sidebar-layout',
646 - 'name' => 'tab_sidebar_layout',
647 - 'label' => __( 'Layout Settings', 'betterdocs' ),
648 - 'classes' => 'tab-layout',
649 - 'type' => "tab",
650 - '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',
651 994 'completionTrack' => true,
652 - 'sidebar' => false,
653 - 'save' => false,
654 - 'title' => false,
655 - 'config' => [
656 - 'active' => 'layout_documentation_page',
995 + 'sidebar' => false,
996 + 'save' => false,
997 + 'title' => false,
998 + 'config' => array(
999 + 'active' => 'layout_documentation_page',
657 1000 'sidebar' => false,
658 - 'title' => false
659 - ],
660 - 'submit' => [
1001 + 'title' => false
1002 + ),
1003 + 'submit' => array(
661 1004 'show' => false
662 - ],
663 - 'step' => [
1005 + ),
1006 + 'step' => array(
664 1007 'show' => false
665 - ],
666 - 'priority' => 20,
667 - 'fields' => [
668 - 'layout_documentation_page' => [
669 - 'id' => 'layout_documentation_page',
670 - 'name' => 'layout_documentation_page',
671 - 'type' => 'section',
672 - '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' ),
673 1016 'priority' => 1,
674 - 'fields' => [
675 - 'tab-nested-layout-1' => [
676 - 'id' => 'tab-nested-layout-1',
677 - 'name' => 'tab_nested_layout_1',
678 - 'label' => __( 'Documentation Page', 'betterdocs' ),
679 - 'classes' => 'tab-nested-layout',
680 - 'type' => "tab",
681 - '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',
682 1025 'completionTrack' => true,
683 - 'sidebar' => false,
684 - 'save' => false,
685 - 'title' => false,
686 - 'config' => [
687 - 'active' => 'layout_documentation_page_general',
1026 + 'sidebar' => false,
1027 + 'save' => false,
1028 + 'title' => false,
1029 + 'config' => array(
1030 + 'active' => 'layout_documentation_page_general',
688 1031 'sidebar' => false,
689 - 'title' => false
690 - ],
691 - 'submit' => [
1032 + 'title' => false
1033 + ),
1034 + 'submit' => array(
692 1035 'show' => false
693 - ],
694 - 'step' => [
1036 + ),
1037 + 'step' => array(
695 1038 'show' => false
696 - ],
697 - 'priority' => 1,
698 - 'fields' => [
699 - 'layout_documentation_page_general' => [
700 - 'id' => 'layout_documentation_page_general',
701 - 'name' => 'layout_documentation_page_general',
702 - 'type' => 'section',
703 - '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' ),
704 1047 'priority' => 1,
705 - 'fields' => [
706 - 'category_title_link' => [
707 - 'name' => 'category_title_link',
708 - 'type' => 'toggle',
709 - 'label' => __( 'Category Title Link', 'betterdocs' ),
710 - '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' ),
711 1062 'enable_disable_text_active' => true,
712 - 'default' => false,
713 - 'priority' => 0
714 - ],
715 - 'masonry_layout' => [
716 - 'name' => 'masonry_layout',
717 - 'type' => 'toggle',
718 - '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' ),
719 1070 'enable_disable_text_active' => true,
720 - 'default' => 1,
721 - 'priority' => 1
722 - ],
723 - 'nested_subcategory' => [
724 - 'name' => 'nested_subcategory',
725 - 'type' => 'toggle',
726 - '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' ),
727 1079 'enable_disable_text_active' => true,
728 - 'default' => '',
729 - 'priority' => 2
730 - ],
731 - 'column_number' => [
732 - 'name' => 'column_number',
733 - 'type' => 'number',
734 - 'label' => __( 'Number Of Columns', 'betterdocs' ),
735 - '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' => '',
736 1089 'priority' => 3
737 - ],
738 - 'posts_number' => apply_filters( 'betterdocs_posts_number', [
739 - 'name' => 'posts_number',
740 - 'type' => 'number',
741 - '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' ),
742 1103 'label_subtitle' => __( 'This setting is not applicable for handbook layout.', 'betterdocs' ),
743 - 'default' => 10,
744 - 'priority' => 4
745 - ] ),
746 - 'post_count' => [
747 - 'name' => 'post_count',
748 - 'type' => 'toggle',
749 - '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' ),
750 1111 'enable_disable_text_active' => true,
751 - 'default' => 1,
752 - 'priority' => 5
753 - ],
754 - 'count_text' => [
755 - 'name' => 'count_text',
756 - 'type' => 'text',
757 - 'label' => __( 'Count Text', 'betterdocs' ),
758 - 'default' => __( 'docs', 'betterdocs' ),
1112 + 'default' => 1,
759 1113 'priority' => 6
760 - ],
761 - 'count_text_singular' => [
762 - 'name' => 'count_text_singular',
763 - 'type' => 'text',
764 - 'label' => __( 'Count Text Singular', 'betterdocs' ),
765 - 'default' => __( 'doc', 'betterdocs' ),
1114 + ),
1115 + 'count_text' => array(
1116 + 'name' => 'count_text',
1117 + 'type' => 'text',
1118 + 'label' => __( 'Count Text', 'betterdocs' ),
1119 + 'default' => __( 'Docs', 'betterdocs' ),
766 1120 'priority' => 7
767 - ],
768 - 'exploremore_btn' => [
769 - 'name' => 'exploremore_btn',
770 - 'type' => 'toggle',
771 - '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' ),
772 1133 'enable_disable_text_active' => true,
773 - 'default' => true,
774 - 'priority' => 8
775 - ],
776 - 'exploremore_btn_txt' => [
777 - 'name' => 'exploremore_btn_txt',
778 - 'type' => 'text',
779 - 'label' => __( 'Explore More Button Text', 'betterdocs' ),
780 - 'default' => __( 'Explore More', 'betterdocs' ),
781 - 'priority' => 9,
782 - 'rules' => Rules::is( 'exploremore_btn', true )
783 - ],
784 - 'betterdocs_popular_docs_text' => [
785 - 'name' => 'betterdocs_popular_docs_text',
786 - 'type' => 'text',
787 - 'label' => __( 'Popular Docs Text', 'betterdocs' ),
788 - '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' ),
789 1142 'priority' => 10,
790 - "is_pro" => true
791 - ],
792 - 'betterdocs_popular_docs_number' => [
793 - 'name' => 'betterdocs_popular_docs_number',
794 - 'type' => 'number',
795 - 'label' => __( 'Popular Docs Number', 'betterdocs' ),
796 - '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' ),
797 1150 'priority' => 11,
798 - "is_pro" => true
799 - ]
800 - ]
801 - ],
802 - 'layout_documentation_page_search' => [
803 - 'id' => 'layout_documentation_page_search',
804 - 'name' => 'layout_documentation_page_search',
805 - 'type' => 'section',
806 - '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' ),
807 1168 'priority' => 2,
808 - 'fields' => [
809 - 'live_search' => [
810 - 'name' => 'live_search',
811 - 'type' => 'toggle',
812 - 'label' => __( 'Live Search', 'betterdocs' ),
1169 + 'fields' => array(
1170 + 'live_search' => array(
1171 + 'name' => 'live_search',
1172 + 'type' => 'toggle',
1173 + 'label' => __( 'Live Search', 'betterdocs' ),
813 1174 'enable_disable_text_active' => true,
814 - 'default' => 1,
815 - 'priority' => 1
816 - ],
817 - 'advance_search' => apply_filters( 'betterdocs_advance_search_settings', [
818 - 'name' => 'advance_search',
819 - 'type' => 'toggle',
820 - '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' ),
821 1182 'enable_disable_text_active' => true,
822 - 'default' => '',
823 - 'priority' => 2,
824 - 'is_pro' => true
825 - ] ),
826 - 'child_category_exclude' => apply_filters( 'child_category_exclude', [
827 - 'name' => 'child_category_exclude',
828 - 'type' => 'toggle',
829 - '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' ),
830 1192 'enable_disable_text_active' => true,
831 - 'default' => '',
832 - 'priority' => 3,
833 - 'is_pro' => true
834 - ] ),
835 - 'popular_keyword_limit' => apply_filters( 'betterdocs_popular_keyword_limit_settings', [
836 - 'name' => 'popular_keyword_limit',
837 - 'type' => 'number',
838 - 'label' => __( 'Minimum amount of Keywords Search', 'betterdocs' ),
839 - '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,
840 1202 'priority' => 4,
841 - 'is_pro' => true
842 - ] ),
843 - 'search_letter_limit' => [
844 - 'name' => 'search_letter_limit',
845 - 'type' => 'number',
846 - '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' ),
847 1209 'priority' => 5,
848 - 'default' => 3
849 - ],
850 - 'search_placeholder' => [
851 - 'name' => 'search_placeholder',
852 - 'type' => 'text',
853 - 'label' => __( 'Search Placeholder', 'betterdocs' ),
854 - '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' ),
855 1217 'priority' => 6
856 - ],
857 - 'search_button_text' => apply_filters( 'betterdocs_search_button_text', [
858 - 'name' => 'search_button_text',
859 - 'type' => 'text',
860 - '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' ),
861 1223 'priority' => 7,
862 - 'default' => __( 'Search', 'betterdocs' ),
863 - 'is_pro' => true
864 - ] ),
865 - 'search_not_found_text' => [
866 - 'name' => 'search_not_found_text',
867 - 'type' => 'text',
868 - 'label' => __( 'Search Not Found Text', 'betterdocs' ),
869 - '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.',
870 1231 'priority' => 8
871 - ],
872 - 'search_result_image' => [
873 - 'name' => 'search_result_image',
874 - 'type' => 'toggle',
875 - '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' ),
876 1237 'enable_disable_text_active' => true,
877 - 'default' => 1,
878 - 'priority' => 9
879 - ],
880 - 'kb_based_search' => apply_filters( 'betterdocs_kb_based_search_settings', [
881 - 'name' => 'kb_based_search',
882 - 'type' => 'toggle',
883 - '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' ),
884 1245 'enable_disable_text_active' => true,
885 - 'default' => '',
886 - 'priority' => 10,
887 - 'is_pro' => true,
888 - 'rules' => Rules::is( 'multiple_kb', true )
889 - ] )
890 - ]
891 - ],
892 - 'layout_documentation_page_order_by' => [
893 - 'id' => 'layout_documentation_page_order_by',
894 - 'name' => 'layout_documentation_page_order_by',
895 - 'type' => 'section',
896 - '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' ),
897 1271 'priority' => 3,
898 - 'fields' => [
899 - 'terms_orderby' => [
900 - 'name' => 'terms_orderby',
901 - 'type' => 'select',
902 - 'label' => __( 'Terms Order By', 'betterdocs' ),
903 - 'default' => 'betterdocs_order',
904 - 'options' => $this->normalize_options( apply_filters( 'betterdocs_terms_orderby_options', [
905 - 'none' => __( 'No order', 'betterdocs' ),
906 - 'name' => __( 'Name', 'betterdocs' ),
907 - 'slug' => __( 'Slug', 'betterdocs' ),
908 - 'term_group' => __( 'Term Group', 'betterdocs' ),
909 - 'term_id' => __( 'Term ID', 'betterdocs' ),
910 - 'id' => __( 'ID', 'betterdocs' ),
911 - 'description' => __( 'Description', 'betterdocs' ),
912 - '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' ),
913 1287 'betterdocs_order' => __( 'BetterDocs Order', 'betterdocs' )
914 - ] ) ),
1288 + ) ) ),
915 1289 'priority' => 1
916 - ],
917 - 'terms_order' => [
918 - 'name' => 'terms_order',
919 - 'type' => 'select',
920 - 'label' => __( 'Terms Order', 'betterdocs' ),
921 - 'default' => 'ASC',
922 - 'options' => $this->normalize_options( [
923 - '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',
924 1298 'DESC' => 'Descending'
925 - ] ),
926 - 'priority' => 3
927 - ],
928 - 'alphabetically_order_post' => [
929 - 'name' => 'alphabetically_order_post',
930 - 'type' => 'select',
931 - 'label' => __( 'Docs Order By', 'betterdocs' ),
932 - 'default' => 'betterdocs_order',
933 - 'options' => $this->normalize_options( [
934 - 'none' => __( 'No order', 'betterdocs' ),
935 - 'ID' => __( 'Docs ID', 'betterdocs' ),
936 - 'author' => __( 'Docs Author', 'betterdocs' ),
937 - 'title' => __( 'Title', 'betterdocs' ),
938 - 'date' => __( 'Date', 'betterdocs' ),
939 - 'modified' => __( 'Last Modified Date', 'betterdocs' ),
940 - 'parent' => __( 'Parent Id', 'betterdocs' ),
941 - 'rand' => __( 'Random', 'betterdocs' ),
942 - 'comment_count' => __( 'Comment Count', 'betterdocs' ),
943 - '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' ),
944 1319 'betterdocs_order' => __( 'BetterDocs Order', 'betterdocs' )
945 - ] ),
1320 + ) ),
946 1321 'priority' => 4
947 - ],
948 - 'docs_order' => [
949 - 'name' => 'docs_order',
950 - 'type' => 'select',
951 - 'label' => __( 'Docs Order', 'betterdocs' ),
952 - 'default' => 'ASC',
953 - 'options' => $this->normalize_options( [
954 - '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',
955 1330 'DESC' => 'Descending'
956 - ] ),
957 - 'priority' => 5
958 - ]
959 - ]
960 - ]
961 - ]
962 - ]
963 - ]
964 - ],
965 - 'layout_single_doc' => apply_filters( 'single_doc_setting_section', [
966 - 'id' => 'layout_single_doc',
967 - 'name' => 'layout_single_doc',
968 - 'type' => 'section',
969 - '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' ),
970 1347 'priority' => 2,
971 - 'fields' => [
972 - 'tab-nested-layout-2' => [
973 - 'id' => 'tab-nested-layout-2',
974 - 'name' => 'tab_nested_layout_2',
975 - 'label' => __( 'Single Doc', 'betterdocs' ),
976 - 'classes' => 'tab-nested-layout',
977 - 'type' => "tab",
978 - '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',
979 1356 'completionTrack' => true,
980 - 'sidebar' => false,
981 - 'save' => false,
982 - 'title' => false,
983 - 'config' => [
984 - 'active' => 'layout_single_doc_general',
1357 + 'sidebar' => false,
1358 + 'save' => false,
1359 + 'title' => false,
1360 + 'config' => array(
1361 + 'active' => 'layout_single_doc_general',
985 1362 'sidebar' => false,
986 - 'title' => false
987 - ],
988 - 'submit' => [
1363 + 'title' => false
1364 + ),
1365 + 'submit' => array(
989 1366 'show' => false
990 - ],
991 - 'step' => [
1367 + ),
1368 + 'step' => array(
992 1369 'show' => false
993 - ],
994 - 'priority' => 20,
995 - 'fields' => [
996 - 'layout_single_doc_general' => [
997 - 'id' => 'layout_single_doc_general',
998 - 'name' => 'layout_single_doc_general',
999 - 'type' => 'section',
1000 - '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' ),
1001 1378 'priority' => 5,
1002 - 'fields' => [
1003 - 'enable_post_title' => [
1004 - 'name' => 'enable_post_title',
1005 - 'type' => 'toggle',
1006 - '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' ),
1007 1384 'enable_disable_text_active' => true,
1008 - 'default' => 1,
1009 - 'priority' => 1
1010 - ],
1011 - 'enable_sidebar_cat_list' => [
1012 - 'name' => 'enable_sidebar_cat_list',
1013 - 'type' => 'toggle',
1014 - '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' ),
1015 1392 'enable_disable_text_active' => true,
1016 - 'default' => 1,
1017 - 'priority' => 2
1018 - ],
1019 - 'enable_print_icon' => [
1020 - 'name' => 'enable_print_icon',
1021 - 'type' => 'toggle',
1022 - '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' ),
1023 1400 'enable_disable_text_active' => true,
1024 - 'default' => 1,
1025 - 'priority' => 3
1026 - ],
1027 - 'enable_tags' => [
1028 - 'name' => 'enable_tags',
1029 - 'type' => 'toggle',
1030 - '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' ),
1031 1409 'enable_disable_text_active' => true,
1032 - 'default' => 1,
1033 - 'priority' => 4
1034 - ],
1035 - 'show_last_update_time' => [
1036 - 'name' => 'show_last_update_time',
1037 - 'type' => 'toggle',
1038 - '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' ),
1039 1427 'enable_disable_text_active' => true,
1040 - 'default' => 1,
1041 - 'priority' => 5
1042 - ],
1043 - 'enable_navigation' => [
1044 - 'name' => 'enable_navigation',
1045 - 'type' => 'toggle',
1046 - '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' ),
1047 1444 'enable_disable_text_active' => true,
1048 - 'default' => 1,
1049 - 'priority' => 6
1050 - ],
1051 - 'enable_comment' => [
1052 - 'name' => 'enable_comment',
1053 - 'type' => 'toggle',
1054 - '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' ),
1055 1452 'enable_disable_text_active' => true,
1056 - 'default' => '',
1057 - 'priority' => 7
1058 - ],
1059 - 'enable_credit' => [
1060 - 'name' => 'enable_credit',
1061 - 'type' => 'toggle',
1062 - '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' ),
1063 1460 'enable_disable_text_active' => true,
1064 - 'default' => 1,
1065 - 'priority' => 8
1066 - ]
1067 - ]
1068 - ],
1069 - 'layout_single_doc_TOC' => [
1070 - 'id' => 'layout_single_doc_TOC',
1071 - 'name' => 'layout_single_doc_TOC',
1072 - 'type' => 'section',
1073 - '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' ),
1074 1526 'priority' => 5,
1075 - 'fields' => [
1076 - 'enable_toc' => [
1077 - 'name' => 'enable_toc',
1078 - 'type' => 'toggle',
1079 - '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' ),
1080 1532 'enable_disable_text_active' => true,
1081 - 'default' => 1,
1082 - 'priority' => 1
1083 - ],
1084 - 'toc_title' => [
1085 - 'name' => 'toc_title',
1086 - 'type' => 'text',
1087 - 'label' => __( 'TOC Title', 'betterdocs' ),
1088 - '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' ),
1089 1541 'priority' => 2,
1090 - 'rules' => Rules::is( 'enable_toc', true )
1542 + 'rules' => Rules::is( 'enable_toc', true )
1091 1543
1092 - ],
1093 - 'toc_hierarchy' => [
1094 - 'name' => 'toc_hierarchy',
1095 - 'type' => 'toggle',
1096 - 'label' => __( 'TOC Hierarchy', 'betterdocs' ),
1544 + ),
1545 + 'toc_hierarchy' => array(
1546 + 'name' => 'toc_hierarchy',
1547 + 'type' => 'toggle',
1548 + 'label' => __( 'TOC Hierarchy', 'betterdocs' ),
1097 1549 'enable_disable_text_active' => true,
1098 - 'default' => 1,
1099 - 'priority' => 3,
1100 - 'rules' => Rules::is( 'enable_toc', true )
1101 - ],
1102 - 'toc_list_number' => [
1103 - 'name' => 'toc_list_number',
1104 - 'type' => 'toggle',
1105 - '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' ),
1106 1558 'enable_disable_text_active' => true,
1107 - 'default' => 1,
1108 - 'priority' => 4,
1109 - 'rules' => Rules::is( 'enable_toc', true )
1110 - ],
1111 - 'toc_dynamic_title' => [
1112 - 'name' => 'toc_dynamic_title',
1113 - 'type' => 'toggle',
1114 - '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' ),
1115 1567 'enable_disable_text_active' => true,
1116 - 'default' => 0,
1117 - 'priority' => 5,
1118 - 'rules' => Rules::is( 'enable_toc', true )
1119 - ],
1120 - 'enable_sticky_toc' => [
1121 - 'name' => 'enable_sticky_toc',
1122 - 'type' => 'toggle',
1123 - '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' ),
1124 1576 'enable_disable_text_active' => true,
1125 - 'default' => 1,
1126 - 'priority' => 6,
1127 - 'rules' => Rules::is( 'enable_toc', true )
1128 - ],
1129 - 'collapsible_toc_mobile' => [
1130 - 'name' => 'collapsible_toc_mobile',
1131 - 'type' => 'toggle',
1132 - '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' ),
1133 1585 'enable_disable_text_active' => true,
1134 - 'default' => '',
1135 - 'priority' => 7,
1136 - 'rules' => Rules::is( 'enable_toc', true )
1137 - ],
1138 - 'title_link_ctc' => [
1139 - 'name' => 'title_link_ctc',
1140 - 'type' => 'toggle',
1141 - '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' ),
1142 1594 'enable_disable_text_active' => true,
1143 - 'default' => 1,
1144 - 'priority' => 8
1145 - ],
1146 - 'supported_heading_tag' => [
1147 - 'name' => 'supported_heading_tag',
1148 - 'label' => __( 'TOC Supported Heading Tag', 'betterdocs' ),
1149 - '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',
1150 1602 'multiple' => true,
1151 1603 'priority' => 10,
1152 - 'default' => ['1', '2', '3', '4', '5', '6'],
1153 - '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(
1154 1613 '1' => 'H1',
1155 1614 '2' => 'H2',
1156 1615 '3' => 'H3',
1157 1616 '4' => 'H4',
@@ -1156,963 +1615,1512 @@
1156 1615 '3' => 'H3',
1157 1616 '4' => 'H4',
1158 1617 '5' => 'H5',
1159 1618 '6' => 'H6'
1160 - ] ),
1619 + ) ),
1161 1620 'priority' => 9,
1162 - 'rules' => Rules::is( 'enable_toc', true )
1163 - ],
1164 - 'sticky_toc_offset' => [
1165 - 'name' => 'sticky_toc_offset',
1166 - 'type' => 'number',
1167 - 'label' => __( 'Content Offset', 'betterdocs' ),
1168 - 'default' => 100,
1169 - '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,
1170 1629 'label_subtitle' => __( 'content offset from top on scroll.', 'betterdocs' ),
1171 - 'rules' => Rules::is( 'enable_toc', true )
1172 - ]
1173 - ]
1174 - ],
1175 - 'layout_single_doc_breadcrumb' => [
1176 - 'id' => 'layout_single_doc_breadcrumb',
1177 - 'name' => 'layout_single_doc_breadcrumb',
1178 - 'type' => 'section',
1179 - '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' ),
1180 1639 'priority' => 5,
1181 - 'fields' => [
1182 - 'enable_breadcrumb' => [
1183 - 'name' => 'enable_breadcrumb',
1184 - 'type' => 'toggle',
1185 - 'label' => __( 'Breadcrumb', 'betterdocs' ),
1640 + 'fields' => array(
1641 + 'enable_breadcrumb' => array(
1642 + 'name' => 'enable_breadcrumb',
1643 + 'type' => 'toggle',
1644 + 'label' => __( 'Breadcrumb', 'betterdocs' ),
1186 1645 'enable_disable_text_active' => true,
1187 - 'default' => 1,
1188 - 'priority' => 1
1189 - ],
1190 - 'breadcrumb_home_text' => [
1191 - 'name' => 'breadcrumb_home_text',
1192 - 'type' => 'text',
1193 - 'label' => __( 'Breadcrumb Home Text', 'betterdocs' ),
1194 - '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,
1195 1655 'priority' => 2,
1196 - 'rules' => Rules::is( 'enable_breadcrumb', true )
1197 - ],
1198 - 'breadcrumb_home_url' => [
1199 - 'name' => 'breadcrumb_home_url',
1200 - 'type' => 'text',
1201 - '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' ),
1202 1663 'priority' => 3,
1203 - 'default' => get_home_url(),
1204 - 'rules' => Rules::is( 'enable_breadcrumb', true )
1205 - ],
1206 - 'enable_breadcrumb_category' => [
1207 - 'name' => 'enable_breadcrumb_category',
1208 - 'type' => 'toggle',
1209 - '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' ),
1210 1684 'enable_disable_text_active' => true,
1211 - 'default' => 1,
1212 - 'priority' => 4,
1213 - 'rules' => Rules::is( 'enable_breadcrumb', true )
1214 - ],
1215 - 'enable_breadcrumb_title' => [
1216 - 'name' => 'enable_breadcrumb_title',
1217 - 'type' => 'toggle',
1218 - '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' ),
1219 1693 'enable_disable_text_active' => true,
1220 - 'default' => 1,
1221 - 'priority' => 5,
1222 - 'rules' => Rules::is( 'enable_breadcrumb', true )
1223 - ]
1224 - ]
1225 - ],
1226 - 'layout_single_doc_email_feedback' => [
1227 - 'id' => 'layout_single_doc_email_feedback',
1228 - 'name' => 'layout_single_doc_email_feedback',
1229 - 'type' => 'section',
1230 - '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' ),
1231 1705 'priority' => 5,
1232 - 'fields' => [
1233 - 'email_feedback' => [
1234 - 'name' => 'email_feedback',
1235 - 'type' => 'toggle',
1236 - 'label' => __( 'Email Feedback', 'betterdocs' ),
1706 + 'fields' => array(
1707 + 'email_feedback' => array(
1708 + 'name' => 'email_feedback',
1709 + 'type' => 'toggle',
1710 + 'label' => __( 'Email Feedback', 'betterdocs' ),
1237 1711 'enable_disable_text_active' => true,
1238 - 'default' => 1,
1239 - 'priority' => 1
1240 - ],
1241 - 'feedback_link_text' => [
1242 - 'name' => 'feedback_link_text',
1243 - 'type' => 'text',
1244 - 'label' => __( 'Feedback Link Text', 'betterdocs' ),
1245 - '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' ),
1246 1720 'priority' => 2,
1247 - 'rules' => Rules::is( 'email_feedback', true )
1248 - ],
1249 - 'feedback_form_title' => [
1250 - 'name' => 'feedback_form_title',
1251 - 'type' => 'text',
1252 - 'label' => __( 'Feedback Form Title', 'betterdocs' ),
1253 - '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' ),
1254 1728 'priority' => 3,
1255 - 'rules' => Rules::is( 'email_feedback', true )
1256 - ],
1257 - 'email_address' => [
1258 - 'name' => 'email_address',
1259 - 'type' => 'text',
1260 - 'label' => __( 'Email Address', 'betterdocs' ),
1261 - 'default' => get_option( 'admin_email' ),
1262 - '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,
1263 1737 'label_subtitle' => __( 'The email address where the Feedback form will be sent', 'betterdocs' ),
1264 - 'rules' => Rules::is( 'email_feedback', true )
1265 - ],
1266 - 'feedback_url' => [
1267 - 'name' => 'feedback_url',
1268 - 'type' => 'text',
1269 - 'label' => __( 'Feedback URL', 'betterdocs' ),
1270 - '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' => '',
1271 1745 'priority' => 5,
1272 - 'rules' => Rules::is( 'email_feedback', true )
1273 - ]
1274 - ]
1275 - ],
1276 - [
1277 - 'id' => 'layout_single_doc_attachments',
1278 - 'name' => 'layout_single_doc_attachments',
1279 - 'type' => 'section',
1280 - 'label' => __( 'Attachments', 'betterdocs-pro' ),
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' ),
1281 1755 'priority' => 6,
1282 - 'fields' => apply_filters( 'betterdocs_single_doc_attachments', [
1283 - 'show_attachment' => [
1284 - 'name' => 'show_attachment',
1285 - 'type' => 'toggle',
1286 - 'is_pro' => true,
1287 - 'priority' => 1,
1288 - 'label' => __( 'Show Attachment', 'betterdocs-pro' ),
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' ),
1289 1763 'enable_disable_text_active' => true,
1290 - 'default' => false
1291 - ]
1292 - ] )
1293 - ],
1294 - [
1295 - 'id' => 'layout_single_doc_related_docs',
1296 - 'name' => 'layout_single_doc_related_docs',
1297 - 'type' => 'section',
1298 - 'label' => __( 'Related Docs', 'betterdocs-pro' ),
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' ),
1299 1773 'priority' => 7,
1300 - 'fields' => apply_filters( 'betterdocs_single_doc_related_docs', [
1301 - 'show_related_docs' => [
1302 - 'name' => 'show_related_docs',
1303 - 'type' => 'toggle',
1304 - 'is_pro' => true,
1305 - 'priority' => 1,
1306 - 'label' => __( 'Show Related Docs', 'betterdocs-pro' ),
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' ),
1307 1781 'enable_disable_text_active' => true,
1308 - 'default' => false
1309 - ]
1310 - ] )
1311 - ]
1312 - ]
1313 - ]
1314 - ]
1315 - ] ),
1316 - 'layout_archive_page' => [
1317 - 'id' => 'layout_archive_page',
1318 - 'name' => 'layout_archive_page',
1319 - 'type' => 'section',
1320 - 'label' => __( 'Archive Page', 'betterdocs' ),
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' ),
1321 1795 'priority' => 3,
1322 - 'fields' => [
1323 - 'enable_archive_sidebar' => [
1324 - 'name' => 'enable_archive_sidebar',
1325 - 'type' => 'toggle',
1326 - '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' ),
1327 1801 'enable_disable_text_active' => true,
1328 - 'default' => 1,
1329 - 'priority' => 31
1330 - ],
1331 - 'archive_nested_subcategory' => [
1332 - 'name' => 'archive_nested_subcategory',
1333 - 'type' => 'toggle',
1334 - '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' ),
1335 1809 'enable_disable_text_active' => true,
1336 - 'default' => 1,
1337 - 'priority' => 32
1338 - ]
1339 - ]
1340 - ]
1341 - ]
1342 - ] )
1343 - ]
1344 - ]
1345 - ]
1346 - ] ),
1347 - 'tab-design' => apply_filters( 'betterdocs_settings_tab_design', [
1348 - 'id' => 'tab-design',
1349 - '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' ),
1350 1832 'priority' => 30,
1351 - 'fields' => [
1352 - 'title-design' => [
1353 - 'name' => 'title-design-tab',
1354 - 'type' => 'section',
1355 - 'label' => __( 'Design', 'betterdocs' ),
1833 + 'fields' => array(
1834 + 'title-design' => array(
1835 + 'name' => 'title-design-tab',
1836 + 'type' => 'section',
1837 + 'label' => __( 'Design', 'betterdocs' ),
1356 1838 'priority' => 30,
1357 - 'fields' => [
1358 - 'customizer_link' => [
1359 - 'name' => 'customizer_link',
1360 - 'type' => 'action',
1361 - 'action' => 'betterdocs_settings_customizer_link',
1362 - 'label' => __( 'Customize BetterDocs', 'betterdocs' ),
1363 - 'url' => $this->customizer_link(),
1364 - 'customizer_img' => betterdocs()->assets->icon( 'customizer/betterdocs-customize.png', true ),
1365 - 'priority' => 1
1366 - ]
1367 - ]
1368 - ]
1369 - ]
1370 - ] ),
1371 - 'tab-shortcodes' => apply_filters( 'betterdocs_settings_tab_shortcodes', [
1372 - 'label' => __( 'Shortcodes', 'betterdocs' ),
1373 - 'id' => 'tab-shortcodes',
1374 - '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',
1375 1847 'priority' => 40,
1376 - 'fields' => [
1377 - 'title-shortcodes' => [
1378 - 'name' => 'title-shortcodes-tab',
1379 - 'type' => 'section',
1380 - 'label' => __( 'Shortcodes', 'betterdocs' ),
1381 - 'priority' => 40,
1382 - 'searchable' => true,
1383 - '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' ),
1384 1856 'searchNotFoundMessage' => '<img src="' . betterdocs()->assets->icon( 'not-found.svg', true ) . '"/><p>' . __( 'No Shortcodes Found with these keywords', 'betterdocs' ) . '</p>',
1385 - 'fields' => apply_filters( 'betterdocs_shortcode_fields', [
1386 - 'search_form' => [
1387 - 'name' => 'search_form',
1388 - 'type' => 'copy-to-clipboard',
1389 - 'label' => __( 'Search Form', 'betterdocs' ),
1390 - 'default' => '[betterdocs_search_form]',
1391 - 'readOnly' => true,
1392 - 'priority' => 1,
1393 - 'description' => __( '[betterdocs_search_form placeholder="Search..." heading="Heading" subheading="Subheading" category_search="true" search_button="true" popular_search="true"]', 'betterdocs' ),
1394 - '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' ),
1395 1867 'descriptionCopyable' => true
1396 - ],
1397 - 'feedback_form' => [
1398 - 'name' => 'feedback_form',
1399 - 'type' => 'copy-to-clipboard',
1400 - 'label' => __( 'Feedback Form', 'betterdocs' ),
1401 - 'default' => '[betterdocs_feedback_form]',
1402 - 'readOnly' => true,
1403 - 'priority' => 2,
1404 - 'description' => __( '[betterdocs_feedback_form button_text="Send"]', 'betterdocs' ),
1405 - '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' ),
1406 1878 'descriptionCopyable' => true
1407 - ],
1408 - 'category_grid' => [
1409 - 'name' => 'category_grid',
1410 - 'type' => 'copy-to-clipboard',
1411 - 'label' => __( 'Category Grid- Layout 1', 'betterdocs' ),
1412 - 'default' => '[betterdocs_category_grid]',
1413 - 'readOnly' => true,
1414 - 'priority' => 3,
1415 - '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' ),
1416 - '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' ),
1417 1889 'descriptionCopyable' => true
1418 - ],
1419 - 'category_box' => [
1420 - 'name' => 'category_box',
1421 - 'type' => 'copy-to-clipboard',
1422 - 'label' => __( 'Category Box- Layout 2', 'betterdocs' ),
1423 - 'default' => '[betterdocs_category_box]',
1424 - 'readOnly' => true,
1425 - 'priority' => 4,
1426 - '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' ),
1427 - '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' ),
1428 1900 'descriptionCopyable' => true
1429 - ],
1430 - 'category_list' => [
1431 - 'name' => 'category_list',
1432 - 'type' => 'copy-to-clipboard',
1433 - 'label' => __( 'Category List', 'betterdocs' ),
1434 - 'default' => '[betterdocs_category_list]',
1435 - 'readOnly' => true,
1436 - 'priority' => 5,
1437 - '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' ),
1438 - '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' ),
1439 1911 'descriptionCopyable' => true
1440 - ],
1441 - 'faq_modern_layout' => [
1442 - 'name' => 'faq_modern_layout',
1443 - 'type' => 'copy-to-clipboard',
1444 - 'label' => __( 'FAQ Layout - 1', 'betterdocs' ),
1445 - 'default' => '[betterdocs_faq_list_modern]',
1446 - 'readOnly' => true,
1447 - 'priority' => 13,
1448 - 'description' => __( '[betterdocs_faq_list_modern groups="group_id" class="" group_exclude="group_id" faq_heading="Frequently Asked Questions"]', 'betterdocs' ),
1449 - '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' ),
1450 1922 'descriptionCopyable' => true
1451 - ],
1452 - 'faq_classic_layout' => [
1453 - 'name' => 'faq_classic_layout',
1454 - 'type' => 'copy-to-clipboard',
1455 - 'label' => __( 'FAQ Layout - 2', 'betterdocs' ),
1456 - 'default' => '[betterdocs_faq_list_classic]',
1457 - 'readOnly' => true,
1458 - 'priority' => 14,
1459 - 'description' => __( '[betterdocs_faq_list_classic groups="group_id" class="" group_exclude="group_id" faq_heading="Frequently Asked Questions"]', 'betterdocs' ),
1460 - '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' ),
1461 1933 'descriptionCopyable' => true
1462 - ]
1463 - ] )
1464 - ]
1465 - ]
1466 - ] ),
1467 - 'tab-advance-settings' => apply_filters( 'betterdocs_settings_tab_advance', [
1468 - 'id' => 'tab-advance-settings',
1469 - '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',
1470 1965 'priority' => 50,
1471 - 'fields' => [
1472 - 'title-advance-settings' => [
1473 - 'name' => 'title-advance-settings-tab',
1474 - 'type' => 'section',
1475 - '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' ),
1476 1971 'priority' => 50,
1477 - 'fields' => apply_filters( 'betterdocs_internal_kb_fields', [
1478 - 'article_roles' => [
1479 - 'name' => 'article_roles',
1480 - 'type' => 'checkbox-select',
1481 - 'label' => __( 'Who Can Write Docs?', 'betterdocs' ),
1482 - 'priority' => 1,
1483 - 'multiple' => true,
1484 - 'search' => true,
1485 - 'is_pro' => true,
1486 - 'default' => ['administrator'],
1487 - 'options' => $wp_roles
1488 - ],
1489 - 'settings_roles' => [
1490 - 'name' => 'settings_roles',
1491 - 'type' => 'checkbox-select',
1492 - 'label' => __( 'Who Can Edit Settings?', 'betterdocs' ),
1493 - 'priority' => 2,
1494 - 'multiple' => true,
1495 - 'is_pro' => true,
1496 - 'search' => true,
1497 - 'default' => ['administrator'],
1498 - 'options' => $wp_roles
1499 - ],
1500 - 'analytics_roles' => [
1501 - 'name' => 'analytics_roles',
1502 - 'type' => 'checkbox-select',
1503 - 'label' => __( 'Who Can Check Analytics?', 'betterdocs' ),
1504 - 'priority' => 3,
1505 - 'multiple' => true,
1506 - 'is_pro' => true,
1507 - 'search' => true,
1508 - 'default' => ['administrator'],
1509 - 'options' => $wp_roles
1510 - ],
1511 - 'enable_content_restriction' => [
1512 - 'name' => 'enable_content_restriction',
1513 - 'type' => 'toggle',
1514 - 'is_pro' => true,
1515 - 'priority' => 4,
1516 - 'label' => __( 'Internal Knowledge Base', 'betterdocs' ),
1517 - 'enable_disable_text_active' => true,
1518 - 'default' => ['all']
1519 - ],
1520 - 'content_visibility' => [
1521 - 'name' => 'content_visibility',
1522 - 'type' => 'checkbox-select',
1523 - 'label' => __( 'Restrict Access to', 'betterdocs' ),
1524 - 'label_subtitle' => __( 'Only selected User Roles will be able to view your Knowledge Base', 'betterdocs' ),
1525 - 'is_pro' => true,
1526 - 'priority' => 5,
1527 - 'multiple' => true,
1528 - 'search' => true,
1529 - 'default' => ['all'],
1530 - 'placeholder' => __( 'Select any', 'betterdocs' ),
1531 - 'options' => $this->normalize_options( array_merge( [
1532 - 'all' => __( 'All logged in users', 'betterdocs' )
1533 - ], wp_roles()->role_names ) ),
1534 - 'rules' => Rules::is( 'enable_content_restriction', true ),
1535 - 'filterValue' => 'all'
1536 - ],
1537 - 'restrict_template' => [
1538 - 'name' => 'restrict_template',
1539 - 'type' => 'checkbox-select',
1540 - 'label' => __( 'Restriction on Docs', 'betterdocs' ),
1541 - 'label_subtitle' => __( 'Selected Docs pages will be restricted', 'betterdocs' ),
1542 - 'is_pro' => true,
1543 - 'priority' => 6,
1544 - 'multiple' => true,
1545 - 'search' => true,
1546 - 'default' => ['all'],
1547 - 'placeholder' => __( 'Select any', 'betterdocs' ),
1548 - 'options' => $this->get_texanomy(),
1549 - 'rules' => Rules::is( 'enable_content_restriction', true ),
1550 - 'filterValue' => 'all'
1551 - ],
1552 - 'restrict_category' => [
1553 - 'name' => 'restrict_category',
1554 - 'type' => 'checkbox-select',
1555 - 'label' => __( 'Restriction on Docs Categories', 'betterdocs' ),
1556 - 'label_subtitle' => __( 'Selected Docs categories will be restricted', 'betterdocs' ),
1557 - 'is_pro' => true,
1558 - 'priority' => 7,
1559 - 'multiple' => true,
1560 - 'search' => true,
1561 - 'default' => ['all'],
1562 - 'placeholder' => __( 'Select any', 'betterdocs' ),
1563 - 'options' => $this->get_terms( 'doc_category' ),
1564 - 'rules' => Rules::is( 'enable_content_restriction', true ),
1565 - 'filterValue' => 'all'
1566 - ],
1567 - 'restricted_redirect_url' => [
1568 - 'name' => 'restricted_redirect_url',
1569 - 'type' => 'text',
1570 - 'label' => __( 'Redirect URL', 'betterdocs' ),
1571 - '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' ),
1572 - 'default' => '',
1573 - 'placeholder' => 'https://',
1574 - 'is_pro' => true,
1575 - 'priority' => 9,
1576 - 'rules' => Rules::is( 'enable_content_restriction', true )
1577 - ]
1578 - ] )
1579 - ]
1580 - ]
1581 - ] ),
1582 - 'tab-email-reporting' => apply_filters( 'betterdocs_settings_tab_email_reporting', [
1583 - 'id' => 'tab-email-reporting',
1584 - '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' ),
1585 2180 'priority' => 60,
1586 - 'fields' => [
1587 - 'title-email-reporting' => [
1588 - 'name' => 'title-email-reporting-tab',
1589 - 'type' => 'section',
1590 - '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' ),
1591 2186 'priority' => 60,
1592 - 'fields' => [
1593 - 'enable_reporting' => [
1594 - 'name' => 'enable_reporting',
1595 - 'label' => __( 'Email Reporting', 'betterdocs' ),
2187 + 'fields' => array(
2188 + 'enable_reporting' => array(
2189 + 'name' => 'enable_reporting',
2190 + 'label' => __( 'Email Reporting', 'betterdocs' ),
1596 2191 'enable_disable_text_active' => true,
1597 - 'type' => 'toggle',
1598 - 'priority' => 1,
1599 - 'default' => 0
1600 - ],
1601 - 'reporting_frequency' => apply_filters( 'betterdocs_reporting_frequency_settings', [
1602 - 'name' => 'reporting_frequency',
1603 - 'type' => 'select',
1604 - 'label' => __( 'Reporting Frequency', 'betterdocs' ),
1605 - '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',
1606 2201 'priority' => 2,
1607 - 'is_pro' => true,
1608 - 'options' => $this->normalize_options( [
1609 - 'betterdocs_daily' => __( 'Once Daily', 'betterdocs' ),
1610 - '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' ),
1611 2206 'betterdocs_monthly' => __( 'Once Monthly', 'betterdocs' )
1612 - ] ),
1613 - 'rules' => Rules::is( 'enable_reporting', true )
1614 - ] ),
1615 - 'reporting_day' => [
1616 - 'name' => 'reporting_day',
1617 - 'type' => 'select',
1618 - 'label' => __( 'Reporting Day', 'betterdocs' ),
1619 - 'default' => 'monday',
1620 - '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(
1621 2216 Rules::is( 'enable_reporting', true ),
1622 2217 Rules::is( 'reporting_frequency', 'betterdocs_weekly' )
1623 - ], 'and' ),
1624 - 'priority' => 3,
1625 - 'options' => $this->normalize_options( [
1626 - 'sunday' => __( 'Sunday', 'betterdocs' ),
1627 - 'monday' => __( 'Monday', 'betterdocs' ),
1628 - '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' ),
1629 2224 'wednesday' => __( 'Wednesday', 'betterdocs' ),
1630 - 'thursday' => __( 'Thursday', 'betterdocs' ),
1631 - 'friday' => __( 'Friday', 'betterdocs' ),
1632 - 'saturday' => __( 'Saturday', 'betterdocs' )
1633 - ] ),
2225 + 'thursday' => __( 'Thursday', 'betterdocs' ),
2226 + 'friday' => __( 'Friday', 'betterdocs' ),
2227 + 'saturday' => __( 'Saturday', 'betterdocs' )
2228 + ) ),
1634 2229 'label_subtitle' => __( 'This is only applicable for the “Weekly” report', 'betterdocs' )
1635 - ],
1636 - 'select_reporting_data' => apply_filters( 'betterdocs_select_reporting_data_settings', [
1637 - 'name' => 'select_reporting_data',
1638 - 'type' => 'checkbox-select',
1639 - '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' ),
1640 2235 'priority' => 4,
1641 2236 'multiple' => true,
1642 - 'options' => $this->normalize_options( [
1643 - 'overview' => 'Overview',
1644 - 'top-docs' => 'Top Docs',
2237 + 'options' => $this->normalize_options( array(
2238 + 'overview' => 'Overview',
2239 + 'top-docs' => 'Top Docs',
1645 2240 'most-search' => 'Most Searched Keywords'
1646 - ] ),
1647 - 'default' => ['overview', 'top-docs', 'most-search'],
1648 - 'is_pro' => true,
1649 - 'rules' => Rules::is( 'enable_reporting', true )
1650 - ] ),
1651 - 'reporting_email' => [
1652 - 'name' => 'reporting_email',
1653 - 'type' => 'text',
1654 - 'label' => __( 'Reporting Email', 'betterdocs' ),
1655 - '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' ),
1656 2251 'priority' => 5,
1657 - 'rules' => Rules::is( 'enable_reporting', true )
1658 - ],
1659 - 'reporting_subject' => apply_filters( 'betterdocs_reporting_subject_settings', [
1660 - 'name' => 'reporting_subject',
1661 - 'type' => 'textarea',
1662 - 'label' => __( 'Reporting Email Subject', 'betterdocs' ),
1663 - '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' ) ),
1664 2260 'priority' => 6,
1665 - 'is_pro' => true,
1666 - 'rules' => Rules::is( 'enable_reporting', true )
1667 - ] ),
1668 - 'test_report' => [
1669 - 'name' => 'test_report',
1670 - 'label' => __( 'Reporting Test', 'betterdocs' ),
1671 - 'text' => __( 'Test Report', 'betterdocs' ),
1672 - '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',
1673 2269 'priority' => 7,
1674 - 'rules' => Rules::is( 'enable_reporting', true ),
1675 - 'ajax' => [
1676 - 'on' => 'click',
1677 - 'api' => '/betterdocs/v1/reporting-test',
1678 - 'data' => [
1679 - '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',
1680 2276 'select_reporting_data' => '@select_reporting_data',
1681 - 'reporting_subject' => '@reporting_subject',
1682 - 'reporting_email' => '@reporting_email',
1683 - 'reporting_day' => '@reporting_day',
1684 - 'reporting_frequency' => '@reporting_frequency'
1685 - ],
1686 - 'swal' => [
1687 - 'text' => __( 'Successfully Sent a Test Report in Your Email.', 'betterdocs' ),
1688 - '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',
1689 2285 'autoClose' => 2000
1690 - ]
1691 - ]
1692 - ]
1693 - ]
1694 - ]
1695 - ]
1696 - ] ),
1697 - 'tab-instant-answer' => apply_filters( 'betterdocs_settings_tab_instant_answer', [
1698 - 'id' => 'tab-instant-answer',
1699 - 'name' => 'tab-instant-answer',
1700 - 'type' => 'section',
1701 - 'label' => __( 'Instant Answer', 'betterdocs' ),
1702 - '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,
1703 2324 'priority' => 70,
1704 - 'fields' => [
1705 - 'title-instant-answer' => [
1706 - 'name' => 'title-instant-answer-tab',
1707 - 'type' => 'section',
1708 - 'label' => __( 'Instant Answer', 'betterdocs' ),
1709 - 'priority' => 80,
1710 - '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,
1711 2332 'showSubmit' => false,
1712 - 'fields' => apply_filters( 'betterdocs_instant_answer_fields', [
1713 - 'enable_disable_wrapper' => [
1714 - 'name' => 'enable_disable_wrapper',
1715 - 'type' => 'section',
2333 + 'fields' => apply_filters( 'betterdocs_instant_answer_fields', array(
2334 + 'enable_disable_wrapper' => array(
2335 + 'name' => 'enable_disable_wrapper',
2336 + 'type' => 'section',
1716 2337 'priority' => 0,
1717 - 'save' => false,
1718 - 'fields' => [
1719 - 'enable_disable' => [
1720 - 'name' => 'enable_disable',
1721 - 'type' => 'toggle',
1722 - 'priority' => 100,
1723 - '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' ),
1724 2345 'enable_disable_text_active' => false,
1725 - 'default' => true,
1726 - 'is_pro' => true
1727 - ]
1728 - ]
1729 - ]
1730 - ] )
1731 - ]
1732 - ]
1733 - ] ),
1734 - 'tab-ai-autowrite' => [
1735 - 'id' => 'tab-ai-autowrite',
1736 - 'name' => 'tab-ai-autowrite',
1737 - 'type' => 'section',
1738 - '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,
1739 2658 'priority' => 75,
1740 - 'fields' => [
1741 - 'title-ai-autowrite' => apply_filters( 'betterdocs_settings_ai_autowrite_fields', [
1742 - 'name' => 'title-ai-autowrite-tab',
1743 - 'type' => 'section',
1744 - 'label' => __( 'Write with AI', 'betterdocs' ),
1745 - 'priority' => 60,
1746 - 'fields' => [
1747 - 'enable_write_with_ai' => [
1748 - 'name' => 'enable_write_with_ai',
1749 - 'type' => 'toggle',
1750 - 'priority' => 0,
1751 - 'label' => __( 'Write Docs with AI', 'betterdocs' ),
1752 - 'label_subtitle' => __( 'Generate AI based Documentation in your Gutenberg Editor', 'betterdocs' ),
1753 - 'enable_disable_text_active' => true,
1754 - 'default' => true
1755 - ],
1756 - 'enable_faq_write_with_ai' => [
1757 - 'name' => 'enable_faq_write_with_ai',
1758 - 'type' => 'toggle',
1759 - 'priority' => 5,
1760 - 'label' => __( 'Write FAQ with AI', 'betterdocs' ),
1761 - 'label_subtitle' => __( 'Generate AI based FAQ in your Editor', 'betterdocs' ),
1762 - 'enable_disable_text_active' => true,
1763 - 'default' => true
1764 - ],
1765 - 'ai_autowrite_api_key' => [
1766 - 'name' => 'ai_autowrite_api_key',
1767 - 'type' => 'text',
1768 - 'label' => __( 'API Key', 'betterdocs' ),
1769 - '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' ),
1770 - 'default' => '',
1771 - 'priority' => 10
1772 - ],
1773 - 'ai_autowrite_max_token' => [
1774 - 'name' => 'ai_autowrite_max_token',
1775 - 'type' => 'number',
1776 - 'label' => __( 'Set Max Tokens', 'betterdocs' ),
1777 - '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' ),
1778 - 'default' => 1500,
1779 - 'priority' => 15
1780 - ]
1781 - ]
1782 - ] )
1783 - ]
1784 - ]
1785 - ] )
1786 - ];
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 + );
1787 2712
2713 + $settings = array_merge( $settings, $this->chatbot_active_localize() );
2714 +
1788 2715 return apply_filters( 'betterdocs_settings_args', $settings );
1789 2716 }
1790 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 +
1791 2760 public function import_export_settings( $settings ) {
1792 2761 if ( ! current_user_can( 'import' ) ) {
1793 2762 return $settings;
1794 2763 }
1795 2764
1796 - $settings['tab-import-export'] = apply_filters( 'betterdocs_settings_tab_import_export', [
1797 - 'id' => 'tab-import-export',
1798 - 'name' => 'tab-import-export',
1799 - 'classes' => 'tab-import-export',
1800 - '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' ),
1801 2770 'priority' => 80,
1802 - 'fields' => [
1803 - 'sections-import-export' => [
1804 - 'name' => 'sections-import-export',
1805 - 'type' => 'section',
1806 - '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' ),
1807 2776 'priority' => 30,
1808 - 'fields' => [
1809 - 'all-tab-import-export' => [
1810 - 'id' => 'all-tab-import-export',
1811 - 'name' => 'all-tab-import-export',
1812 - 'label' => __( 'Import Export Settings', 'betterdocs' ),
1813 - 'classes' => 'tab-layout',
1814 - 'type' => "tab",
1815 - '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',
1816 2785 'completionTrack' => true,
1817 - 'sidebar' => false,
1818 - 'save' => false,
1819 - 'title' => false,
1820 - 'config' => [
1821 - 'active' => 'import',
2786 + 'sidebar' => false,
2787 + 'save' => false,
2788 + 'title' => false,
2789 + 'config' => array(
2790 + 'active' => 'import',
1822 2791 'sidebar' => false,
1823 - 'title' => false
1824 - ],
1825 - 'submit' => [
2792 + 'title' => false
2793 + ),
2794 + 'submit' => array(
1826 2795 'show' => false
1827 - ],
1828 - 'step' => [
2796 + ),
2797 + 'step' => array(
1829 2798 'show' => false
1830 - ],
1831 - 'priority' => 20,
1832 - 'fields' => [
1833 - 'import' => [
1834 - 'id' => 'import',
1835 - 'name' => 'import',
1836 - 'type' => 'section',
1837 - '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' ),
1838 2807 'priority' => 1,
1839 - 'fields' => [
1840 - 'import_tab_nested' => [
1841 - 'id' => 'import_tab_nested',
1842 - 'name' => 'import_tab_nested',
1843 - 'label' => __( 'Import', 'betterdocs' ),
1844 - 'classes' => 'tab-nested-layout',
1845 - 'type' => "tab",
1846 - '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',
1847 2816 'completionTrack' => true,
1848 - 'sidebar' => false,
1849 - 'save' => false,
1850 - 'title' => false,
1851 - 'config' => [
1852 - 'active' => 'import_docs_nested',
2817 + 'sidebar' => false,
2818 + 'save' => false,
2819 + 'title' => false,
2820 + 'config' => array(
2821 + 'active' => 'import_docs_nested',
1853 2822 'sidebar' => false,
1854 - 'title' => false
1855 - ],
1856 - 'submit' => [
2823 + 'title' => false
2824 + ),
2825 + 'submit' => array(
1857 2826 'show' => false
1858 - ],
1859 - 'step' => [
2827 + ),
2828 + 'step' => array(
1860 2829 'show' => false
1861 - ],
1862 - 'priority' => 1,
1863 - 'fields' => [
1864 - 'import_docs_nested' => [
1865 - 'id' => 'import_docs_nested',
1866 - 'name' => 'import_docs_nested',
1867 - 'type' => 'section',
1868 - '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' ),
1869 2838 'priority' => 1,
1870 - 'fields' => [
1871 - 'import_docs' => [
1872 - 'name' => 'import_docs',
1873 - 'type' => 'importerupload',
1874 - 'label' => __( 'Import Docs', 'betterdocs' ),
1875 - '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 ) ),
1876 - 'text' => [
1877 - 'normal' => __( 'Proceed', 'betterdocs' ),
1878 - 'saved' => __( 'Proceed', 'betterdocs' ),
1879 - 'loading' => __( 'Importing...', 'betterdocs' ),
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' ),
1880 2850 'exists_notice' => __( 'It seems like documentations with same slugs already exist on your website. What would you like to do?', 'betterdocs' )
1881 - ],
1882 - 'ajax' => [
1883 - 'on' => 'click',
1884 - 'api' => '/betterdocs/v1/import-docs',
1885 - 'swal' => [
1886 - 'text' => __( 'Import completed successfully.', 'betterdocs' ),
1887 - 'icon' => 'success',
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',
1888 2858 'autoClose' => 2000
1889 - ]
1890 - ],
1891 - 'file_type' => '.xml, .csv',
1892 - 'priority' => 1
1893 - ]
1894 - ]
1895 - ],
2859 + )
2860 + ),
2861 + 'file_type' => '.xml, .csv',
2862 + 'priority' => 1
2863 + )
2864 + )
2865 + ),
1896 2866
1897 - 'import_settings_nested' => [
1898 - 'id' => 'import_settings_nested',
1899 - 'name' => 'import_settings_nested',
1900 - 'type' => 'section',
1901 - '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' ),
1902 2872 'priority' => 1,
1903 - 'fields' => [
1904 - 'settings_importer' => [
1905 - 'name' => 'settings_importer',
1906 - 'type' => 'settingsuploader',
1907 - 'label' => __( 'Import Settings', 'notificationx' ),
2873 + 'fields' => array(
2874 + 'settings_importer' => array(
2875 + 'name' => 'settings_importer',
2876 + 'type' => 'settingsuploader',
2877 + 'label' => __( 'Import Settings', 'betterdocs' ),
1908 2878 'label_subtitle' => __( 'To import BetterDocs Settings, please upload BetterDocs settings you have exported from another website in .json format', 'betterdocs' ),
1909 - 'reset' => __( 'Change', 'notificationx' ),
1910 - 'priority' => 1
1911 - ],
1912 - 'import_settings' => [
1913 - 'name' => 'import_settings',
1914 - 'type' => 'button',
1915 - 'rules' => Rules::is( 'settings_importer', null, true ),
1916 - 'text' => [
1917 - 'normal' => __( 'Proceed', 'betterdocs' ),
1918 - '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' ),
1919 2889 'loading' => __( 'Importing...', 'betterdocs' )
1920 - ],
1921 - 'ajax' => [
1922 - 'on' => 'click',
1923 - 'api' => '/betterdocs/v1/import-settings',
1924 - 'data' => [
2890 + ),
2891 + 'ajax' => array(
2892 + 'on' => 'click',
2893 + 'api' => '/betterdocs/v1/import-settings',
2894 + 'data' => array(
1925 2895 'settings' => '@settings_importer'
1926 - ],
1927 - 'swal' => [
1928 - 'text' => __( 'Import completed successfully.', 'betterdocs' ),
1929 - 'icon' => 'success',
2896 + ),
2897 + 'swal' => array(
2898 + 'text' => __( 'Import completed successfully.', 'betterdocs' ),
2899 + 'icon' => 'success',
1930 2900 'autoClose' => 1000
1931 - ],
2901 + ),
1932 2902 'reload' => true
1933 - ],
2903 + ),
1934 2904 'priority' => 2
1935 - ]
1936 - ]
1937 - ]
1938 - ]
1939 - ]
1940 - ]
1941 - ],
1942 - 'export' => [
1943 - 'id' => 'export',
1944 - 'name' => 'export',
1945 - 'type' => 'section',
1946 - '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' ),
1947 2917 'priority' => 1,
1948 - 'fields' => [
1949 - 'export_tab_nested' => [
1950 - 'id' => 'export_tab_nested',
1951 - 'name' => 'export_tab_nested',
1952 - 'label' => __( 'Export', 'betterdocs' ),
1953 - 'classes' => 'tab-nested-layout',
1954 - 'type' => "tab",
1955 - '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',
1956 2926 'completionTrack' => true,
1957 - 'sidebar' => false,
1958 - 'save' => false,
1959 - 'title' => false,
1960 - 'config' => [
1961 - 'active' => 'export_docs_nested',
2927 + 'sidebar' => false,
2928 + 'save' => false,
2929 + 'title' => false,
2930 + 'config' => array(
2931 + 'active' => 'export_docs_nested',
1962 2932 'sidebar' => false,
1963 - 'title' => false
1964 - ],
1965 - 'submit' => [
2933 + 'title' => false
2934 + ),
2935 + 'submit' => array(
1966 2936 'show' => false
1967 - ],
1968 - 'step' => [
2937 + ),
2938 + 'step' => array(
1969 2939 'show' => false
1970 - ],
1971 - 'priority' => 1,
1972 - 'fields' => [
1973 - 'export_docs_nested' => [
1974 - 'id' => 'export_docs_nested',
1975 - 'name' => 'export_docs_nested',
1976 - 'type' => 'section',
1977 - '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' ),
1978 2948 'priority' => 1,
1979 - 'fields' => apply_filters( 'betterdocs_export_fields', [
1980 - 'export_type' => [
1981 - 'name' => 'export_type',
1982 - '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' ),
1983 2953 'label_subtitle' => __( 'Choose an export type: All Docs, a specific Knowledge Base, or a Doc Category', 'betterdocs' ),
1984 - 'type' => 'select',
1985 - 'default' => 'docs',
1986 - 'priority' => 3,
1987 - 'search' => true,
1988 - 'options' => $this->normalize_options( apply_filters( 'betterdocs_export_type_options', [
1989 - 'docs' => __( 'Docs', 'betterdocs' ),
1990 - 'doc_category' => __( 'Docs Category', 'betterdocs' )
1991 - ] ) )
1992 - ],
1993 - 'export_docs' => [
1994 - 'name' => 'export_docs',
1995 - 'type' => 'checkbox-select',
1996 - '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' ),
1997 2968 'label_subtitle' => __( 'Selected docs will be included in the export.', 'betterdocs' ),
1998 - 'priority' => 4,
1999 - 'multiple' => true,
2000 - 'search' => true,
2001 - 'default' => ['all'],
2002 - 'placeholder' => __( 'Select any', 'betterdocs' ),
2003 - 'options' => array_merge( [
2004 - [
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(
2005 2976 'value' => 'all',
2006 2977 'label' => 'All'
2007 - ]
2008 - ], $this->docs() ),
2009 - 'filterValue' => 'all',
2010 - 'rules' => Rules::is( 'export_type', 'docs' )
2011 - ],
2012 - 'export_categories' => [
2013 - 'name' => 'export_categories',
2014 - 'type' => 'checkbox-select',
2015 - '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' ),
2016 2987 'label_subtitle' => __( 'Selected categories and its docs will be included in the export.', 'betterdocs' ),
2017 - 'priority' => 6,
2018 - 'multiple' => true,
2019 - 'search' => true,
2020 - 'default' => ['all'],
2021 - 'placeholder' => __( 'Select any', 'betterdocs' ),
2022 - 'options' => $this->get_terms( 'doc_category' ),
2023 - 'filterValue' => 'all',
2024 - 'rules' => Rules::is( 'export_type', 'doc_category' )
2025 - ],
2026 - 'file_type' => [
2027 - 'name' => 'file_type',
2028 - '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' ),
2029 3014 'label_subtitle' => __( 'Choose a file type', 'betterdocs' ),
2030 - 'type' => 'select',
2031 - 'default' => 'xml',
2032 - 'priority' => 7,
2033 - 'search' => true,
2034 - '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(
2035 3020 'xml' => __( '.xml', 'betterdocs' ),
2036 3021 'csv' => __( '.csv', 'betterdocs' )
2037 - ] ) )
2038 - ],
2039 - 'export_docs_btn' => [
2040 - 'name' => 'export_docs_btn',
2041 - 'text' => [
2042 - 'normal' => __( 'Proceed', 'betterdocs' ),
2043 - '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' ),
2044 3039 'loading' => __( 'Exporting...', 'betterdocs' )
2045 - ],
2046 - 'type' => 'button',
2047 - 'priority' => 8,
2048 - 'ajax' => [
2049 - 'on' => 'click',
2050 - 'api' => '/betterdocs/v1/export-docs',
2051 - 'data' => [
2052 - 'export_type' => '@export_type',
2053 - 'export_docs' => '@export_docs',
2054 - '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',
2055 3050 'export_categories' => '@export_categories',
2056 - 'file_type' => '@file_type'
2057 - ],
2058 - 'swal' => [
2059 - 'text' => __( 'Exported Successfully.', 'betterdocs' ),
2060 - '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',
2061 3058 'autoClose' => 2000
2062 - ]
2063 - ]
2064 - ]
2065 - ] )
2066 - ],
3059 + )
3060 + )
3061 + )
3062 + ) )
3063 + ),
2067 3064
2068 - 'export_settings_nested' => [
2069 - 'id' => 'export_settings_nested',
2070 - 'name' => 'export_settings_nested',
2071 - 'type' => 'section',
2072 - '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' ),
2073 3070 'priority' => 1,
2074 - 'fields' => [
2075 - 'export_settings' => [
2076 - 'name' => 'export_settings',
2077 - 'label' => __( 'Export Settings', 'betterdocs' ),
3071 + 'fields' => array(
3072 + 'export_settings' => array(
3073 + 'name' => 'export_settings',
3074 + 'label' => __( 'Export Settings', 'betterdocs' ),
2078 3075 'label_subtitle' => __( 'Simply click on “Export Settings” button to download your BetterDocs settings in .json format', 'betterdocs' ),
2079 - 'text' => [
2080 - 'normal' => __( 'Export Settings', 'betterdocs' ),
2081 - 'saved' => __( 'Export Settings', 'betterdocs' ),
3076 + 'text' => array(
3077 + 'normal' => __( 'Export Settings', 'betterdocs' ),
3078 + 'saved' => __( 'Export Settings', 'betterdocs' ),
2082 3079 'loading' => __( 'Exporting...', 'betterdocs' )
2083 - ],
2084 - 'type' => 'button',
2085 - 'priority' => 8,
2086 - 'ajax' => [
2087 - 'on' => 'click',
2088 - 'api' => '/betterdocs/v1/export-settings',
2089 - 'data' => [
3080 + ),
3081 + 'type' => 'button',
3082 + 'priority' => 8,
3083 + 'ajax' => array(
3084 + 'on' => 'click',
3085 + 'api' => '/betterdocs/v1/export-settings',
3086 + 'data' => array(
2090 3087 'betterdocs_settings' => get_option( 'betterdocs_settings' )
2091 - ],
2092 - 'swal' => [
2093 - 'text' => __( 'File downloaded successfully.', 'betterdocs' ),
2094 - 'icon' => 'success',
3088 + ),
3089 + 'swal' => array(
3090 + 'text' => __( 'File downloaded successfully.', 'betterdocs' ),
3091 + 'icon' => 'success',
2095 3092 'autoClose' => 2000
2096 - ]
2097 - ]
2098 - ]
2099 - ]
2100 - ]
2101 - ]
2102 - ]
2103 - ]
2104 - ]
2105 - ]
2106 - ]
2107 - ]
2108 - ]
2109 - ]
2110 - ] );
3093 + )
3094 + )
3095 + )
3096 + )
3097 + )
3098 + )
3099 + )
3100 + )
3101 + )
3102 + )
3103 + )
3104 + )
3105 + )
3106 + )
3107 + ) );
2111 3108
2112 3109 return $settings;
2113 3110 }
2114 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 +
2115 3123 public function normalize_options( $options ) {
2116 3124 return GlobalFields::normalize_fields( $options );
2117 3125 }
2118 3126
@@ -2122,20 +3130,20 @@
2122 3130 if ( $docs_tax ) {
2123 3131 return $docs_tax;
2124 3132 }
2125 3133
2126 - $taxonomies = get_taxonomies( [
2127 - 'object_type' => ['docs']
2128 - ], 'objects' );
3134 + $taxonomies = get_taxonomies( array(
3135 + 'object_type' => array( 'docs' )
3136 + ), 'objects' );
2129 3137
2130 - $docs_tax = [
2131 - 'all' => 'All Docs Archive',
3138 + $docs_tax = array(
3139 + 'all' => 'All Docs Archive',
2132 3140 'docs' => 'Docs Page'
2133 - ];
3141 + );
2134 3142 foreach ( $taxonomies as $key => $value ) {
2135 - $docs_tax[$key] = $value->label;
3143 + $docs_tax[ $key ] = $value->label;
2136 3144 }
2137 - unset( $docs_tax['doc_tag'] );
3145 + unset( $docs_tax[ 'doc_tag' ] );
2138 3146
2139 3147 $docs_tax = $this->normalize_options( $docs_tax );
2140 3148 if ( count( $docs_tax ) > 2 ) {
2141 3149 $this->database->set_cache( 'betterdocs::settings::taxonomies', $docs_tax );
@@ -2143,9 +3151,9 @@
2143 3151
2144 3152 return $docs_tax;
2145 3153 }
2146 3154
2147 - public function get_terms( $taxonomy ) {
3155 + public function get_terms( $taxonomy, $hide_empty = true ) {
2148 3156 $_cache_key = 'betterdocs::settings::terms::' . trim( $taxonomy );
2149 3157 $docs_tax = $this->database->get_cache( $_cache_key );
2150 3158
2151 3159 if ( $docs_tax ) {
@@ -2151,21 +3159,21 @@
2151 3159 if ( $docs_tax ) {
2152 3160 return $docs_tax;
2153 3161 }
2154 3162
2155 - $get_terms = get_terms( [
2156 - 'taxonomy' => $taxonomy,
2157 - 'hide_empty' => false
2158 - ] );
3163 + $get_terms = get_terms( array(
3164 + 'taxonomy' => $taxonomy,
3165 + 'hide_empty' => $hide_empty
3166 + ) );
2159 3167
2160 - $terms = [
3168 + $terms = array(
2161 3169 'all' => 'All'
2162 - ];
3170 + );
2163 3171
2164 3172 if ( ! empty( $get_terms ) && ! is_wp_error( $get_terms ) ) {
2165 3173 foreach ( $get_terms as $value ) {
2166 3174 if ( isset( $value->slug ) && isset( $value->name ) ) {
2167 - $terms[$value->slug] = $value->name;
3175 + $terms[ $value->slug ] = $value->name;
2168 3176 }
2169 3177 }
2170 3178 }
2171 3179
@@ -2176,8 +3184,40 @@
2176 3184
2177 3185 return $terms;
2178 3186 }
2179 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 +
2180 3220 /**
2181 3221 * Get all docs
2182 3222 */
2183 3223 public function docs() {
@@ -2186,19 +3226,19 @@
2186 3226 if ( $docs ) {
2187 3227 return $docs;
2188 3228 }
2189 3229
2190 - $docs = [];
3230 + $docs = array();
2191 3231
2192 - $_docs = get_posts( [
2193 - 'post_type' => 'docs',
2194 - 'numberposts' => -1,
3232 + $_docs = get_posts( array(
3233 + 'post_type' => 'docs',
3234 + 'numberposts' => -1,
2195 3235 'posts_per_page' => -1
2196 - ] );
3236 + ) );
2197 3237
2198 3238 if ( ! empty( $_docs ) ) {
2199 3239 foreach ( $_docs as $doc ) {
2200 - $docs[$doc->ID] = betterdocs()->template_helper->kses( $doc->post_title );
3240 + $docs[ $doc->ID ] = betterdocs()->template_helper->kses( $doc->post_title );
2201 3241 }
2202 3242 $docs = GlobalFields::normalize_fields( $docs );
2203 3243 $this->database->set_cache( 'betterdocs::settings::all_docs', $docs );
2204 3244 }
@@ -2205,15 +3245,16 @@
2205 3245
2206 3246 return $docs;
2207 3247 }
2208 3248
2209 - public function hide_roles_management( $tabData = [] ) {
3249 + public function hide_roles_management( $tabData = array() ) {
2210 3250 global $current_user;
2211 3251
2212 3252 if ( $current_user instanceof WP_User && ! in_array( 'administrator', $current_user->roles ) ) {
2213 - unset( $tabData['fields']['title-advance-settings']['fields']['article_roles'] );
2214 - unset( $tabData['fields']['title-advance-settings']['fields']['settings_roles'] );
2215 - 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' ] );
2216 3257 }
2217 3258
2218 3259 return $tabData;
2219 3260 }