我正在try 创建一个单一产品页面的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);

我try 使用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样式文件入队需要单独的函数(you may need to make some CSS changes in your style rules):

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__));
}

对于您的自定义数据库查询,最好将每个设置在单独的函数(reason: code modularity)中:

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");
}

下面是您重新访问的代码函数,它挂接到了另一个钩子(其中我在产品表单中包含了一个强制隐藏的输入字段):

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']);
        }
    }
}

代码放在活动子主题(或活动主题)的unctions.php文件中,或者也放在插件中.经过测试,效果良好.

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

Php相关问答推荐

如何使用属性#[Embedded]嵌入带有规则的对象集合?

根据用户组或登录状态显示或隐藏定价后添加的文本

在WooCommerce管理订单页面中显示区域名称

Htaccess-重写对&api.php";的API请求以及对";web.php";的其他请求

Laravel Nova不使用数组键作为筛选器中的选项值

我必须对所有的SQL查询使用预准备语句吗?

是否重新排序多维数组元素以将所有子数组中的子数组移动到元素列表的底部?

如何在Laravel Model中自定义多个日期属性的日期格式?

PHP -将字符串拆分为两个相等的部分,但第二个字符串中的单词更多

在WooCommercel邮箱通知上添加来自Apaczka插件的选定交付点

以编程方式同步 WPML 翻译更改 Woocommerce 产品销售价格

Symfony:从控制器内部调用自定义命令

invalid_grant 和无效的 JWT 签名

如何判断php中wordpress路径之外的文件夹是否存在?

在 WooCommerce wc_get_products 函数中处理自定义分类法

在 Symfony 测试中何时使用 TestCase 而不是 KernelTestCase

适当的时区处理 Laravel / Carbon

我正在使用 Baryryvdh/laravel-snappy 从 HTML 导出 PDF 它正在工作但缩小了 pdf 文件

为什么非贪婪匹配会消耗整个模式,即使后面跟着另一个非贪婪匹配

使用 OOP PHP 创建动态 WHERE 子句.如何实现 BETWEEN 运算符?