Search code examples
phpwordpresswoocommerceadminorders

Update admin custom order metadata for WooCommerce High Performance Orders Storage (HPOS)


I am working on a way our sales team can mark orders as manual and check back on them. We are using High Performance Orders Storage (HPOS) enabled. I need to be able to update the field value when the update/publish button is clicked.

Here is what I have:

function update_manual_order( $order_id, 'manual_order', $value = '' ) {
    $order = wc_get_order( $order_id );
    $order = get_meta( 'manual_order' );
        if ( empty( $value ) ) {
            $order = update_meta_data( $post_id, $field_name, '0' );
        } else {
            $order = update_meta_data( $post_id, $field_name, '1' );
        }
    $order->update_meta_data( 'manual_order', $manual_order_option );
    //$order->save();
}
add_action( 'woocommerce_process_shop_order_meta', 'update_manual_order', 60 );

The field is currently a checkbox, false would be 0 and true would be 1. As for the checkbox format, it is visually a toggle but here are the lines:

<input type="checkbox" id="toggle" class="checkbox" name="manual_order" value="' . checked( 1, get_option( 'manual_order' ), false ) . '" /> <label for="toggle" class="switcher"></label>

I want to be able to update the field with the updates and sync the current order meta value. Is there something I am missing? I am not too familiar with the new system, any help would be much appreciated!

I attempted to use the new HPOS documentation to have it find the field and use that to add/update the meta field. Current code results in a critical error.


Solution

  • Here is your correct input checkbox field,here displayed after shipping address (for testing):

    add_action( 'woocommerce_admin_order_data_after_shipping_address', 'display_manual_order_checkbox'  );
    function display_manual_order_checkbox( $order ){
        $checked = $order->get_meta('manual_order');
        echo '<div>
        <input type="checkbox" id="toggle" class="checkbox" name="manual_order" '. 
        checked($checked, '1', false).' /> <label for="toggle" class="switcher">'.
        __('Is Manual Order?').'</label>
        </div>';
    }
    

    Here is the correct code, compatible with HPOS, to save the checkbox checked state:

    add_action( 'woocommerce_process_shop_order_meta', 'save_manual_order_checkbox_value', 20 );
    function save_manual_order_checkbox_value( $order_id ) {
        $order = wc_get_order( $order_id );
        
        if ( isset($_POST['manual_order']) ) {
            $order->update_meta_data('manual_order', '1');
        } else {
            $order->update_meta_data('manual_order', '0');
        }
        $order->save();
    }
    

    Code goes in functions.php file of your child theme (or in a plugin). Tested and works with High Performance Orders Storage (HPOS) too.