UnfinishedPrepare "$source_table.$source_primary_id_column IN ($source_ids_placeholder)", $source_ids ); } /** * Verify data from both source and destination tables and check if they were migrated properly. * * @param array $collected_data Collected data in array format, should be in same structure as returned from query in `$this->build_verification_query`. * * @return array Array of failed IDs if any, along with columns/meta_key names. */ protected function verify_data( $collected_data ) { $failed_ids = array(); foreach ( $collected_data as $row ) { $failed_ids = $this->verify_entity_columns( $row, $failed_ids ); $failed_ids = $this->verify_meta_columns( $row, $failed_ids ); } return $failed_ids; } /** * Helper method to verify and compare core columns. * * @param array $row Both migrated and source data for a single row. * @param array $failed_ids Array of failed IDs. * * @return array Array of failed IDs if any, along with columns/meta_key names. */ private function verify_entity_columns( $row, $failed_ids ) { $primary_key_column = "{$this->schema_config['source']['entity']['table_name']}_{$this->schema_config['source']['entity']['primary_key']}"; foreach ( $this->core_column_mapping as $column_name => $schema ) { $source_alias = "{$this->schema_config['source']['entity']['table_name']}_$column_name"; $destination_alias = "{$this->schema_config['destination']['table_name']}_{$schema['destination']}"; $row = $this->pre_process_row( $row, $schema, $source_alias, $destination_alias ); if ( $row[ $source_alias ] !== $row[ $destination_alias ] ) { if ( ! isset( $failed_ids[ $row[ $primary_key_column ] ] ) ) { $failed_ids[ $row[ $primary_key_column ] ] = array(); } $failed_ids[ $row[ $primary_key_column ] ][] = array( 'column' => $column_name, 'original_value' => $row[ $source_alias ], 'new_value' => $row[ $destination_alias ], ); } } return $failed_ids; } /** * Helper method to verify meta columns. * * @param array $row Both migrated and source data for a single row. * @param array $failed_ids Array of failed IDs. * * @return array Array of failed IDs if any, along with columns/meta_key names. */ private function verify_meta_columns( $row, $failed_ids ) { $primary_key_column = "{$this->schema_config['source']['entity']['table_name']}_{$this->schema_config['source']['entity']['primary_key']}"; foreach ( $this->meta_column_mapping as $meta_key => $schema ) { $meta_alias = "meta_source_{$schema['destination']}"; $destination_alias = "{$this->schema_config['destination']['table_name']}_{$schema['destination']}"; $row = $this->pre_process_row( $row, $schema, $meta_alias, $destination_alias ); if ( $row[ $meta_alias ] !== $row[ $destination_alias ] ) { if ( ! isset( $failed_ids[ $row[ $primary_key_column ] ] ) ) { $failed_ids[ $row[ $primary_key_column ] ] = array(); } $failed_ids[ $row[ $primary_key_column ] ][] = array( 'column' => $meta_key, 'original_value' => $row[ $meta_alias ], 'new_value' => $row[ $destination_alias ], ); } } return $failed_ids; } /** * Helper method to pre-process rows to make sure we parse the correct type. * * @param array $row Both migrated and source data for a single row. * @param array $schema Column schema. * @param string $alias Name of source column. * @param string $destination_alias Name of destination column. * * @return array Processed row. */ private function pre_process_row( $row, $schema, $alias, $destination_alias ) { if ( ! isset( $row[ $alias ] ) ) { $row[ $alias ] = $this->get_type_defaults( $schema['type'] ); } if ( is_null( $row[ $destination_alias ] ) ) { $row[ $destination_alias ] = $this->get_type_defaults( $schema['type'] ); } if ( in_array( $schema['type'], array( 'int', 'decimal', 'float' ), true ) ) { if ( '' === $row[ $alias ] || null === $row[ $alias ] ) { $row[ $alias ] = 0; // $wpdb->prepare forces empty values to 0. } $row[ $alias ] = wc_format_decimal( floatval( $row[ $alias ] ), false, true ); $row[ $destination_alias ] = wc_format_decimal( floatval( $row[ $destination_alias ] ), false, true ); } if ( 'bool' === $schema['type'] ) { $row[ $alias ] = wc_string_to_bool( $row[ $alias ] ); $row[ $destination_alias ] = wc_string_to_bool( $row[ $destination_alias ] ); } if ( 'date_epoch' === $schema['type'] ) { if ( '' === $row[ $alias ] || null === $row[ $alias ] ) { $row[ $alias ] = null; } else { $row[ $alias ] = ( new \DateTime( "@{$row[ $alias ]}" ) )->format( 'Y-m-d H:i:s' ); } if ( '0000-00-00 00:00:00' === $row[ $destination_alias ] ) { $row[ $destination_alias ] = null; } } return $row; } /** * Helper method to get default value of a type. * * @param string $type Type. * * @return mixed Default value. */ private function get_type_defaults( $type ) { switch ( $type ) { case 'float': case 'int': case 'decimal': return 0; case 'string': return ''; } } }