PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.9.2
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.9.2
4.9.2 4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 All 200 releases
← All changes | includes/Core/Install.php +200 -126 3.5.04.9.2 View file →
@@ -1,157 +1,175 @@
1 1 <?php
2 +namespace WPDeveloper\BetterDocs\Core;
2 3
3 -namespace WPDeveloper\BetterDocs\Core;
4 +if ( ! defined( 'ABSPATH' ) ) {
5 + exit;
6 +}
4 7
8 +
5 9 use WPDeveloper\BetterDocs\Utils\Base;
6 10 use WPDeveloper\BetterDocs\Utils\Database;
7 11 use WPDeveloper\BetterDocs\Dependencies\DI\Container;
8 12
9 13 class Install extends Base {
10 - /**
11 - * Container
12 - * @var Container
13 - */
14 - public $container;
15 - /**
16 - * Database
17 - * @var Database
18 - */
19 - public $database;
14 + /**
15 + * Container
16 + * @var Container
17 + */
18 + public $container;
19 + /**
20 + * Database
21 + * @var Database
22 + */
23 + public $database;
20 24
21 - public function __construct( Container $container ) {
22 - $this->container = $container;
23 - $this->database = $this->container->get( Database::class );
25 + public function __construct( Container $container ) {
26 + $this->container = $container;
27 + $this->database = $this->container->get( Database::class );
24 28
25 - register_activation_hook( BETTERDOCS_PLUGIN_FILE, [$this, 'activate'] );
26 - register_deactivation_hook( BETTERDOCS_PLUGIN_FILE, [$this, 'deactivate'] );
29 + register_activation_hook( BETTERDOCS_PLUGIN_FILE, [ $this, 'activate' ] );
30 + register_deactivation_hook( BETTERDOCS_PLUGIN_FILE, [ $this, 'deactivate' ] );
27 31
28 - //Update message for showing notice for new release
29 - add_action( 'in_plugin_update_message-betterdocs/betterdocs.php', [$this, 'plugin_update_message'], 10, 2 );
30 - add_action( 'init', [$this, 'check_db_updates'], 1 );
31 - add_action( 'init', [$this, 'check_version'], 5 );
32 - }
32 + //Update message for showing notice for new release
33 + add_action( 'in_plugin_update_message-betterdocs/betterdocs.php', [ $this, 'plugin_update_message' ], 10, 2 );
34 + add_action( 'init', [ $this, 'check_db_updates' ], 1 );
35 + add_action( 'init', [ $this, 'check_version' ], 5 );
36 + }
33 37
34 - /**
35 - * This is for upgrade message.
36 - *
37 - * @param mixed $plugin_data
38 - * @param mixed $response
39 - * @return void
40 - */
41 - public function plugin_update_message( $plugin_data, $response ) {
42 - if ( isset( $response->upgrade_notice ) ) {
43 - $new_version = $plugin_data['new_version'];
44 - $current_version = betterdocs()->version;
45 - $current_version_minor_part = explode( '.', $current_version )[1];
46 - $new_version_minor_part = explode( '.', $new_version )[1];
38 + /**
39 + * This is for upgrade message.
40 + *
41 + * @param mixed $plugin_data
42 + * @param mixed $response
43 + * @return void
44 + */
45 + public function plugin_update_message( $plugin_data, $response ) {
46 + if ( isset( $response->upgrade_notice ) ) {
47 + $new_version = $plugin_data['new_version'];
48 + $current_version = betterdocs()->version;
49 + $current_version_minor_part = explode( '.', $current_version )[1];
50 + $new_version_minor_part = explode( '.', $new_version )[1];
47 51
48 - betterdocs()->views->get( 'admin/notices/upgrade', [
49 - 'response' => $response,
50 - 'plugin_data' => $plugin_data,
51 - 'major' => ! ( $current_version_minor_part === $new_version_minor_part )
52 - ] );
53 - }
54 - }
52 + betterdocs()->views->get(
53 + 'admin/notices/upgrade',
54 + [
55 + 'response' => $response,
56 + 'plugin_data' => $plugin_data,
57 + 'major' => ! ( $current_version_minor_part === $new_version_minor_part )
58 + ]
59 + );
60 + }
61 + }
55 62
56 - /**
57 - * This method will run when version is updated.
58 - * @return void
59 - */
60 - public function check_version() {
61 - $betterdocs_version = get_option( 'betterdocs_version', '2.3.6' );
62 - $betterdocs_code_version = betterdocs()->version;
63 - $requires_update = version_compare( $betterdocs_version, $betterdocs_code_version, '<' );
63 + /**
64 + * This method will run when version is updated.
65 + * @return void
66 + */
67 + public function check_version() {
68 + $betterdocs_version = get_option( 'betterdocs_version', '2.3.6' );
69 + $betterdocs_code_version = betterdocs()->version;
70 + $requires_update = version_compare( $betterdocs_version, $betterdocs_code_version, '<' );
64 71
65 - if ( $requires_update ) {
66 - /**
67 - * This block of codes will execute
68 - * if this plugin is activated via PRO PLUGIN.
69 - */
70 - if ( $this->database->get_transient( 'maybe_betterdocs_installed_by_pro' ) ) {
71 - $this->activate();
72 + if ( $requires_update ) {
73 + /**
74 + * This block of codes will execute
75 + * if this plugin is activated via PRO PLUGIN.
76 + */
77 + if ( $this->database->get_transient( 'maybe_betterdocs_installed_by_pro' ) ) {
78 + $this->activate();
72 79
73 - $this->database->delete_transient( 'maybe_betterdocs_installed_by_pro' );
74 - }
80 + $this->database->delete_transient( 'maybe_betterdocs_installed_by_pro' );
81 + }
75 82
76 - // Re-check if any setup needed.
77 - $this->check_db_updates();
83 + // Re-check if any setup needed.
84 + $this->check_db_updates();
78 85
79 - // Re-check if any migration is needed.
80 - $this->container->get( Migration::class )->init( str_replace( '.', '', $betterdocs_code_version ) );
86 + if ( get_option( 'betterdocs_version' ) && str_replace( '.', '', $betterdocs_code_version ) >= 370 ) {
87 + $this->migrate_customizer();
88 + }
81 89
82 - // Updated current version number of plugin.
83 - $this->update_version();
84 - }
85 - }
90 + // Re-check if any migration is needed.
91 + $this->container->get( Migration::class )->init( str_replace( '.', '', $betterdocs_code_version ) );
86 92
87 - /**
88 - * Update BetterDocs version to current.
89 - */
90 - private function update_version() {
91 - update_option( 'betterdocs_version', betterdocs()->version );
92 - }
93 + // Updated current version number of plugin.
94 + $this->update_version();
95 + }
96 + }
93 97
94 - /**
95 - * This method will run when activation hit
96 - * @return void
97 - */
98 - public function activate() {
99 - // Create DB Tables if not created.
100 - $this->check_db_updates();
98 + /**
99 + * Update BetterDocs version to current.
100 + */
101 + private function update_version() {
102 + update_option( 'betterdocs_version', betterdocs()->version );
103 + }
101 104
102 - // Set admin roles
103 - $this->container->get( Roles::class )->setup();
105 + /**
106 + * This method will run when activation hit
107 + * @return void
108 + */
109 + public function activate() {
110 + // Create DB Tables if not created.
111 + $this->check_db_updates();
104 112
105 - // Save default settings.
106 - // $this->container->get( Settings::class )->save_default_settings();
113 + // Set admin roles
114 + $this->container->get( Roles::class )->setup();
107 115
108 - // Set redirect transient
109 - if ( current_user_can( 'delete_users' ) ) {
110 - $this->database->set_transient( 'betterdocs_maybe_redirect', true );
111 - }
116 + // Save default settings.
117 + // $this->container->get( Settings::class )->save_default_settings();
112 118
113 - $this->database->set_transient( 'betterdocs_flush_rewrite_rules', true );
114 - }
119 + // Set redirect transient
120 + if ( current_user_can( 'delete_users' ) ) {
121 + $this->database->set_transient( 'betterdocs_maybe_redirect', true );
122 + }
115 123
116 - /**
117 - * This method will run when deactivation hit.
118 - * @return void
119 - */
120 - public function deactivate() {
121 - // Flush all the existing rewrite rules
122 - flush_rewrite_rules();
124 + $this->database->set_transient( 'betterdocs_flush_rewrite_rules', true );
125 + }
123 126
124 - // Reset admin roles
125 - $this->container->get( Roles::class )->setup( true );
126 - }
127 + /**
128 + * This method will run when deactivation hit.
129 + * @return void
130 + */
131 + public function deactivate() {
132 + // Flush all the existing rewrite rules
133 + flush_rewrite_rules();
127 134
128 - /**
129 - * This method responsible for setup db tables for the plugin
130 - * @return void
131 - */
132 - public function check_db_updates() {
133 - $_db_version = get_option( 'betterdocs_db_version', '1.0' );
134 - $_db_code_version = betterdocs()->db_version;
135 - $requires_update = version_compare( $_db_version, $_db_code_version, '<' );
135 + // Reset admin roles
136 + $this->container->get( Roles::class )->setup( true );
137 + }
136 138
137 - if ( ! $requires_update ) {
138 - return;
139 - }
139 + /**
140 + * This method responsible for setup db tables for the plugin
141 + * @return void
142 + */
143 + public function check_db_updates() {
144 + $_db_version = get_option( 'betterdocs_db_version', '1.0' );
145 + $_db_code_version = betterdocs()->db_version;
146 + $requires_update = version_compare( $_db_version, $_db_code_version, '<' );
140 147
141 - global $wpdb;
148 + if ( ! $requires_update ) {
149 + return;
150 + }
142 151
143 - $charset_collate = $wpdb->get_charset_collate();
152 + global $wpdb;
144 153
145 - $search_keyword_table = $wpdb->prefix . 'betterdocs_search_keyword';
146 - $search_keyword = "CREATE TABLE $search_keyword_table (
154 + $charset_collate = $wpdb->get_charset_collate();
155 +
156 + // keyword_hash exists purely to make the lookup indexable: `keyword` is
157 + // TEXT and is matched with BINARY (for collation safety), which no index
158 + // can serve — so every front-end search used to full-scan this table.
159 + // The hash narrows to a single row via the index; the BINARY comparison
160 + // still decides the match, so behaviour is unchanged.
161 + $search_keyword_table = $wpdb->prefix . 'betterdocs_search_keyword';
162 + $search_keyword = "CREATE TABLE $search_keyword_table (
147 163 id bigint NOT NULL AUTO_INCREMENT,
148 164 keyword text NOT NULL,
149 - PRIMARY KEY (id)
165 + keyword_hash char(32) NOT NULL DEFAULT '',
166 + PRIMARY KEY (id),
167 + KEY keyword_hash (keyword_hash)
150 168 ) {$charset_collate};";
151 169
152 - $search_log_table = $wpdb->prefix . 'betterdocs_search_log';
153 - $search_log = "CREATE TABLE $search_log_table (
170 + $search_log_table = $wpdb->prefix . 'betterdocs_search_log';
171 + $search_log = "CREATE TABLE $search_log_table (
154 172 id bigint NOT NULL AUTO_INCREMENT,
155 173 keyword_id bigint NOT NULL,
156 174 count mediumint(9) NULL,
157 175 not_found_count mediumint(9) NULL,
@@ -157,13 +175,14 @@
157 175 not_found_count mediumint(9) NULL,
158 176 created_at date DEFAULT '0000-00-00' NOT NULL,
159 177 PRIMARY KEY (id),
160 178 KEY keyword_id (keyword_id),
161 - KEY created_at (created_at)
179 + KEY created_at (created_at),
180 + KEY keyword_created (keyword_id, created_at)
162 181 ) {$charset_collate};";
163 182
164 - $_analytics_table = $wpdb->prefix . 'betterdocs_analytics';
165 - $analytics_table = "CREATE TABLE $_analytics_table (
183 + $_analytics_table = $wpdb->prefix . 'betterdocs_analytics';
184 + $analytics_table = "CREATE TABLE $_analytics_table (
166 185 id bigint NOT NULL AUTO_INCREMENT,
167 186 post_id bigint DEFAULT 0 NOT NULL,
168 187 impressions bigint DEFAULT 0 NOT NULL,
169 188 unique_visit bigint DEFAULT 0 NOT NULL,
@@ -177,14 +196,69 @@
177 196 KEY unique_visit (unique_visit),
178 197 KEY happy (happy),
179 198 KEY sad (sad),
180 199 KEY normal (normal),
181 - KEY created_at (created_at)
200 + KEY created_at (created_at),
201 + UNIQUE KEY post_created (post_id, created_at)
182 202 ) {$charset_collate};";
183 203
184 - require_once ABSPATH . 'wp-admin/includes/upgrade.php';
185 - dbDelta( $search_keyword . $search_log . $analytics_table );
204 + // The betterdocs_api_specs table moved to Pro (API Documentation is a
205 + // Pro-only feature; Pro's Install creates it).
186 206
187 - // Update DB Version
188 - update_option( 'betterdocs_db_version', $_db_code_version );
189 - }
207 + require_once ABSPATH . 'wp-admin/includes/upgrade.php';
208 + dbDelta( $search_keyword . $search_log . $analytics_table );
209 +
210 + // Update DB Version
211 + update_option( 'betterdocs_db_version', $_db_code_version );
212 + }
213 +
214 + public function migrate_customizer() {
215 + /**
216 + * Seed the layout Customizer settings for installs that never explicitly
217 + * picked a layout. Some consumers read the raw theme_mod without a fallback
218 + * (e.g. FrontEnd::article_reactions()), so an unseeded mod can render
219 + * differently from the layout the front-end otherwise defaults to.
220 + *
221 + * Two rules keep this safe and correct:
222 + * 1. Only seed a mod that has never been set ( get_theme_mod() === false ).
223 + * An explicit choice — including an explicit 'layout-1' — is never
224 + * overwritten, so existing sites cannot change layout on update.
225 + * 2. Pull the value from Customizer\Defaults (the single source of truth
226 + * the front-end already renders from) instead of a hardcoded string, so
227 + * it can never drift from the real default again. Pro defaults are merged
228 + * in automatically when BetterDocs Pro is active.
229 + */
230 + $defaults = betterdocs()->customizer->defaults->defaults();
231 + $layout_mods = [
232 + 'betterdocs_search_layout_select',
233 + 'betterdocs_docs_layout_select',
234 + 'betterdocs_single_layout_select',
235 + 'betterdocs_archive_layout_select',
236 + 'betterdocs_select_faq_template',
237 + 'betterdocs_multikb_layout_select', // BetterDocs Pro.
238 + 'betterdocs_select_faq_template_mkb', // BetterDocs Pro.
239 + ];
240 +
241 + foreach ( $layout_mods as $mod ) {
242 + // Respect an explicit user choice (including an explicit 'layout-1').
243 + if ( get_theme_mod( $mod, false ) !== false ) {
244 + continue;
245 + }
246 +
247 + // Only seed when a real default is registered (skips inactive add-ons).
248 + if ( empty( $defaults[ $mod ] ) ) {
249 + continue;
250 + }
251 +
252 + set_theme_mod( $mod, $defaults[ $mod ] );
253 + }
254 +
255 + $search_heading = get_theme_mod( 'betterdocs_live_search_heading_switch' );
256 + if ( empty( $search_heading ) ) {
257 + set_theme_mod( 'betterdocs_live_search_heading_switch', false );
258 + }
259 +
260 + if ( get_option( 'betterdocs_settings' ) && betterdocs()->settings->get( 'enable_estimated_reading_time' ) == false ) {
261 + betterdocs()->settings->save( 'enable_estimated_reading_time', false );
262 + }
263 + }
190 264 }