【问题标题】:Save custom metadata from subscription product variation to order将订阅产品变体中的自定义元数据保存到订单
【发布时间】:2019-12-06 04:32:27
【问题描述】:

我需要能够将管理数据添加到订阅产品变体(Woo 订阅扩展),以便在下订单时将此数据传递到履行中心。

我遇到的问题是从产品中获取这些值并将它们传递到订单和电子邮件通知中,以便它们可以正确导出、添加到运输标签并通过各种 woo 通知通过电子邮件发送。

我在订阅产品的变体中添加了自定义元字段。我可以将数据添加到这些数据中,然后它们会以正确的变体 ID 将数据正确保存到数据库中。没问题。

我可以在购物车和结帐页面上显示自定义测试数据,并将这些数据保存到您将在代码中看到的订单中。

为简洁起见,以下代码被简化,但实际上有 6 个文本字段:

// Add custom field inputs to each product variation
add_action( 'woocommerce_variation_options_pricing', 'add_custom_field_to_variations', 10, 3 );

function add_custom_field_to_variations( $loop, $variation_data, $variation ) {
    woocommerce_wp_text_input( 
        array(
            'id' => '_dose_customer_field[' . $loop . ']',
            'label'       => __( 'Dose (Customer)', 'woocommerce' ), 
            'placeholder' => __('Enter the treatment dosage','woocommerce' ),
            'desc_tip'    => 'true',
            'description' => __( 'Enter dosage info for this variation', 'woocommerce' ),
            'class' => '',
            'value' => get_post_meta( $variation->ID, '_dose_customer_field', true )
        )
    );
}

// Save custom field on product variation save 
add_action( 'woocommerce_save_product_variation', 'save_custom_field_variations', 10, 2 );

function save_custom_field_variations( $variation_id, $i ) {
    $_dose_customer_field = $_POST['_dose_customer_field'][$i];
    if ( isset( $_dose_customer_field ) ) update_post_meta( $variation_id, '_dose_customer_field', esc_attr( $_dose_customer_field ) );   
}

// Add metadata to cart item post.
add_filter( 'woocommerce_add_cart_item_data', 'add_custom_fields_cart_item_data', 10, 2 );

function add_custom_fields_cart_item_data( $cart_item_data, $product_id ){    

    $cart_item_data['custom_data']['_dose_customer_field'] = 'TEST DATA' /* HOW TO GET DATA FROM CUSTOM FIELD HERE */       

    $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 meta data on cart and checkout page.
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;

    if( array_key_exists( '_dose_customer_field', $cart_item['custom_data'] ) )
        $item_data[] = array(
            'key'   => __('Dose (Customer)', 'woocommerce'),
            'value' => $cart_item['custom_data']['_dose_customer_field']
        );

    return $item_data;
}

// Add metadata to the order.
add_action('woocommerce_checkout_create_order_line_item', 'save_custom_fields_as_order_item_meta', 20, 4);

function save_custom_fields_as_order_item_meta($item, $cart_item_key, $values, $order) {
    if( ! isset($values['custom_data']) )
        return;

    $text_domain ='woocommerce';

    if( array_key_exists('_dose_customer_field', $values['custom_data']) ){
        $item->update_meta_data( __('Dose (Customer)', $text_domain), $values['custom_data']['_dose_customer_field'] );
    }    
}

// Frontend & emails: Display data on notifications
add_action( 'woocommerce_order_item_meta_start', 'vp_order_item_display_commodity_code', 10, 4 );
function vp_order_item_display_commodity_code( $item_id, $item, $order, $plain_text ) {
    // Not on admin
    //if( is_admin() ) return;

    if( $value = $item->get_meta('_dose_customer_field') ) {
        $value = '<strong>' . __("Dose (Customer)", "woocommerce") . ':</strong> ' . esc_attr( $value );

        // On orders
        if( is_wc_endpoint_url() )
            echo '<div class="vp-ccode"><small>' . $value . '</small></div>';
        // On Emails
        else
            echo '<div>' . $value . '</div>';
    }
}

除了从自定义字段中获取数据外,一切正常。我必须创建一个新数组(此处称为“custom_data”)并将其添加到 cart_item_data 中,这似乎很奇怪,因为数据已经在产品变体中可用,尽管是私有的。

我的问题是如何在 add_custom_fields_cart_item_data() 中获取元数据?这甚至是正确的方法吗?

非常感谢

【问题讨论】:

    标签: php wordpress woocommerce woocommerce-subscriptions


    【解决方案1】:

    由于产品存在此自定义数据,您可以轻松获取并将其保存为订单项自定义数据(因此它将在任何地方显示):

    完整代码(更改了最后两个函数):

    // Add custom field inputs to each product variation
    add_action( 'woocommerce_variation_options_pricing', 'add_custom_field_to_variations', 10, 3 );
    function add_custom_field_to_variations( $loop, $variation_data, $variation ) {
        woocommerce_wp_text_input( 
            array(
                'id' => '_dose_customer_field[' . $loop . ']',
                'label'       => __( 'Dose (Customer)', 'woocommerce' ), 
                'placeholder' => __('Enter the treatment dosage','woocommerce' ),
                'desc_tip'    => 'true',
                'description' => __( 'Enter dosage info for this variation', 'woocommerce' ),
                'class' => '',
                'value' => get_post_meta( $variation->ID, '_dose_customer_field', true )
            )
        );
    }
    
    // Save custom field on product variation save 
    add_action( 'woocommerce_save_product_variation', 'save_custom_field_variations', 10, 2 );
    function save_custom_field_variations( $variation_id, $i ) {
        $_dose_customer_field = $_POST['_dose_customer_field'][$i];
        if ( isset( $_dose_customer_field ) ) update_post_meta( $variation_id, '_dose_customer_field', esc_attr( $_dose_customer_field ) );   
    }
    
    // Display custom meta data on cart and checkout page.
    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( $value = $cart_item['data']->get_meta( '_dose_customer_field' ) )
            $item_data[] = array(
                'key'   => __('Dose (Customer)', 'woocommerce'),
                'value' => $value
            );
    
        return $item_data;
    }
    
    // Add metadata to the order item (and display it everywhere).
    add_action('woocommerce_checkout_create_order_line_item', 'save_custom_fields_as_order_item_meta', 10, 4);
    function save_custom_fields_as_order_item_meta( $item, $cart_item_key, $values, $order ) {
        if( $meta_value = $values['data']->get_meta( '_dose_customer_field' ) )
            $item->update_meta_data( __('Dose (Customer)', 'woocommerce'), $meta_value );  
    }
    

    代码在您的活动子主题(或活动主题)的functions.php 文件中。它应该可以工作。

    【讨论】:

    • 他射门得分!感谢 Loic,这是一种享受。感谢您在这方面的时间。
    猜你喜欢
    • 2020-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-25
    • 2021-05-21
    • 2020-07-06
    • 1970-01-01
    相关资源
    最近更新 更多