Search code examples
phpwoocommercehook-woocommerceorderscustom-fields

Add custom cart item data array as order item metadata array in WooCommerce


I have this setup to add my custom meta fields for products to the item in the order.

1: I use woocommerce_before_add_to_cart_button to create a custom field which is a list field with multiple fields. These are saved as an multidimensional array.

2: I then use woocommerce_add_cart_item_data to add the meta data to the item in the cart when its added to the cart. The multidimensional array are save in one custom field.

3: I then use woocommerce_cart_item_name and woocommerce_order_item_name to display there fields in the cart and in the checkout under the title of the product. I use foreach to display the data from the array. No problem.

4: Last I use woocommerce_checkout_create_order_line_item to save the custom meta data to the order and the item. Here is where I run in to issues with the array, I does not get saved. The other fields, which is not arrays but numbers or variables are no problem.

I have tried these:

$item->add_meta_data( 'team', $values['team'], false );
$item->add_meta_data( 'team', $values['team'], true );

The problem is also that I can not echo or print in that hook to see whats going on or how the data looks like. In the order the field is blank after checkout.

Why can I not just take the array and add to to the custom meta for the item in the order here? It has to do with the fact that its an array because the other fields works, maybe :)


Solution

  • Sorry, but there is something else that is making trouble in your case, that nobody can guess by magic with the provided details in your question.

    Here below is a static example demonstrating that an array can be saved as custom order item data, from custom cart item data array:

    // Add an array of data as custom cart item data
    add_filter( 'woocommerce_add_cart_item_data', 'add_custom_cart_item_data' );
    function add_custom_cart_item_data( $cart_item_data ) {
        $cart_item_data['team_test'] = array(
            'Set 1' => 'Value one', 
            'Set 2' => 'Value two',
        );
        return $cart_item_data;
    }
    
    // Display custom cart item data in mini cart, Cart and Checkout pages
    add_filter( 'woocommerce_get_item_data', 'display_custom_cart_item_data', 10, 2 );
    function display_custom_cart_item_data( $cart_data, $cart_item ) {
        if( isset($cart_item['team_test']) && is_array($cart_item['team_test']) ) {
            // Loop through custom cart item data array
            foreach($cart_item['team_test'] as $key => $value ) {
                $cart_data[] = array(
                    'key'   => $key,
                    'value' => $value
                );
            }
        }
        return $cart_data;
    }
    
    // Save cart item custom data as order item metadata
    add_action( 'woocommerce_checkout_create_order_line_item', 'save_custom_cart_item_data_as_order_item_meta', 10, 4 );
    function save_custom_cart_item_data_as_order_item_meta( $item, $cart_item_key, $values, $order ) {
        if( isset($values['team_test']) ) {
            $item->update_meta_data('team_test', $values['team_test']);
        }
    }
    
    // Display custom order item metadata array in admin order
    add_action( 'woocommerce_after_order_itemmeta', 'admin_display_custom_order_item_data_array', 10, 3 );
    function admin_display_custom_order_item_data_array( $item_id, $item, $product ) {
        if( ! is_admin() && $item->get_type() !== 'line_item' ) return;
    
        if( $data_array = $item->get_meta('team_test') ) {
            foreach($data_array as $key => $value ) {
                printf('<div class="wc-order-item-%s" style="color:#888"><strong>%s:</strong> %s</div>', 
                    sanitize_title($key), esc_html($key), esc_html($value));
            }
        }
    }
    

    After adding a product from single product pages, you will get in cart page:

    enter image description here

    Once the order is submitted and saved, in wp_woocommerce_order_itemmeta table you can see that the data is saved (when searching for "team_test" meta key):

    enter image description here

    And finally, as I use a function to display that order item metadata in admin order:

    enter image description here