允许客户定义特定 WooCommerce 产品的价格

问题描述 投票:0回答:1

我想要一款特定的 WooCommerce 产品,客户可以在其中输入自己的礼品卡价格/价值。我发现了一个非常好的脚本,如果您创建一个价格值为 0 的简单产品,它几乎可以解决问题,但有三个问题我无法解决:

  1. 使用此脚本,客户可以在类别页面上以 0 价格订购产品。
  2. 客户还可以在价格字段中输入文本值,而不仅仅是数字值。
  3. 价格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'] );
   } 
}
php wordpress woocommerce product price
1个回答
0
投票

您的代码中存在一些错误和遗漏的内容。请尝试以下方法:

// 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']) ) {
        $custom_price = str_replace(',','.', esc_attr($_POST['custom_price'])); // replace "," with "." for float numbers
        
        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']) ) {
        $cart_item_data['custom_price'] = floatval($_POST['custom_price']);
        $cart_item_data['unique_key']   = md5(microtime().rand());
    }
    return $cart_item_data;
}

// Display the correct cart item custom price html
add_action( '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 档案和单个产品页面中显示的价格

© www.soinside.com 2019 - 2024. All rights reserved.