在WooCommerce中,with this code,我正在使用产品自定义字段在购买时为订购商品添加一些自定义元数据。我还需要自动将一些自定义元数据添加到客户订单备注中(基本上它会被发送到我的运输履行服务)。
以下是我目前正在使用的代码:
add_action('woocommerce_checkout_create_order', 'before_checkout_create_order', 20, 2);
function before_checkout_create_order( $order, $data ) {
$items_in_order=array();
foreach( $order->get_items() as $item_id => $item ) {
$product = $order->get_product_from_item( $item );
$text = $product->get_sku();
$bags_count = array(
'neutral_bags' => 0,
'bright_bags' => 0,
'pastel_bags' => 0,
'reg_tendons' => 0,
'gid_tendons' => 0
);
$meta_key1 = __('Neutral Bags', 'woocommerce');
$meta_key2 = __('Bright Bags', 'woocommerce');
$meta_key3 = __('Pastel Bags', 'woocommerce');
$meta_key4 = __('Reg Tendons', 'woocommerce');
$meta_key5 = __('GID Tendons', 'woocommerce');
$bags_count['neutral_bags'] += wc_get_order_item_meta( $item_id, $meta_key1, true );
$bags_count['bright_bags'] += wc_get_order_item_meta( $item_id, $meta_key2, true );
$bags_count['pastel_bags'] += wc_get_order_item_meta( $item_id, $meta_key3, true );
$bags_count['reg_tendons'] += wc_get_order_item_meta( $item_id, $meta_key4, true );
$bags_count['gid_tendons'] += wc_get_order_item_meta( $item_id, $meta_key5, true );
$text .= ' | ' . $bags_count['neutral_bags'];
$text .= ' | ' . $bags_count['bright_bags'];
$text .= ' | ' . $bags_count['pastel_bags'];
$text .= ' | ' . $bags_count['reg_tendons'];
$text .= ' | ' . $bags_count['gid_tendons'];
array_push( $items_in_order , $text );
}
$text = implode('<br/>', $items_in_order );
// get customer note
$note = $order->get_customer_note();
// Merging existing customer note with bags count (if it exist)
$note = empty( $note ) ? $text : $note . '<br/>' . $text . ' V1';
// Set the new customer note before saving
$order->set_customer_note( $note );
}
根据以下屏幕截图,您会看到数据已保存到产品中,但未正确进入订单备注部分。
为什么会出现这种情况?
答案 0 :(得分:1)
由于这与您的其他问题和my answer there有关,因此元键略有不同:
neutral_bag_count
元键替换为:Neutral Bags
,bright_bag_count
元键替换为:Bright Bags
。更新:我完全重新审视了所有现有代码,避免重复,使其更加有效和紧凑。
我在所有其他挂钩函数中调用的函数中设置了您的自定义字段键和标签,现在我在各处使用foreach循环。如果您想更改标签,您只需在此实用程序功能中执行一次。
新代码:
// Utility function (keys + translatable labels)
function bags_and_sheets_labels_keys(){
$domain = 'woocommerce';
return array(
'neutral_bag' => __('Neutral Bags', $domain),
'bright_bag' => __('Bright Bags', $domain),
'pastel_bag' => __('Pastel Bags', $domain),
'reg_tendon' => __('Regular Tendon Sheets', $domain),
'gid_tendon' => __('GID Tendon Sheets', $domain),
);
}
// Add custom fields to single product pages
add_action( 'woocommerce_before_add_to_cart_button', 'add_custom_fields_single_product', 20 );
function add_custom_fields_single_product(){
global $product;
$bags = bags_and_sheets_labels_keys();
?>
<div class="product-custom-fields">
<?php foreach($bags as $key => $value ): ?>
<input type="text" placeholder="<?php echo $value; ?>" name="<?php echo $key; ?>">
<?php endforeach; ?>
</div>
<div class="clear"></div>
<?php
}
// Save custom fields to cart object
add_filter( 'woocommerce_add_cart_item_data', 'save_custom_fields_cart_item_data', 10, 2 );
function save_custom_fields_cart_item_data( $cart_item_data, $product_id ){
$bags = bags_and_sheets_labels_keys();
foreach($bags as $key => $value ):
if(isset($_POST[$key]))
$cart_item_data['custom_data'][$key] = sanitize_text_field($_POST[$key]);
endforeach;
$cart_item_data['custom_data']['unique_key'] = md5( microtime().rand() );
WC()->session->set( 'custom_data', $cart_item_data['custom_data'] );
return $cart_item_data;
}
// Display custom fields in cart items (cart and checkout pages)
add_filter( 'woocommerce_get_item_data', 'display_custom_fields_cart_item_data', 10, 2 );
function display_custom_fields_cart_item_data($item_data, $cart_item){
if( ! array_key_exists( 'custom_data', $cart_item ) )
return $item_data;
$bags = bags_and_sheets_labels_keys();
foreach($bags as $key => $value ):
if( array_key_exists( $key, $cart_item['custom_data'] ) )
$item_data[] = array(
'key' => $value,
'value' => $cart_item['custom_data'][$key]
);
endforeach;
return $item_data;
}
// Save and display custom fields in order item meta
add_action( 'woocommerce_add_order_item_meta', 'add_custom_fields_order_item_meta', 20, 3 );
function add_custom_fields_order_item_meta( $item_id, $cart_item, $cart_item_key ) {
$bags = bags_and_sheets_labels_keys();
foreach($bags as $key => $meta_key_label ):
if( array_key_exists($key, $cart_item['custom_data']) )
wc_update_order_item_meta( $item_id, $meta_key_label, $cart_item['custom_data'][$key] );
endforeach;
}
// Add products SKUs and cutom fields as formated data in customer note
add_action('woocommerce_checkout_update_order_meta', 'after_checkout_create_order', 20, 2);
function after_checkout_create_order( $order_id, $data ) {
$skus = $counts = $output = array();
$bags = bags_and_sheets_labels_keys();
// Get the WC_Order Object (instance)
$order = wc_get_order($order_id);
// Loop through order items
foreach( $order->get_items() as $item_id => $item ) {
$product = $item->get_product();
$skus[] = $product->get_sku(); // Set SKUs in an array
// Add metakeys to the array (if they exist)
foreach( $bags as $meta_key_label ){
$item_meta = wc_get_order_item_meta( $item_id, $meta_key_label, true );
if( ! empty($item_meta) ){
$counts[$meta_key_label] += $item_meta;
$count = true;
}
}
}
// Add Products SKUs
$text = __('Products SKUs', 'woocommerce') . ': ' . implode(' - ', $skus ). ' | ';
// Get each custom item meta data count (if they exist)
if( isset($count)){
foreach( $counts as $key_label => $value ){
$output[] = $key_label . __(' count: ', 'woocommerce') . $value;
}
// Format all data as a text string
$text .= implode(' - ', $output );
}
// Get customer note
$note = $order->get_customer_note();
// Merging existing customer note with bags count (if it exist)
$note = empty( $note ) ? $text : $note . '<br/>' . $text;
// Set the new customer note before saving
$order->set_customer_note( $note );
$order->save();
}
代码进入活动子主题(或活动主题)的function.php文件。
经过测试并按预期工作。