给 WooCommerce 产品页面添加自定义字段,并使其影响价格,在很多电商的场景中会需要这个功能。注意这里强调的是用户自定义字段,而非我之前写的 博客 介绍的产品自定义字段,两者不是一个东西。
WooCommerce 产品用户自定义字段,英文翻译叫做“WooCommerce product add-on”,在产品页面上可以这样表现:
我们可以同时添加多个字段,也可以用 select、radio、checkbox,datepicker,甚至是 file uploader 做自定义字段。
要实现这个功能,市面上已经有不少插件了,在官方插件市场上搜一下“WooCommerce product add-on”关键词,就能找到不少同类插件。我测试过过几款,发现功能都差不多,它们也都有免费版和收费版两个版本。一般来说,这类插件的免费版提供各种常规类型的自定义字段,收费版则提供一些特殊类型的自定义字段。另外如果你需要通过这些字段影响商品价格,这个功能我没有在免费版里见过,都需要购买付费版实现。付费版价格在 39 – 69 美元之间,看上去并不贵。但我的原则仍然是能不用插件就不用,需要用户自定义字段的场景,实际上字段都不多,这个功能不复杂,完全可以自己写出来。
下面直接上打包代码,尽量标注释
<?php
//product页面增加用户自定义字段
//1.在购物车按钮所在表单里,添加字段
add_action( 'woocommerce_before_add_to_cart_button', 'brain1981_product_add_on', 9 );
function brain1981_product_add_on() {
$my_custom_addon = isset( $_POST['my_custom_addon'] ) ? sanitize_text_field( $_POST['my_custom_addon'] ) : '';
echo '<input type="text" name="my_custom_addon" value="' . $my_custom_addon . '" />';
}
//2.如果字段为空,抛出报错信息
add_filter( 'woocommerce_add_to_cart_validation', 'brain1981_product_add_on_validation', 10, 3 );
function brain1981_product_add_on_validation( $passed, $product_id, $qty ){
if( isset( $_POST['my_custom_addon'] ) && sanitize_text_field( $_POST['my_custom_addon'] ) == '' ) {
wc_add_notice( '需要输出的报错信息', 'error' );
$passed = false;
}
return $passed;
}
//3.保存字段信息到购物车
add_filter( 'woocommerce_add_cart_item_data', 'brain1981_product_add_on_cart_item_data', 10, 3 );
function brain1981_product_add_on_cart_item_data( $cart_item, $product_id, $variation_id ){
if( isset( $_POST['my_custom_addon'] ) ) {
$cart_item['my_custom_addon'] = sanitize_text_field( $_POST['my_custom_addon'] );
}
return $cart_item;
}
//4.在购物车的产品单项里显示自定义字段
add_filter( 'woocommerce_get_item_data', 'brain1981_product_add_on_display_cart', 10, 2 );
function brain1981_product_add_on_display_cart( $data, $cart_item ) {
if ( isset( $cart_item['my_custom_addon'] ) ){
$data[] = array(
'name' => "My Custom Add-on",
'value' => sanitize_text_field( $cart_item['my_custom_addon'] )
);
}
return $data;
}
//5.干预产品价格
add_action( 'woocommerce_before_calculate_totals', 'brain1981_add_custom_price' );
function brain1981_add_custom_price( $cart_object ) {
$addition_price = 5; //增加的费用
if( !WC()->session->__isset( "reload_checkout" )) {
foreach ( $cart_object->cart_contents as $cart_item_key => $cart_item ) {
if ( isset( $cart_item['my_custom_addon'] ) ){
$newprice = $cart_item['data']->get_price() + $addition_price;
$cart_item['data']->set_price($newprice);
}
}
}
}
//6.在订单中保存自定义字段
add_action( 'woocommerce_add_order_item_meta', 'brain1981_product_add_on_order_item_meta', 10, 2 );
function brain1981_product_add_on_order_item_meta( $item_id, $values ) {
if ( !empty( $values['my_custom_addon'] ) ) {
wc_add_order_item_meta( $item_id, 'my_custom_addon', $values['my_custom_addon'], true );
}
}
//7.在订单详情中显示自定义字段
add_filter( 'woocommerce_order_item_product', 'brain1981_product_add_on_display_order', 10, 2 );
function brain1981_product_add_on_display_order( $cart_item, $order_item ){
if( isset( $order_item['my_custom_addon'] ) ){
$cart_item['my_custom_addon'] = $order_item['my_custom_addon'];
}
return $cart_item;
}
//8.在订单邮件中显示自定义字段
add_filter( 'woocommerce_email_order_meta_fields', 'brain1981_product_add_on_display_emails' );
function brain1981_product_add_on_display_emails( $fields ) {
$fields['my_custom_addon'] = "My Custom Add-on";
return $fields;
}
总结,整个订单流程一共需要在 8 个钩子中增加输出、保存的代码。本例程作用其实就是整理这些用得到的钩子,WordPress 二次开发中最耗时间的其实就是翻文档找钩子了,钩子一确定,后面的逻辑代码就容易写了。至于字段,这里为了精简,只列举一个字段的行进流程,相信你定能举一反三。
专业提供WordPress主题安装、深度汉化、加速优化等各类网站建设服务,详询在线客服!