PluginProbe
WP Synchro – The Ultimate WordPress Migration Tool / trunk
WP Synchro – The Ultimate WordPress Migration Tool vtrunk
1.16.1 1.16.0 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.1.0 1.10.0 1.11.0 1.11.1 1.11.2 1.11.3 1.11.4 1.11.5 1.12.0 1.13.0 1.14.0 1.15.0 1.2.0 1.3.0 1.3.1 1.3.2 All 45 releases
wpsynchro / src / Database / DatabaseHelperFunctions.php

DatabaseHelperFunctions.php in WP Synchro – The Ultimate WordPress Migration Tool trunk, at src/Database/DatabaseHelperFunctions.php

191 lines 7.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPSynchro\Database;
4
5 /**
6 * Database helper functions
7 */
8 class DatabaseHelperFunctions
9 {
10 public function databaseContainsTablesWithDifferentPrefix(): bool
11 {
12 global $wpdb;
13 $current_prefix = $wpdb->prefix;
14
15 $tablelist = $wpdb->get_results("SHOW TABLES");
16
17 $contains_different_prefix = false;
18 foreach ($tablelist as $table) {
19 $table_name = array_values((array)$table)[0];
20 if (substr($table_name, 0, strlen($current_prefix)) != $current_prefix) {
21 $contains_different_prefix = true;
22 }
23 }
24 return $contains_different_prefix;
25 }
26
27
28 /**
29 * Handle table prefix name changes, if needed
30 */
31 public static function handleTablePrefixChange($table_name, $source_prefix, $target_prefix)
32 {
33
34 // Check if we need to change prefixes
35 if ($source_prefix != $target_prefix) {
36 if (substr($table_name, 0, strlen($source_prefix)) == $source_prefix) {
37 $table_name = substr($table_name, strlen($source_prefix));
38 $table_name = $target_prefix . $table_name;
39 }
40 }
41 return $table_name;
42 }
43
44 /**
45 * Check if specific table is being moved, by search for table name ends with X
46 */
47 public static function isTableBeingTransferred($tablelist, $table_prefix, $table_ends_with)
48 {
49 foreach ($tablelist as $table) {
50 $tablename_with_prefix = str_replace($table_prefix, "", $table->name);
51 if ($tablename_with_prefix === $table_ends_with) {
52 return true;
53 }
54 }
55 return false;
56 }
57
58 /**
59 * Get last db query error
60 */
61 public function getLastDBQueryErrors()
62 {
63 global $wpdb;
64 $log_errors = [];
65 $user_errors = [];
66
67 // Check what error we have
68 $base_error = sprintf(
69 __('Migration aborted, due to a SQL query failing. See WP Synchro log (found in menu "Logs") for specific information about the query that failed. The specific error from database server was: "%s".', 'wpsynchro'),
70 $wpdb->last_error
71 );
72 if (strpos($wpdb->last_error, 'Specified key was too long') !== false) {
73 // Too long key
74 $user_errors[] = $base_error . " " . __('That means that the key was longer than supported on the target database. The table need to be fixed or excluded from migration. See documentation for further help.', 'wpsynchro');
75 } elseif (strpos($wpdb->last_error, 'Unknown collation') !== false) {
76 // Not supported collation/charset
77 $user_errors[] = $base_error . " " . __('That means that the charset/collation used is not supported by the target database engine. The table charset/collations needs to be changed into a supported charset/collation for the target database or excluded from migration. See documentation for further help.', 'wpsynchro');
78 } elseif (strpos($wpdb->last_query, 'CREATE VIEW') === 0) {
79 // Could not create view. Typically, because the required other tables are not there
80 $user_errors[] = $base_error . " " . __('The error was caused by trying to create a view in the database. The error is normally thrown from the database server, when the view references tables that do not exist on the target database, so make sure they are there.', 'wpsynchro');
81 } else {
82 // General error message
83 $user_errors[] = $base_error . " " . __('If you need help, contact WP Synchro support.', 'wpsynchro');
84 }
85
86 // Logging for log files
87 $log_errors[] = "SQL query failed execution: " . $wpdb->last_query;
88 $log_errors[] = "WPDB last error: " . $wpdb->last_error;
89
90 return [
91 'log_errors' => $log_errors,
92 'user_errors' => $user_errors,
93 ];
94 }
95
96 /**
97 * Get data from local DB, with a certain primary key and max response size
98 */
99 public function getDataFromDB($table, $column_names, $primary_key_column, $last_primary_key, $completed_rows, $max_response_size, $default_rows_per_request, $time_limit_in_seconds)
100 {
101 global $wpdb;
102 $data = [];
103 $has_more_rows_in_table = true;
104 $errors = [];
105 $current_response_size = 0;
106 $is_using_primary_key = strlen($primary_key_column) > 0;
107 $start_time = microtime(true);
108
109 while ($current_response_size < $max_response_size) {
110 $rows_to_fetch = $default_rows_per_request;
111
112 if ($is_using_primary_key) {
113 $sql_stmt = $wpdb->prepare(
114 "SELECT * FROM `$table` WHERE `$primary_key_column` > %s ORDER BY `$primary_key_column` ASC LIMIT %d",
115 $last_primary_key,
116 $rows_to_fetch
117 );
118 } else {
119 $sql_stmt = "SELECT * FROM `$table` LIMIT $completed_rows, $rows_to_fetch";
120 }
121
122 $sql_result = $wpdb->get_results($sql_stmt);
123
124 if (!empty($wpdb->last_error)) {
125 $errors[] = $wpdb->last_error;
126 $wpdb->last_error = '';
127 }
128
129 if (empty($sql_result)) {
130 $has_more_rows_in_table = false;
131 break;
132 }
133
134 foreach ($sql_result as $data_row) {
135 // Estimate row size in PHP
136 $row_size = 0;
137 foreach ($column_names as $col) {
138 if (isset($data_row->$col) && $data_row->$col !== null) {
139 $row_size += strlen((string)$data_row->$col);
140 }
141 }
142
143 // Always include the first row, even if it exceeds the max_response_size
144 if (empty($data)) {
145 $current_response_size += $row_size;
146 if ($is_using_primary_key) {
147 $last_primary_key = $data_row->$primary_key_column;
148 } else {
149 $completed_rows += 1;
150 }
151 $data[] = $data_row;
152 continue;
153 }
154
155 // For subsequent rows, check if adding would exceed the max_response_size
156 if ($current_response_size + $row_size > $max_response_size) {
157 $has_more_rows_in_table = true;
158 break 2; // Stop fetching more rows
159 }
160
161 $current_response_size += $row_size;
162
163 if ($is_using_primary_key) {
164 $last_primary_key = $data_row->$primary_key_column;
165 } else {
166 $completed_rows += 1;
167 }
168
169 $data[] = $data_row;
170 }
171
172 // Check time limit
173 if ((microtime(true) - $start_time) > $time_limit_in_seconds) {
174 break;
175 }
176
177 // If less than requested rows returned, no more data
178 if (count($sql_result) < $rows_to_fetch) {
179 $has_more_rows_in_table = false;
180 break;
181 }
182 }
183
184 return (object) [
185 'data' => $data,
186 'has_more_rows_in_table' => $has_more_rows_in_table,
187 'errors' => $errors
188 ];
189 }
190 }
191