WooCommerce:将自定义Metabox添加到管理订单页面 [英] WooCommerce : Add custom Metabox to admin order page

查看:95
本文介绍了WooCommerce:将自定义Metabox添加到管理订单页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我当前已成功在WooCommerce产品页面上添加了一个显示值的字段:

  • 在购物车(前端)中,
  • 在结帐页面(前端)上,
  • 在订单页面(前端)上,
  • 和在管理员个人订单页面(后端)中.

问题:在管理订单自定义字段" Metabox中,它没有显示为具有自定义字段的自定义字段,而是在订单页面中显示为文本.

这是我的工作代码:

// 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 );

我认为这是代码的最后一部分需要更改.它当前在订单项下显示文本,所以也许我需要将wc_add_order_item_meta调整为其他内容?

我已经尝试了一切,但似乎没有用.当我的字段在结帐页面上时,我可以使它工作,但是当我从产品页面中将其拉出时,它却无法工作.

也许我错过了结帐流程摘要?

解决方案

更新2017/11/02 (在Woocommerce 3+中完美运行)

首先,我已经获得了所有预期的工作,除了在订单页面的后端自定义字段" Metabox中获取my_field_name的值.

然后,在经历一场真正的噩梦之后,我找到了一个很好的工作解决方案,比以前更好.在后端,您现在有了一个自定义元框,其中的自定义字段my_field_name显示正确的值,如以下屏幕截图所示:


我的代码分为两部分.

1)订单"页面中的后端元框,其中可编辑字段显示了来自产品页面(前端)中的自定义字段的正确值:

// 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)前端/后端:

•产品页面自定义字段(前端).
•在购物车,结帐页面和谢谢您的订单上显示此数据(前端).
•在订单页面(后端)上显示数据

// 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);
}

现在一切正常.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆