Home > Software engineering >  Save custom item meta data once order has been saved in WooCommerce
Save custom item meta data once order has been saved in WooCommerce

Time:10-04

I'm using the save_post_{$post->post_type} hook, which fires once a post (order) has been saved.

The intention is to save product meta based on certain order statuses. This is the code I wrote/used for this:

add_action ( 'save_post_shop_order', function (int $postId, \WP_Post $post, bool $update): void   {

        
    $order = new WC_Order( $postId );
    
    $order_status = $order->get_status();
    $status_arrays = array( 'processing', 'on-hold', 'to-order', 'needed' );
    
    if ( in_array($order_status, $status_arrays) ) {
        return;
    }
        
    $items = $order->get_items();
    
     foreach ( $items as $item ) {
        $product_id = $item->get_product_id();
        $product    = wc_get_product( $product_id );
        $final_product->update_meta_data( '_test', '_test' );
        $final_product->save();

    }

   },
    10,
    3
);

However, I can't find the new metadata in my database. Any advice? can anyone help me how to achieve this?

CodePudding user response:

Your code contains some mistakes, for example $final_product is not equal to $product and is therefore not defined.

This should suffice: (explanation via comment tags, added in the code)

function action_save_post_shop_order( $post_id, $post, $update ) {
    // Checking that is not an autosave && current user has the specified capability
    if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || ! current_user_can( 'edit_shop_order', $post_id ) ) {
        return;
    }
    
    // Get $order object
    $order = wc_get_order( $post_id );

    // Is a WC_Order
    if ( is_a( $order, 'WC_Order' ) ) {
        // NOT has status
        if ( ! $order->has_status( array( 'processing', 'on-hold', 'to-order', 'needed' ) ) ) { 
            // Loop through order items
            foreach( $order->get_items() as $item ) {
                // Get an instance of corresponding the WC_Product object
                $product = $item->get_product();
                
                // Meta: key - value
                $product->update_meta_data( '_test', '_test' );
                
                // Save
                $product->save();
            }
        }
    }
}
add_action( 'save_post_shop_order', 'action_save_post_shop_order', 10, 3 );

Note: If the order should have a certain status versus NOT having the status, just remove the ! from:

// NOT has status
if ( ! $order->has_status(..
  • Related