提问人:Sjors 提问时间:11/13/2023 最后编辑:LoicTheAztecSjors 更新时间:11/17/2023 访问量:53
允许客户定义特定 WooCommerce 产品的价格
Allow customer to define the price on specific WooCommerce product
问:
我想要一个特定的 WooCommerce 产品,客户可以在其中输入自己的价格/价值来购买礼品卡。我找到了一个非常好的脚本,如果你创建一个价格值为 0 的简单产品,它几乎可以解决问题,但有三个问题我无法解决:
- 使用此脚本,客户可以在类别页面上以价格 0 订购产品。
- 客户还可以在价格字段中输入文本值,而不仅仅是数值。
- 价格 0 在产品页面上可见,隐藏它会更好。我使用css代码来隐藏它,但我认为这不是一种非常简洁的方式。
.single-product.postid-241982 div.product p.price {display: none;}
add_action( 'woocommerce_before_add_to_cart_button', 'bbloomer_product_price_input', 9 );
function bbloomer_product_price_input() {
global $product;
if ( 241982 !== $product->get_id() ) return;
woocommerce_form_field( 'set_price', array(
'type' => 'text',
'required' => true,
'label' => 'Set price ' . get_woocommerce_currency_symbol(),
));
}
add_filter( 'woocommerce_add_to_cart_validation', 'bbloomer_product_add_on_validation', 9999, 3 );
function bbloomer_product_add_on_validation( $passed, $product_id, $qty ) {
if ( isset( $_POST['set_price'] ) && sanitize_text_field( $_POST['set_price'] ) == '' ) {
wc_add_notice( 'Set price is a required field', 'error' );
$passed = false;
}
return $passed;
}
add_filter( 'woocommerce_add_cart_item_data', 'bbloomer_product_add_on_cart_item_data', 9999, 2 );
function bbloomer_product_add_on_cart_item_data( $cart_item, $product_id ) {
if ( 241982 !== $product_id ) return $cart_item;
$cart_item['set_price'] = sanitize_text_field( $_POST['set_price'] );
return $cart_item;
}
add_action( 'woocommerce_before_calculate_totals', 'bbloomer_alter_price_cart', 9999 );
function bbloomer_alter_price_cart( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return;
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$product = $cart_item['data'];
if ( 241982 !== $product->get_id() ) continue;
$cart_item['data']->set_price( $cart_item['set_price'] );
}
}
答:
1赞
LoicTheAztec
11/13/2023
#1
您的代码中存在一些错误和遗漏的内容。请尝试以下操作:
// Remove specific product displayed price on archive pages
add_action( 'woocommerce_after_shop_loop_item_title', 'remove_loop_specific_product_displayed_price', 1 );
function remove_loop_specific_product_displayed_price(){
global $product;
// Only for specific product ID
if ( 241982 == $product->get_id() ) {
// Remove price
remove_action('woocommerce_after_shop_loop_item_title', 'woocommerce_template_loop_price', 10 );
}
}
// Remove specific product displayed price in single product
add_action( 'woocommerce_single_product_summary', 'remove_specific_product_displayed_price', 1 );
function remove_specific_product_displayed_price() {
global $product;
// Only for specific product ID
if ( 241982 == $product->get_id() ) {
// Remove price
remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_price', 10 );
}
}
// Replace loop add to cart button with a link to the product page
add_filter( 'woocommerce_loop_add_to_cart_link', 'replace_specific_product_add_to_cart_link', 100, 3 );
function replace_specific_product_add_to_cart_link( $button, $product, $args ) {
// Only for specific product ID
if ( 241982 == $product->get_id() ) {
$button = sprintf( '<a href="%s" class="%s" %s>%s</a>',
esc_url( $product->get_permalink() ),
esc_attr( 'button' ),
isset( $args['attributes'] ) ? wc_implode_html_attributes( $args['attributes'] ) : '',
esc_html__( 'Set a price', 'woocommerce' )
);
}
return $button;
}
// Display price input field on specific single product
add_action( 'woocommerce_before_add_to_cart_button', 'display_product_price_input_field', 9 );
function display_product_price_input_field() {
global $product;
// Only for specific product ID
if ( 241982 == $product->get_id() ) {
woocommerce_form_field( 'custom_price', array(
'type' => 'text',
'label' => sprintf(__('Set price (%s)', 'woocommerce'), get_woocommerce_currency_symbol()),
'required' => true,
));
}
}
// Add to cart field validation (Accept only a numerical value greater than zero)
add_filter( 'woocommerce_add_to_cart_validation', 'sov_product_add_on_validation' );
function sov_product_add_on_validation( $passed ) {
if ( isset($_POST['custom_price']) ) {
// Replace "," with "." for float numbers
$custom_price = str_replace(',', '.', esc_attr($_POST['custom_price']));
if ( empty($custom_price) || ! is_numeric($custom_price) || ! ($custom_price > 0) ) {
wc_add_notice( 'Set price is a required field (only accepts a numerical value greater than zero)', 'error' );
$passed = false;
}
}
return $passed;
}
// Add custom cart item data
add_filter( 'woocommerce_add_cart_item_data', 'filter_add_cart_item_data', 10, 2 );
function filter_add_cart_item_data( $cart_item_data, $product_id ) {
if ( isset($_POST['custom_price']) ) {
// Replace "," with "." for float numbers
$custom_price = str_replace(',', '.', esc_attr($_POST['custom_price']));
$cart_item_data['custom_price'] = floatval($custom_price);
$cart_item_data['unique_key'] = md5(microtime().rand());
}
return $cart_item_data;
}
// Display the correct cart item custom price html
add_filter( 'woocommerce_cart_item_price', 'filter_cart_displayed_price', 10, 2 );
function filter_cart_displayed_price($price, $cart_item) {
if ( isset($cart_item['custom_price']) ) {
$args = array('price' => floatval($cart_item['custom_price']));
if ('incl' === get_option('woocommerce_tax_display_cart')) {
$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;
}
// Set cart item custom price
add_action( 'woocommerce_before_calculate_totals', 'set_price_before_calculate_totals' );
function set_price_before_calculate_totals( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
if ( isset($cart_item['custom_price']) ) {
$cart_item['data']->set_price( $cart_item['custom_price'] );
}
}
}
代码进入子主题functions.php文件(或插件)中。经过测试并有效。
注意:某些主题会进行自己的自定义,因此可能需要一些不同的东西来删除 WooCommerce 档案和单个产品页面中显示的价格。
评论
0赞
Snuffy
11/13/2023
woocommerce_form_field接受数字作为类型。
0赞
LoicTheAztec
11/13/2023
@Snuffy(我知道,谢谢),但在这种情况下,该字段将向上/向下箭头相加,这对于数量输入字段很好,但对于价格输入则不然。
0赞
Sjors
11/13/2023
谢谢Loic,效果很好!我勾选了“单独销售”,因为如果您购买两种或更多产品,则金额会加到购物车中。我认为,如果以不同的金额购买了两种产品,则在订单确认中看不到单独的金额。
0赞
LoicTheAztec
11/13/2023
正如我所添加的那样,您不需要“单独出售”,这使得每个具有自定义价格的购物车项目都独一无二,并且不能与其他商品混合使用......$cart_item_data['unique_key'] …
评论