I added an input element to a product like so:
add_action( 'woocommerce_before_add_to_cart_button', 'add_tip_input', 9 );
function add_tip_input() {
if (is_single(1272)){
$value = isset( $_POST['custom_tip_add_on']);
echo '<div><label class="pour_boire" title="votre appréciation">Votre appréciation</label><p><input type="number" step="1" min="0" name="custom_tip_add_on" value="' . $value . '"></p></div>';
}
}
This works well. Now I try to add this value to the cart and update the total. For that I use woocommerce_cart_calculate_fees
hook:
add_action( 'woocommerce_cart_calculate_fees', 'add_tip', 20, 1 );
function add_tip( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
$value = WC()->session->get( 'custom_tip_add_on' );
$cart->add_fee( 'Votre appréciation', $value );
}
This adds e new line to the cart, but the value is 0,00 ! Obviously, this is the wrong way. When I replace $value with a positive number then all works. But I try to pass the value of the input field to $value and here i fail.
Any help will be highly appreciated.
Using WC_sessions is not required in this case. Instead you need to add this custom product field as custom cart item data:
add_action( 'woocommerce_before_add_to_cart_button', 'add_product_tip_input_field', 9 );
function add_product_tip_input_field() {
// Targeting specific product (or post)
if (is_single(1272)){
$title = __("Votre appréciation", "woocommerce");
printf(
'<div class="custom-tip-wrapper">
<label for="custom_tip" class="pour_boire" title="%s">%s</label>
<p><input type="number" step="1" min="0" name="custom_tip" value="%s"></p>
</div>',
$title, $title, isset($_POST['custom_tip']) ? (int) $_POST['custom_tip'] : '0'
);
}
}
// Add the tip as custom cart item data
add_filter( 'woocommerce_add_cart_item_data', 'filter_add_cart_item_data_callback', 10, 3 );
function filter_add_cart_item_data_callback( $cart_item_data, $product_id, $variation_id ) {
if ( isset( $_POST['custom_tip'] ) && $_POST['custom_tip'] > 0 ) {
$cart_item_data['custom_tip'] = (int) wc_clean( $_POST['custom_tip'] );
$cart_item_data['unique_key'] = md5( microtime().rand() ); // Make each item unique
}
return $cart_item_data;
}
add_action( 'woocommerce_cart_calculate_fees', 'wc_tips_fee', 20, 1 );
function wc_tips_fee( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$fee = 0; // Initializing variable
// Loop through cart items and get the tips from each item
foreach ( $cart->get_cart() as $cart_item ) {
if ( isset($cart_item['custom_tip']) ) {
$fee += $cart_item['custom_tip'];
}
}
if( $fee > 0 ) {
$cart->add_fee( __("Votre appréciation", "woocommerce"), $fee );
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.