Search code examples
phpwordpresswoocommercehook-woocommerceorders

Add a custom Metabox to WooCommerce admin orders with HPOS enabled


I'm trying to add a new meta box on the woocommerce order page in the dashboard.

add_action( 'add_meta_boxes', 'add_meta_box_wrapper' );
function add_meta_box_wrapper() {
    add_meta_box( 'custom_meta_box', __( 'Facture' ), 'metabox_content', 'shop_order', 'side', 'core');
}

function metabox_content() {
    echo '<a>Test button</a>';
}

This is the code I tried, but it doesn't seem work.

If I change the fourth parameter of the add_meta_box function to post, I can get it to display in the post edit page so the problem must be with the slug I'm using. I also tried changing that parameter to 'wc-orders' as well as changing the action hook to 'add_meta_boxes_shop_order' and 'add_meta_boxes_wc-orders' like some people suggest in other threads, but nothing seems to work.

Anyone has an idea?


Solution

  • This issue is related to the fact that High Performance Order Storage (HPOS) is enabled, so you need something a bit different to add a custom Metabox to admin orders:

    use Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController;
    
    // Add a custom metabox
    add_action( 'add_meta_boxes', 'admin_order_custom_metabox' );
    function admin_order_custom_metabox() {
        $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(
            'custom',
            'Custom Meta Box',
            'custom_metabox_content',
            $screen,
            'side',
            'high'
        );
    }
    
    // Metabox content
    function custom_metabox_content( $object ) {
        // Get the WC_Order object
        $order = is_a( $object, 'WP_Post' ) ? wc_get_order( $object->ID ) : $object;
    
        echo '<p>Number (ID): '.$order->get_order_number().'<p>';
        echo '<a>Test button</a>';
    }
    

    Code goes in functions.php file of your child theme (or in a plugin). Tested and works with or without HPOS enabled.

    enter image description here

    Related documentation: High Performance Order Storage Upgrade Recipe Book

    Related: