is_active() ) { Robotstxt_Mlp2_Mlp5_Logger::log( 'skipped', 'cleanup', null, null, __( 'MLP2 deactivation: plugin is already inactive.', 'robotstxt-mlp2-mlp5' ) ); return 'skipped'; } if ( ! function_exists( 'deactivate_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } deactivate_plugins( $mlp2->get_plugin_file(), true ); Robotstxt_Mlp2_Mlp5_Logger::log( 'success', 'cleanup', null, null, __( 'MLP2 plugin deactivated network-wide.', 'robotstxt-mlp2-mlp5' ) ); return 'success'; } /** * Drop all MLP2 backup tables ({prefix}mlp2bak_*). * * Each table drop is logged individually. * * @return array { @type int $dropped, @type int $errors } */ public static function drop_backup_tables(): array { global $wpdb; $tables = Robotstxt_Mlp2_Mlp5_Table_Preparer::get_backup_tables(); $dropped = 0; $errors = 0; foreach ( $tables as $table ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.InterpolatedNotPrepared $result = $wpdb->query( "DROP TABLE IF EXISTS `{$table}`" ); if ( false === $result ) { Robotstxt_Mlp2_Mlp5_Logger::log( 'error', 'cleanup', null, null, sprintf( /* translators: %s: table name */ __( 'Failed to drop backup table: %s', 'robotstxt-mlp2-mlp5' ), $table ) ); ++$errors; } else { Robotstxt_Mlp2_Mlp5_Logger::log( 'success', 'cleanup', null, null, sprintf( /* translators: %s: table name */ __( 'Backup table dropped: %s', 'robotstxt-mlp2-mlp5' ), $table ) ); ++$dropped; } } return array( 'dropped' => $dropped, 'errors' => $errors, ); } /** * Delete MLP2-related entries from wp_sitemeta. * * Removes all sitemeta keys whose name starts with 'mlp_' (MLP2 prefix). * * @return int Number of keys deleted. */ public static function remove_mlp2_sitemeta(): int { global $wpdb; $like = $wpdb->esc_like( 'mlp_' ) . '%'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $keys = $wpdb->get_col( $wpdb->prepare( "SELECT meta_key FROM {$wpdb->sitemeta} WHERE meta_key LIKE %s AND site_id = %d", $like, get_current_network_id() ) ); $deleted = 0; foreach ( (array) $keys as $key ) { if ( delete_site_option( $key ) ) { ++$deleted; } } Robotstxt_Mlp2_Mlp5_Logger::log( 'success', 'cleanup', null, null, sprintf( /* translators: %d: key count */ __( 'Removed %d MLP2 sitemeta entries.', 'robotstxt-mlp2-mlp5' ), $deleted ) ); return $deleted; } /** * Render the Step 6 UI. */ public static function render(): void { $backup_tables = Robotstxt_Mlp2_Mlp5_Table_Preparer::get_backup_tables(); $mlp2 = new Robotstxt_Mlp2_Mlp5_Detector_Mlp2(); ?>