php - WooCommerce 单一添加到购物车页面中的产品动态定价

标签 php wordpress woocommerce product price

我正在尝试为单个产品页面创建一个 WooCommerce 插件。我需要将常规定价与自定义定价相加。我能够获得常规价格与自定义价格的总和,但是当我单击“添加到购物车”时,我无法在购物车中设置新的计算价格。

感谢任何帮助。

// WooCommerce activation
function custom_product_page()
{
    global $wpdb;
    global $product;
    wp_enqueue_style('my-plugin-styles', plugins_url('assets/css/diamond_style.css', __FILE__));

    if (class_exists('WooCommerce') && is_product()) {
        $product = wc_get_product(get_the_ID());

        $product_categories = wp_get_post_terms(get_the_ID(), 'product_cat');
        $is_ring = false;
        foreach ($product_categories as $product_category) {
            if ($product_category->slug === 'rings' || $product_category->slug === 'ring') {
                $is_ring = true;
                break;
            }
        }
        $table_name = $wpdb->prefix . 'diamond_purity';
        $ring_size_table = $wpdb->prefix . 'ring_size';

        // Show Metal Color only if the product category is "ring"
        if ($is_ring) {
            // Retrieve the latest gold rate
            $gold_rate_table = $wpdb->prefix . 'gold_rate';
            $gold_rate = $wpdb->get_var("SELECT final_price FROM $gold_rate_table ORDER BY id DESC LIMIT 1");

            // Get the net weight attribute
            $net_weight = $product->get_attribute('net-weight-g');

            // Get the regular price
            $regular_price = $product->get_regular_price();

            // Calculate the updated price
            $updated_price = ($gold_rate * $net_weight) + $regular_price;

            // Display the updated price
            echo '<p class="productprice">&#8377;' . $updated_price . '</p>';

            $gross_weight = $product->get_attribute('gross-weight');
            echo 'Weight: ' . $gross_weight . ' g';

          

            // Update cart item price with the custom price
            add_filter('woocommerce_add_cart_item', function ($cart_item) use ($updated_price) {
                $cart_item['data']->set_price($updated_price);
                return $cart_item;
            });
        }
    }
}
add_action('woocommerce_single_product_summary', 'custom_product_page', 25);

我尝试使用 add_filter 但没有用。

最佳答案

我重新审视了你的代码,因为有一些错误、错误和遗漏的东西。在这里,缺少的是产品添加到购物车表单中的隐藏输入字段,用于在添加到购物车操作时发布自定义价格。然后您将能够使用该自定义价格。

由于您似乎在插件中使用代码,因此您应该开始将以下内容添加到主插件文件中,以检查 WooCommerce 是否处于事件状态:

defined( 'ABSPATH' ) or exit;

// Make sure WooCommerce is active
if ( ! in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
    return;
}

对 CSS 样式文件进行排队需要一个单独的函数(您可能需要在样式规则中进行一些 CSS 更改):

add_action( 'wp_enqueue_scripts', 'custom_product_pricing_css' );
function custom_product_pricing_css() {
    // Only on product single pages
    if( ! is_product() ) return;

    wp_enqueue_style('my-plugin-styles', plugins_url('assets/css/diamond_style.css', __FILE__));
}

对于自定义数据库查询,最好将每个查询设置在单独的函数中(原因:代码模块化):

function get_the_gold_rate() {
    global $wpdb;

    return $wpdb->get_var( "SELECT final_price FROM {$wpdb->prefix}gold_rate ORDER BY id DESC LIMIT 1");
}

这是您重新访问的代码函数,卡在另一个钩子(Hook)中(我在产品表单中包含一个强制隐藏输入字段):

add_action('woocommerce_before_add_to_cart_button', 'add_to_cart_product_pricing', );
function add_to_cart_product_pricing() {
    global $woocommerce, $product;

    if ( is_a($woocommerce, 'WooCommerce') && is_product() ) {

        // Targeting "ring" or "rings" product category
        if ( has_term( array('ring', 'rings'), 'product_cat' ) ) {
            // Load the latest gold rate
            $gold_rate = (float) get_the_gold_rate();

            // Get net weight product attribute
            $net_weight = $product->get_attribute('net-weight-g');

            // Get product regular price
            $regular_price = $product->get_regular_price();

            // Calculate product updated price
            $updated_price = ($gold_rate * $net_weight) + $regular_price;

            // Get the displayed price 
            $args = array( 'price' => floatval( $updated_price ) );

            if ( 'incl' === get_option('woocommerce_tax_display_shop') ) {
                $displayed_price = wc_get_price_including_tax( $product, $args );
            } else {
                $displayed_price = wc_get_price_excluding_tax( $product, $args );
            }

            // Display product updated price
            printf( '<p class="productprice">%s</p>', wc_price( $displayed_price ) );

            // Display a hidden input field with the "updated_price" as value
            printf( '<input type="hidden" name="updated_price" value="%s" />', $updated_price );
            
            // Get gross weight product attribute 
            $gross_weight = $product->get_attribute('gross-weight');

            // Display the Gross Weight
            printf( '<p class="grossweight">' . __('Weight: %s g') . '</p>', $gross_weight );
        }
    }
}

现在,为了将更新后的价格包含为自定义购物车商品数据,我们使用以下内容:

add_filter( 'woocommerce_add_cart_item_data', 'save_custom_cart_item_data', 10, 2 );
function save_custom_cart_item_data( $cart_item_data, $product_id ) {

    if( isset($_POST['updated_price']) && ! empty($_POST['updated_price'])  ) {
        // Set the custom data in the cart item
        $cart_item_data['updated_price'] = (float) wc_clean($_POST['updated_price']);

        // Make each item as a unique separated cart item
        $cart_item_data['unique_key'] = md5( microtime().rand() );
    }
    return $cart_item_data;
}

因此,我们现在可以在 Minicart 中显示具有此自定义更新价格的商品:

add_action( 'woocommerce_cart_item_price', 'filter_cart_displayed_price', 10, 2 );
function filter_cart_displayed_price( $price, $cart_item ) {
    if ( isset($cart_item['updated_price']) ) {
        $args = array( 'price' => floatval( $cart_item['updated_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;
}

最后,我们使用自定义更新价格设置购物车商品价格:

add_action( 'woocommerce_before_calculate_totals', 'set_new_cart_item_updated_price' );
function set_new_cart_item_updated_price( $cart ) {
    if ( ( is_admin() && ! defined( 'DOING_AJAX' ) ) )
        return;

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

    // Loop through cart items and set the updated price
    foreach ( $cart->get_cart() as $cart_item ) {
        // Set the new price
        if( isset($cart_item['updated_price']) ){
            $cart_item['data']->set_price($cart_item['updated_price']);
        }
    }
}

代码也位于事件子主题(或事件主题)的functions.php 文件中或插件中。经过测试并有效。

相关:Custom cart item price set from product hidden input field in Woocommerce 3

关于php - WooCommerce 单一添加到购物车页面中的产品动态定价,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76530827/

相关文章:

css - 在 WordPress 插件中集成 bootstrap 时避免命名空间冲突

javascript - 相同的 div 类具有不同的 css 样式

php - 根据产品类别自动添加 WooCommerce 优惠券代码

php mysql 只选择最后 3 行,如果它们相似并且在 15 分钟前更新

javascript - 使用户能够在新窗口中返回上一页

javascript - 我将如何根据所选语言订购品牌 div?

php - 在 Woocommerce 中将 COD 默认订单状态更改为 "On Hold"而不是 "Processing"

javascript - 检测页面中任何文本区域的更改,并将此特定输入中更改的数据添加到其他表中

php - MySql - 为数组组织变量

javascript - 将 Facebook Pixel 购买事件代码添加到 WooCommerce 购买完成页面