Optimizing WooCommerce: A Guide to High-Performance Order Storage

In the dynamic world of e-commerce, where speed and efficiency are paramount, optimizing order storage in WooCommerce becomes crucial for a seamless shopping experience. The High-Performance-Order-Storage feature in WooCommerce provides developers with tools to enhance the performance of order-related operations. In this article, we'll explore how developers can implement their code for compatibility with WooCommerce's High-Performance-Order-Storage (HPOS).

1. Understanding High-Performance Order Storage

Traditionally, WooCommerce has stored order-related data within the post and postmeta tables in the database, treating orders as a custom WordPress post type. However, in a notable evolution, WooCommerce has transitioned from this conventional approach to a more advanced paradigm. The latest iteration involves the migration of orders into dedicated tables.

2. Enabling/Disabling High-Performance Order Storage

In legacy stores, High-Performance Order Storage (HPOS) remains disabled even after updating WooCommerce to the latest version. However, in newly established installations, HPOS is activated by default. The flexibility to enable or disable HPOS is conveniently accessible through the WooCommerce settings menu. Simply navigate to WooCommerce > Settings > Advanced > Features.

3. Detecting whether HPOS tables are being used

use Automattic\WooCommerce\Utilities\OrderUtil;

if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
	// HPOS usage is enabled.
} else {
	// Traditional CPT-based orders are in use.
}

4. Getting/Setting Orders and Order meta

Instead of using:

$post = get_post( $post_id );

get_post_meta( $post_id, 'meta_key', true );

add_post_meta( $post_id, 'meta_key', 'meta_value' );
update_post_meta( $post_id, 'meta_key', 'meta_value' );
delete_post_meta( $post_id, 'meta_key', 'meta_value' );

Use:

$order = wc_get_order( $post_id );

$order->get_meta( 'meta_key', true );

$order->update_meta_data( 'meta_key', 'meta_value' );
$order->add_meta_data( 'meta_key', 'meta_value' );
$order->delete_meta_data( 'meta_key', 'meta_value' );
$order->save();

5. Checking if the given ID is an order

Instead of using:

$is_order = 'shop_order' === get_post_type( $post_id );
// or
$is_order = in_array( get_post_type( $post_id ), wc_get_order_types() );

Use:

use Automattic\WooCommerce\Utilities\OrderUtil;

'shop_order' === OrderUtil::get_order_type( $post_id );
// or
OrderUtil::is_order( $post_id, wc_get_order_types() );

6. Adding a custom meta box

<?php

use Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController;

function you_bou_add_custom_meta_box() {

	$screen = class_exists( '\Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController' )
        && wc_get_container()->get( CustomOrdersTableController::class )->custom_orders_table_usage_is_enabled()
		? wc_get_page_screen_id( 'shop-order' )
		: 'shop_order';

	add_meta_box(
		'you_bou_custom_meta_box',
		__( 'Custom Meta Box', 'you-bou' ),
		'you_bou_render_custom_meta_box',
		$screen,
		'side',
		'high'
	);
}
add_action( 'add_meta_boxes', 'you_bou_add_custom_meta_box' );

function you_bou_render_custom_meta_box( $post_or_order_object ) {

    $order = ( $post_or_order_object instanceof WP_Post ) ? wc_get_order( $post_or_order_object->ID ) : $post_or_order_object;

    ?>
        <div class="inside"><?php echo sprintf( __( 'Order ID: %s', 'you-bou' ), $order->get_id() ); ?></div>
    <?php
}