【问题标题】:Auto add order item custom meta data to order note in WooCommerce在 WooCommerce 中自动将订单项目自定义元数据添加到订单备注
【发布时间】:2018-07-12 10:13:25
【问题描述】:

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

}

根据下面的屏幕截图,您会看到数据已保存到产品中,但未正确拉入订单备注部分。

任何想法为什么会这样?

【问题讨论】:

    标签: php wordpress woocommerce custom-fields orders


    【解决方案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 文件中。

    经过测试并按预期工作。

    【讨论】:

    • 实际上我在您的屏幕截图中注意到它实际上并没有将值拉入注释字段?中性计数应为 3,明亮计数应为 2,而不是 0?
    • @warm__tape 我已经重写了一切,也就是你所有的代码。这一次它可以完美运行,正如您将在屏幕截图中看到的那样。因此,要对其进行测试,您必须替换所有相关代码。它既适用于单一产品,也适用于多种不同的产品。
    • @warm__tape 测试后,您可以删除/删除您的新问题。
    猜你喜欢
    • 1970-01-01
    • 2021-07-13
    • 1970-01-01
    • 2021-06-01
    • 1970-01-01
    • 2018-01-03
    • 1970-01-01
    • 2021-02-12
    • 2023-03-15
    相关资源
    最近更新 更多