WP Data Optimizer > HPCT Import tab * - CLI: wp wpdo import-hpct */ class TMDO_HPCT_Import { /** Option key that marks import as completed. */ public const IMPORTED_OPTION = 'wpdo_hpct_imported'; /** * Check if HPCT import has already been completed. */ public static function is_imported(): bool { return (bool) get_option( self::IMPORTED_OPTION, false ); } /** * Check if hp-custom-tables is active and has data to import. */ public static function can_import(): bool { if ( self::is_imported() ) { return false; } return TMDO_Compatibility::is_hpct_active(); } /** * Preview: return what will be imported without actually doing it. * * @return array{modules: array, migration_records: int, has_data: bool} */ public static function preview(): array { $hpct_features = get_option( 'hpct_features', array() ); if ( ! is_array( $hpct_features ) ) { $hpct_features = array(); } $modules = array(); foreach ( TMDO_Feature_Flags::HPCT_MODULES as $module ) { $hpct_status = $hpct_features[ $module ] ?? 'disabled'; $wpdo_state = TMDO_Feature_Flags::map_hpct_status( $hpct_status ); $modules[] = array( 'module' => $module, 'hpct_status' => $hpct_status, 'wpdo_state' => $wpdo_state, ); } // Count HPCT migration records. global $wpdb; $hpct_migrations_table = $wpdb->prefix . 'hpct_migrations'; $migration_count = 0; // Check if hpct_migrations table exists. if ( TMDO_IS_SQLITE ) { $table_exists = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name = %s", $hpct_migrations_table ) ); } else { $table_exists = $wpdb->get_var( $wpdb->prepare( 'SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = %s', $hpct_migrations_table ) ); } if ( $table_exists ) { $migration_count = (int) $wpdb->get_var( "SELECT COUNT(*) FROM `{$hpct_migrations_table}`" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- table name is $wpdb->prefix . 'hpct_migrations'. } return array( 'modules' => $modules, 'migration_records' => $migration_count, 'has_data' => ! empty( $hpct_features ), ); } /** * Execute the import. * * @return array{success: bool, message: string, imported: array} */ public static function run(): array { if ( self::is_imported() ) { return array( 'success' => false, 'message' => 'HPCT import has already been completed.', 'imported' => array(), ); } // Step 1: Read HPCT feature flags. $hpct_features = get_option( 'hpct_features', array() ); if ( ! is_array( $hpct_features ) ) { $hpct_features = array(); } $imported = array(); // Step 2: Map each HPCT module state to WPDO state. foreach ( TMDO_Feature_Flags::HPCT_MODULES as $module ) { $hpct_status = $hpct_features[ $module ] ?? 'disabled'; $wpdo_state = TMDO_Feature_Flags::map_hpct_status( $hpct_status ); TMDO_Feature_Flags::set( $module, $wpdo_state ); $imported[] = array( 'module' => $module, 'hpct_status' => $hpct_status, 'wpdo_state' => $wpdo_state, ); } // Step 3: Copy HPCT migration records to WPDO. self::copy_migration_records(); // Step 4: Mark import as completed. update_option( self::IMPORTED_OPTION, true ); return array( 'success' => true, 'message' => sprintf( 'Successfully imported %d HPCT modules. You can now deactivate hp-custom-tables.', count( $imported ) ), 'imported' => $imported, ); } /** * Copy HPCT migration progress records to wpdo_migrations. */ private static function copy_migration_records(): void { global $wpdb; $hpct_table = $wpdb->prefix . 'hpct_migrations'; $wpdo_table = TMDO_DB::table( 'wpdo_migrations' ); $now = TMDO_DB::now(); // Check if hpct_migrations table exists. $exists = false; if ( TMDO_IS_SQLITE ) { $exists = (bool) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name = %s", $hpct_table ) ); } else { $exists = (bool) $wpdb->get_var( $wpdb->prepare( 'SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = %s', $hpct_table ) ); } if ( ! $exists ) { return; } $hpct_records = $wpdb->get_results( "SELECT * FROM `{$hpct_table}`", ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- table name is $wpdb->prefix . 'hpct_migrations'. if ( ! $hpct_records ) { return; } foreach ( $hpct_records as $record ) { $module = $record['module'] ?? ''; if ( ! $module ) { continue; } // Map HPCT status to WPDO state. $hpct_status = $record['status'] ?? 'pending'; $state = self::map_migration_status( $hpct_status ); // Check if WPDO already has a record for this module. // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- table name from TMDO_DB::table(). $existing = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM `{$wpdo_table}` WHERE module = %s", $module ) ); // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared $data = array( 'module' => $module, 'zone' => '', 'state' => $state, 'total_rows' => (int) ( $record['total_rows'] ?? 0 ), 'processed_rows' => (int) ( $record['processed_rows'] ?? 0 ), 'last_offset' => (int) ( $record['last_offset'] ?? 0 ), 'error_count' => (int) ( $record['error_count'] ?? 0 ), 'started_at' => $record['started_at'] ?? null, 'completed_at' => $record['completed_at'] ?? null, 'updated_at' => $now, ); if ( $existing ) { $wpdb->update( $wpdo_table, $data, array( 'id' => (int) $existing ) ); } else { $data['created_at'] = $now; $wpdb->insert( $wpdo_table, $data ); } } } /** * Map HPCT migration record status to WPDO migration state. * * @param string $hpct_status HPCT migration status string. * @return string Corresponding WPDO migration state. */ private static function map_migration_status( string $hpct_status ): string { return match ( $hpct_status ) { 'pending' => 'idle', 'running' => 'backfill', 'completed' => 'verify', 'failed' => 'idle', default => 'idle', }; } }