PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 3.5.3
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v3.5.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 3.5.0 3.5.1 All 200 releases
← All changes | includes/Core/Migration.php +83 -133 4.5.63.5.3 View file →
@@ -1,12 +1,8 @@
1 1 <?php
2 -// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange -- one-shot data/schema migrations; caching unwanted.
2 +
3 3 namespace WPDeveloper\BetterDocs\Core;
4 4
5 -if ( ! defined( 'ABSPATH' ) ) {
6 - exit;
7 -}
8 -
9 5 use WP_Query;
10 6 use WPDeveloper\BetterDocs\Utils\Base;
11 7 use WPDeveloper\BetterDocs\Utils\Database;
12 8 use WPDeveloper\BetterDocs\Dependencies\DI\Container;
@@ -11,149 +7,103 @@
11 7 use WPDeveloper\BetterDocs\Utils\Database;
12 8 use WPDeveloper\BetterDocs\Dependencies\DI\Container;
13 9
14 10 class Migration extends Base {
15 - /**
16 - * Database
17 - * @var Database
18 - */
19 - private $database;
20 - private $settings;
21 - private $container;
11 + /**
12 + * Database
13 + * @var Database
14 + */
15 + private $database;
16 + private $settings;
17 + private $container;
22 18
23 - public function __construct( Container $container ) {
24 - $this->container = $container;
25 - $this->database = $container->get( Database::class );
26 - $this->settings = $container->get( Settings::class );
27 - }
19 + public function __construct( Container $container ) {
20 + $this->container = $container;
21 + $this->database = $container->get( Database::class );
22 + $this->settings = $container->get( Settings::class );
23 + }
28 24
29 - public function init( $version ) {
30 - if ( $version > 250 ) {
31 - for ( $_version = 250; $_version <= $version; $_version++ ) {
32 - if ( method_exists( $this, "v$_version" ) ) {
33 - call_user_func( [ $this, "v$_version" ] );
34 - }
35 - }
36 - }
25 + public function init( $version ) {
26 + if( $version > 250 ) {
27 + for( $_version = 250; $_version <= $version; $_version++ ) {
28 + if( method_exists( $this, "v$_version") ) {
29 + call_user_func([$this, "v$_version"]);
30 + }
31 + }
32 + }
37 33
38 - $this->search_migration();
39 - $this->fix_search_table_collation();
34 + $this->search_migration();
40 35
41 - /**
42 - * Settings Migration
43 - */
44 - $this->settings->migration( $version );
45 - }
36 + /**
37 + * Settings Migration
38 + */
39 + $this->settings->migration( $version );
40 + }
46 41
47 - public function search_migration() {
48 - global $wpdb;
49 - if ( ! $this->database->get( 'betterdocs_search_data_migration', false ) ) {
50 - $search_data = $this->database->get( 'betterdocs_search_data' );
51 - if ( ! empty( $search_data ) ) {
52 - $search_data_arr = unserialize( $search_data );
53 - foreach ( $search_data_arr as $key => $value ) {
54 - $args = [
55 - 'post_type' => 'docs',
56 - 'post_status' => 'publish',
57 - 'posts_per_page' => -1,
58 - 'suppress_filters' => true, // phpcs:ignore WordPressVIPMinimum.Hooks.PreGetPosts.PreGetPosts,WordPressVIPMinimum.Performance.WPQueryParams.SuppressFilters_suppress_filters -- migration must run on raw posts without language filters.
59 - 's' => $key
60 - ];
42 + public function search_migration() {
43 + global $wpdb;
44 + if ( ! $this->database->get( 'betterdocs_search_data_migration', false ) ) {
45 + $search_data = $this->database->get( 'betterdocs_search_data' );
46 + if ( ! empty( $search_data ) ) {
47 + $search_data_arr = unserialize( $search_data );
48 + foreach ( $search_data_arr as $key => $value ) {
49 + $args = [
50 + 'post_type' => 'docs',
51 + 'post_status' => 'publish',
52 + 'posts_per_page' => -1,
53 + 'suppress_filters' => true,
54 + 's' => $key
55 + ];
61 56
62 - $loop = new WP_Query( $args );
63 - if ( $loop->have_posts() ) {
64 - $count = $value;
65 - $not_found_count = 0;
66 - } else {
67 - $count = 0;
68 - $not_found_count = $value;
69 - }
57 + $loop = new WP_Query( $args );
58 + if ( $loop->have_posts() ) {
59 + $count = $value;
60 + $not_found_count = 0;
61 + } else {
62 + $count = 0;
63 + $not_found_count = $value;
64 + }
70 65
71 - // Use BINARY comparison to avoid collation mismatch errors
72 - $keyword = $wpdb->get_var(
73 - $wpdb->prepare(
74 - "
66 + $keyword = $wpdb->get_var(
67 + $wpdb->prepare( "
75 68 SELECT keyword
76 69 FROM {$wpdb->prefix}betterdocs_search_keyword
77 - WHERE BINARY keyword = %s",
78 - $key
79 - )
80 - );
70 + WHERE keyword = %s",
71 + $key
72 + )
73 + );
81 74
82 - if ( $keyword == null ) {
83 - $insert = $wpdb->query(
84 - $wpdb->prepare(
85 - "INSERT INTO {$wpdb->prefix}betterdocs_search_keyword
75 + if ( $keyword == NUll ) {
76 + $insert = $wpdb->query(
77 + $wpdb->prepare(
78 + "INSERT INTO {$wpdb->prefix}betterdocs_search_keyword
86 79 ( keyword )
87 80 VALUES ( %s )",
88 - [
89 - $key
90 - ]
91 - )
92 - );
81 + [
82 + $key
83 + ]
84 + )
85 + );
93 86
94 - if ( $insert ) {
95 - $wpdb->query(
96 - $wpdb->prepare(
97 - "INSERT INTO {$wpdb->prefix}betterdocs_search_log
87 + if ( $insert ) {
88 + $wpdb->query(
89 + $wpdb->prepare(
90 + "INSERT INTO {$wpdb->prefix}betterdocs_search_log
98 91 (keyword_id, count, not_found_count, created_at)
99 92 VALUES (%d, %d, %d, %s)",
100 - [
101 - $wpdb->insert_id,
102 - $count,
103 - $not_found_count,
104 - gmdate( 'Y-m-d' )
105 - ]
106 - )
107 - );
108 - }
109 - }
110 - }
93 + [
94 + $wpdb->insert_id,
95 + $count,
96 + $not_found_count,
97 + date( 'Y-m-d' )
98 + ]
99 + )
100 + );
101 + }
102 + }
103 + }
111 104
112 - $this->database->save( 'betterdocs_search_data_migration', '1.0' );
113 - }
114 - }
115 - }
116 -
117 - /**
118 - * Fix collation issues in search tables
119 - * Converts tables to proper UTF-8 charset and collation to prevent
120 - * "Illegal mix of collations" errors when searching with non-Latin characters
121 - *
122 - * @since 1.0.2
123 - * @return void
124 - */
125 - public function fix_search_table_collation() {
126 - global $wpdb;
127 -
128 - // Check if migration already ran
129 - if ( $this->database->get( 'betterdocs_search_collation_fixed', false ) ) {
130 - return;
131 - }
132 -
133 - // Get the WordPress default charset and collation; restrict to a safe identifier
134 - // alphabet because they're interpolated into ALTER TABLE statements below.
135 - $charset = preg_replace( '/[^A-Za-z0-9_]/', '', $wpdb->charset ? $wpdb->charset : 'utf8mb4' );
136 - $collate = preg_replace( '/[^A-Za-z0-9_]/', '', $wpdb->collate ? $wpdb->collate : 'utf8mb4_unicode_520_ci' );
137 -
138 - // Fix search_keyword table
139 - $search_keyword_table = $wpdb->prefix . 'betterdocs_search_keyword';
140 - // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange -- one-shot collation migration; identifiers come from $wpdb only.
141 - if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $search_keyword_table ) ) === $search_keyword_table ) {
142 - // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange,PluginCheck.Security.DirectDB.UnescapedDBParameter
143 - $wpdb->query( "ALTER TABLE `{$search_keyword_table}` CONVERT TO CHARACTER SET {$charset} COLLATE {$collate}" );
144 - // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange,PluginCheck.Security.DirectDB.UnescapedDBParameter
145 - $wpdb->query( "ALTER TABLE `{$search_keyword_table}` MODIFY keyword TEXT CHARACTER SET {$charset} COLLATE {$collate} NOT NULL" );
146 - }
147 -
148 - // Fix search_log table
149 - $search_log_table = $wpdb->prefix . 'betterdocs_search_log';
150 - // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
151 - if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $search_log_table ) ) === $search_log_table ) {
152 - // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange,PluginCheck.Security.DirectDB.UnescapedDBParameter
153 - $wpdb->query( "ALTER TABLE `{$search_log_table}` CONVERT TO CHARACTER SET {$charset} COLLATE {$collate}" );
154 - }
155 -
156 - // Mark migration as complete
157 - $this->database->save( 'betterdocs_search_collation_fixed', '1.0' );
158 - }
105 + $this->database->save( 'betterdocs_search_data_migration', '1.0' );
106 + }
107 + }
108 + }
159 109 }