/home/vianto5/heredit.mx/wp-content/plugins/wpforms/src/Pro/Tasks/Actions
NameSizeModeActions
EntryEmailCSVCleanupTask.php69550644editdlrm
ImportCleanupTask.php48350644editdlrm
Migration176Task.php58230644editdlrm
Migration190Task.php56430644editdlrm
Migration199Task.php86810644editdlrm
MigrationOrphanEntryMetaTask.php49110644editdlrm
MigrationPaymentEntriesTask.php147960644editdlrm
PurgeEntriesTask.php61840644editdlrm
PurgeTemplateEntryTask.php35000644editdlrm
Edit: /home/vianto5/heredit.mx/wp-content/plugins/wpforms/src/Pro/Tasks/Actions/Migration199Task.php (8681B)
entry_handler = wpforms()->obj( 'entry' ); $this->entry_fields_handler = wpforms()->obj( 'entry_fields' ); $this->temp_table_name = "{$wpdb->prefix}wpforms_temp_entries"; if ( ! $this->entry_handler || ! $this->entry_fields_handler ) { return; } // Bail out if migration is not started or completed. $status = get_option( self::STATUS ); if ( ! $status || $status === self::COMPLETED ) { return; } $this->hooks(); if ( $status === self::START ) { // Mark that migration is in progress. update_option( self::STATUS, self::IN_PROGRESS ); // Init migration. $this->init_migration(); } } /** * Add hooks. * * @since 1.9.9 */ private function hooks(): void { // Register the migrate action. add_action( self::ACTION, [ $this, 'migrate' ] ); // Register after process queue action. add_action( 'action_scheduler_after_process_queue', [ $this, 'after_process_queue' ] ); } /** * Migrate entry fields with dynamic values. * * @param int $action_index Action index. * * @since 1.9.9 */ public function migrate( $action_index ): void { global $wpdb; // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.NoCaching // Using OFFSET makes a way longer request, as MySQL has to access all rows before OFFSET. // We follow very fast way with indexed column (id > $action_index). $entry_records = $wpdb->get_results( $wpdb->prepare( "SELECT id, entry_id, form_id FROM $this->temp_table_name WHERE id > %d LIMIT %d", $action_index, self::TASK_CHUNK_SIZE ) ); if ( empty( $entry_records ) ) { return; } $entry_ids = array_column( $entry_records, 'entry_id' ); // Get all entries data at once. $entries_data = $wpdb->get_results( $wpdb->prepare( "SELECT entry_id, form_id, fields FROM {$this->entry_handler->table_name} WHERE entry_id IN (" . implode( ',', $entry_ids ) . ')' // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared ), OBJECT_K ); // Process entries in chunks. $i = 0; $records_count = count( $entry_records ); while ( $i < $records_count ) { $records_chunk = array_slice( $entry_records, $i, self::CHUNK_SIZE ); $this->process_entries_dynamic_fields( $records_chunk, $entries_data ); $i += self::CHUNK_SIZE; } // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.NoCaching } /** * After process queue action. * Set status as completed. * * @since 1.9.9 */ public function after_process_queue(): void { $tasks = wpforms()->obj( 'tasks' ); if ( ! $tasks || $tasks->is_scheduled( self::ACTION ) ) { return; } $this->drop_temp_table(); // Mark that migration is finished. update_option( self::STATUS, self::COMPLETED ); } /** * Init migration. * * @since 1.9.9 * * @noinspection PhpUndefinedFunctionInspection */ private function init_migration(): void { // Get all entries that need processing. $count = $this->get_entries_for_migration(); if ( ! $count ) { $this->drop_temp_table(); return; } $index = 0; while ( $index < $count ) { // We do not use Task class here as we do not need meta. So, we reduce the number of DB requests. as_enqueue_async_action( self::ACTION, [ $index ], Tasks::GROUP ); $index += self::TASK_CHUNK_SIZE; } } /** * Process entries and update dynamic fields in entry_fields table. * * @param array $records Array of entry records. * @param array $entries_data Array of entry data indexed by entry_id. * * @since 1.9.9 */ private function process_entries_dynamic_fields( $records, $entries_data ): void { global $wpdb; if ( empty( $records ) || empty( $entries_data ) ) { return; } foreach ( $records as $record ) { // Check if we have entry data for this record. if ( ! isset( $entries_data[ $record->entry_id ] ) ) { continue; } $entry = $entries_data[ $record->entry_id ]; $fields_array = json_decode( $entry->fields, true ); // Skip if fields is not a valid JSON array. if ( ! is_array( $fields_array ) ) { continue; } // Process each field in the entry. foreach ( $fields_array as $field ) { // Skip if the field is not dynamic. if ( ! isset( $field['id'], $field['dynamic'] ) ) { continue; } $field_id = $field['id']; $dynamic_value = $field['value']; // Update the entry field with the dynamic value. // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $result = $wpdb->update( $this->entry_fields_handler->table_name, [ 'value' => $dynamic_value ], [ 'entry_id' => $record->entry_id, 'form_id' => $entry->form_id, 'field_id' => $field_id, ], [ '%s' ], [ '%d', '%d', '%d' ] ); // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching } } } /** * Get entries that need migration. * Store them in a temporary table. * * @since 1.9.9 * * @return int */ private function get_entries_for_migration(): int { global $wpdb; $this->drop_temp_table(); // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.InterpolatedNotPrepared $wpdb->query( "CREATE TABLE $this->temp_table_name ( id BIGINT AUTO_INCREMENT PRIMARY KEY, entry_id BIGINT NOT NULL, form_id BIGINT NOT NULL, INDEX idx_entry_id (entry_id) )" ); // Get entries from the wp_wpforms_entries table after START_DATE. $wpdb->query( $wpdb->prepare( "INSERT INTO $this->temp_table_name (entry_id, form_id) SELECT entry_id, form_id FROM {$this->entry_handler->table_name} WHERE date >= %s", self::START_DATE ) ); // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.InterpolatedNotPrepared return $wpdb->rows_affected; } /** * Drop a temporary table. * * @since 1.9.9 */ private function drop_temp_table(): void { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.SchemaChange $wpdb->query( "DROP TABLE IF EXISTS $this->temp_table_name" ); } }