Use Code Added In functions.php:
<?php
// Add Custom Fields in after add to cart button
add_action( 'woocommerce_before_add_to_cart_button', 'cxc_before_add_to_cart_button_custom_field' );
function cxc_before_add_to_cart_button_custom_field() {
?>
<div class="woocommerce-variation-add-to-cart variations_button woocommerce-variation-add-to-cart-disabled">
<table class="variations" cellspacing="0" width="100px">
<tbody>
<tr>
<td colspan="2" style="text-align: center;"><label for="cxc-additional-fields"><?php echo __("Cxc Additional Fields", "cxc-codexcoach"); ?></label></td>
</tr>
<tr>
<td class="label" style="width:100px"><label for="color"><?php echo __("Width", "cxc-codexcoach"); ?></label></td>
<td class="value">
<input type="text" name="new-width" value="" required/>
</td>
</tr>
<tr>
<td class="label"><label for="color"><?php echo __("Hight", "cxc-codexcoach"); ?></label></td>
<td class="value">
<input type="text" name="new-height" value="" required/>
</td>
</tr>
</tbody>
</table>
<?php
}
?>
Then you will be able to use woocommerce_add_to_cart_validation hook for field validation
<?php
// Field validation
add_action( 'woocommerce_add_to_cart_validation', 'cxc_woocommerce_add_to_cart_validation_call_back' );
function cxc_woocommerce_add_to_cart_validation_call_back( $passed ) {
$error_notice = array(); // Initializing
if ( isset($_POST['new-width']) && empty($_POST['new-width']) ) {
$passed = false;
$error_notice[] = __('"Width" is a required field', 'cxc-codexcoach');
}
if ( isset($_POST['new-height']) && empty($_POST['new-height']) ) {
$passed = false;
$error_notice[] = __('"Hight" is a required field', 'cxc-codexcoach');
}
// Display errors notices
if ( ! empty($error_notice) ) {
wc_add_notice( implode('<br>', $error_notice), 'error' );
}
return $passed;
}
?>
The following fields must now be saved as custom cart item data and displayed in the shopping cart and checkout pages:
<?php
// Save as custom cart item data
add_filter( 'woocommerce_add_cart_item_data', 'cxc_woocommerce_add_cart_item_data', 10, 2 );
function cxc_woocommerce_add_cart_item_data( $cart_item_data, $product_id ) {
if ( isset($_POST['new-width']) && ! empty($_POST['new-width']) ) {
$cart_item_data['new-width'] = sanitize_text_field($_POST['new-width']);
}
if ( isset($_POST['new-height']) && ! empty($_POST['new-height']) ) {
$cart_item_data['new-height'] = sanitize_text_field($_POST['new-height']);
}
return $cart_item_data;
}
// Display in cart and checkout
add_filter( 'woocommerce_get_item_data', 'cxc_display_on_cart_and_checkout', 10, 2 );
function cxc_display_on_cart_and_checkout( $cart_data, $cart_item ) {
if ( isset($cart_item['new-width']) ) {
$cart_data[] = array( "name" => __("Width", "cxc-codexcoach"), "value" => $cart_item['new-width'] );
}
if ( isset($cart_item['new-height']) ) {
$cart_data[] = array( "name" => __("Hight", "cxc-codexcoach"), "value" => $cart_item['new-height'] );
}
return $cart_data;
}
?>
You must display the data from the fields in orders and emails after saving them as custom order item data:
<?php
// Display on orders and email notifications (save as custom order item meta data)
add_action( 'woocommerce_checkout_create_order_line_item', 'cxc_display_on_orders_and_emails', 10, 4 );
function cxc_display_on_orders_and_emails( $item, $cart_item_key, $values, $order ) {
if ( isset($values['new-width']) ) {
$item->add_meta_data( __("Width", "cxc-codexcoach"), $values['new-width'] );
}
if ( isset($values['new-height']) ) {
$item->add_meta_data( __("Hight", "cxc-codexcoach"), $values['new-height'] );
}
}
?>
We need to use 2 different hooks:
- The first one just as yours without trying to change the price in it.
- The second one where you will change your cart item price.
The code:
<?php
add_filter( 'woocommerce_add_cart_item', 'cxc_add_custom_cart_item_data', 10, 2 );
function cxc_add_custom_cart_item_data( $cart_item_data, $cart_item_key ) {
if( isset( $_POST['new-width'] ) )
$cart_item_data['new-width'] = $_POST['new-width'];
if( isset( $_POST['new-height'] ) )
$cart_item_data['new-height'] = $_POST['new-height'];
return $cart_item_data;
}
add_action( 'woocommerce_before_calculate_totals', 'cxc_set_custom_cart_item_price', 20, 1 );
function cxc_set_custom_cart_item_price( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ){
return;
}
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ){
return;
}
// First loop to check if product 11 is in cart
foreach ( $cart->get_cart() as $cart_item ){
if( isset($cart_item['new-width']) && isset($cart_item['new-height']) && ! empty($cart_item['new-width']) && ! empty($cart_item['new-height']) ){
$cart_item['data']->set_price( 50 );
}
}
}
?>
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.