Make Woocommerce checkout phone field not required based on shipping country - woocommerce

I saw this question come up before but it was answered reversely.
I would like question answered exactly as asked. I would like the phone number field to change from required to optional if a country is chosen.
I currently have the phone number field is required for all countries. I would like that if United States is chosen then phone number should be change to optional.
For reference, here is original posthttps://stackoverflow.com/questions/55206672/make-woocommerce-checkout-phone-field-optional-based-on-shipping-country and below is the code to have list of countries changed to required.
// SETTINGS: The countries codes (2 capital letters) in the array
function defined_countries_for_phone_field(){
return array( 'GB', 'JE', 'GG', 'IM' );
}
// Remove "(optional)" from non required "Billing phone" field
add_filter( 'woocommerce_form_field' , 'remove_checkout_optional_fields_label', 10, 4 );
function remove_checkout_optional_fields_label( $field, $key, $args, $value ) {
// Get the defined countries codes
$countries = defined_countries_for_phone_field();
// Get Customer shipping country
$shipping_country = WC()->customer->get_shipping_country();
// Only on checkout page and My account > Edit address for billing phone field
if( 'billing_phone' === $key && ( ( is_wc_endpoint_url( 'edit-address' )
&& in_array($shipping_country, $countries) ) || is_checkout() ) ) {
$optional = ' <span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>';
$field = str_replace( $optional, '', $field );
}
return $field;
}
// Make the billing phone field optional (by default)
add_filter( 'woocommerce_billing_fields', 'filter_billing_phone_field', 10, 1 );
function filter_billing_phone_field( $fields ) {
// Get the defined countries codes
$countries = defined_countries_for_phone_field();
// Get Customer shipping country
$shipping_country = WC()->customer->get_shipping_country();
// Only on checkout page and My account > Edit address
if ( ( is_wc_endpoint_url( 'edit-address' )
&& in_array($shipping_country, $countries) ) || is_checkout() )
$fields['billing_phone']['required'] = false;
return $fields;
}
// Real time shipping country selection actions
add_action( 'woocommerce_after_order_notes', 'custom_checkout_scripts_and_fields', 10, 1 );
function custom_checkout_scripts_and_fields( $checkout ) {
$required = esc_attr__( 'required', 'woocommerce' );
// Get the defined countries codes
$countries = defined_countries_for_phone_field();
// Hidden field for the phone number validation
echo '<input type="hidden" name="billing_phone_check" id="billing_phone_check" value="0">';
$countries_str = "'".implode( "', '", $countries )."'"; // Formatting countries for jQuery
?>
<script type="text/javascript">
(function($){
var required = '<abbr class="required" title="<?php echo $required; ?>">*</abbr>';
var countries = [<?php echo $countries_str; ?>];
if($('.shipping_address').is(':visible')) {
// ship to different country selected
var selectedcountry = $('#shipping_country option:selected').val();
} else {
var selectedcountry = $('#billing_country option:selected').val();
}
//var selectedcountry = $('#shipping_country option:selected').val();
var phoneCheck = 'input#billing_phone_check';
var phoneField = '#billing_phone_field';
function actionRequire( actionToDo='yes', selector='' ){
if ( actionToDo == 'yes' ) {
$(selector).addClass("validate-required");
$(selector+' label > .required').remove();
$(selector+' label').append(required);
} else {
$(selector).removeClass("validate-required");
$(selector+' label > .required').remove();
}
$(selector).removeClass("woocommerce-validated");
$(selector).removeClass("woocommerce-invalid woocommerce-invalid-required-field");
}
// Default value Once DOM is loaded (with a 300 ms delay)
setTimeout( function(){
if($('.shipping_address').is(':visible')) {
// ship to different country selected
var selectedcountry = $('#shipping_country option:selected').val();
} else {
var selectedcountry = $('#billing_country option:selected').val();
}
actionRequire( 'no', phoneField );
if( $.inArray( selectedcountry, countries ) == -1){
actionRequire( 'yes',phoneField );
$(phoneCheck).val('1');
}
}, 300 );
// Live value
$( 'form.checkout' ).on( 'change', '#billing_country, #shipping_country, #ship-to-different-address-checkbox', function(){
setTimeout( function(){
if($('.shipping_address').is(':visible')) {
// ship to different country selected
var selectedcountry = $('#shipping_country option:selected').val();
} else {
var selectedcountry = $('#billing_country option:selected').val();
}
if ( $.inArray( selectedcountry, countries ) == -1) {
actionRequire( 'yes' ,phoneField );
$(phoneCheck).val('1');
} else {
actionRequire( 'no' ,phoneField );
$(phoneCheck).val('0');
}
}, 300 );
});
})(jQuery);
</script>
<?php
}
// Phone number validation, when the field is required
add_action('woocommerce_checkout_process', 'billing_phone_field_process');
function billing_phone_field_process() {
// Check if set, if its not set add an error.
if ( ! $_POST['billing_phone'] && $_POST['billing_phone_check'] == '1' )
wc_add_notice( __( 'Please enter a number phone.' ), 'error' );
}

Related

Creating a button to hide Woocommerce out of stock products

so I have some code to show an 'out of stock' box under a product, if a product is out of stock.
I would like to have this so I tick a box and the out of stock products 'hide'. Then I untick this box, and they unhide.
// display an 'Out of Stock' label on archive pages
add_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_template_loop_stock', 10 );
function woocommerce_template_loop_stock() {
global $product;
if ( ! $product->managing_stock() && ! $product->is_in_stock() )
echo '<p class="stock out-of-stock">Out of Stock</p>';
}
add_filter( 'woocommerce_get_availability_text', 'custom_backorders_stock_availability_text', 10, 2 );
function custom_backorders_stock_availability_text( $availability, $product ) {
if ( $product->managing_stock() && $product->is_on_backorder( 1 ) ) {
if ( ! $product->backorders_require_notification() ) {
$availability = __( 'Out of stock', 'woocommerce' );
}
}
return $availability;
}
Tick box code (below) to hide prices on tick/untick. Can I do this with out of stock css?
<script>
$(function() {
var status = localStorage.getItem('chkStatus');
if(status == 'true'){
$("span.price").css("display", "none");
$("p.price").css("display", "none");
$(".tradePriceToggle").attr('checked', true)
}
else{
$("span.price").css("display", "block");
$("p.price").css("display", "block");
$(".tradePriceToggle").attr('checked', false)
}
$(".tradePriceToggle").click(function() {
if (this.checked) {
$("span.price").hide();
$("p.price").hide();
}
else {
$("span.price").show();
$("p.price").show();
}
localStorage.setItem("chkStatus", this.checked);
});
});
</script>

Remove Selected Checkout Fields with Woocommerce Depending on Shipping Method Redux

In reference to this Remove selected checkout fields with woocommerce depending on shipping method
How can I adapt the codes in order remove different fields based on different shipping methods selected?
I've tried modifying the beginnging part to below, but it just stops working...
add_filter( 'woocommerce_checkout_fields', 'xa_remove_billing_checkout_fields' );
function xa_remove_billing_checkout_fields( $fields ) {
$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
// uncomment below line and reload checkout page to check current $chosen_methods
// print_r($chosen_methods);
$chosen_shipping = $chosen_methods[0];
if ($chosen_shipping == 'flat_rate:13') {
$shipping_method = 'flat_rate:13';
$hide_fields = array( 'billing_address_2', 'billing_city', 'billing_state', 'billing_postcode' );
}
if ($chosen_shipping =='flat_rate:7') {
$shipping_method = 'flat_rate:7';
$hide_fields = array( 'billing_city', 'billing_state', 'billing_postcode' );
}
foreach($hide_fields as $field ) {
if ($chosen_shipping == $shipping_method) {
$fields['billing'][$field]['required'] = false;
$fields['billing'][$field]['class'][] = 'hide';
}
$fields['billing'][$field]['class'][] = 'billing-dynamic';
}
return $fields;
}
The other part looks like this, which I copied and modified from another answer
add_action( 'wp_footer', 'cart_update_script', 999 );
function cart_update_script() {
if (is_checkout()) :
?>
<style>
.hide {display: none!important;}
</style>
<script>
jQuery( function( $ ) {
// woocommerce_params is required to continue, ensure the object exists
if ( typeof woocommerce_params === 'undefined' ) {
return false;
}
var show = ['flar_rate:7', 'flat_rate:13'];
$(document).on( 'change', '#shipping_method input[type="radio"]', function() {
// console.log($.inArray($(this).val(), show));
if ($.inArray($(this).val(), show) > -1) { // >-1 if found in array
$('.billing-dynamic').removeClass('hide');
// console.log('show');
} else {
$('.billing-dynamic').addClass('hide');
// console.log('hide');
}
});
});
</script>
<?php
endif;
}
Also, if I change the country, which changes also the shipping zone, the fields ain't reverted until I select the shipping method again.
Thanks in advance.

How to rename the Add to Cart button if the product is already added to cart in WooCommerce

When Ajax add to cart functionality is active on my WooCommerce store, on Ajax add to cart first click It shows a checked icon symbol like:
The code below changes the add to button cart text to "Seçildi !" if product is already in to cart, only after refreshing page like:
//Rename the button on the Product page
add_filter( 'woocommerce_product_single_add_to_cart_text', 'ts_product_add_cart_button' );
function ts_product_add_cart_button( $label ) {
foreach( WC()->cart->get_cart() as $cart_item_key => $values ) {
$product = $values['data'];
if( get_the_ID() == $product->get_id() ) {
$label = __('Seçildi !', 'woocommerce');
}
}
return $label;
}
//Rename the button on the Shop page
add_filter( 'woocommerce_product_add_to_cart_text', 'ts_shop_add_cart_button', 99, 2 );
function ts_shop_add_cart_button( $label, $product ) {
if ( $product->get_type() == 'simple' && $product->is_purchasable() && $product->is_in_stock() )
{
foreach( WC()->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if( get_the_ID() == $_product->get_id() ) {
$label = __('Seçildi !', 'woocommerce');
}
}
}
return $label;
}
But if you don't refresh the page the button remains like before with the checked icon symbol.
What I would like is to change add to cart button with the quantity that has been added for this product like:
Is this possible? What do I need to change? Any help is appreciated.
You can use WC woocommerce_product_add_to_cart_text action hook and you can get wc cart loop through all products and compare path second params $prodcuct object. check below code. code will go active theme functions.php file.
function change_add_to_cart_text_if_product_already_in_cart( $add_to_cart_text, $product ) {
if ( WC()->cart ) {
$cart = WC()->cart; // Get cart
if ( ! $cart->is_empty() ) {
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$_product_id = $cart_item['product_id'];
if ( $product->get_id() == $_product_id ) {
$add_to_cart_text = '('.$cart_item['quantity'].')'.' Already in cart';
break;
}
}
}
}
return $add_to_cart_text;
}
add_filter( 'woocommerce_product_add_to_cart_text', 'change_add_to_cart_text_if_product_already_in_cart', 10, 2 );
add_filter( 'woocommerce_product_single_add_to_cart_text', 'change_add_to_cart_text_if_product_already_in_cart', 10, 2 );
Updated ( as per OP request how to change text quick on click with quantity ).
There is two way You can do this.
you can use woocommerce_loop_add_to_cart_args and add product qty attribute and based on that you can display.
function add_product_qty( $args, $product ){
if ( WC()->cart ) {
$cart = WC()->cart; // Get cart
if ( ! $cart->is_empty() ) {
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$_product_id = $cart_item['product_id'];
if ( $product->get_id() == $_product_id ) {
$args['attributes']['data-product-qty'] = $cart_item['quantity'];
}else{
$args['attributes']['data-product-qty'] = 0;
}
}
}else{
$args['attributes']['data-product-qty'] = 0;
}
}
return $args;
}
add_filter( 'woocommerce_loop_add_to_cart_args', 'add_product_qty', 10, 2 );
add_action( 'wp_footer', 'ajax_button_text_quick_change_js_script' );
function ajax_button_text_quick_change_js_script() {
?>
<script>
(function($) {
$(document.body).on('click', '.ajax_add_to_cart', function(event){
$this = $(this);
var product_qty = parseInt($this.attr('data-product-qty')) + 1;
$this.attr('data-product-qty',product_qty);
var buttonText = '<span class="add_to_cart_text product-is-added">('+product_qty+') Already in cart</span><i class="cart-icon pe-7s-cart"></i>';
$this.html(buttonText).attr('data-tip','('+product_qty+') Already in cart');
});
})(jQuery);
</script>
<?php
}
You can use added_to_cart jQuery event that triggers after adding to the cart you call ajax and get add_to_cart_text in response.
add_action( 'wp_footer', 'ajax_button_text_js_script' );
function ajax_button_text_js_script() {
?>
<script>
(function($) {
$(document.body).on('added_to_cart', function(event, fragments, cart_hash, button){
var product_id = button.data('product_id'),
product_qty = button.data('quantity');
button.addClass('loading');
$.ajax({
url: "<?php //echo admin_url('admin-ajax.php'); ?>",
method: 'POST',
data:{action:'change_add_to_cart_text',product_id:product_id},
dataType: "json",
success: function( response ){
var buttonText = '<span class="add_to_cart_text product-is-added">'+response.data.button_text+'</span><i class="cart-icon pe-7s-cart"></i>';
button.html(buttonText).attr('data-tip',response.data.button_text);
button.removeClass('loading');
},error: function (jqXHR, exception) {
var msg = '';
if (jqXHR.status === 0) {
msg = 'Not connect.\n Verify Network.';
} else if (jqXHR.status == 404) {
msg = 'Requested page not found. [404]';
} else if (jqXHR.status == 500) {
msg = 'Internal Server Error [500].';
} else if (exception === 'parsererror') {
msg = 'Requested JSON parse failed.';
} else if (exception === 'timeout') {
msg = 'Time out error.';
} else if (exception === 'abort') {
msg = 'Ajax request aborted.';
} else {
msg = 'Uncaught Error.\n' + jqXHR.responseText;
}
console.log(msg);
},
});
});
})(jQuery);
</script>
<?php
}
add_action('wp_ajax_change_add_to_cart_text', 'change_add_to_cart_text');
add_action('wp_ajax_nopriv_change_add_to_cart_text', 'change_add_to_cart_text');
function change_add_to_cart_text(){
$product_id = $_POST['product_id'];
if ( WC()->cart ) {
$cart = WC()->cart; // Get cart
if ( ! $cart->is_empty() ) {
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$_product_id = $cart_item['product_id'];
if ( $product_id == $_product_id ) {
$add_to_cart_text = '('.$cart_item['quantity'].')'.' Already in cart';
break;
}
}
}
}
wp_send_json_success(array(
'button_text' => $add_to_cart_text
));
}
This below code only for OP site.
add_filter( 'woocommerce_loop_add_to_cart_link', 'custom_add_quantity_fields', 99, 2 );
function custom_add_quantity_fields($html, $product) {
//add quantity field only to simple products
if ( $product && $product->is_type( 'simple' ) && $product->is_purchasable() && $product->is_in_stock() && ! $product->is_sold_individually() ) {
if ( WC()->cart ) {
$cart = WC()->cart; // Get cart
if ( ! $cart->is_empty() ) {
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$_product_id = $cart_item['product_id'];
if ( $product->get_id() == $_product_id ) {
$data_product_qty = $cart_item['quantity'];
}else{
$data_product_qty = 0;
}
}
}else{
$data_product_qty = 0;
}
}
//rewrite form code for add to cart button
$html = '<form action="' . esc_url( $product->add_to_cart_url() ) . '" class="cart" method="post" enctype="multipart/form-data">';
$html .= woocommerce_quantity_input( array(), $product, false );
$html .= '<button type="submit" data-quantity="1" data-product_id="' . $product->get_id() . '" class="button alt ajax_add_to_cart add_to_cart_button product_type_simple" data-product-qty="'.$data_product_qty.'">' . esc_html( $product->add_to_cart_text() ) . '</button>';
$html .= '</form>';
}
return $html;
}
Tested and works.

How to dynamically change shipping costs in WooCommerce checkout based on a custom field?

How can I change shipping cost in Woocommerce by Ajax request?
I tried this:
add_action('wp_ajax_set_shipping_price', 'set_shipping_price');
add_action('wp_ajax_nopriv_set_shipping_price', 'set_shipping_price');
function set_shipping_price(){
$packages = WC()->cart->get_shipping_packages();
foreach ($packages as $package_key => $package){
$session_key = 'shipping_for_package_'.$package_key;
$stored_rates = WC()->session->__unset( $session_key );
$WC_Shipping = new WC_Shipping();
$WC_Shipping->calculate_shipping_for_package( $package, $package_key = 0);
WC()->cart->calculate_shipping();
WC()->cart->calculate_totals();
}
wp_die();
}
and:
add_filter( 'woocommerce_package_rates', 'custom_shipping_costs', 20, 2 );
function custom_shipping_costs( $rates, $package ) {
if (isset($_POST['cost'])){
$new_cost = $_POST['cost'];
}
$new_cost = 0;
$tax_rate = 0.2;
foreach( $rates as $rate_key => $rate ){
if( $rate->method_id != 'free_shipping'){
$rates[$rate_key]->cost = $new_cost;
$taxes = array();
foreach ($rates[$rate_key]->taxes as $key => $tax){
if( $rates[$rate_key]->taxes[$key] > 0 )
$taxes[$key] = $new_cost * $tax_rate;
}
$rates[$rate_key]->taxes = $taxes;
}
}
return $rates;
}
The hook woocommerce_package_rates works at page load but do nothing by ajax. Help please.
Here is the explanation on how to get post data from an Ajax call.
Additionally, you can use the WooCommerce update_checkout event to update the checkout (and thus recalculate shipping costs) after a field in the checkout has changed or been clicked (instead of creating a custom Ajax call). Here you will find a complete list.
So, assuming you want to recalculate shipping costs when the field with id custom_shipping_price (for example) changes, you can use this script:
// updates the checkout (and shipping charge calculation) when the value of a field changes
add_action( 'wp_footer', 'update_checkout' );
function update_checkout() {
// only in the checkout
if ( ! is_checkout() ) {
return;
}
?>
<script type="text/javascript">
jQuery( document ).ready(function( $ ) {
// when the value of the field with id "custom_shipping_price" changes it updates the checkout
jQuery('#custom_shipping_price').change(function(){
jQuery('body').trigger('update_checkout');
});
});
</script>
<?php
}
Now you will need to use the woocommerce_package_rates hook to calculate the new shipping cost.
Make sure you initialize the value of the $new_cost variable in
case the custom field is not set or is empty.
Here the function:
// update the shipping cost based on a custom field in the checkout
add_filter( 'woocommerce_package_rates', 'update_shipping_cost_based_on_custom_field', 10, 2 );
function update_shipping_cost_based_on_custom_field( $rates, $package ) {
if ( ! $_POST || is_admin() || ! is_ajax() ) {
return;
}
// gets the post serialized data sent with the Ajax call
if ( isset( $_POST['post_data'] ) ) {
parse_str( $_POST['post_data'], $post_data );
} else {
$post_data = $_POST;
}
// set the cost of shipping (if the custom field should be empty)
$new_cost = 0;
// if the field is set it gets the value
if ( isset( $post_data['custom_shipping_price'] ) && ! empty( $post_data['custom_shipping_price'] ) ) {
// forces conversion of value into number
$new_cost = (float) str_replace( ',', '.', $post_data['custom_shipping_price'] );
}
// set the percentage of taxes (ex. 22%)
$tax_rate = 0.22;
foreach( $rates as $rate_key => $rate ) {
if ( 'free_shipping' !== $rate->method_id ) {
// set rate cost
$rates[$rate_key]->cost = $new_cost;
// set taxes rate cost (if enabled)
$taxes = array();
foreach ( $rates[$rate_key]->taxes as $key => $tax ) {
if ( $rates[$rate_key]->taxes[$key] > 0 ) {
$taxes[$key] = $new_cost * $tax_rate;
}
}
$rates[$rate_key]->taxes = $taxes;
}
}
return $rates;
}
Both codes have been tested and work. Add them to your active theme's functions.php.

Checkbox field that add a subscription product and change prices of other products

In Woocommerce checkout section, I am trying to add a checkbox that adds an additional subscription product. It is working fine and I took help from here
One more requirement is that if there are other products in the cart then I want to change each product prices based on custom fields and new prices should display in the checkout.
Thanks in advance.
I used this code and working fine but product price is not changing in PayPal payment page.
// Display a custom checkout field
add_action( 'woocommerce_checkout_before_terms_and_conditions', 'custom_checkbox_checkout_field' );
function custom_checkbox_checkout_field() {
$value = WC()->session->get('add_a_product');
woocommerce_form_field( 'cb_add_product', array(
'type' => 'checkbox',
'label' => ' ' . __('Please check here to get VIP Membership'),
'class' => array('form-row-wide'),
), $value == 'yes' ? true : false );
}
// The jQuery Ajax request
add_action( 'wp_footer', 'checkout_custom_jquery_script' );
function checkout_custom_jquery_script() {
// Only checkout page
if( is_checkout() && ! is_wc_endpoint_url() ):
// Remove "ship_different" custom WC session on load
if( WC()->session->get('add_a_product') ){
WC()->session->__unset('add_a_product');
}
if( WC()->session->get('product_added_key') ){
WC()->session->__unset('product_added_key');
}
// jQuery Ajax code
?>
<script type="text/javascript">
jQuery( function($){
if (typeof wc_checkout_params === 'undefined')
return false;
$('form.checkout').on( 'change', '#cb_add_product', function(){
var value = $(this).prop('checked') === true ? 'yes' : 'no';
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: {
'action': 'add_a_product',
'add_a_product': value,
},
success: function (result) {
$('body').trigger('update_checkout');
//console.log(result);
}
});
});
});
</script>
<?php
endif;
}
// The Wordpress Ajax PHP receiver
add_action( 'wp_ajax_add_a_product', 'checkout_ajax_add_a_product' );
add_action( 'wp_ajax_nopriv_add_a_product', 'checkout_ajax_add_a_product' );
function checkout_ajax_add_a_product() {
if ( isset($_POST['add_a_product']) ){
WC()->session->set('add_a_product', esc_attr($_POST['add_a_product']));
echo $_POST['add_a_product'];
}
die();
}
// Add remove free product
add_action( 'woocommerce_before_calculate_totals', 'adding_removing_specific_product' );
function adding_removing_specific_product( $cart ) {
if (is_admin() && !defined('DOING_AJAX'))
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// HERE the specific Product ID
$product_id = 179;
if( WC()->session->get('add_a_product') == 'yes' && ! WC()->session->get('product_added_key') )
{
foreach ( $cart->get_cart() as $cart_item ) {
$cart_item_key = $cart->add_to_cart( $product_id );
WC()->session->set('product_added_key', $cart_item_key);
// get the product id (or the variation id)
$product_id = $cart_item['data']->get_id();
// GET THE NEW PRICE (code to be replace by yours)
$new_price = get_post_meta( $product_id, 'pro_price_extra_info', true );
// Updated cart item price
$cart_item['data']->set_price( floatval( $new_price ) );
}
}
elseif( WC()->session->get('add_a_product') == 'no' && WC()->session->get('product_added_key') )
{
$cart_item_key = WC()->session->get('product_added_key');
$cart->remove_cart_item( $cart_item_key );
WC()->session->__unset('product_added_key');
}
}
I got solution for my above post. It might help others in future.
// Display a custom checkout field
add_action( 'woocommerce_checkout_before_terms_and_conditions', 'custom_checkbox_checkout_field' );
function custom_checkbox_checkout_field() {
$value = WC()->session->get('add_a_product');
woocommerce_form_field( 'cb_add_product', array(
'type' => 'checkbox',
'label' => ' ' . __('Please check here to get VIP Membership'),
'class' => array('form-row-wide'),
), $value == 'yes' ? true : false );
}
// The jQuery Ajax request
add_action( 'wp_footer', 'checkout_custom_jquery_script' );
function checkout_custom_jquery_script() {
// Only checkout page
if( is_checkout() && ! is_wc_endpoint_url() ):
// Remove "ship_different" custom WC session on load
if( WC()->session->get('add_a_product') ){
WC()->session->__unset('add_a_product');
}
if( WC()->session->get('product_added_key') ){
WC()->session->__unset('product_added_key');
}
// jQuery Ajax code
?>
<script type="text/javascript">
jQuery( function($){
if (typeof wc_checkout_params === 'undefined')
return false;
$('form.checkout').on( 'change', '#cb_add_product', function(){
var value = $(this).prop('checked') === true ? 'yes' : 'no';
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: {
'action': 'add_a_product',
'add_a_product': value,
},
success: function (result) {
$('body').trigger('update_checkout');
//console.log(result);
}
});
if(value == 'no'){
window.location.reload();
}
});
});
</script>
<?php
endif;
}
// The Wordpress Ajax PHP receiver
add_action( 'wp_ajax_add_a_product', 'checkout_ajax_add_a_product' );
add_action( 'wp_ajax_nopriv_add_a_product', 'checkout_ajax_add_a_product' );
function checkout_ajax_add_a_product() {
if ( isset($_POST['add_a_product']) ){
WC()->session->set('add_a_product', esc_attr($_POST['add_a_product']));
echo $_POST['add_a_product'];
}
die();
}
// Add remove free product
add_action( 'woocommerce_before_calculate_totals', 'adding_removing_specific_product' );
function adding_removing_specific_product( $cart ) {
if (is_admin() && !defined('DOING_AJAX'))
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
$has_sub = wcs_user_has_subscription( '', '179', 'active' );
$product_id = 179;
if( WC()->session->get('add_a_product') == 'yes' && ! WC()->session->get('product_added_key') ){
// HERE the specific Product ID
foreach ( $cart->get_cart() as $cart_item ) {
// get the product id (or the variation id)
$product_idnew = $cart_item['data']->get_id();
// GET THE NEW PRICE (code to be replace by yours)
$new_price = get_post_meta( $product_idnew, 'pro_price_extra_info', true );
$old_price = $cart_item['data']->get_price();
if($new_price == NULL){
$cart_item['data']->set_price( floatval( $old_price ) );
} else {
$cart_item['data']->set_price( floatval( $new_price ) );
}
}
$cart_item_key = $cart->add_to_cart( $product_id );
WC()->session->set('product_added_key', $cart_item_key);
} elseif( WC()->session->get('add_a_product') == 'no' && WC()->session->get('product_added_key') ) {
$cart_item_key = WC()->session->get('product_added_key');
$cart->remove_cart_item( $cart_item_key );
WC()->session->__unset('product_added_key');
}elseif ( $has_sub ) {
foreach ( $cart->get_cart() as $cart_item ) {
// get the product id (or the variation id)
$product_idnew = $cart_item['data']->get_id();
// GET THE NEW PRICE (code to be replace by yours)
$new_price = get_post_meta( $product_idnew, 'pro_price_extra_info', true );
$cart_item['data']->set_price( floatval( $new_price ) );
}
}
}
function woo_in_cart($product_id) {
global $woocommerce;
foreach($woocommerce->cart->get_cart() as $key => $val ) {
$_product = $val['data'];
if($product_id == $_product->id ) {
return true;
}
}
return false;
}
add_action( 'woocommerce_cart_loaded_from_session', 'adding_vip_product' );
function adding_vip_product( $cart ) {
$product_id = 179;
if(woo_in_cart($product_id) ) {
foreach ( $cart->get_cart() as $cart_item ) {
// get the product id (or the variation id)
$product_idnew = $cart_item['data']->get_id();
// GET THE NEW PRICE (code to be replace by yours)
$new_price = get_post_meta( $product_idnew, 'pro_price_extra_info', true );
if($new_price != 0){
$cart_item['data']->set_price( floatval( $new_price ) );
}
}
}
}

Resources