在store 中,产品的价格是根据用户在产品页面上提交的"长度"字段来计算的.由于这个长度是重要的信息,我想显示提交的长度也在购物车,在 checkout 和发票审查订单.

我已经成功地将该字段添加到购物车中,但如何才能将其添加到审查订单和发票中的购物车项目中?(甚至在整个过程中提到的每个产品中).是否有我可以使用的滤镜或操作?那又是怎么做的呢?我找不到吗?

我有以下(相关)代码:

// Get custom field value Length, calculate new item price, save it as custom cart item data
add_filter('woocommerce_add_cart_item_data', 'add_custom_field_data', 20, 2 );
function add_custom_field_data( $cart_item_data, $product_id ){
    if (! isset($_POST['length']))
        return $cart_item_data;

    $length = (float) sanitize_text_field( $_POST['length'] );
    if( empty($length) )
        return $cart_item_data;

    $product    = wc_get_product($product_id); // The WC_Product Object
    $base_price = (float) $product->get_regular_price(); // Product reg price

    // New price calculation
    $new_price = (($base_price * $length)/1000)+1.90;

    // Set the custom amount in cart object
    $cart_item_data['custom_data']['extra_charge'] = (float) $length;
    $cart_item_data['custom_data']['new_price'] = (float) $new_price;
    $cart_item_data['custom_data']['unique_key'] = md5( microtime() . rand() ); // Make each item unique

    return $cart_item_data;
}

// Set the new calculated cart item price
add_action( 'woocommerce_before_calculate_totals', 'new_price_add_length', 20, 1 );
function new_price_add_length( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    foreach ( $cart->get_cart() as $cart_item ) {
        if( isset($cart_item['custom_data']['new_price']) )
            $cart_item['data']->set_price( (float) $cart_item['custom_data']['new_price'] );
    }
}

//Add length to product in cart
add_action( 'woocommerce_after_cart_item_name', 'wmw_display_length', 20  );
function wmw_display_length( $cart_item ) {
    if( isset($cart_item['custom_data']['extra_charge']) ) {
        $length = $cart_item['custom_data']['extra_charge'];
        echo '<dl class="variation"><dt class="variation-Length">Length(mm):</dt><dd class="variation-Length"><p>' . $cart_item['custom_data']['extra_charge'] . '</dd></dl>';
    }
}

您知道如何在其他位置/屏幕上获取这些数据吗?

推荐答案

Update

For testing purpose only,因为您没有提供在单一产品页面中显示"长度"输入字段的代码,所以我使用以下函数:

// FOR testing: Display length field in single product pages
add_action('woocommerce_before_add_to_cart_button', 'testing_custom_product_input_field', 5 );
function testing_custom_product_input_field() {
    
    woocommerce_form_field('length', array(
        'class'       => array( 'form-row-left') ,
        'label'       => __('Length(mm)', 'woocommerce' ),
        'placeholder' => __('Define the required Length (in mm)') ,
        'required'    => true,
    ) , '');
}

然后我对您提供的代码进行了简化和更改,因此现在"长度"显示在购物车、微型购物车和 checkout 页面中.
使用以下代码替换:

// Get custom field value Length, calculate new item price, save it as custom cart item data
add_filter('woocommerce_add_cart_item_data', 'add_custom_cart_item_data', 20, 2 );
function add_custom_cart_item_data( $cart_item_data, $product_id ){
    if ( isset($_POST['length']) && ! empty($_POST['length']) ) {
        $product = wc_get_product($product_id); // Get WC_Product Object
        $length  = (float) sanitize_text_field( $_POST['length'] );
        $price   = ( floatval($product->get_regular_price()) * $length / 1000 ) + 1.90;  // New price calculation

        $cart_item_data['custom_data']['length'] = $length;
        $cart_item_data['custom_data']['price']  = $price;
        $cart_item_data['custom_data']['unique_key'] = md5( microtime() . rand() ); // Make each item unique
    }
    return $cart_item_data;
}


// Display custom cart item data in mini cart, Cart and Checkout pages
add_filter( 'woocommerce_get_item_data', 'display_custom_cart_item_data', 20, 2 );
function display_custom_cart_item_data( $cart_data, $cart_item ) {
    if( isset($cart_item['custom_data']['length']) ) {
        $cart_data[] = array(
            'key'   => __('Length(mm)', 'woocommerce'),
            'value' => $cart_item['custom_data']['length'],
        );
    }
    return $cart_data;
}


// Set the new calculated cart item price
add_action( 'woocommerce_before_calculate_totals', 'new_price_add_length', 20, 1 );
function new_price_add_length( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    foreach ( $cart->get_cart() as $cart_item ) {
        if( isset($cart_item['custom_data']['price']) )
            $cart_item['data']->set_price($cart_item['custom_data']['price']);
    }
}

添加以下缺少的代码,用于处理小型购物车显示的定制价格:

// Handle mini cart displayed price
add_filter( 'woocommerce_cart_item_price', 'display_new_price_add_length', 20, 2 );
function display_new_price_add_length( $price_html, $cart_item ) {

    if( isset($cart_item['custom_data']['price']) ) {
        $args = array( 'price' => floatval($cart_item['custom_data']['price']) ); 

        if ( WC()->cart->display_prices_including_tax() ) {
            $product_price = wc_get_price_including_tax( $cart_item['data'], $args );
        } else {
            $product_price = wc_get_price_excluding_tax( $cart_item['data'], $args );
        }
        return wc_price( $product_price );
    }
    return $price_html;
}

要完成此操作,请添加以下内容,以显示您在客户订单、管理订单、邮箱通知和发票上的"长度":

// Save and display the Length (custom order item metadata)
add_action( 'woocommerce_checkout_create_order_line_item', 'save_order_item_custom_meta_data', 10, 4 );
function save_order_item_custom_meta_data( $item, $cart_item_key, $values, $order ) {
    if( isset($values['custom_data']['length']) ) {
        $item->update_meta_data( 'length', $values['custom_data']['length'] ); 
    }
}

// Add readable "meta key" label name replacement
add_filter('woocommerce_order_item_display_meta_key', 'filter_wc_order_item_display_meta_key', 10, 3 );
function filter_wc_order_item_display_meta_key( $display_key, $meta, $item ) {
    if( $item->get_type() === 'line_item' && $meta->key === 'length' ) {
        $display_key = __('Length(mm)', 'woocommerce' );
    }
    return $display_key;
}

代码位于您的子主题的unctions.php文件中(或在插件中).经过测试和工作.


Checkout page:

enter image description here


Customer order:

enter image description here


Admin order:

enter image description here


Email notification:

enter image description here

Php相关问答推荐

输入手写CSV时在PHP中进行日期判断

闭包绑定$This和垃圾收集器

如何在UML类图中可视化变量引用数组

未检测到laravel控制器

如何在其他数组php中创建具有关联数组的数组

如何在 apache Laragon - laravel 10 中允许方法 DELETE?

execute_query 和prepare+execute 有什么区别?

奇怪的 preg_match_all() 行为

无法使用 slim 的父级容器

循环中未序列化数组显示的问题

Laravel:ArgumentCountError: 函数 App\Mail 的参数太少

我怎样才能在 .htaccess 中有 2 个参数?

计算组合指数

Laravel 10 单元测试看不到来自 Artisan Command 的数据库更改

如何将数字文本文件添加到 PHP 数学方程式中?

Docker: unixodbc.h 没有这样的文件或目录.已安装 unixodbc-dev 时出现pecl install sqlsrv错误

Symfony 自定义注销

Symfony 在将它传递给 Twig 时是否从数据库中获取整个对象?

路由未定义的 laravel 导出

在管理表单字段中