Change Allowed Delivery Days Dynamically

Using the iconic_wds_allowed_days filter, it is possible to change the days available in the calendar when checking out. The following examples show you how to do it based on products in the cart, or the selected shipping method.

Change Days Based on Products in the Cart

In this scenario, let’s say you allow deliveries to be selected on any weekday. However, when a certain product is in the cart, you want to restrict it to Tuesdays and Thursdays only.

You can add the following code to your child theme’s functions.php file, and modify it to suit your needs.

/**
 * Change allowed days for delivery.
 *
 * If a certain product is in the cart (ID 100), change
 * the days that are allowed for delivery.
 *
 * @param array $allowed_days
 *
 * @return array
 */
function iconic_change_allowed_days( $allowed_days ) {
	// The product ID to check for in the cart.
	$product_id = 70;

	// If the product is not in the cart, return the original data.
	if ( ! iconic_is_product_in_cart( $product_id ) ) {
		return $allowed_days;
	}

	return array(
		0 => false, // Sunday
		1 => false, // Monday
		2 => true, // Tuesday
		3 => false, // Wednesday
		4 => true, // Thursday
		5 => false, // Friday
		6 => false, // Saturday
	);
}

add_filter( 'iconic_wds_allowed_days', 'iconic_change_allowed_days' );

/**
 * Is product in cart?
 *
 * @param $product_id
 *
 * @return bool
 */
function iconic_is_product_in_cart( $product_id ) {
	$product_cart_id = WC()->cart->generate_cart_id( $product_id );
	$in_cart = WC()->cart->find_product_in_cart( $product_cart_id );

	return ! empty( $in_cart );
}

Here we’re using the iconic_change_allowed_days function on the iconic_wds_allowed_days filter.

It accepts 1 argument and return value, which is an array of true/false value.

Each array key is associated with a day of the week, ranging from Sunday to Saturday (see comments in code).

Firstly we use iconic_is_product_in_cart() to check if the product is in the customer’s cart. If it isn’t we return the default allowed days.

If the product is in the cart, we return a new array where only Tuesday and Thursday deliveries are available.

Before the filter is applied:

Example of delivery dates

After the filter is applied, and the product is in my cart:

Example after applying filter

Change Days Based on Selected Shipping Method

In this scenario, the shipping days available depend on the shipping method selected at checkout.

You can add the following code to your child theme’s functions.php file, and modify it to suit your needs.

/**
 * Modify allowed delivery days based on the selected shipping method.
 *
 * @param array $allowed_days
 *
 * @return array
 */
function iconic_change_allowed_days( $allowed_days ) {
    $chosen_methods  = iconic_wds_get_shipping_method();
	$chosen_shipping = $chosen_methods[0]; 
	
	if ( empty( $chosen_shipping ) ) {
		return $allowed_days;
	}
	
	$glen_rock = 'flat_rate:15';
	$wyckoff = 'flat_rate:17';
	$franklin = 'flat_rate:18';
	$oakland = 'flat_rate:20';
	
	$days = array(
		0 => false, // Sunday
		1 => false, // Monday
		2 => false, // Tuesday
		3 => false, // Wednesday
		4 => false, // Thursday
		5 => false, // Friday
		6 => false, // Saturday
	);
	
	if ( in_array( $chosen_shipping, array( $glen_rock, $wyckoff ) ) ) {
		$days[1] = true; // Monday
		$days[5] = true; // Friday
	} elseif ( in_array( $chosen_shipping, array( $franklin, $oakland ) ) ) {
		$days[2] = true; // Tuesday
		$days[3] = true; // Wednesday
		$days[4] = true; // Thursday
	}

	return $days;
}

add_filter( 'iconic_wds_allowed_days', 'iconic_change_allowed_days' );

/**
 * Returns currently selected shipping method.
 *
 * @return string
 */
function iconic_wds_get_shipping_method() {
	$post_data = filter_input( INPUT_POST, 'post_data' );
	$data      = array();

	parse_str( $post_data, $data );

	if ( empty( $data['shipping_method'] ) ) {
		if ( ! empty( WC()->session ) ) {
			return WC()->session->get( 'chosen_shipping_methods' );
		}

		return false;
	}

	return $data['shipping_method'];
}

In this snippet, we start by getting the selected shipping method from the current user’s session.

If it’s not set, we return the default delivery days based on the settings. Otherwise, we proceed to the next section.

Here we’ve defined 4 shipping methods for different areas we ship to. 

To find out the shipping method values, we can “Inspect” the Delivery Slots settings page, under the “General Settings” tab.

Open the browser inspector, then use the element select tool (1.). Select the relevant shipping method checkbox (2.) and take a look at the value (3.). This is the value you can use in the snippet above.

Applying a shipping method

In the snippet, we then proceed to define the available delivery days.

We set up an array, $days, which disables all delivery days. Then, if the selected shipping method is $glen_rock or $wyckoff, we enable Monday and Friday. If it’s $franklin or $oakland, we enable Tuesday, Wednesday, and Thursday.

WooCommerce Delivery Slots

Choose a delivery date and time for each order. Add a limit to the number of allowed reservations, restrict time slots to specific delivery methods, and so much more.

Was this helpful?

Please let us know if this article was useful. It is the best way to ensure our documentation is as helpful as possible.