Automattic\WooCommerce\Internal\DataStores\Orders

LegacyDataHandler::backfill_order_to_datastore()publicWC 8.7.0

Backfills an order from/to the CPT or HPOS datastore.

Method of the class: LegacyDataHandler{}

No Hooks.

Return

null. Nothing (null).

Usage

$LegacyDataHandler = new LegacyDataHandler();
$LegacyDataHandler->backfill_order_to_datastore( $order_id, $source_data_store, $destination_data_store, $fields );
$order_id(int) (required)
Order ID.
$source_data_store(string) (required)
Datastore to use as source. Should be either 'hpos' or 'posts'.
$destination_data_store(string) (required)
Datastore to use as destination. Should be either 'hpos' or 'posts'.
$fields(array)
List of metakeys or order properties to limit the backfill to.
Default: array()

Changelog

Since 8.7.0 Introduced.

LegacyDataHandler::backfill_order_to_datastore() code WC 9.3.3

public function backfill_order_to_datastore( int $order_id, string $source_data_store, string $destination_data_store, array $fields = array() ) {
	$valid_data_stores = array( 'posts', 'hpos' );

	if ( ! in_array( $source_data_store, $valid_data_stores, true ) || ! in_array( $destination_data_store, $valid_data_stores, true ) || $destination_data_store === $source_data_store ) {
		throw new \Exception( esc_html( sprintf( 'Invalid datastore arguments: %1$s -> %2$s.', $source_data_store, $destination_data_store ) ) );
	}

	$fields    = array_filter( $fields );
	$src_order = $this->get_order_from_datastore( $order_id, $source_data_store );

	// Backfill entire orders.
	if ( ! $fields ) {
		if ( 'posts' === $destination_data_store ) {
			$src_order->get_data_store()->backfill_post_record( $src_order );
		} elseif ( 'hpos' === $destination_data_store ) {
			$this->posts_to_cot_migrator->migrate_orders( array( $src_order->get_id() ) );
		}

		return;
	}

	$this->validate_backfill_fields( $fields, $src_order );

	$dest_order = $this->get_order_from_datastore( $src_order->get_id(), $destination_data_store );

	if ( 'posts' === $destination_data_store ) {
		$datastore = $this->data_store->get_cpt_data_store_instance();
	} elseif ( 'hpos' === $destination_data_store ) {
		$datastore = $this->data_store;
	}

	if ( ! $datastore || ! method_exists( $datastore, 'update_order_from_object' ) ) {
		throw new \Exception( esc_html__( 'The backup datastore does not support updating orders.', 'woocommerce' ) );
	}

	// Backfill meta.
	if ( ! empty( $fields['meta_keys'] ) ) {
		foreach ( $fields['meta_keys'] as $meta_key ) {
			$dest_order->delete_meta_data( $meta_key );

			foreach ( $src_order->get_meta( $meta_key, false, 'edit' ) as $meta ) {
				$dest_order->add_meta_data( $meta_key, $meta->value );
			}
		}
	}

	// Backfill props.
	if ( ! empty( $fields['props'] ) ) {
		$new_values = array_combine(
			$fields['props'],
			array_map(
				fn( $prop_name ) => $src_order->{"get_{$prop_name}"}(),
				$fields['props']
			)
		);

		$dest_order->set_props( $new_values );

		if ( 'hpos' === $destination_data_store ) {
			$dest_order->apply_changes();
			$limit_cb = function ( $rows, $order ) use ( $dest_order, $fields ) {
				if ( $dest_order->get_id() === $order->get_id() ) {
					$rows = $this->limit_hpos_update_to_props( $rows, $fields['props'] );
				}

				return $rows;
			};
			add_filter( 'woocommerce_orders_table_datastore_db_rows_for_order', $limit_cb, 10, 2 );
		}
	}

	$datastore->update_order_from_object( $dest_order );

	if ( 'hpos' === $destination_data_store && isset( $limit_cb ) ) {
		remove_filter( 'woocommerce_orders_table_datastore_db_rows_for_order', $limit_cb );
	}
}