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?
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.