PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.9.4
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.9.4
4.9.4 4.9.3 4.9.2 4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 All 202 releases
← All changes | betterdocs.php +66 -5 4.8.1 → 4.9.4 View file →
@@ -3,9 +3,9 @@
3 3 /**
4 4 * Plugin Name: BetterDocs
5 5 * Plugin URI: https://betterdocs.co/
6 6 * Description: Create stunning Knowledge base & FAQs for your WordPress website and reduce support pressure with the help of BetterDocs. Get access to amazing templates and create fully customizable KB with AI Write.
7 - * Version: 4.8.1
7 + * Version: 4.9.4
8 8 * Requires at least: 6.4
9 9 * Requires PHP: 7.4
10 10 * Author: WPDeveloper
11 11 * Author URI: https://wpdeveloper.com
@@ -25,8 +25,31 @@
25 25 require_once __DIR__ . '/includes/v2x-compatibility.php';
26 26 require_once __DIR__ . '/vendor/autoload.php';
27 27
28 28 /**
29 + * Bundled MCP runtime (WordPress Abilities API + Parsedown).
30 + *
31 + * Loaded through the Jetpack Autoloader so that if the same library is also
32 + * shipped by another plugin — or lands in WordPress core — the newest copy
33 + * wins and loads once, with no fatal class collisions. This lets BetterDocs
34 + * serve its MCP connector out of the box, without the standalone Abilities
35 + * API plugin. See docs/mcp-server.md for the update procedure.
36 + *
37 + * On WordPress 7.1+, where core ships the Abilities API itself, Runtime::init()
38 + * stands the bundled copy down so it stops duplicating core's REST routes and
39 + * admin assets; on 6.4-7.0 the bundle is the only API and is left untouched.
40 + *
41 + * @since 4.9.0
42 + */
43 +$betterdocs_mcp_runtime = __DIR__ . '/dependencies/vendor/autoload_packages.php';
44 +if ( is_readable( $betterdocs_mcp_runtime ) ) {
45 + require_once $betterdocs_mcp_runtime;
46 +
47 + \WPDeveloper\BetterDocs\Abilities\Runtime::init();
48 +}
49 +unset( $betterdocs_mcp_runtime );
50 +
51 +/**
29 52 * Declare WooCommerce HPOS (custom order tables) compatibility. BetterDocs
30 53 * never touches order storage, so this is a pure compatibility flag. Must run
31 54 * on before_woocommerce_init — the Plugin bootstraps on `init`, which is too
32 55 * late for WooCommerce to read the declaration.
@@ -58,14 +81,52 @@
58 81 return Plugin::get_instance();
59 82 }
60 83
61 84 /**
85 + * Whether an active BetterDocs add-on has not been loaded yet.
86 + *
87 + * Pro and the AI Chatbot hook `betterdocs_init_before` / `betterdocs_loaded`
88 + * and the `betterdocs_container_config` filter, all of which fire while Free
89 + * boots. They are meant to load first (alphabetically they do), but a migrated
90 + * `active_plugins` order, a plugin-ordering tool or a network-activated Free
91 + * can put an add-on after Free. Booting then is too early: the add-on's hooks
92 + * are missing, and the Chatbot's config needs Pro's classes, which fatals the
93 + * whole site when Pro has not loaded yet.
94 + *
95 + * @since 4.9.4
96 + * @return bool
97 + */
98 +function betterdocs_has_pending_addons() {
99 + $addons = [
100 + 'betterdocs-pro/betterdocs-pro.php' => 'BETTERDOCS_PRO_FILE',
101 + 'betterdocs-ai-chatbot/betterdocs-ai-chatbot.php' => 'BETTERDOCS_CHATBOT_FILE',
102 + ];
103 +
104 + $active = (array) get_option( 'active_plugins', [] );
105 + if ( is_multisite() ) {
106 + $active = array_merge( $active, array_keys( (array) get_site_option( 'active_sitewide_plugins', [] ) ) );
107 + }
108 +
109 + foreach ( $addons as $plugin => $loaded_constant ) {
110 + if ( in_array( $plugin, $active, true ) && ! defined( $loaded_constant ) ) {
111 + return true;
112 + }
113 + }
114 +
115 + return false;
116 +}
117 +
118 +/**
62 119 * Initialize BetterDocs (Free)
63 120 * Here, begins the execution of the plugin.
64 121 *
65 - * Returns the main instance of BetterDocs.
122 + * Boots right away, as always, unless an active add-on is still to load; then
123 + * boots first thing on `plugins_loaded`, once every plugin has registered its
124 + * hooks, so any load order behaves like the default one.
66 125 *
67 - * @return Plugin
68 126 * @since 3.0
69 127 */
70 -
71 -betterdocs();
128 +if ( ! did_action( 'plugins_loaded' ) && betterdocs_has_pending_addons() ) {
129 + add_action( 'plugins_loaded', 'betterdocs', PHP_INT_MIN );
130 +} else {
131 + betterdocs();
132 +}