How To Get Order Meta From WooCommerce Order Without Loading Order Object (HPOS)

5/5

The World's No.1 WooCommerce Plugin

How To Get Order Meta From A WooCommerce Order By Order ID Without Loading The Order Object

Before the inclusion of WooCommerce HPOS (High Performance Order Storage), you could call meta data by simply using get_post_meta().

With the implementation of HPOS you are required to load the order object and then use $order->get_meta(), which is fine in most cases, but can be very expensive if you are trying to call meta data on multiple orders.

By our assessment, this function is about 2x faster when you’re using HPOS, and about 4x faster when you’re not using HPOS.

This is because loading the order object can be very expensive, both in terms of memory and compute.

If the only thing you need is an order meta value whilst being comatible with HPOS, then this is the solution for you.

The way our function works is that it first checks if you are using HPOS, and if so it will check the HPOS database table directly, otherwise use the get_post_meta function.

You will need both functions included below, one is for checking for the existance of HPOS and the other makes the call.

It will return false if there is a failure at any point, otherwise will return null if nothing found, or the relevant data if found.

Without further adiue, copy paste the snippets below.

As always, if you have any question, do not hesitate to ask away 🙂

Thanks, Chris

The Code Snippet

Make sure you copy paste both of the functions below.

To use this snippet, you simply call wpd_get_order_meta_by_order_id( $order_id, $meta_key ) and replace the $order_id with your order_id and $meta_key with your desired meta_key.

E.g. wpd_get_order_meta_by_order_id( 12654, ‘_your_meta_key’ );

				
					/**
 * 
 * 	Will fetch order meta by order ID without loading the order object
 * 	Compatible with WooCommerce HPOS / standard
 * 
 * 	@param int $order_id The order ID
 * 	@param string $meta_key The meta key to search for
 * 
 * 	@return mixed The result for the meta key fetch, will always return a single result if succesful. Will return Null if nothing found, and false on bad params.
 * 
 * 	@see https://wpdavies.dev/how-to-get-order-meta-from-woocommerce-order-without-loading-order-object-hpos/
 * 	@author Christopher Davies - WP Davies
 * 
 **/
function wpd_get_order_meta_by_order_id( $order_id, $meta_key ) {

	// Default result
	$result = null;

	// Make sure we have an order id formatted correctly
	if ( ! is_numeric($order_id) || $order_id < 1 ) return false;

	// Make sure we have an appropriately formatted meta key
	if ( ! is_string($meta_key) ) return false;

	// If we are using HPOS
	if ( wpd_is_hpos_enabled() ) {

		// Call the database directly
		global $wpdb;

		// Meta table name
		$meta_table_name = $wpdb->prefix . 'wc_orders_meta';

		// Sanitize the query
		$query = $wpdb->prepare( "SELECT meta_value FROM $meta_table_name WHERE order_id = %d AND meta_key = %s", $order_id, $meta_key );

		// Execute the query & transform if required
		$result = maybe_unserialize( $wpdb->get_var( $query ) );

	} else {

		// Call get_post_meta
		$result = get_post_meta( $order_id, $meta_key, true );

	}

	// Return the finding
	return $result;

}

/**
 * 
 * 	Check if the customer is using HPOS (High Performance Order Storage)
 * 
 * 	@return bool True if HPOS is enabled, false if not
 * 
 *  @see https://wpdavies.dev/how-to-get-order-meta-from-woocommerce-order-without-loading-order-object-hpos/
 * 	@author Christopher Davies - WP Davies
 *	 
 **/
function wpd_is_hpos_enabled() {

	if ( class_exists(\Automattic\WooCommerce\Utilities\OrderUtil::class) ) {

		return Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled();

	} else {

		return false;

	}

}
				
			
Subscribe
Notify of
guest
0 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments