WooCommerce:将自定义 Metabox 添加到管理订单页面 [英] WooCommerce : Add custom Metabox to admin order page
问题描述
我目前正在成功地向我的 WooCommerce 产品页面添加一个显示值的字段:
- 在购物车(前端)中,
- 在结账页面(前端),
- 在订单页面(前端),
- 在管理个人订单页面(后端).
问题:它不是在管理订单自定义字段"Metabox 中显示为自定义字段,其中包含值,而是在订单页面中显示为文本.
这是我的工作代码:
//将字段添加到产品中add_action('woocommerce_before_add_to_cart_button', 'my_custom_checkout_field');函数 my_custom_checkout_field() {echo '<div id="my_custom_checkout_field"><h3>'.__('My Field').'</h3>';echo '<label>填写这个字段</label><input type="text" name="my_field_name">';回声'</div>';}//存储自定义字段函数 save_my_custom_checkout_field( $cart_item_data, $product_id ) {if( isset( $_REQUEST['my_field_name'] ) ) {$cart_item_data['my_field_name'] = $_REQUEST['my_field_name'];/* 下面的语句确保每个添加到购物车的操作都是唯一的行项目 */$cart_item_data['unique_key'] = md5( microtime().rand() );}返回 $cart_item_data;}add_action('woocommerce_add_cart_item_data', 'save_my_custom_checkout_field', 10, 2);//在购物车和结帐上呈现元数据函数 render_meta_on_cart_and_checkout( $cart_data, $cart_item = null ) {$custom_items = array();/* Woo 2.4.2 更新 */if( !empty( $cart_data ) ) {$custom_items = $cart_data;}if( isset( $cart_item['my_field_name'] ) ) {$custom_items[] = array( "name" => 'My Field', "value" => $cart_item['my_field_name'] );}返回 $custom_items;}add_filter('woocommerce_get_item_data', 'render_meta_on_cart_and_checkout', 10, 2);//这就是我认为需要改变的地方?函数subscription_order_meta_handler( $item_id, $values, $cart_item_key ) {if( isset( $values['my_field_name'] ) ) {wc_add_order_item_meta( $item_id, "我的字段", $values['my_field_name'] );}}add_action('woocommerce_add_order_item_meta', 'subscription_order_meta_handler', 1, 3);
我认为这是代码的最后一点需要更改.它目前显示订单项下的文本,所以也许我需要将 wc_add_order_item_meta
调整为其他内容?
我已经尝试了所有方法,但似乎不起作用.当我的字段在结账页面上时,我可以让它工作,但当我从产品页面中拉出它时,我可以让它工作.
也许我遗漏了一个结账流程片段?
UPDATE 2017/11/02 (在 Woocommerce 3+ 中完美运行)
首先,我让一切都按预期进行,除了在订单页面的后端自定义字段"Metabox 中获取 my_field_name
的值.
在经历了一场真正的噩梦之后,我找到了一个非常好的工作解决方案,比以前更好.在后端,您现在有一个自定义元框,其中自定义字段 my_field_name
显示正确的值,如下图所示:
我的代码分为两部分.
1) 订单页面中的后端 Metabox,带有一个可编辑的字段,显示来自产品页面(前端)上的自定义字段的正确值:
//添加 Meta 容器管理 shop_order 页面add_action('add_meta_boxes', 'mv_add_meta_boxes');如果(!function_exists('mv_add_meta_boxes')){函数 mv_add_meta_boxes(){add_meta_box('mv_other_fields', __('My Field','woocommerce'), 'mv_add_other_fields_for_packaging', 'shop_order', 'side', 'core');}}//在元容器管理 shop_order 页面中添加 Meta 字段如果(!function_exists('mv_add_other_fields_for_packaging')){函数 mv_add_other_fields_for_packaging(){全球 $post;$meta_field_data = get_post_meta( $post->ID, '_my_field_slug', true ) ?get_post_meta( $post->ID, '_my_field_slug', true ) : '';echo '<input type="hidden" name="mv_other_meta_field_nonce" value="'.wp_create_nonce().'"><p style="border-bottom:solid 1px #eee;padding-bottom:13px;"><input type="text" style="width:250px;";" name="my_field_name" placeholder="' .$meta_field_data .'" 值="' .$meta_field_data .'"></p>';}}//保存Meta字段的数据add_action('save_post', 'mv_save_wc_order_other_fields', 10, 1);如果(!function_exists('mv_save_wc_order_other_fields')){函数 mv_save_wc_order_other_fields( $post_id ) {//我们需要使用适当的授权(安全性的东西)来验证这一点.//检查我们的随机数是否设置.如果(!isset($_POST['mv_other_meta_field_nonce'])){返回 $post_id;}$nonce = $_REQUEST['mv_other_meta_field_nonce'];//验证nonce是否有效.如果(!wp_verify_nonce($nonce)){返回 $post_id;}//如果这是自动保存,我们的表单还没有提交,所以我们不想做任何事情.如果(定义('DOING_AUTOSAVE')&& DOING_AUTOSAVE){返回 $post_id;}//检查用户的权限.如果('页面'==$_POST['post_type']){如果(!current_user_can('edit_page',$post_id)){返回 $post_id;}} 别的 {如果(!current_user_can('edit_post',$post_id)){返回 $post_id;}}//--- 我们保存数据是安全的!---////清理用户输入并更新数据库中的元字段.update_post_meta( $post_id, '_my_field_slug', $_POST[ 'my_field_name' ] );}}
<小时>
2) 前端/后端:
• 产品页面自定义字段(前端).
• 在购物车、结帐页面和感谢订单(前端)上显示此数据.
• 在订单页面(后端)显示数据
//将字段添加到产品中add_action('woocommerce_before_add_to_cart_button', 'my_custom_product_field');函数 my_custom_product_field() {echo '<div id="my_custom_field"><标签>'.__('我的领域') .' </标签><input type="text" name="my_field_name" value=""></div><br>';}//存储自定义字段add_filter( 'woocommerce_add_cart_item_data', 'save_my_custom_product_field', 10, 2 );函数 save_my_custom_product_field( $cart_item_data, $product_id ) {if( isset( $_REQUEST['my_field_name'] ) ) {$cart_item_data['my_field_name'] = $_REQUEST['my_field_name'];//下面的语句确保每个添加到购物车的操作都是唯一的订单项$cart_item_data['unique_key'] = md5( microtime().rand() );WC()->session->set('my_order_data', $_REQUEST['my_field_name']);}返回 $cart_item_data;}//添加一个具有正确值的隐藏字段到结账add_action('woocommerce_after_order_notes', 'my_custom_checkout_field');函数 my_custom_checkout_field( $checkout ) {$value = WC()->session->get('my_order_data');echo '<div id="my_custom_checkout_field"><input type="hidden" class="input-hidden" name="my_field_name" id="my_field_name" value="'.$value.'">
';}//保存带有隐藏字段值的订单元数据add_action('woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta');函数 my_custom_checkout_field_update_order_meta( $order_id ) {如果(!空($_POST['my_field_name'])){update_post_meta( $order_id, '_my_field_slug', $_POST['my_field_name'] );}}//在订单编辑页面上显示字段值(不在自定义字段元框中)add_action('woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1);函数 my_custom_checkout_field_display_admin_order_meta($order){$my_custom_field = get_post_meta( $order->id, '_my_field_slug', true );如果(!空($my_custom_field)){回声'<p><strong>'.__("My Field", "woocommerce").':</strong>' .get_post_meta( $order->id, '_my_field_slug', true ) .'</p>';}}//在购物车和结帐上呈现元数据add_filter('woocommerce_get_item_data', 'render_meta_on_cart_and_checkout', 10, 2);函数 render_meta_on_cart_and_checkout( $cart_data, $cart_item = null ) {$custom_items = array();if( !empty( $cart_data ) ) $custom_items = $cart_data;if( isset( $cart_item['my_field_name'] ) )$custom_items[] = array( "name" => 'My Field', "value" => $cart_item['my_field_name'] );返回 $custom_items;}//将信息添加为元数据,以便可以将其视为订单的一部分add_action('woocommerce_add_order_item_meta','add_values_to_order_item_meta', 10, 3);函数 add_values_to_order_item_meta( $item_id, $cart_item, $cart_item_key ) {//让我们将元数据添加到订单中(使用标签作为关键 slug)if( !empty( $cart_item['my_field_name'] ) )wc_add_order_item_meta($item_id, __('我的字段标签名称'), $cart_item['my_field_name'], true);}
现在一切都按预期进行.
I am currently successfully adding a field to my WooCommerce product pages which is showing the value:
- in the cart (front end),
- on checkout page (front end),
- on order page (front end),
- and in admin individual order page (back end).
The problem: It isn't showing as a custom field in the admin order "custom fields" Metabox with the value inside it, but just as a text in the order page.
Here is my working code:
// Add the field to the product
add_action('woocommerce_before_add_to_cart_button', 'my_custom_checkout_field');
function my_custom_checkout_field() {
echo '<div id="my_custom_checkout_field"><h3>'.__('My Field').'</h3>';
echo '<label>fill in this field</label> <input type="text" name="my_field_name">';
echo '</div>';
}
// Store custom field
function save_my_custom_checkout_field( $cart_item_data, $product_id ) {
if( isset( $_REQUEST['my_field_name'] ) ) {
$cart_item_data[ 'my_field_name' ] = $_REQUEST['my_field_name'];
/* below statement make sure every add to cart action as unique line item */
$cart_item_data['unique_key'] = md5( microtime().rand() );
}
return $cart_item_data;
}
add_action( 'woocommerce_add_cart_item_data', 'save_my_custom_checkout_field', 10, 2 );
// Render meta on cart and checkout
function render_meta_on_cart_and_checkout( $cart_data, $cart_item = null ) {
$custom_items = array();
/* Woo 2.4.2 updates */
if( !empty( $cart_data ) ) {
$custom_items = $cart_data;
}
if( isset( $cart_item['my_field_name'] ) ) {
$custom_items[] = array( "name" => 'My Field', "value" => $cart_item['my_field_name'] );
}
return $custom_items;
}
add_filter( 'woocommerce_get_item_data', 'render_meta_on_cart_and_checkout', 10, 2 );
// This is what I think needs changing?
function subscription_order_meta_handler( $item_id, $values, $cart_item_key ) {
if( isset( $values['my_field_name'] ) ) {
wc_add_order_item_meta( $item_id, "My Field", $values['my_field_name'] );
}
}
add_action( 'woocommerce_add_order_item_meta', 'subscription_order_meta_handler', 1, 3 );
I think it is this last bit of the code that needs changing. It currently shows the text under the order item, so perhaps I need to adjust wc_add_order_item_meta
to something else?
I've tried everything but it doesn't seem to work. I can get it to work when my field is on the checkout page but not when I pull it from the product page.
Perhaps I am missing a checkout process snippet?
UPDATE 2017/11/02 (Works perfectly in Woocommerce 3+)
First I have get everything working has expected, except getting the value for my_field_name
in back end "Custom fields" Metabox within Order pages.
Then after a real nightmare, I have found a pretty nice working solution, better than before. In back end you have now a Custom metabox with the custom field my_field_name
displaying the right value, like in this screenshot:
My code is divided In 2 parts.
1) The backend Metabox in Order pages, with an editable field showing the correct value coming from a custom field on the product pages (in front end):
// Adding Meta container admin shop_order pages
add_action( 'add_meta_boxes', 'mv_add_meta_boxes' );
if ( ! function_exists( 'mv_add_meta_boxes' ) )
{
function mv_add_meta_boxes()
{
add_meta_box( 'mv_other_fields', __('My Field','woocommerce'), 'mv_add_other_fields_for_packaging', 'shop_order', 'side', 'core' );
}
}
// Adding Meta field in the meta container admin shop_order pages
if ( ! function_exists( 'mv_add_other_fields_for_packaging' ) )
{
function mv_add_other_fields_for_packaging()
{
global $post;
$meta_field_data = get_post_meta( $post->ID, '_my_field_slug', true ) ? get_post_meta( $post->ID, '_my_field_slug', true ) : '';
echo '<input type="hidden" name="mv_other_meta_field_nonce" value="' . wp_create_nonce() . '">
<p style="border-bottom:solid 1px #eee;padding-bottom:13px;">
<input type="text" style="width:250px;";" name="my_field_name" placeholder="' . $meta_field_data . '" value="' . $meta_field_data . '"></p>';
}
}
// Save the data of the Meta field
add_action( 'save_post', 'mv_save_wc_order_other_fields', 10, 1 );
if ( ! function_exists( 'mv_save_wc_order_other_fields' ) )
{
function mv_save_wc_order_other_fields( $post_id ) {
// We need to verify this with the proper authorization (security stuff).
// Check if our nonce is set.
if ( ! isset( $_POST[ 'mv_other_meta_field_nonce' ] ) ) {
return $post_id;
}
$nonce = $_REQUEST[ 'mv_other_meta_field_nonce' ];
//Verify that the nonce is valid.
if ( ! wp_verify_nonce( $nonce ) ) {
return $post_id;
}
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
// Check the user's permissions.
if ( 'page' == $_POST[ 'post_type' ] ) {
if ( ! current_user_can( 'edit_page', $post_id ) ) {
return $post_id;
}
} else {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return $post_id;
}
}
// --- Its safe for us to save the data ! --- //
// Sanitize user input and update the meta field in the database.
update_post_meta( $post_id, '_my_field_slug', $_POST[ 'my_field_name' ] );
}
}
2) Front end / Back end:
• The product page custom field (front end).
• Displaying this data on cart, checkout pages and thank you order (front end).
• Displaying data on order page (back end)
// Add the field to the product
add_action('woocommerce_before_add_to_cart_button', 'my_custom_product_field');
function my_custom_product_field() {
echo '<div id="my_custom_field">
<label>' . __( 'My Field') . ' </label>
<input type="text" name="my_field_name" value="">
</div><br>';
}
// Store custom field
add_filter( 'woocommerce_add_cart_item_data', 'save_my_custom_product_field', 10, 2 );
function save_my_custom_product_field( $cart_item_data, $product_id ) {
if( isset( $_REQUEST['my_field_name'] ) ) {
$cart_item_data[ 'my_field_name' ] = $_REQUEST['my_field_name'];
// below statement make sure every add to cart action as unique line item
$cart_item_data['unique_key'] = md5( microtime().rand() );
WC()->session->set( 'my_order_data', $_REQUEST['my_field_name'] );
}
return $cart_item_data;
}
// Add a hidden field with the correct value to the checkout
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
$value = WC()->session->get( 'my_order_data' );
echo '<div id="my_custom_checkout_field">
<input type="hidden" class="input-hidden" name="my_field_name" id="my_field_name" value="' . $value . '">
</div>';
}
// Save the order meta with hidden field value
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['my_field_name'] ) ) {
update_post_meta( $order_id, '_my_field_slug', $_POST['my_field_name'] );
}
}
// Display field value on the order edit page (not in custom fields metabox)
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
$my_custom_field = get_post_meta( $order->id, '_my_field_slug', true );
if ( ! empty( $my_custom_field ) ) {
echo '<p><strong>'. __("My Field", "woocommerce").':</strong> ' . get_post_meta( $order->id, '_my_field_slug', true ) . '</p>';
}
}
// Render meta on cart and checkout
add_filter( 'woocommerce_get_item_data', 'render_meta_on_cart_and_checkout', 10, 2 );
function render_meta_on_cart_and_checkout( $cart_data, $cart_item = null ) {
$custom_items = array();
if( !empty( $cart_data ) ) $custom_items = $cart_data;
if( isset( $cart_item['my_field_name'] ) )
$custom_items[] = array( "name" => 'My Field', "value" => $cart_item['my_field_name'] );
return $custom_items;
}
// Add the information as meta data so that it can be seen as part of the order
add_action('woocommerce_add_order_item_meta','add_values_to_order_item_meta', 10, 3 );
function add_values_to_order_item_meta( $item_id, $cart_item, $cart_item_key ) {
// lets add the meta data to the order (with a label as key slug)
if( ! empty( $cart_item['my_field_name'] ) )
wc_add_order_item_meta($item_id, __('My field label name'), $cart_item['my_field_name'], true);
}
Everything is working as expected now.
这篇关于WooCommerce:将自定义 Metabox 添加到管理订单页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!