Search code examples
phpwordpresswoocommercemetadatahook-woocommerce

Is there a way to limit WooCommerce wc_get_orders to only query certain orders


I am in the process of converting some code over to support the new WooCommerce HPOS. The old query is as follows:

$orders = get_posts(
    array(
        'post__in'    => $order_ids,
        'numberposts' => -1,
        'order'       => 'ASC',
        'fields'      => 'ids',
        'post_type'   => array( 'shop_order' ),
        'post_status' => $statuses,
        'meta_query'  => array(
            array(
                'key'     => '_my_meta_key',
                'value'   => '',
                'compare' => '!=',
            ),
        ),
    )
);

Here's the updated query. The problem is I can't find a replacement for the post__in option. I know wc_get_orders has an exclude option for excluding certain orders but I cannot seem to find an "include" option.

$orders = wc_get_orders(
    array(
        '???????'    => $order_ids,
        'limit'      => -1,
        'order'      => 'ASC',
        'return'     => 'ids',
        'type'       => array( 'shop_order' ),
        'status'     => $statuses,
        'meta_query' => array(
            array(
                'key'     => '_my_meta_key',
                'value'   => '',
                'compare' => '!=',
            ),
        ),
    )
);

I tried using "post__in" but it didn't work. I also tried using "include" (since there's an exclude) but no luck.


Solution

  • It is possible to add support for custom query variables in wc_get_orders and WC_Order_Query. To do this you need to filter the generated query.

    add_filter(
        'woocommerce_order_data_store_cpt_get_orders_query',
        function ( $query, $query_vars ) {
            if ( ! empty( $query_vars['custom_meta_query'] ) ) {
                foreach ( $query_vars['custom_meta_query'] as $meta_querys ) {
                    foreach ( $meta_querys as $key => $value ) {
                        $meta_query[ $key ] = $value;
                    }
    
                    if ( ! empty( $meta_query ) ) {
                        $query['meta_query'][] = $meta_query;
                    }
                }
            }
    
            return $query;
        },
        10,
        2
    );
    

    Now the wc_get_orders() can be called like the below code. You can use the post__in in the function.

    $order_ids = array(51060, 51071); // Replace with your desired order IDs
    $orders = wc_get_orders(
        array(
            'post__in'    => $order_ids,
            'limit'      => -1,
            'order'      => 'ASC',
            'return'     => 'ids',
            'type'       => array( 'shop_order' ),
            'status'     => $statuses,
            'custom_meta_query' => array(
                array(
                    'key'     => '_my_meta_key',
                    'value'   => '',
                    'compare' => '!=',
                ),
            ),
        )
    );
    

    Tested OK with WooCommerce 6.8