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 +53 -42 4.6.14.9.2 View file →
@@ -152,13 +152,20 @@
152 152 global $wpdb;
153 153
154 154 $charset_collate = $wpdb->get_charset_collate();
155 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.
156 161 $search_keyword_table = $wpdb->prefix . 'betterdocs_search_keyword';
157 162 $search_keyword = "CREATE TABLE $search_keyword_table (
158 163 id bigint NOT NULL AUTO_INCREMENT,
159 164 keyword text NOT NULL,
160 - PRIMARY KEY (id)
165 + keyword_hash char(32) NOT NULL DEFAULT '',
166 + PRIMARY KEY (id),
167 + KEY keyword_hash (keyword_hash)
161 168 ) {$charset_collate};";
162 169
163 170 $search_log_table = $wpdb->prefix . 'betterdocs_search_log';
164 171 $search_log = "CREATE TABLE $search_log_table (
@@ -168,9 +175,10 @@
168 175 not_found_count mediumint(9) NULL,
169 176 created_at date DEFAULT '0000-00-00' NOT NULL,
170 177 PRIMARY KEY (id),
171 178 KEY keyword_id (keyword_id),
172 - KEY created_at (created_at)
179 + KEY created_at (created_at),
180 + KEY keyword_created (keyword_id, created_at)
173 181 ) {$charset_collate};";
174 182
175 183 $_analytics_table = $wpdb->prefix . 'betterdocs_analytics';
176 184 $analytics_table = "CREATE TABLE $_analytics_table (
@@ -188,11 +196,15 @@
188 196 KEY unique_visit (unique_visit),
189 197 KEY happy (happy),
190 198 KEY sad (sad),
191 199 KEY normal (normal),
192 - KEY created_at (created_at)
200 + KEY created_at (created_at),
201 + UNIQUE KEY post_created (post_id, created_at)
193 202 ) {$charset_collate};";
194 203
204 + // The betterdocs_api_specs table moved to Pro (API Documentation is a
205 + // Pro-only feature; Pro's Install creates it).
206 +
195 207 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
196 208 dbDelta( $search_keyword . $search_log . $analytics_table );
197 209
198 210 // Update DB Version
@@ -199,11 +211,46 @@
199 211 update_option( 'betterdocs_db_version', $_db_code_version );
200 212 }
201 213
202 214 public function migrate_customizer() {
203 - $search_layout = get_theme_mod( 'betterdocs_search_layout_select' );
204 - if ( empty( $search_layout ) ) {
205 - set_theme_mod( 'betterdocs_search_layout_select', 'layout-1' );
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 ] );
206 253 }
207 254
208 255 $search_heading = get_theme_mod( 'betterdocs_live_search_heading_switch' );
209 256 if ( empty( $search_heading ) ) {
@@ -209,45 +256,9 @@
209 256 if ( empty( $search_heading ) ) {
210 257 set_theme_mod( 'betterdocs_live_search_heading_switch', false );
211 258 }
212 259
213 - $docs_layout = get_theme_mod( 'betterdocs_docs_layout_select' );
214 - if ( empty( $docs_layout ) ) {
215 - set_theme_mod( 'betterdocs_docs_layout_select', 'layout-1' );
216 - }
217 -
218 - $single_layout = get_theme_mod( 'betterdocs_single_layout_select' );
219 - if ( empty( $single_layout ) ) {
220 - set_theme_mod( 'betterdocs_single_layout_select', 'layout-1' );
221 - }
222 -
223 - $category_archive_layout = get_theme_mod( 'betterdocs_archive_layout_select' );
224 - if ( empty( $category_archive_layout ) ) {
225 - set_theme_mod( 'betterdocs_archive_layout_select', 'layout-1' );
226 - }
227 -
228 - $search_layout_select = get_theme_mod( 'betterdocs_search_layout_select' );
229 - if ( empty( $search_layout_select ) ) {
230 - set_theme_mod( 'betterdocs_search_layout_select', 'layout-1' );
231 - }
232 -
233 - $docs_faq = get_theme_mod( 'betterdocs_select_faq_template' );
234 - if ( empty( $docs_faq ) ) {
235 - set_theme_mod( 'betterdocs_select_faq_template', 'layout-1' );
236 - }
237 -
238 260 if ( get_option( 'betterdocs_settings' ) && betterdocs()->settings->get( 'enable_estimated_reading_time' ) == false ) {
239 261 betterdocs()->settings->save( 'enable_estimated_reading_time', false );
240 - }
241 -
242 - if ( function_exists( 'betterdocs_pro' ) ) {
243 - $mkb_layout = get_theme_mod( 'betterdocs_multikb_layout_select' );
244 - if ( empty( $mkb_layout ) ) {
245 - set_theme_mod( 'betterdocs_multikb_layout_select', 'layout-1' );
246 - }
247 - $mkb_faq = get_theme_mod( 'betterdocs_select_faq_template_mkb' );
248 - if ( empty( $mkb_faq ) ) {
249 - set_theme_mod( 'betterdocs_select_faq_template_mkb', 'layout-1' );
250 - }
251 262 }
252 263 }
253 264 }