phpwoocommercemetadataordershighperformance

Check if specific Order metadata or order item metadata exist in WooCommerce


We're working on updating some custom plugins to HPOS. I've looked at https://developer.woocommerce.com/docs/hpos-order-querying-apis/ for the answer and it didn't seem to have it.

I'm looking for code to determine if Order Meta Data exists. Something similar to metadata_exists().

Is there code to determine if the key exists in wp_wc_orders_meta table?

How about determining if the key exists in the wp_woocommerce_order_itemmeta table?

Finally, would just getting the data with $order->get_meta('my_stuff') execute about as fast then reviewing what is returned? Sometimes a 4 or 5-data array is the value. I'm thinking that nowadays that the executions are so rapid that maybe just getting the values would be as fast - it's the memory that would increase a bit. Is this not a concern these days? Your thoughts?

if (empty(metadata_exists('post', $order_id, 'some_order_meta_tag'))) {
    $my_metadata_exists = 0;
}

Solution

  • To check for WooCommerce order metadata or order item metadata, you can use the following WC_Data methods from an existing WC_Order object (compatible with High Performance Order Storage HPOS):

    1. meta_exists( $key = '' ) method (the most efficient way),
    2. get_meta( $key = '', $single = true, $context = 'view' ) method, (alternative).

    You can replace in the examples below 'desired_meta_key' with the desired meta-key:

    1. Usage examples for meta_exists() method:
    ## For order metadata
    
    // check if metadata exists
    if ( $order->meta_exists( 'desired_meta_key' ) ) {
       // Do something
    }
    
    ## For order item metadata
    
    // Get order items (line items)
    $line_items = $order->get_items();
    
    // Loop through order items
    foreach ( $line_items as $item ) {
        // check if metadata exists
        if ( $order->meta_exists( 'desired_meta_key' ) ) {
           // Do something
        }
    }
    
    1. Usage examples for get_meta() method:
    ## For order metadata
    
    // Get specific metadata if it exists and is not empty
    if ( $metadata = $order->get_meta( 'desired_meta_key' ) ) {
       // Do something with this existiong $metadata
    }
    
    ## For order item metadata
    
    // Get order items (line items)
    $line_items = $order->get_items();
    
    // Loop through order items
    foreach ( $line_items as $item ) {
        // Get specific metadata if it exists and is not empty
        if ( $metadata = $order->get_meta( 'desired_meta_key' ) ) {
           // Do something with this existiong $metadata
        }
    }
    

    Works with or without HPOS enabled...

    Since WooCommerce version 3, note that all those WC_Data methods work on WooCommerce CRUD object classes, like on WC_Order, WC_Order_Item, WC_Product, WC_Coupon, WC_Customer, etc…


    Additions:

    To be sure that $order variable exist and is a WC_Order object, you can use (at least with a valid Order ID):

    if ( ! is_a( $order, 'WC_Order' ) && $order_id > 0 ) {
       // Get the WC_Order object from an existing order ID
        $order = wc_get_order( $order_id );
    }
    
    if ( is_a( $order, 'WC_Order' ) ) {
       // Your code using $order variable
    }
    

    To check if HPOS is enabled you can use the following custom conditional function:

    ## Conditional function: Check if HPOS is enabled
    
    use Automattic\WooCommerce\Utilities\OrderUtil;
    
    function is_hpos() {
        return OrderUtil::custom_orders_table_usage_is_enabled();
    }
    

    Like in this example:

    if ( is_hpos() ) {
       // HPOS is enabled
    } else {
       // HPOS is disabled
    }