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