PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 3.8.9
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v3.8.9
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/Admin.php +51 -185 4.4.13.8.9 View file →
@@ -9,9 +9,8 @@
9 9 use WPDeveloper\BetterDocs\Utils\Helper;
10 10 use WPDeveloper\BetterDocs\Utils\Enqueue;
11 11 use WPDeveloper\BetterDocs\Utils\Insights;
12 12 use PriyoMukul\WPNotice\Utils\NoticeRemover;
13 -use WPDeveloper\BetterDocs\Core\PluginInstaller;
14 13 use WPDeveloper\BetterDocs\Dependencies\DI\Container;
15 14
16 15 class Admin extends Base {
17 16 /**
@@ -21,9 +20,9 @@
21 20 /**
22 21 * Admin Root Menu Slug
23 22 * @var string
24 23 */
25 - private $slug = 'betterdocs-dashboard';
24 + private $slug = 'betterdocs-admin';
26 25 /**
27 26 * Insights
28 27 *
29 28 * @var Insights
@@ -56,11 +55,8 @@
56 55 * @var Enqueue
57 56 */
58 57 private $assets;
59 58
60 - // modules
61 - protected $installer;
62 -
63 59 /**
64 60 * FAQBuilder
65 61 * @var FAQBuilder
66 62 */
@@ -71,12 +67,11 @@
71 67 $this->container = $container;
72 68 $this->assets = $assets;
73 69 $this->settings = $settings;
74 70 $this->kbmigration = $kbmigration;
75 - $this->slug = 'betterdocs-dashboard';
71 + $this->slug = 'betterdocs-admin';
76 72
77 73 add_action( 'init', [ $type, 'register' ], 9 );
78 - add_action('rest_api_init', [$this, 'order_terms_in_wp_terms_admin_table']);
79 74
80 75 $type->init();
81 76 $type->admin_init();
82 77
@@ -86,10 +81,8 @@
86 81 if ( ! is_admin() ) {
87 82 return;
88 83 }
89 84
90 - $this->installer = new PluginInstaller();
91 -
92 85 $this->plugin_insights();
93 86 add_action( 'admin_notices', [ $this, 'compatibility_notices' ] );
94 87 // add_action( 'admin_init', [$this, 'notices'], 9 );
95 88 add_filter( 'admin_init', [ $this, 'save_admin_page' ], 99 );
@@ -126,10 +119,9 @@
126 119 add_action( 'admin_footer-plugins.php', array( $this, 'disable_deactivation' ) );
127 120 }
128 121
129 122 if ( $this->settings->get( 'enable_estimated_reading_time' ) ) {
130 - // Hook into unified metabox instead of creating separate metabox
131 - add_action( 'betterdocs_reading_time_tab_content', [ $this, 'render_estimated_time_markup' ] );
123 + add_action( 'add_meta_boxes', [ $this, 'reading_meta_box_' ], 10 );
132 124 }
133 125
134 126 self::$cache_bank = CacheBank::get_instance();
135 127
@@ -142,17 +134,8 @@
142 134 unset( $e );
143 135 }
144 136 }
145 137
146 - public function order_terms_in_wp_terms_admin_table() {
147 - //order the terms correctly to be shown on the admin panel categories menu with betterdocs order
148 - add_action('rest_insert_doc_category', function( $term, $request, $bool ) {
149 - $max_order = Helper::get_max_doc_category_order_from_term_meta() ?? 0;
150 - $next_order = $max_order + 1;
151 - update_term_meta( $term->term_id, 'doc_category_order', $next_order );
152 - }, 10, 3);
153 - }
154 -
155 138 public function disable_deactivation() {
156 139 $tooltip_text = esc_html__( 'Deactivate BetterDocs Pro First', 'betterdocs' );
157 140 ?>
158 141 <style type="text/css">
@@ -212,8 +195,20 @@
212 195 }
213 196 return $output;
214 197 }
215 198
199 + public function reading_meta_box_() {
200 + add_meta_box(
201 + 'betterdocs_estimated_time_metabox',
202 + __( 'Estimated Reading Time', 'betterdocs' ),
203 + [
204 + $this,
205 + 'render_estimated_time_markup'
206 + ],
207 + 'docs'
208 + );
209 + }
210 +
216 211 public function render_estimated_time_markup() {
217 212 betterdocs()->views->get( 'admin/metabox/estimated-reading-box' );
218 213 }
219 214
@@ -400,52 +395,14 @@
400 395 ]
401 396 );
402 397 }
403 398
404 - $spring_campaign_message = '<div class="betterdocs-spring-notice-body"><p style="margin-top: 0; margin-bottom: 0;">🌸 <strong>Spring Savings:</strong> Build AI-powered Knowledge Bases & FAQs to empower support and improve user experience – now <strong>Flat 25% OFF!</strong> ⚡️</p></div>';
405 - $_spring_campaign_notice = [
406 - 'thumbnail' => $this->assets->icon( 'betterdocs-logo.svg', true ),
407 - 'html' => $spring_campaign_message,
408 - 'links' => [
409 - 'support' => [
410 - 'link' => 'https://betterdocs.co/spring2026-admin-notice',
411 - 'attributes' => [
412 - 'target' => '_blank',
413 - 'class' => 'offer-button',
414 - ],
415 - 'label' => __( 'Upgrade To PRO Now', 'betterdocs' ),
416 - ],
417 - 'maybe_later' => [
418 - 'label' => __( 'I\'ll Grab It Later', 'betterdocs' ),
419 - 'attributes' => [
420 - 'target' => '_blank',
421 - 'data-later' => true,
422 - 'class' => 'dismiss-btn',
423 - ],
424 - ],
425 - ],
426 - ];
427 -
428 - $notices->add(
429 - 'spring-campaign-26',
430 - $_spring_campaign_notice,
431 - [
432 - 'start' => $notices->time(),
433 - 'recurrence' => false,
434 - 'dismissible' => true,
435 - 'refresh' => BETTERDOCS_VERSION,
436 - 'expire' => strtotime( '11:59:59pm May 31, 2026' ),
437 - 'display_if' => ! is_plugin_active( 'betterdocs-pro/betterdocs-pro.php' ),
438 - ]
439 - );
440 -
441 399 self::$cache_bank->create_account( $notices );
442 400 self::$cache_bank->calculate_deposits( $notices );
443 401 if ( method_exists( self::$cache_bank, 'clear_notices_in_' ) ) {
444 402 self::$cache_bank->clear_notices_in_(
445 403 [
446 - 'toplevel_page_betterdocs-dashboard',
447 - 'admin_page_betterdocs-admin',
404 + 'toplevel_page_betterdocs-admin',
448 405 'betterdocs_page_betterdocs-admin',
449 406 'betterdocs_page_betterdocs-settings',
450 407 'betterdocs_page_betterdocs-faq',
451 408 'betterdocs_page_betterdocs-analytics',
@@ -463,13 +420,12 @@
463 420 public function body_classes( $classes ) {
464 421 $saved_settings = get_option( 'betterdocs_settings', false );
465 422 $dark_mode = isset( $saved_settings['dark_mode'] ) ? $saved_settings['dark_mode'] : false;
466 423 $dark_mode = ! empty( $dark_mode ) ? boolval( $dark_mode ) : false;
467 - $current_screen_id = get_current_screen() != null ? str_replace( 'betterdocs_page_', '', str_replace( 'toplevel_page_', '', str_replace( 'admin_page_', '', get_current_screen()->id ) ) ) : '';
424 + $current_screen_id = get_current_screen() != null ? str_replace( 'betterdocs_page_', '', str_replace( 'toplevel_page_', '', get_current_screen()->id ) ) : '';
468 425 $registered_screens = [
469 426 'betterdocs-settings',
470 427 'betterdocs-admin',
471 - 'betterdocs-dashboard',
472 428 'betterdocs-analytics',
473 429 'betterdocs-glossaries',
474 430 'betterdocs-faq',
475 431 'edit-doc_category',
@@ -602,9 +558,9 @@
602 558
603 559 /**
604 560 * This scripts enqueued for Dashboard App.
605 561 */
606 - $this->assets->enqueue( 'betterdocs', 'admin/css/dashboard.css', [ 'betterdocs-old' ], '', BETTERDOCS_VERSION );
562 + $this->assets->enqueue( 'betterdocs', 'admin/css/dashboard.css', [ 'betterdocs-old' ] );
607 563 $this->assets->enqueue( 'betterdocs-icons', 'admin/btd-icon/style.css' );
608 564 }
609 565
610 566 /**
@@ -644,9 +600,8 @@
644 600 if ( ! betterdocs()->is_betterdocs_screen( $hook ) ) {
645 601 return;
646 602 }
647 603
648 - wp_enqueue_media(); // load early to fix problems with media upload issues on settings for wordpress 6.0.9
649 604 $this->assets->register( 'betterdocs-admin', 'admin/js/dashboard.js' );
650 605
651 606 $saved_settings = get_option( 'betterdocs_settings', false );
652 607 $dark_mode = $saved_settings['dark_mode'] ?? false;
@@ -669,12 +624,11 @@
669 624 'rest_url' => esc_url_raw( rest_url() ),
670 625 'free_version' => betterdocs()->version,
671 626 'generate_data_url' => get_rest_url( null, '/betterdocs/v1/create-sample-docs' ),
672 627 'nonce' => wp_create_nonce( 'wp_rest' ),
673 - 'sync_nonce' => wp_create_nonce( 'ai_chatbot_embed' ),
674 - 'count_all_docs' => array_sum((array) wp_count_posts('docs')),
675 - 'count_all_faq' => array_sum((array) wp_count_posts('betterdocs_faq')),
676 - 'count_new_docs' => count(get_option('saved_docs_post_ids', [])) + count(get_option('betterdocs_ai_chatbot_error_posts', [])),
628 + 'sync_nonce' => wp_create_nonce( 'ai_chatbot_embed' ),
629 + 'count_all_docs' => wp_count_posts('docs')->publish,
630 + 'count_new_docs' => count(get_option('saved_docs_post_ids', [])),
677 631 'admin_url' => admin_url(),
678 632 'ia_preview' => betterdocs()->settings->get( 'ia_enable_preview', false ),
679 633 'multiple_kb' => betterdocs()->settings->get( 'multiple_kb' ),
680 634 'previewMode' => betterdocs()->settings->get( 'ia_enable_preview', false ),
@@ -681,18 +635,9 @@
681 635 'dashboard_mode' => get_option( 'dashboard_mode' ),
682 636 'betterdocs_pro_plugin' => betterdocs()->is_pro_active(),
683 637 'betterdocs_pro_version' => betterdocs()->pro_version(),
684 638 'analytics_older' => version_compare( betterdocs()->pro_version(), '3.3.4', '<=' ),
685 - 'disabled_embed_model_option' => get_option('disabled_embed_model_option'),
686 - 'betterdocs_ChatBot_plugin' => is_plugin_active( 'betterdocs-ai-chatbot/betterdocs-ai-chatbot.php' ),
687 - 'total_doc_category_terms' => wp_count_terms( 'doc_category'),
688 - 'github_oauth_nonce' => wp_create_nonce( 'betterdocs_github_oauth_nonce' ),
689 - 'git_settings' => [
690 - 'git_repository_url' => betterdocs()->settings->get_raw_field( 'git_repository_url', '' ),
691 - 'git_branch' => betterdocs()->settings->get_raw_field( 'git_branch', '' ),
692 - 'git_docs_directory' => betterdocs()->settings->get_raw_field( 'git_docs_directory', '' ),
693 - 'git_provider' => betterdocs()->settings->get_raw_field( 'git_provider', 'github' ),
694 - ],
639 + 'disabled_embed_model_option'=> get_option('disabled_embed_model_option'),
695 640 ]
696 641 );
697 642
698 643 // If wp-date (which includes moment.js) is not registered, enqueue your custom moment.js
@@ -781,13 +726,14 @@
781 726 *
782 727 * @return void
783 728 * @since 1.0.0
784 729 */
730 +
785 731 public function menus() {
786 732 $default_args = [
787 733 'page_title' => 'BetterDocs',
788 734 'menu_title' => 'BetterDocs',
789 - 'capability' => 'edit_docs', // Unified capability
735 + 'capability' => 'edit_posts',
790 736 'menu_slug' => $this->slug,
791 737 'callback' => [ $this, 'output' ],
792 738 'icon_url' => betterdocs()->assets->icon( 'betterdocs-icon-white.svg', true ),
793 739 'position' => 5
@@ -793,65 +739,24 @@
793 739 'position' => 5
794 740 ];
795 741
796 742 $_menu_position = 5;
797 - global $submenu;
798 743
799 - // Always register both UI endpoints
800 - $this->register_modern_ui_fallback();
801 -
802 744 foreach ( $this->menu_list() as $key => $value ) {
803 745 if ( $key === 'betterdocs' ) {
804 746 $callable = 'add_menu_page';
805 747 $value = wp_parse_args( $value, $default_args );
806 - call_user_func_array( $callable, $value );
807 748 } else {
808 - $is_core_page = strpos($value['menu_slug'], '?') !== false;
809 -
810 - if ($is_core_page) {
811 - // Add classic UI directly
812 - $submenu[$this->slug][] = [
813 - $value['menu_title'],
814 - $value['capability'],
815 - $value['menu_slug'],
816 - $value['page_title']
817 - ];
818 - } else {
819 - // Add modern UI through WordPress API
820 - add_submenu_page(
821 - $this->slug,
822 - $value['page_title'],
823 - $value['menu_title'],
824 - $value['capability'],
825 - $value['menu_slug'],
826 - $value['callback']
827 - );
828 - }
829 - $_menu_position++;
749 + $callable = 'add_submenu_page';
750 + $default_args['callback'] = '';
751 + $default_args['position'] = $_menu_position;
752 + unset( $default_args['icon_url'] );
753 + $value = wp_parse_args( $value, array_merge( [ 'parent_slug' => $this->slug ], $default_args ) );
830 754 }
831 - }
832 - }
833 755
834 - private function register_modern_ui_fallback() {
835 - // Add the submenu with valid parent slug
836 - add_submenu_page(
837 - 'betterdocs', // Valid parent slug
838 - __('All Docs', 'betterdocs'),
839 - '', // Empty menu title hides it
840 - 'edit_docs',
841 - 'betterdocs-admin',
842 - [ $this, 'output' ]
843 - );
756 + ++$_menu_position;
844 757
845 - // Hide the menu item from appearing in the admin sidebar
846 - global $submenu;
847 - if (isset($submenu['betterdocs'])) {
848 - foreach ($submenu['betterdocs'] as $key => $item) {
849 - if ($item[2] === 'betterdocs-admin') {
850 - unset($submenu['betterdocs'][$key]);
851 - break;
852 - }
853 - }
758 + call_user_func_array( $callable, $value );
854 759 }
855 760 }
856 761
857 762 /**
@@ -909,38 +814,12 @@
909 814 'callback' => [ $this, 'output' ],
910 815 'icon_url' => betterdocs()->assets->icon( 'betterdocs-icon-white.svg', true ),
911 816 'position' => 5
912 817 ],
913 - 'dashboard' => $this->normalize_menu(
914 - __( 'Dashboard', 'betterdocs' ),
915 - 'betterdocs-dashboard',
916 - 'edit_docs',
917 - [
918 - $this,
919 - 'output'
920 - ]
921 - ),
922 - 'all_docs' => $this->normalize_menu(
923 - __( 'All Docs', 'betterdocs' ),
924 - $this->ui_slug(),
925 - 'edit_docs',
926 - [ $this, 'output' ],
927 - $parent_slug
928 - ),
929 - 'add_new' => $this->normalize_menu(
930 - __( 'Add New', 'betterdocs' ),
931 - 'post-new.php?post_type=docs'
932 - ),
933 - 'categories' => $this->normalize_menu(
934 - __( 'Categories', 'betterdocs' ),
935 - 'edit-tags.php?taxonomy=doc_category&post_type=docs',
936 - 'manage_doc_terms'
937 - ),
938 - 'tags' => $this->normalize_menu(
939 - __( 'Tags', 'betterdocs' ),
940 - 'edit-tags.php?taxonomy=doc_tag&post_type=docs',
941 - 'manage_doc_terms'
942 - ),
818 + 'all_docs' => $this->normalize_menu( __( 'All Docs', 'betterdocs' ), $this->ui_slug() ),
819 + 'add_new' => $this->normalize_menu( __( 'Add New', 'betterdocs' ), 'post-new.php?post_type=docs' ),
820 + 'categories' => $this->normalize_menu( __( 'Categories', 'betterdocs' ), 'edit-tags.php?taxonomy=doc_category&post_type=docs', 'manage_doc_terms' ),
821 + 'tags' => $this->normalize_menu( __( 'Tags', 'betterdocs' ), 'edit-tags.php?taxonomy=doc_tag&post_type=docs', 'manage_doc_terms' ),
943 822 'settings' => $this->normalize_menu(
944 823 __( 'Settings', 'betterdocs' ),
945 824 'betterdocs-settings',
946 825 'edit_docs_settings',
@@ -962,9 +841,9 @@
962 841 ),
963 842 'faq' => $this->normalize_menu(
964 843 __( 'FAQ Builder', 'betterdocs' ),
965 844 'betterdocs-faq',
966 - 'read_faq_builder',
845 + 'read_docs_analytics',
967 846 [
968 847 $this,
969 848 'output'
970 849 ],
@@ -984,22 +863,8 @@
984 863 $parent_slug
985 864 );
986 865 }
987 866
988 -
989 - if (!betterdocs()->is_chatbot_active()) {
990 - $betterdocs_admin_pages['ai_chatbot'] = $this->normalize_menu(
991 - __('AI Chatbot', 'betterdocs'),
992 - 'betterdocs-ai-chatbot',
993 - 'edit_docs_settings',
994 - [
995 - $this,
996 - 'output'
997 - ],
998 - $parent_slug
999 - );
1000 - }
1001 -
1002 867 return apply_filters( 'betterdocs_admin_menu', $betterdocs_admin_pages, [$this, 'output'], $parent_slug);
1003 868
1004 869 }
1005 870
@@ -1090,13 +955,8 @@
1090 955 }
1091 956
1092 957 $slug = $this->settings->get( 'encyclopedia_root_slug' );
1093 958
1094 - global $wp_rewrite;
1095 - if ( $wp_rewrite->using_index_permalinks() ) {
1096 - $slug = $wp_rewrite->index . '/' . $slug;
1097 - }
1098 -
1099 959 $encyclopedia_url = home_url( $slug );
1100 960
1101 961 $admin_bar->add_node(
1102 962 [
@@ -1141,18 +1001,24 @@
1141 1001 * @return string
1142 1002 * @since 3.0.1
1143 1003 */
1144 1004 public function ui_slug() {
1145 - $last_visited = get_user_meta(get_current_user_id(), 'last_visited_docs_admin_page', true);
1146 - $docs_exist = get_posts([
1147 - 'post_type' => 'docs',
1148 - 'post_status' => 'any',
1149 - 'numberposts' => 1
1150 - ]);
1005 + $last_visited = get_user_meta( get_current_user_id(), 'last_visited_docs_admin_page', true );
1006 + $docs = get_posts(
1007 + [
1008 + 'post_type' => 'docs',
1009 + 'post_status' => 'any',
1010 + 'numberposts' => 2
1011 + ]
1012 + );
1151 1013
1152 - return ($last_visited === 'modern_ui' || empty($docs_exist))
1153 - ? 'betterdocs-admin'
1154 - : 'edit.php?post_type=docs&bdocs_view=classic';
1014 + if ( $last_visited === 'modern_ui' || count( $docs ) == 0 ) {
1015 + $slug = 'betterdocs-admin';
1016 + } else {
1017 + $slug = admin_url( 'edit.php?post_type=docs&bdocs_view=classic' );
1018 + }
1019 +
1020 + return $slug;
1155 1021 }
1156 1022
1157 1023 /**
1158 1024 * Resets a duplicate submenu in WordPress if the parent main menu and the first submenu permalink are not the same.