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