Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Woocommerce: how do I add metadata to a cart item?

Tags:

woocommerce

I have a digital product which is described by a quantity and a price, but which also needs 3 more numbers to completely specify it (Unix dates, etc). Problem: how do I get these numbers into the cart?

As far as I can see, there are 2 possible ways to handle this:

  1. A product variation
  2. A product custom field

It looks like variations can only handle discrete values with a limited range (ie. red/yellow/green, S/M/L, etc), and can't handle general integers, like dates. That leaves custom fields. I think I'm right in saying that custom fields are ordinary meta data on the product post page, so I can handle them with get_post_meta and update_post_meta.

So, if I go for custom fields, then I would update the product page field during ordering, and then I would read back the field during checkout, when the WC_Order is created, and add the field to the new order. However, this won't work. I can't change metadata on the product page, because the product is global to all customers, and this operation would interfere with other customers. In other words, you can't store order-specific information in a product, so neither of these options would work.

So, how do I store temporary product metadata and pass it between the ordering and checkout phases (ie. between WC_Cart and WC_Order)?

One option would be to store it as user metadata (or as session data?), but there's got to be a better way - any ideas?

like image 540
EML Avatar asked Apr 30 '15 10:04

EML


1 Answers

It turns out to be easy to do this with session data. When you're adding an item to the cart (see the source for add_to_cart_action) you create a session variable, containing all your additional meta data:

  WC()->session->set(
     'my_session_var_name',
     array(
        'members' => $members,
        'start'   => $start,
        'expiry'  => $expiry,
        'etc'     => $etc));

When the user checks out, the cart data disappears, and a new order is created. You can hook into woocommerce_add_order_item_meta to add the session meta data to the order meta data:

add_action(
   'woocommerce_add_order_item_meta', 'hook_new_order_item_meta', 10, 3);

function hook_new_order_item_meta($item_id, $values, $cart_item_key) {
   $session_var  = 'my_session_var_name';
   $session_data = WC()->session->get($session_var);
   if(!empty($session_data))
      wc_add_order_item_meta($item_id, $session_var, $session_data);
   else
      error_log("no session data", 0);
}

That's it. You do have to figure out how to get the order metadata out and do something useful with it, though. You may also want to clear the session data, from hooks into woocommerce_before_cart_item_quantity_zero, and woocommerce_cart_emptied. There's gist here which has some example code for this.

like image 150
EML Avatar answered Nov 14 '22 12:11

EML