I am using WooCommerce with WooCommerce Multilingual.
So I am using different currencies. I want to unset billing and shipping countries based on the current active currency.
I found this function to unset countries:
function woo_remove_specific_country( $country ) {
unset($country["US"]);
unset($country["GB"]);
return $country;
}
add_filter( 'woocommerce_countries', 'woo_remove_specific_country', 10, 1 );
But I want to change this function so there is conditional logic in it. So for example when EUR is the active current currency US and GB has to be the unset countries. If GBP is the current active currency only US needs to be unset.
So I found this to get the current active currency:
$currency = get_woocommerce_currency();
When using this to test it inside a shortcode it gives me the right active currency.
So I rewrote the function:
function woo_remove_specific_country( $country ) {
$currency = get_woocommerce_currency();
if ($currency == 'EUR') {
unset($country["US"]);
unset($country["GB"]);
}
if ($currency == 'GBP') {
unset($country["US"]);
}
return $country;
}
add_filter( 'woocommerce_countries', 'woo_remove_specific_country', 10, 1 );
But this doesn't work. It looks like it always takes the way of the if with EUR while my currency is GBP at that moment.
Related
Here's my code below which works but it's not yet fully completed. Currently it just checks if an added product in the cart has tech shipping class then apply a static $5 discount. However, what I want to achieve is to add an additional requirement.
Most of my products on my website are with NO set shipping class and the rest are set with 'tech shipping class'. I want to do the following:
The discount of $5 should only be given if the customer add one or more (it doesn't matter) of products with no shipping class assigned to them. Discount should NOT be given if there are only tech shipping class items in the cart. If there are products with no set class and tech shipping class regardless of the quantity of the items then apply a static $5 discount.
It seems unclear to me how to check if cart has other items and more specifically items with NO set class + tech shipping class then to apply that discount..
Any help is greatly appreciated. Thanks!
add_filter( 'woocommerce_package_rates', 'adjustment_in_rates_of_product_with_shipping_class', 12, 2 );
function adjustment_in_rates_of_product_with_shipping_class( $available_shipping_methods, $package ) {
// Shipping class slug to be eligible for a discount
$shipping_class = array(
'tech',
);
// Discount
$discount = 5;
// Enter the Shipping Method Value
$shipping_services = array(
'flat_rate:2',
);
$shipping_class_exists = false;
foreach(WC()->cart->get_cart_contents() as $key => $values) {
if ( in_array($values['data']->get_shipping_class() , $shipping_class) ) {
$shipping_class_exists = true;
break;
}
}
if ($shipping_class_exists) {
foreach ($available_shipping_methods as $key => $value) {
if ( in_array($value->get_id() , $shipping_services) ) {
$available_shipping_methods[$key]->cost -= $discount;
}
}
}
return $available_shipping_methods;
}
Replace this
if ( in_array($values['data']->get_shipping_class() , $shipping_class) )
For
if ( $values['data']->get_shipping_class() == '' )
I think that with this modification your code will check if there is at least one product in the cart without shipping class and in this case apply the discount.
I'm trying to add estimated delivery times to orders on the checkout page, under the shipping price within WooCommerce.
I have worked out how to do this, such as:
add_action( 'woocommerce_after_shipping_rate', 'blm_action_after_shipping_rate', 20, 2 );
function blm_action_after_shipping_rate ( $method, $index ) {
if( is_cart() ) {
return; // Exit on cart page
}
// Use $method->method_id in here to check delivery option
}
Now, to be able to estimate the days (unfortunately the shipping API doesn't return this data) I need to find out the shipping country and shipping state/province in here - is there a way to do that?
The shipping rates are calculated from customer shipping location.
So you asked for the customer shipping country and state that you can get from WC_Customer object using dedicated methods as follows:
add_action( 'woocommerce_after_shipping_rate', 'blm_action_after_shipping_rate', 20, 2 );
function blm_action_after_shipping_rate ( $method, $index ) {
if( is_cart() ) {
return; // Exit on cart page
}
$shipping_country = WC()->customer->get_shipping_country();
$shipping_state = WC()->customer->get_shipping_state();
// Testing output
echo '<br><small>Country code:' . $shipping_country . ' | State code: ' . $shipping_state . '</small>';
}
Code goes in function.php file of the active child theme (or active theme). Tested and works.
If customer change of country and state, the data is refreshed and the new country and state are set in WC_Customer Object.
I've developed a catalogue using woocommerce, however I need to be able to hide product prices from users who are visiting the site from outside of the UK due to reasons outside of my control.
I've found plugins that allow me to change product prices based on visitor location, but nothing allows me to hide the prices.
Is there any plugins that I've missed or anything I can add in to the woocommerce files to achieve this?
There are various web APIs that will help you. For example http://ipinfo.io
ip = $_SERVER['REMOTE_ADDR'];
$details = json_decode(file_get_contents("http://ipinfo.io/{$ip}"));
echo $details->country; // -> "US"
If you have to do many checks a local database is better. MaxMind offer a free database that you can use with various PHP libraries, including GeoIP.
The following will hide prices outside United kingdom based on customer geolocated country:
add_filter( 'woocommerce_get_price_html', 'country_geolocated_based_hide_price', 10, 2 );
function country_geolocated_based_hide_price( $price, $product ) {
// Get an instance of the WC_Geolocation object class
$geo_instance = new WC_Geolocation();
// Get geolocated user geo data.
$user_geodata = $geo_instance->geolocate_ip();
// Get current user GeoIP Country
$country = $user_geodata['country'];
return $country !== 'GB' ? '' : $price;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
If you want to enable that geolocated feature only for unlogged customers, use the following:
add_filter( 'woocommerce_get_price_html', 'country_geolocated_based_hide_price', 10, 2 );
function country_geolocated_based_hide_price( $price, $product ) {
if( get_current_user_id() > 0 ) {
$country = WC()->customer->get_billing_country();
} else {
// Get an instance of the WC_Geolocation object class
$geo_instance = new WC_Geolocation();
// Get geolocated user geo data.
$user_geodata = $geo_instance->geolocate_ip();
// Get current user GeoIP Country
$country = $user_geodata['country'];
}
return $country !== 'GB' ? '' : $price;
}
An updated version of this code is available on this answer avoiding a backend bug.
I have added in the function on start:
if ( is admin() ) return $price;
Code goes in function.php file of your active child theme (or active theme). Tested and works.
I'm trying to implement currency change on checkout with WooCommerce Multilingual Plugin. I need a country with COP and the rest of countries with USD. First I tried to use the wcml_client_currency hook.
function modify_client_currency( $currency ) {
$country = WC()->customer->get_billing_country();
if ($country === 'CO') {
return 'COP';
} else {
return 'USD';
}
}
add_filter( 'wcml_client_currency', 'modify_client_currency', 10, 1 );
If I start with Colombia selected, the currency is in COP, but if I change to another country, the currency stay on COP. I need to change the country again to see the change.
I tried another approach with the woocommerce_checkout_update_order_review and analyzing how the multilingual plugin works.
function action_woocommerce_checkout_update_order_review( $post_data ) {
// This part will change dynamically based on the country contained in $post_data
$currency = 'COP';
global $woocommerce_wpml;
$woocommerce_wpml->multi_currency->set_client_currency($currency);
global $woocommerce, $current_user;
if(empty($woocommerce->session->data) && empty($current_user->ID)){
$woocommerce->session->set_customer_session_cookie(true);
}
do_action('wcml_switch_currency', $currency );
WC()->cart->calculate_totals();
}
add_action('woocommerce_checkout_update_order_review', 'action_woocommerce_checkout_update_order_review', 10, 1);
With this approach I have exactly the same problem, I need to change the country twice to see the currency change.
I need some help in WooCommerce Shipping method. How can I show the value of shipping class on the cart page. Let me explain little bit my problem.
I added a flat rate to charge shipping for some products i.e. chairs €7 which is working perfect and show on cart page as => Shipping: Flat rate: €7 but I've some chairs to ship free to my customers. I added new class like "Free Shipping" and set the value to 0.00 EUR on checkout it's no charging any cost which fine, but when client view cart and in shipping it only show the name of shipping method like Flat Rate without any cost because that was set to 0.00 which doesn't convince the customer and he think we've hidden cost.
Is there any way to show the zero value of shipping class or is this possible to show the class name rather than shipping method's title?
You can add a filter, checking if the cost of your shipping method is zero (WooCommerce currently is doing nothing else in their function than printing the "flat rate" label, if the cost isn't above zero) and changing your label to whatever you'd like:
add_filter( 'woocommerce_cart_shipping_method_full_label', 'add_free_shipping_label', 10, 2 );
function add_free_shipping_label( $label, $method ) {
if ( $method->cost == 0 ) {
$label = 'Free shipping'; //not quite elegant hard coded string
}
return $label;
}
Based on https://stackoverflow.com/a/23581656/8264519 and works like a charm.
Thank you #DhirenPatel for your question. The following additional code works for the thank you page and email:
add_filter( 'woocommerce_order_shipping_to_display', 'add_free_shipping_label_email', 10, 2 );
function add_free_shipping_label_email( $label, $method ) {
if ( $method->cost == 0 ) {
$label = 'Free shipping'; //not quite elegant hard coded string
}
return $label;
}
Here is what I did.
1.Open \wp-content\plugins\woocommerce\includes\wc-cart-functions.php
2.Search for wc_cart_totals_shipping_method_label function
3.Replace if ( $method->cost > 0 ) with if ( $method->cost >= 0 ) and it should show the shipping cost even if it is set to 0.