In Woocommerce on each product page there is a Text Box, which allows users to enter their own custom text. This text is then applied to the product, with the customer being charged on a per letter basis.
I have managed to get everything working, apart from the Maths Logic. When a visitor enters x amount of letters, the current Maths logic correctly calculates the Product Price + Cost of Custom Letters and outputs this sum to the Basket Widget.
Where I am running into problems, is when the visitor goes to the Basket Page, the Cost of the Custom Lettering is doubled.
I just cannot seem to work out why this is.
Create Text Field in Product Dashboard:
<?php
/*Create Text Field in Product Dashboard*/
function add_text_field_product_dashboard(){
global $post;
$input_checkbox = get_post_meta( $post->ID, '_custom_text_option', true );
if( empty( $input_checkbox ) || $input_checkbox == 'no' ) $input_checkbox = '';
echo '<div class="product_custom_field">';
/*Product Checkbox Field*/
woocommerce_wp_checkbox(
array(
'id' => '_custom_text_option',
'desc' => __('set custom custom text field', 'woocommerce'),
'label' => __('Display custom custom text field', 'woocommerce'),
'desc_tip' => 'true',
'value' => $input_checkbox
)
);
/*Minimum Letter Text Box*/
woocommerce_wp_text_input(
array(
'id' => '_minimum_custom_text_option',
'name' => '_minimum_custom_text_option',
'desc' => __('set custom minimum Lettering text field', 'woocommerce'),
'label' => __('Minimum Letters', 'woocommerce'),
'desc_tip' => 'true'
)
);
/*Maximum Letter Text Box*/
woocommerce_wp_text_input(
array(
'id' => '_maximum_custom_text_option',
'desc' => __('set custom maximum Lettering text field', 'woocommerce'),
'label' => __('Maximum Letters', 'woocommerce'),
'desc_tip' => 'true'
)
);
/*Cost Per Letter Pricing*/
woocommerce_wp_text_input(
array(
'id' => '_pricing_custom_text_option',
'desc' => __('set custom pricing Lettering text field', 'woocommerce'),
'label' => __('Cost Per Letter', 'woocommerce'),
'desc_tip' => 'true'
)
);
echo '</div>';
}
add_action('woocommerce_product_options_advanced', 'add_text_field_product_dashboard');
?>
Save Text Field Entries:
<?php
/*Save Inputted Entries, in the Product Dashboard Text Fields.*/
/*Checkbox Field*/
function woocommerce_product_custom_fields_save($post_id){
$_custom_text_option = isset( $_POST['_custom_text_option'] ) ? 'yes' : '';
update_post_meta( $post_id, '_custom_text_option', $_custom_text_option );
}
add_action('woocommerce_process_product_meta', 'woocommerce_product_custom_fields_save');
/*Save Minimum Letters*/
function woocommerce_product_custom_fields_save1($post_id){
if ( isset( $_POST['_minimum_custom_text_option'] ) )
update_post_meta($post_id, '_minimum_custom_text_option', esc_attr( $_POST['_minimum_custom_text_option'] ));
}
add_action( 'woocommerce_process_product_meta', 'woocommerce_product_custom_fields_save1' );
/*Save Maximum Letters*/
function woocommerce_product_custom_fields_save2($post_id){
if ( isset( $_POST['_maximum_custom_text_option'] ) )
update_post_meta($post_id, '_maximum_custom_text_option', esc_attr( $_POST['_maximum_custom_text_option'] ));
}
add_action( 'woocommerce_process_product_meta', 'woocommerce_product_custom_fields_save2' );
/*Save Cost Per Letter*/
function woocommerce_product_custom_fields_save3($post_id){
if ( isset( $_POST['_pricing_custom_text_option'] ) )
update_post_meta($post_id, '_pricing_custom_text_option', esc_attr( $_POST['_pricing_custom_text_option'] ));
}
add_action( 'woocommerce_process_product_meta', 'woocommerce_product_custom_fields_save3' );
?>
Output Custom Text to Product Page:
<?php
/*Output Custom Text Field to Product Page*/
function add_custom_text_field() {
global $post;
// Get the checkbox value
$custom_option = get_post_meta( $post->ID, '_custom_text_option', true );
// If is single product page and have the "custom text option" enabled we display the field
if ( is_product() && ! empty($custom_option) ) {
?>
<div>
<label class="product-custom-text-label" for="custom_text"><?php _e( 'Custom Letters:', 'woocommerce'); ?><br>
<input style="min-width:220px" type="text" class="product-counter" name="custom_text" placeholder="<?php _e( 'Enter Your Custom Letters ...', 'woocommerce'); ?>" minlength="<?php global $post; echo get_post_meta($post->ID,'_minimum_custom_text_option',true);?>" maxlength="<?php global $post; echo get_post_meta($post->ID,'_maximum_custom_text_option',true);?>" />
</label>
</div><br>
<?php
}
}
add_action( 'woocommerce_before_add_to_cart_button', 'add_custom_text_field', 0 );
?>
?>
Append to Cart:
<?php
/*Append to Cart once Shoper adds to Cart*/
function save_custom_text( $cart_item_data, $product_id ) {
if( isset( $_POST['custom_text'] ) && !empty( $_POST['custom_text'] ) ) {
$cart_item_data[ "custom_text" ] = esc_attr( $_POST['custom_text'] );
}
return $cart_item_data;
}
add_filter( 'woocommerce_add_cart_item_data', 'save_custom_text', 99, 2 );
?>
Sum of Product plus Cost Per Letter Entered:
<?php
/*Sum of Product Price plus Custom Text*/
function calculate_custom_text_fee( $cart_object ) {
foreach ( $cart_object->get_cart() as $cart_item ) {
// Checking that we got the custom text in cart object
if( ! empty( $cart_item["custom_text"] ) ) {
// Quantity of characters entered into Custom Text Field:
$lenght = strlen( $cart_item["custom_text"] );
// get the custom pricing for this product
$pricing_custom = get_post_meta( $cart_item['product_id'], '_pricing_custom_text_option', true );
// Characters Entered Multiplied by Cost of Each Letter:
$custom_text_fee = $lenght * $pricing_custom;
// get product price
$price = floatval( $cart_item['data']->get_price() );
// set new price
$cart_item['data']->set_price( $price + $custom_text_fee );
}
}
}
add_action( 'woocommerce_before_calculate_totals', 'calculate_custom_text_fee', 99, 1 );
?>
Output to Cart Description:
<?php
/*Output to Cart Description*/
function render_meta_on_cart_and_checkout( $cart_data, $cart_item = null ) {
$meta_items = array();
if( !empty( $cart_data ) ) {
$meta_items = $cart_data;
}
if( isset( $cart_item["custom_text"] ) ) {
$meta_items[] = array( "name" => "Your Custom Text", "value" => $cart_item["custom_text"] );
}
return $meta_items;
}
add_filter( 'woocommerce_get_item_data', 'render_meta_on_cart_and_checkout', 99, 2 );
?>
Ensure Product is in Emails:
<?php
/*Ensure Product is in Email Notifications*/
function custom_text_order_meta_handler( $item_id, $values, $cart_item_key ) {
if( isset( $values["custom_text"] ) ) {
wc_add_order_item_meta( $item_id, "Custom Text", $values["custom_text"] );
}
}
add_action( 'woocommerce_add_order_item_meta', 'custom_text_order_meta_handler', 99, 3 );
?>
Is anyone able to see where I could be going wrong, which is causing my Maths to double the costs in the Basket page?
Just to be clear, the Product Price is called fine. That is not doubled. Just the cost of the Custom Text. I feel there may be an issue with $price
but I am just not so sure.
Any pointers, on this matter, would be greatly appreciated.