将值从函数传递到 woocommerce 钩子

Passing value from function to woocommerce hook

在 Woocommerce 中,我试图将一些值从自定义简单函数传递到 "woocommerce_before_calculate_totals" 操作挂钩中的挂钩函数。但我总是得到一个空值。

我试图将 $new_price 转储到 add_custom_item_price() 函数中,它仍然是 int(0)
我还尝试将 $_POST['fabric_length'] 转储到 add_custom_item_price() 函数及其 NULL.

这是我的代码:

function calculate_new_price() {
    global $post;

    $category = wp_get_post_terms($post->ID,'product_cat');
    $meter_price = get_field('meter_price');
    $price_per_centimeter = $meter_price / 100;
    $total_height_price = $_POST['fabric_length'] * $price_per_centimeter;

    return $total_height_price;
}

$new_price = calculate_new_price();

add_filter( 'woocommerce_before_calculate_totals', 'add_custom_item_price', 10, 1 );
function add_custom_item_price( $cart_object ) {
    global $new_price; <------ returns int(0) when var_dump in this function

    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    foreach (  $cart_object->get_cart() as $item_values ) {
        $item_values['data']->set_price(ceil($new_price));
    }
}

我错过了什么?

感谢任何帮助。

更新…

这是一个完整的代码(可验证),包含前端和后端自定义字段,将向您展示无需使用高级自定义字段即可使其在高级自定义上运行的正确方法:

// Frontend: The product custom field [FOR TESTING]
add_action( 'woocommerce_before_add_to_cart_button', 'fabric_length_product_field' );
function fabric_length_product_field() {
    global $product;
    // The fake calculated price
    ?>
        <div>
            <label class="product-custom-text-label" for="servicetime"><?php _e( 'Fabric lenght:', 'woocommerce'); ?><br>
                <input type="text" id="fabric_length" name="fabric_length" value="">
            </label>
        </div><br>
    <?php
}

// Backend: Add a custom field to product in backend [FOR TESTING]
add_action( 'woocommerce_product_options_pricing', 'add_field_product_options_pricing' );
function add_field_product_options_pricing() {
    global $post;

    echo '<div class="options_group">';

    woocommerce_wp_text_input( array(
        'id'            => '_meter_price',
        'label'         => __('Metter price', 'woocommerce') . ' (' . get_woocommerce_currency_symbol() . ')',
        'placeholder'   => __('Set the Metter price…', 'woocommerce'),
        'description'   => __('Enter the custom value here.', 'woocommerce'),
        'desc_tip'      => 'true',
    ));

    echo '</div>';
}

// Save product custom field to database when submitted in Backend [FOR TESTING]
add_action( 'woocommerce_process_product_meta', 'save_product_options_custom_fields', 30, 1 );
function save_product_options_custom_fields( $post_id ){
    // Saving custom field value
    if( isset( $_POST['_meter_price'] ) ){
        update_post_meta( $post_id, '_meter_price', sanitize_text_field( $_POST['_meter_price'] ) );
    }
}

// Add custom calculated price conditionally as custom data to cart items
add_filter( 'woocommerce_add_cart_item_data', 'add_custom_price_to_cart_item_data', 20, 2 );
function add_custom_price_to_cart_item_data( $cart_item_data, $product_id ){
    if( ! isset($_POST['fabric_length']) )
        return $cart_item_data;

    // Get your data
    $meter_price = get_post_meta( $product_id, '_meter_price', true );
    if( empty($meter_price) || $meter_price == 0 )
        return $cart_item_data;

    $fabric_length = (float) sanitize_text_field( $_POST['fabric_length'] );
    if( empty($fabric_length) || $fabric_length == 0 )
        return $cart_item_data;

    // Price Calculations and saving
    $cart_item_data['custom_price'] = ceil( $fabric_length * $meter_price / 100 );
    $cart_item_data['unique_key'] = md5( microtime() . rand() ); // Make each item unique

    return $cart_item_data;
}

// Set conditionally a custom item price
add_action('woocommerce_before_calculate_totals', 'set_cutom_cart_item_price', 20, 1);
function set_cutom_cart_item_price( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

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

    foreach (  $cart->get_cart() as $cart_item ) {
        if ( isset( $cart_item['custom_price'] ) )
            $cart_item['data']->set_price( $cart_item['custom_price'] );
    }
}

代码进入您的活动子主题(或活动主题)的 function.php 文件。测试和工作。