Get product custom field values as variables in WooCommerce

GunStreetGirl picture GunStreetGirl · Feb 10, 2018 · Viewed 16.5k times · Source

I am using Woocommerce for registration for classes; each class/product has up to 20 custom fields, which I need to return as variables in order to highly customize the checkout and order details pages and customer email template.

I don't just want to add all of the custom meta data with hooks, because I need very tight control over the output. For instance, the following answer worked fine for including custom fields in the cart page: Display Custom Field's Value in Woocommerce Cart & Checkout items

But I would like them in checkout, order details and emails as well, with full control over the HTML where they appear (in some cases they will need to be converted as well, e.g., Unix timestamps to human readable time).

In order-item-details.php template I have tried the following:

$room = get_post_meta( $product->ID, 'room', true );
$room_number = get_post_meta( $product->ID, 'room_number', true );
$instructor = get_post_meta( $product->ID, 'instructor', true );

echo 'Your instructor is ' . $instructor . '.';
echo 'Your class is in ' . $room . '.';

But it didn't work…

How can I access and use custom field values associated with a specific product?

Answer

LoicTheAztec picture LoicTheAztec · Feb 10, 2018

First $product->ID will not work any way. So your problem is how to get the product ID.

Multiple cases

1) In Archive pages like shop or in Single product pages:

  • Using get_the_id() will give you mostly always the product id (the post ID)

    $room = get_post_meta( get_the_id(), 'room', true );
    
  • You can also use global $product; with $product->get_id() if $product is not defined.

    global $product;
    
    $room = get_post_meta( $product->get_id(), 'room', true );
    
  • You can also use global $post; with $post->ID (if $post is not defined):

    global $post;
    
    $room = get_post_meta( $post->ID, 'room', true );
    

2) for cart items (from the cart object):

// Loop through cart items
foreach( WC()->cart->get_cart() as $cart_item ){
    // Get the WC_Product object (instance)
    $product = $cart_item['data'];
    $product_id = $product->get_id(); // get the product ID

    $room = get_post_meta( $product->get_id(), 'room', true );
    ## … / … 
}
  • Now for product variations, if you need to get the parent variable product ID, you will use:

    // Get the parent product ID (the parent variable product)
    $parent_id = $cart_item['product_id'];
    
    $room = get_post_meta( $parent_id, 'room', true );
    ## … / … 
    

3) For order items (from a defined WC_Order object $order):

// Loop through cart items
foreach( $order->get_items() as $item ){
    // Get the Product ID
    $product_id = $item->get_product_id();

    $room = get_post_meta( $product_id, 'room', true );
    ## … / … 
}
  • Now for product variations, if you need to get the parent variable product ID, you will use:

    // Loop through cart items
    foreach( $order->get_items() as $item ){
        // Get the parent Product ID
        $product = $item->get_product();
        $parent_id = $product->get_parent_id(); // The parent product ID
    
        $room = get_post_meta( $parent_id, 'room', true );
        ## … / … 
    }
    

So it's up to you now.