Last active
November 29, 2021 18:40
-
-
Save damiencarbery/4c6a8ef3cd06fa9f003d329e93fe00cd to your computer and use it in GitHub Desktop.
WooCommerce: Promote Free Shipping by listing how much to add to cart to avail of it.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Plugin Name: Promote Free Shipping (WooCommerce) | |
Plugin URI: http://www.damiencarbery.com | |
Description: Encourage customer to add more items to the cart to avail of free shipping. | |
Author: Damien Carbery | |
Version: 0.3 | |
*/ | |
class PromoteFreeShipping { | |
private $free_shipping_min_amount; | |
private $debug_mode; | |
public function __construct() { | |
$this->free_shipping_min_amount = false; | |
// Allow debug mode to be enabled when WordPress debug mode is enabled. | |
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { | |
$this->debug_mode = true; | |
} | |
// Or set it manually. | |
$this->debug_mode = false; | |
} | |
public function init() { | |
add_action( 'woocommerce_load_shipping_methods', array( $this, 'get_free_shipping_amount' ) ); | |
add_action( 'woocommerce_cart_totals_before_order_total', array( $this, 'promote_free_shipping_notice' ) ); | |
add_action( 'woocommerce_review_order_after_shipping', array( $this, 'promote_free_shipping_notice' ) ); | |
add_action( 'woocommerce_before_cart', array( $this, 'promote_free_shipping_notice_before_cart' ) ); | |
} | |
// Determine the minimum amount for free shipping. | |
function get_free_shipping_amount( $package ) { | |
if ( $this->debug_mode ) { | |
error_log( 'PromoteFreeShipping: Entering get_free_shipping_amount().' ); | |
//error_log( 'PromoteFreeShipping: $package:' . var_export( $package, true ) ); | |
} | |
// Retrieve Rest of World (default) zone. | |
$row_zone = new WC_Shipping_Zone(0); | |
$all_zones[$row_zone->get_id()] = $row_zone->get_data(); | |
$all_zones[$row_zone->get_id()]['formatted_zone_location'] = $row_zone->get_formatted_location(); | |
$all_zones[$row_zone->get_id()]['shipping_methods'] = $row_zone->get_shipping_methods(); | |
// Add user configured zones | |
$all_zones = array_merge( $all_zones, WC_Shipping_Zones::get_zones() ); | |
if ( $this->debug_mode ) { | |
error_log( 'PromoteFreeShipping - $all_zones: ' . var_export( $all_zones, true ) ); | |
} | |
// Note: This sometimes triggers a PHP warning - it appears that the $package array is not always | |
// populated. I don't know the circumstances when this happens or the cause. | |
$shipping_zone = WC_Shipping_Zones::get_zone_matching_package( $package ); | |
if ( $this->debug_mode ) { | |
error_log( 'PromoteFreeShipping: Matched zone: ' . var_export( $shipping_zone, true ) ); | |
} | |
$min_amounts = array(); | |
// Verify that the shipping zone is in $all_zones (zone id 0 isn't!) | |
if ( array_key_exists( $shipping_zone->get_id(), $all_zones ) ) { | |
// Get all the methods for this zone and look for free_shipping methods. | |
$methods = $all_zones[ $shipping_zone->get_id() ][ 'shipping_methods' ]; | |
foreach ( $methods as $method_id => $method_obj ) { | |
// Verify that the free_shipping method requires a minimum cart amount (some require a coupon) | |
if ( ( 'free_shipping' == $method_obj->id ) && ( 'min_amount' == $method_obj->requires || 'either' == $method_obj->requires ) ) { | |
$min_amounts[] = $method_obj->min_amount; | |
} | |
} | |
} | |
// Set to false if no free shipping. | |
$this->free_shipping_min_amount = ( empty( $min_amounts ) ) ? false : min( $min_amounts ); | |
if ( $this->debug_mode ) { | |
error_log( 'PromoteFreeShipping: Free Shipping Min Amounts: ' . var_export( $min_amounts, true ) ); | |
error_log( 'PromoteFreeShipping: Free Shipping Min Amount set to: ' . $this->free_shipping_min_amount ); | |
} | |
} | |
// Add a notice to encourage the customer to add more items to the cart to avail of free shipping. | |
public function promote_free_shipping_notice( $location ) { | |
// Simply return if free shipping not available for the current zone. | |
if ( ! $this->free_shipping_min_amount ) { | |
return; | |
} | |
if (WC()->cart->cart_contents_total) { | |
$total = WC()->cart->get_displayed_subtotal(); | |
// If cart is under free shipping threshold AND shipping to a country that has free shipping option, | |
// then tell them how much to add to the cart to get free shipping. | |
if ($total < $this->free_shipping_min_amount) { | |
$notice = 'To avail of free shipping add <em>'.wc_price($this->free_shipping_min_amount - $total).'</em> to your cart.'; | |
if ( 'before_cart' == $location ) { | |
wc_print_notice( $notice, 'notice' ); | |
} | |
else { | |
echo '<tr class="promote_free_shipping"><td colspan="2">'. $notice . '</td></tr>'; | |
} | |
} | |
} | |
} | |
// Add the notice before the cart. | |
public function promote_free_shipping_notice_before_cart() { | |
$this->promote_free_shipping_notice( 'before_cart' ); | |
} | |
} | |
$Promote_Free_Shipping = new PromoteFreeShipping(); | |
$Promote_Free_Shipping->init(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Encourage customers to add items to cart to avail of free shipping. | |
add_action('woocommerce_cart_totals_before_order_total', 'rac_promote_free_shipping'); | |
add_action('woocommerce_review_order_after_shipping', 'rac_promote_free_shipping'); | |
function rac_promote_free_shipping() { | |
if (WC()->cart->cart_contents_total) { | |
$total = WC()->cart->get_displayed_subtotal(); | |
// If cart is under free shipping threshold AND shipping to a country that has free shipping option, | |
// then tell them how much to add to the cart to get free shipping. | |
$free_shipping_threshold = 25; | |
if ($total < $free_shipping_threshold) { | |
$country = WC()->checkout->get_value('billing_country'); | |
$free_shipping_countries = array('IE', 'GB', 'IM', 'JE'); // Free shipping to Ireland, UK, Isle of Man and Jersey | |
if (in_array($country, $free_shipping_countries)) { | |
echo '<tr class="promote_free_shipping"><td colspan="2">To avail of free shipping add <em>'.wc_price($free_shipping_threshold-$total).'</em> to your cart.</td></tr>'; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment