PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.0.12
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.0.12
6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 5.2.2 5.3 All 153 releases
mainwp / class / class-mainwp-install.php

class-mainwp-install.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 6.0.12, at class/class-mainwp-install.php

714 lines 27.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MainWP Install
4 *
5 * This file handles install MainWP DB.
6 *
7 * @package MainWP/Dashboard
8 */
9
10 namespace MainWP\Dashboard;
11
12 // Exit if accessed directly.
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17
18 /**
19 * Class MainWP_Install
20 *
21 * @package MainWP\Dashboard
22 *
23 * @uses \MainWP\Dashboard\MainWP_DB_Base
24 */
25 class MainWP_Install extends MainWP_DB_Base { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
26
27 // phpcs:disable WordPress.DB.RestrictedFunctions, WordPress.DB.PreparedSQL.NotPrepared -- unprepared SQL ok, accessing the database directly to custom database functions.
28
29 /**
30 * Private variable to hold the database version info.
31 *
32 * @var string DB version info.
33 */
34 protected $mainwp_db_version = '9.0.1.4'; // NOSONAR - no IP.
35
36 /**
37 * Protected variable to hold the database option name.
38 *
39 * @var string DB version info.
40 */
41 protected $option_db_key = 'mainwp_db_version';
42
43 /**
44 * Private static variable to hold the single instance of the class.
45 *
46 * @static
47 *
48 * @var mixed Default null
49 */
50 private static $instance = null;
51
52 /**
53 * Method instance()
54 *
55 * Return public static instance.
56 *
57 * @static
58 * @return MainWP_DB
59 */
60 public static function instance() {
61 if ( null === static::$instance ) {
62 static::$instance = new self();
63 }
64
65 static::$instance->test_connection();
66
67 return static::$instance;
68 }
69
70 /**
71 * Method install()
72 *
73 * Installs the new DB.
74 *
75 * @return void
76 *
77 * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
78 */
79 public function install() { // phpcs:ignore -- NOSONAR - complex function. Current complexity is the only way to achieve desired results, pull request solutions appreciated.
80 // get_site_option is multisite aware!
81 $currentVersion = get_site_option( $this->option_db_key );
82
83 if ( empty( $currentVersion ) ) {
84 update_option( 'mainwp_run_quick_setup', 'yes' );
85 MainWP_Utility::update_option( 'mainwp_enableLegacyBackupFeature', 0 );
86 } elseif ( false === get_option( 'mainwp_enableLegacyBackupFeature' ) ) {
87 MainWP_Utility::update_option( 'mainwp_enableLegacyBackupFeature', 1 );
88 }
89
90 if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.8', '<' ) ) {
91 MainWP_Utility::update_option( 'mainwp_selected_theme', 'default' );
92 }
93
94 $wp_table = esc_sql( $this->table_name( 'wp' ) );
95 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table name escaped via esc_sql.
96 $rslt = static::instance()->query( "SHOW TABLES LIKE '{$wp_table}'" );
97 if ( empty( static::num_rows( $rslt ) ) ) {
98 $currentVersion = false;
99 }
100
101 if ( $currentVersion === $this->mainwp_db_version ) {
102 return;
103 }
104
105 $this->pre_update_tables();
106
107 $charset_collate = $this->wpdb->get_charset_collate();
108
109 $sql = array();
110 $tbl = 'CREATE TABLE ' . $this->table_name( 'wp' ) . " (
111 id int(11) NOT NULL auto_increment,
112 userid int(11) NOT NULL,
113 adminname text NOT NULL,
114 name text NOT NULL,
115 url text NOT NULL,
116 pubkey text NOT NULL,
117 privkey text NOT NULL,
118 siteurl text NOT NULL,
119 ga_id text NOT NULL,
120 gas_id int(11) NOT NULL,
121 offline_checks_last int(11) NOT NULL,
122 offline_check_result int(11) NOT NULL,
123 http_response_code int(11) NOT NULL DEFAULT 0,
124 http_code_noticed tinyint(1) NOT NULL DEFAULT 1,
125 disable_health_check tinyint(1) NOT NULL DEFAULT 0,
126 health_threshold int(11) NOT NULL DEFAULT 0,
127 note text NOT NULL,
128 statsUpdate int(11) NOT NULL,
129 directories longtext NOT NULL,
130 plugin_upgrades longtext NOT NULL,
131 theme_upgrades longtext NOT NULL,
132 translation_upgrades longtext NOT NULL,
133 premium_upgrades longtext NOT NULL,
134 securityIssues longtext NOT NULL,
135 themes longtext NOT NULL,
136 ignored_themes longtext NOT NULL,
137 plugins longtext NOT NULL,
138 ignored_plugins longtext NOT NULL,
139 users longtext NOT NULL,
140 categories longtext NOT NULL,
141 pluginDir text NOT NULL,
142 automatic_update tinyint(1) NOT NULL,
143 backup_before_upgrade tinyint(1) NOT NULL DEFAULT 2,
144 mainwpdir tinyint(1) NOT NULL,
145 loadFilesBeforeZip tinyint(1) NOT NULL DEFAULT 1,
146 is_ignoreCoreUpdates tinyint(1) NOT NULL DEFAULT 0,
147 is_ignorePluginUpdates tinyint(1) NOT NULL DEFAULT 0,
148 is_ignoreThemeUpdates tinyint(1) NOT NULL DEFAULT 0,
149 verify_certificate tinyint(1) NOT NULL DEFAULT 1,
150 force_use_ipv4 tinyint(1) NOT NULL DEFAULT 0,
151 ssl_version tinyint(1) NOT NULL DEFAULT 0,
152 ip text NOT NULL DEFAULT '',
153 uniqueId text NOT NULL,
154 maximumFileDescriptorsOverride tinyint(1) NOT NULL DEFAULT 0,
155 maximumFileDescriptorsAuto tinyint(1) NOT NULL DEFAULT 1,
156 maximumFileDescriptors int(11) NOT NULL DEFAULT 150,
157 primary_backup_method varchar(64) NOT NULL DEFAULT '',
158 http_user text NOT NULL DEFAULT '',
159 http_pass text NOT NULL DEFAULT '',
160 wpe tinyint(1) NOT NULL,
161 is_staging tinyint(1) NOT NULL DEFAULT 0,
162 client_id int(11) NOT NULL DEFAULT 0,
163 `suspended` tinyint(1) NOT NULL DEFAULT 0,
164 KEY idx_wp_staging_name_id (is_staging, name(191), id),
165 KEY idx_userid (userid),
166 KEY idx_client_id (client_id),
167 KEY idx_url (url(191))";
168
169 if ( empty( $currentVersion ) ) {
170 $tbl .= ',
171 PRIMARY KEY (id) ';
172 }
173 $tbl .= ') ' . $charset_collate;
174 $sql[] = $tbl;
175
176 $tbl = 'CREATE TABLE ' . $this->table_name( 'wp_sync' ) . " (
177 sync_id int(11) NOT NULL auto_increment,
178 wpid int(11) NOT NULL,
179 version text NOT NULL DEFAULT '',
180 sync_errors longtext NOT NULL DEFAULT '',
181 uptodate longtext NOT NULL DEFAULT '',
182 dtsAutomaticSync int(11) NOT NULL DEFAULT 0,
183 dtsAutomaticSyncStart int(11) NOT NULL DEFAULT 0,
184 dtsSync int(11) NOT NULL DEFAULT 0,
185 dtsSyncStart int(11) NOT NULL DEFAULT 0,
186 totalsize int(11) NOT NULL DEFAULT 0,
187 dbsize int(11) NOT NULL DEFAULT 0,
188 extauth text NOT NULL DEFAULT '',
189 last_post_gmt int(11) NOT NULL DEFAULT 0,
190 health_value int(11) NOT NULL DEFAULT 0,
191 health_status tinyint(1) NOT NULL DEFAULT 0,
192 health_site_noticed tinyint(1) NOT NULL DEFAULT 1,
193 KEY idx_wpid (wpid)";
194
195 if ( empty( $currentVersion ) ) {
196 $tbl .= ',
197 PRIMARY KEY (sync_id)';
198 }
199
200 $tbl .= ') ' . $charset_collate;
201
202 $sql[] = $tbl;
203
204 $tbl = 'CREATE TABLE ' . $this->table_name( 'wp_options' ) . " (
205 opt_id int(11) NOT NULL auto_increment,
206 wpid int(11) NOT NULL,
207 name text NOT NULL DEFAULT '',
208 value longtext NOT NULL DEFAULT '',
209 KEY idx_options_wpid_name (wpid, name(191)),
210 KEY idx_wpid (wpid)";
211
212 if ( empty( $currentVersion ) ) {
213 $tbl .= ',
214 PRIMARY KEY (opt_id)';
215 }
216 $tbl .= ') ' . $charset_collate;
217 $sql[] = $tbl;
218
219 $tbl = 'CREATE TABLE ' . $this->table_name( 'wp_settings_backup' ) . ' (
220 set_id int(11) NOT NULL auto_increment,
221 wpid int(11) NOT NULL,
222 archiveFormat text NOT NULL,
223 KEY idx_wpid (wpid)';
224
225 if ( empty( $currentVersion ) ) {
226 $tbl .= ',
227 PRIMARY KEY (set_id)';
228 }
229 $tbl .= ') ' . $charset_collate;
230 $sql[] = $tbl;
231
232 $tbl = 'CREATE TABLE ' . $this->table_name( 'users' ) . " (
233 userid int(11) NOT NULL,
234 user_email text NOT NULL DEFAULT '',
235 ignored_plugins longtext NOT NULL DEFAULT '',
236 trusted_plugins longtext NOT NULL DEFAULT '',
237 trusted_plugins_notes longtext NOT NULL DEFAULT '',
238 ignored_themes longtext NOT NULL DEFAULT '',
239 ignored_wp_upgrades longtext NOT NULL DEFAULT '',
240 trusted_themes longtext NOT NULL DEFAULT '',
241 trusted_themes_notes longtext NOT NULL DEFAULT '',
242 site_view tinyint(1) NOT NULL DEFAULT '0',
243 pluginDir text NOT NULL DEFAULT '',
244 dismissed_plugins longtext NOT NULL DEFAULT '',
245 dismissed_themes longtext NOT NULL DEFAULT ''";
246 if ( empty( $currentVersion ) ) {
247 $tbl .= ',
248 PRIMARY KEY (userid) ';
249 }
250 $tbl .= ') ' . $charset_collate;
251 $sql[] = $tbl;
252
253 $tbl = 'CREATE TABLE ' . $this->table_name( 'wp_status' ) . ' (
254 statusid bigint(20) unsigned NOT NULL auto_increment,
255 wpid int(11) NOT NULL,
256 http_code smallint NOT NULL DEFAULT 0,
257 status tinyint(1) NOT NULL DEFAULT 0,
258 event_timestamp int(11) NOT NULL,
259 duration int(11) NOT NULL DEFAULT 0';
260 if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.31', '<=' ) ) {
261 $tbl .= ',
262 PRIMARY KEY (statusid) ';
263 }
264 $tbl .= ') ' . $charset_collate;
265 $sql[] = $tbl;
266
267 $tbl = 'CREATE TABLE ' . $this->table_name( 'group' ) . ' (
268 id int(11) NOT NULL auto_increment,
269 userid int(11) NOT NULL,
270 name text NOT NULL,
271 color varchar(32) NOT NULL DEFAULT ""';
272 if ( empty( $currentVersion ) ) {
273 $tbl .= ',
274 PRIMARY KEY (id) ';
275 }
276 $tbl .= ') ' . $charset_collate;
277 $sql[] = $tbl;
278
279 $tbl = 'CREATE TABLE ' . $this->table_name( 'wp_group' ) . ' (
280 wp_group_id int(11) NOT NULL auto_increment,
281 wpid int(11) NOT NULL,
282 groupid int(11) NOT NULL,
283 KEY idx_wpid (wpid),
284 KEY idx_groupid (groupid)';
285 if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.57', '<=' ) ) {
286 $tbl .= ',
287 PRIMARY KEY (wp_group_id) ';
288 }
289 $tbl .= ') ' . $charset_collate;
290 $sql[] = $tbl;
291
292 $tbl = 'CREATE TABLE ' . $this->table_name( 'lookup_item_objects' ) . ' (
293 lookup_id bigint(20) unsigned NOT NULL auto_increment,
294 item_id bigint(20) unsigned NOT NULL,
295 item_name varchar(32) NOT NULL,
296 object_id bigint(20) unsigned NOT NULL,
297 object_name varchar(32) NOT NULL,
298 KEY item_id (item_id),
299 KEY object_id (object_id)';
300
301 if ( empty( $currentVersion ) || version_compare( $currentVersion, '9.0.0.5', '<' ) ) { // NOSONAR - none IP.
302 $tbl .= ',
303 PRIMARY KEY (lookup_id) ';
304 }
305 $tbl .= ') ' . $charset_collate . ';';
306 $sql[] = $tbl;
307
308 $tbl = 'CREATE TABLE ' . $this->table_name( 'wp_backup_progress' ) . " (
309 task_id int(11) NOT NULL,
310 wp_id int(11) NOT NULL,
311 dtsFetched int(11) NOT NULL DEFAULT 0,
312 fetchResult text NOT NULL DEFAULT '',
313 downloadedDB text NOT NULL DEFAULT '',
314 downloadedFULL text NOT NULL DEFAULT '',
315 downloadedDBComplete tinyint(1) NOT NULL DEFAULT 0,
316 downloadedFULLComplete tinyint(1) NOT NULL DEFAULT 0,
317 removedFiles tinyint(1) NOT NULL DEFAULT 0,
318 attempts int(11) NOT NULL DEFAULT 0,
319 last_error text NOT NULL DEFAULT '',
320 pid int(11) NOT NULL DEFAULT 0,
321 KEY idx_task_id (task_id)";
322 if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.53', '<=' ) ) {
323 $tbl .= ',
324 UNIQUE (task_id)';
325 }
326 $tbl .= ') ' . $charset_collate;
327 $sql[] = $tbl;
328
329 $tbl = 'CREATE TABLE ' . $this->table_name( 'wp_backup' ) . ' (
330 id int(11) NOT NULL auto_increment,
331 userid int(11) NOT NULL,
332 name text NOT NULL,
333 schedule text NOT NULL,
334 type text NOT NULL,
335 exclude text NOT NULL,
336 sites text NOT NULL,
337 `groups` text NOT NULL,
338 last int(11) NOT NULL,
339 last_run int(11) NOT NULL,
340 lastStartNotificationSent int(11) NOT NULL DEFAULT 0,
341 last_run_manually int(11) NOT NULL,
342 completed_sites text NOT NULL,
343 completed int(11) NOT NULL,
344 backup_errors text NOT NULL,
345 subfolder text NOT NULL,
346 filename text NOT NULL,
347 paused tinyint(1) NOT NULL,
348 template tinyint(1) DEFAULT 0,
349 excludebackup tinyint(1) DEFAULT 0,
350 excludecache tinyint(1) DEFAULT 0,
351 excludenonwp tinyint(1) DEFAULT 0,
352 excludezip tinyint(1) DEFAULT 0,
353 archiveFormat text NOT NULL,
354 loadFilesBeforeZip tinyint(1) NOT NULL DEFAULT 1,
355 maximumFileDescriptorsOverride tinyint(1) NOT NULL DEFAULT 0,
356 maximumFileDescriptorsAuto tinyint(1) NOT NULL DEFAULT 1,
357 maximumFileDescriptors int(11) NOT NULL DEFAULT 150';
358 if ( empty( $currentVersion ) ) {
359 $tbl .= ',
360 PRIMARY KEY (id) ';
361 }
362 $tbl .= ') ' . $charset_collate;
363 $sql[] = $tbl;
364
365 $tbl = 'CREATE TABLE ' . $this->table_name( 'api_keys' ) . ' (
366 key_id bigint(20) unsigned NOT NULL auto_increment,
367 user_id bigint(20) unsigned NOT NULL,
368 description varchar(200) NULL,
369 permissions varchar(10) NOT NULL,
370 consumer_key char(64) NOT NULL,
371 consumer_secret char(43) NOT NULL,
372 nonces longtext NULL,
373 truncated_key char(7) NOT NULL,
374 key_pass char(64) NOT NULL DEFAULT "",
375 key_type tinyint(1) NOT NULL DEFAULT 0,
376 `enabled` tinyint(1) DEFAULT 0,
377 last_access datetime NULL default null,
378 KEY consumer_key (consumer_key),
379 KEY consumer_secret (consumer_secret)';
380 if ( empty( $currentVersion ) || version_compare( $currentVersion, '9.0.0.9', '<=' ) ) { // NOSONAR - none IP.
381 $tbl .= ',
382 PRIMARY KEY (key_id) ';
383 }
384 $tbl .= ') ' . $charset_collate . ';';
385 $sql[] = $tbl;
386
387 $tbl = 'CREATE TABLE ' . $this->table_name( 'action_log' ) . " (
388 id int(11) NOT NULL auto_increment,
389 log_content mediumtext NOT NULL DEFAULT '',
390 log_type tinyint(1) DEFAULT 0,
391 log_color tinyint(1) DEFAULT 0,
392 log_user varchar(128) NOT NULL DEFAULT '',
393 log_timestamp int(11) NOT NULL DEFAULT 0";
394 if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.50', '<=' ) ) {
395 $tbl .= ',
396 PRIMARY KEY (id) ';
397 }
398 $tbl .= ') ' . $charset_collate . ';';
399 $sql[] = $tbl;
400
401 $tbl = 'CREATE TABLE ' . $this->table_name( 'request_log' ) . " (
402 id int(11) NOT NULL auto_increment,
403 wpid int(11) NOT NULL,
404 ip text NOT NULL DEFAULT '',
405 subnet text NOT NULL DEFAULT '',
406 micro_timestamp_stop DECIMAL( 12, 2 ) NOT NULL DEFAULT 0,
407 micro_timestamp_start DECIMAL( 12, 2 ) NOT NULL DEFAULT 0";
408 if ( empty( $currentVersion ) || version_compare( $currentVersion, '5.7', '<=' ) ) {
409 $tbl .= ',
410 PRIMARY KEY (id) ';
411 }
412 $tbl .= ') ' . $charset_collate . ';';
413 $sql[] = $tbl;
414
415 $tbl = 'CREATE TABLE ' . $this->table_name( 'schedule_processes' ) . " (
416 process_id int(11) NOT NULL auto_increment,
417 item_id int(11) NOT NULL,
418 `type` varchar(32) NOT NULL,
419 `process_slug` varchar(64) NOT NULL,
420 `status` varchar(32) NOT NULL DEFAULT '',
421 dts_process_start int(11) NOT NULL DEFAULT 0,
422 dts_process_init_time int(11) NOT NULL DEFAULT 0,
423 dts_process_stop int(11) NOT NULL DEFAULT 0";
424
425 if ( empty( $currentVersion ) || version_compare( $currentVersion, '9.0.0.45', '<' ) ) { //phpcs:ignore -- NOSONAR - no ip.
426 $tbl .= ',
427 PRIMARY KEY (process_id) ';
428 }
429
430 $tbl .= ') ' . $charset_collate . ';';
431 $sql[] = $tbl;
432
433 // End of tables.
434
435 $sql = apply_filters( 'mainwp_db_install_tables', $sql, $currentVersion, $charset_collate );
436
437 MainWP_DB_Uptime_Monitoring::instance()->get_db_schema( $sql, $currentVersion );
438
439 require_once ABSPATH . 'wp-admin/includes/upgrade.php'; // NOSONAR - WP compatible.
440
441 global $wpdb;
442
443 if ( MainWP_Utility::instance()->is_disabled_functions( 'error_log' ) || ! function_exists( '\error_log' ) ) {
444 error_reporting(0); // phpcs:ignore -- try to disabled the error_log somewhere in WP.
445 }
446
447 $suppress = $wpdb->suppress_errors();
448 foreach ( $sql as $query ) {
449 dbDelta( $query );
450 }
451 $wpdb->suppress_errors( $suppress );
452
453 $this->post_update();
454
455 do_action( 'mainwp_db_after_update', $currentVersion, $this->mainwp_db_version ); // new version: $this->mainwp_db_version.
456
457 if ( ! is_multisite() ) {
458 MainWP_Utility::update_option( $this->option_db_key, $this->mainwp_db_version );
459 } else {
460 update_site_option( $this->option_db_key, $this->mainwp_db_version );
461 }
462 }
463
464 /**
465 * Returns the database version.
466 *
467 * @return string
468 */
469 public function get_db_version() {
470 return get_site_option( $this->option_db_key );
471 }
472
473 /**
474 * Method post_update()
475 *
476 * Update MainWP DB.
477 *
478 * @return void
479 */
480 public function post_update() { // phpcs:ignore -- NOSONAR - complex.
481
482 // get_site_option is multisite aware!
483 $currentVersion = get_site_option( $this->option_db_key );
484
485 if ( false === $currentVersion ) {
486 return;
487 }
488
489 $suppress = $this->wpdb->suppress_errors();
490
491 $this->post_update_81( $currentVersion );
492
493 if ( version_compare( $currentVersion, '8.984', '<' ) ) {
494 $sslColumns = array(
495 'nossl',
496 'nosslkey',
497 );
498 $wp_table = esc_sql( $this->table_name( 'wp' ) );
499 foreach ( $sslColumns as $col ) {
500 $col = esc_sql( $col );
501 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- Column name escaped via esc_sql, table name escaped separately.
502 $this->wpdb->query( "ALTER TABLE {$wp_table} DROP COLUMN {$col}" );
503 }
504 }
505
506 // delete old columns.
507 if ( version_compare( $currentVersion, '8.17', '<' ) ) {
508 $rankColumns = array(
509 'pagerank',
510 'indexed',
511 'alexia',
512 'pagerank_old',
513 'indexed_old',
514 'alexia_old',
515 'last_db_backup_size',
516 );
517
518 foreach ( $rankColumns as $rankColumn ) {
519 $rankColumn = esc_sql( $rankColumn );
520 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- Column name escaped via esc_sql, table name escaped separately.
521 $this->wpdb->query( "ALTER TABLE {$wp_table} DROP COLUMN {$rankColumn}" );
522 }
523
524 $syncColumns = array( 'uptodate' );
525 $wp_sync_table = esc_sql( $this->table_name( 'wp_sync' ) );
526 foreach ( $syncColumns as $column ) {
527 $column = esc_sql( $column );
528 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- Column name escaped via esc_sql, table name escaped separately.
529 $this->wpdb->query( "ALTER TABLE {$wp_sync_table} DROP COLUMN {$column}" );
530 }
531 }
532
533 // delete old columns.
534 if ( version_compare( $currentVersion, '8.35', '<' ) ) {
535 $delColumns = array( 'offline_checks' );
536 foreach ( $delColumns as $column ) {
537 $column = esc_sql( $column );
538 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- Column name escaped via esc_sql, table name escaped separately.
539 $this->wpdb->query( "ALTER TABLE {$wp_table} DROP COLUMN {$column}" );
540 }
541 $delColumns = array( 'heatMap' );
542 $users_table = esc_sql( $this->table_name( 'users' ) );
543 foreach ( $delColumns as $column ) {
544 $column = esc_sql( $column );
545 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- Column name escaped via esc_sql, table name escaped separately.
546 $this->wpdb->query( "ALTER TABLE {$users_table} DROP COLUMN {$column}" );
547 }
548 }
549
550 // delete columns.
551 if ( version_compare( $currentVersion, '8.42', '<' ) ) {
552 $delColumns = array( 'offlineChecksOnlineNotification' );
553 foreach ( $delColumns as $column ) {
554 $column = esc_sql( $column );
555 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- Column name escaped via esc_sql, table name escaped separately.
556 $this->wpdb->query( "ALTER TABLE {$users_table} DROP COLUMN {$column}" );
557 }
558 }
559
560 // fix missing PRIMARY keys.
561 if ( version_compare( $currentVersion, '8.53', '<=' ) ) {
562 $wp_options_table = esc_sql( $this->table_name( 'wp_options' ) );
563 $wp_settings_backup_table = esc_sql( $this->table_name( 'wp_settings_backup' ) );
564 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table name escaped via esc_sql.
565 $this->wpdb->query( "ALTER TABLE {$wp_options_table} ADD opt_id int NOT NULL AUTO_INCREMENT PRIMARY KEY" );
566 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table name escaped via esc_sql.
567 $this->wpdb->query( "ALTER TABLE {$wp_settings_backup_table} ADD set_id int NOT NULL AUTO_INCREMENT PRIMARY KEY" );
568 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table name escaped via esc_sql.
569 $this->wpdb->query( "ALTER TABLE {$wp_sync_table} ADD sync_id int NOT NULL AUTO_INCREMENT PRIMARY KEY" );
570 }
571
572 $this->update_optimize_indexes_55( $currentVersion );
573
574 $this->wpdb->suppress_errors( $suppress );
575 MainWP_DB_Client::instance()->check_to_updates_reports_data_861( $currentVersion );
576 }
577
578 /**
579 * Handle optimize tables indexes.
580 *
581 * @param string $current_ver Current DB version.
582 *
583 * @return void
584 */
585 public function update_optimize_indexes_55( $current_ver ) {
586 if ( ! empty( $current_ver ) && version_compare( $current_ver, '9.0.1.1', '<' ) ) { // NOSONAR - no ip.
587 $this->wpdb->query( 'ALTER TABLE ' . $this->table_name( 'wp' ) . ' ADD INDEX idx_wp_staging_name_id (is_staging, name(191), id)' ); //phpcs:ignore -- ok.
588 $this->wpdb->query( 'ALTER TABLE ' . $this->table_name( 'wp_options' ) . ' ADD INDEX KEY idx_options_wpid_name (wpid, name(191))' ); //phpcs:ignore -- ok.
589 }
590 if ( ! empty( $current_ver ) && version_compare( $current_ver, '9.0.1.3', '<' ) ) { // NOSONAR - no ip.
591 $this->wpdb->query( 'ALTER TABLE ' . $this->table_name( 'wp' ) . ' ADD INDEX idx_userid (userid)' ); //phpcs:ignore -- ok.
592 $this->wpdb->query( 'ALTER TABLE ' . $this->table_name( 'wp' ) . ' ADD INDEX idx_client_id (client_id)' ); //phpcs:ignore -- ok.
593 $this->wpdb->query( 'ALTER TABLE ' . $this->table_name( 'wp' ) . ' ADD INDEX idx_url (url(191))' ); //phpcs:ignore -- ok.
594 }
595 }
596
597 /**
598 * Method pre_update_tables()
599 *
600 * Handle pre update tables.
601 *
602 * @return void
603 */
604 public function pre_update_tables() {
605 // get_site_option is multisite aware!
606 $currentVersion = get_site_option( $this->option_db_key );
607
608 if ( false === $currentVersion ) {
609 return;
610 }
611
612 $suppress = $this->wpdb->suppress_errors();
613
614 if ( version_compare( $currentVersion, '8.98', '<=' ) ) {
615 $wp_table = esc_sql( $this->table_name( 'wp' ) );
616 $existing_columns = $this->wpdb->get_col( "SHOW COLUMNS FROM {$wp_table}", 0 ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- DDL introspection; table name is a hardcoded internal identifier escaped via esc_sql(), no user input involved.
617 foreach ( array( 'backups', 'note_lastupdate', 'pages' ) as $column ) {
618 if ( in_array( $column, $existing_columns, true ) ) {
619 $this->wpdb->query( 'ALTER TABLE ' . $wp_table . ' DROP COLUMN ' . esc_sql( $column ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- DDL statement; table and column names are hardcoded internal identifiers escaped via esc_sql(), no user input involved.
620 }
621 }
622 }
623
624 $this->wpdb->suppress_errors( $suppress );
625 }
626
627 /**
628 * Method post_update_81()
629 *
630 * Update MainWP DB for version 8.1.
631 *
632 * @param string $current_version Current version DB.
633 *
634 * @return void
635 */
636 public function post_update_81( $current_version ) { //phpcs:ignore -- NOSONAR - complex.
637
638 if ( version_compare( $current_version, '8.1', '<' ) ) {
639
640 // We can't split up here!
641 $wpSyncColumns = array(
642 'version',
643 'totalsize',
644 'dbsize',
645 'extauth',
646 'last_post_gmt',
647 'sync_errors',
648 'dtsSync',
649 'dtsSyncStart',
650 'dtsAutomaticSync',
651 'dtsAutomaticSyncStart',
652 );
653 $wp_table = esc_sql( $this->table_name( 'wp' ) );
654 $wp_sync_table = esc_sql( $this->table_name( 'wp_sync' ) );
655 foreach ( $wpSyncColumns as $wpSyncColumn ) {
656 $wpSyncColumn = esc_sql( $wpSyncColumn );
657 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- Column name escaped via esc_sql, table name escaped separately.
658 $rslts = $this->wpdb->get_results( "SELECT id,{$wpSyncColumn} FROM {$wp_table}", ARRAY_A );
659 if ( empty( $rslts ) ) {
660 continue;
661 }
662
663 foreach ( $rslts as $rslt ) {
664 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table name escaped via esc_sql and query uses proper prepare.
665 $exists = $this->wpdb->get_results( $this->wpdb->prepare( "SELECT wpid FROM {$wp_sync_table} WHERE wpid = %d", $rslt['id'] ), ARRAY_A );
666 if ( empty( $exists ) ) {
667 $this->wpdb->insert(
668 $this->table_name( 'wp_sync' ),
669 array(
670 'wpid' => $rslt['id'],
671 $wpSyncColumn => $rslt[ $wpSyncColumn ],
672 )
673 );
674 } else {
675 $this->wpdb->update( $this->table_name( 'wp_sync' ), array( $wpSyncColumn => $rslt[ $wpSyncColumn ] ), array( 'wpid' => $rslt['id'] ) );
676 }
677 }
678
679 $suppress = $this->wpdb->suppress_errors();
680 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- Column name escaped via esc_sql, table name escaped separately.
681 $this->wpdb->query( "ALTER TABLE {$wp_table} DROP COLUMN {$wpSyncColumn}" );
682 $this->wpdb->suppress_errors( $suppress );
683 }
684
685 $optionColumns = array(
686 'last_wp_upgrades',
687 'last_plugin_upgrades',
688 'last_theme_upgrades',
689 'wp_upgrades',
690 'recent_comments',
691 'recent_posts',
692 'recent_pages',
693 );
694 foreach ( $optionColumns as $optionColumn ) {
695 $optionColumn = esc_sql( $optionColumn );
696 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- Column name escaped via esc_sql, table name escaped separately.
697 $rslts = $this->wpdb->get_results( "SELECT id,{$optionColumn} FROM {$wp_table}", ARRAY_A );
698 if ( empty( $rslts ) ) {
699 continue;
700 }
701
702 foreach ( $rslts as $rslt ) {
703 static::update_website_option( (object) $rslt, $optionColumn, $rslt[ $optionColumn ] );
704 }
705
706 $suppress = $this->wpdb->suppress_errors();
707 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- Column name escaped via esc_sql, table name escaped separately.
708 $this->wpdb->query( "ALTER TABLE {$wp_table} DROP COLUMN {$optionColumn}" );
709 $this->wpdb->suppress_errors( $suppress );
710 }
711 }
712 }
713 }
714