The following code adds editable short description of the product as order item metadata in Woocommerce. The code is working as expected for simple products but for variable products the $item->get_formatted_meta_data('')
returns empty array at first and only after editing the item, the short description shows as expected.
<?php
/**
* Add product description meta to order item
*/
add_action( 'woocommerce_before_order_itemmeta', 'add_order_item_description_meta', 10, 3 );
function add_order_item_description_meta( $item_id, $item, $product ) {
// Add only if not present
$product_description_meta = wc_get_order_item_meta( $item_id, '_product_short_desc', true );
if( empty( $product_description_meta ) ) {
if( $product->is_type('variation') ) {
$parent_product = wc_get_product( $product->get_parent_id() );
$excerpt = $product->get_description();
$excerpt = empty($excerpt) ? $parent_product->get_short_description() : $excerpt;
} else {
$excerpt = $product->get_short_description();
}
wc_add_order_item_meta( $item_id, '_product_short_desc', $excerpt );
}
}
/**
* Hide product description meta
*/
add_filter( 'woocommerce_hidden_order_itemmeta', 'custom_hidden_order_itemmeta' );
function custom_hidden_order_itemmeta( $hidden_order_itemmeta ) {
$hidden_order_itemmeta[] = '_product_short_desc';
return $hidden_order_itemmeta;
}
/**
* Add custom column to display product description meta
*/
add_action( 'woocommerce_admin_order_item_headers', 'custom_admin_order_items_headers', 20, 1 );
function custom_admin_order_items_headers( $order ) {
echo '<th class="item_short_description">';
echo __('Short Description', 'woocommerce') . '</th>';
}
/**
* Custom column content in table
*/
add_action( 'woocommerce_admin_order_item_values', 'custom_admin_order_item_values', 20, 3 );
function custom_admin_order_item_values( $product, $item, $item_id ) {
?>
<td class="product_short_desc">
<?php
if( $meta_data = $item->get_formatted_meta_data( '' ) ) {
$meta = array_filter( $meta_data, function( $value, $key ) {
return '_product_short_desc' === $value->key;
}, ARRAY_FILTER_USE_BOTH );
if( ! empty( $meta ) ) {
// Get the key of first value
$meta_id = 0;
foreach( $meta as $key => $value) {
$meta_id = $key;
break;
}
$product_desc_meta = $meta[$meta_id];
?>
<div class="view">
<?php echo wp_kses_post( force_balance_tags( $product_desc_meta->display_value ) ); ?>
</div>
<div class="edit" style="display: none;">
<input type="hidden" placeholder="<?php esc_attr_e( 'Name (required)', 'woocommerce' ); ?>" name="meta_key[<?php echo esc_attr( $item_id ); ?>][<?php echo esc_attr( $meta_id ); ?>]" value="<?php echo esc_attr( $product_desc_meta->key ); ?>" />
<textarea placeholder="<?php esc_attr_e( 'Short Description', 'woocommerce' ); ?>" name="meta_value[<?php echo esc_attr( $item_id ); ?>][<?php echo esc_attr( $meta_id ); ?>]"><?php echo esc_textarea( rawurldecode( $product_desc_meta->value ) ); ?></textarea>
</div>
<?php
}
} else {
echo '-';
} ?>
</td>
<?php
}
For simple product the Short Description
column is displaying value when adding the item to order but for variable product it shows -
as it goes into else
condition of function custom_admin_order_item_values
at first and then after editing the item, it displays the short description correctly.
Here's screenshot for the simple and variable product added without being edited:
Please help to find the underlying bug.
UPDATE: Anyone trying to help on this, I can confirm that problem lies either in first hooked function i.e. add_order_item_description_meta
or in the Woocommerce core because even if you comment out the later hooks and their respective functions the same problem is there.
So the meta data for the variable product is not loaded first time when product is added to the order, but when it is refreshed such as by editing it, the meta data loads fine. Also note as I mentioned earlier the meta data loads as expected for simple products at first time without need of refresh of order items.
$product
variable and the short description can be easily obtain by$product->get_short_description()
which works for variable and simple product – Reigel$product->get_short_description()
on variable$product
object. You need to get parent$product
object as it holds the short description. Correct me if I misunderstood. – rmalviya