I am trying to enable free shipping for specific shipping zones (array) on selected days.
I'm using therefore this code:
add_filter( 'woocommerce_shipping_free_shipping_is_available', 'enable_free_shipping_on_selected_days', 10, 3 );
function enable_free_shipping_on_selected_days( $is_available, $package, $shipping_method ) {
$shipping_zones = array('US, Europe');
if ( array_key_exists( $shipping_zones, $rates ) && in_array( date( 'w' ), [ 6, 7 ] ) ) {
return true;
}
return $is_available;
}
But I am getting an error: "Uncaught TypeError: array_key_exists(): Argument #2 ($array) must be of type array, null given in.."
Any advice on how to make free shipping available for certain shipping zones on specific days of the week?
$rates
is not set in your code, hence the error message
To make free shipping available based on shipping zones and specific days of the week, you can use:
function filter_woocommerce_shipping_free_shipping_is_available( $available, $package, $shipping_method ) {
// The targeted shipping zones. Multiple can be entered, separated by a comma
$shipping_zones = array( 'US', 'Europe', 'België' );
// The targeted day numbers. 0 = Sunday, 1 = Monday.. to 6 for Saturday. Multiple can be entered, separated by a comma
$day_numbers = array( 0, 1, 6 );
// Message
$notice = __( 'free shipping available', 'woocommerce' );
/* END settings */
// Default
$available = false;
// Get shipping zone
$shipping_zone = wc_get_shipping_zone( $package );
// Get the zone name
$zone_name = $shipping_zone->get_zone_name();
// Checks if a value exists in an array (zone name)
if ( in_array( $zone_name, $shipping_zones ) ) {
// Set the default timezone to use.
date_default_timezone_set( 'UTC' );
// Day number
$day_number = date( 'w' );
// Checks if a value exists in an array (day number)
if ( in_array( $day_number, $day_numbers ) ) {
// Clear all other notices
wc_clear_notices();
// Display notice
wc_add_notice( $notice, 'notice' );
// True
$available = true;
}
}
// Return
return $available;
}
add_filter( 'woocommerce_shipping_free_shipping_is_available', 'filter_woocommerce_shipping_free_shipping_is_available', 10, 3 );
// Optional: Hide other shipping methods when free shipping is available
function filter_woocommerce_package_rates( $rates, $package ) {
// Empty array
$free = array();
// Loop trough
foreach ( $rates as $rate_id => $rate ) {
if ( $rate->method_id === 'free_shipping' ) {
$free[ $rate_id ] = $rate;
// Break loop
break;
}
}
return ! empty( $free ) ? $free : $rates;
}
add_filter( 'woocommerce_package_rates', 'filter_woocommerce_package_rates', 10, 2 );
Based on: