Change Allowed Delivery Days Based On Cart Items

It’s possible to change the allowed delivery days based on items in your cart.

For example, perhaps your store sells drinks and food. You can deliver drinks every day of the week, but food can only be delivered on a Sunday.

As such, if the cart contains an item in the “food” category, we want to disable every available delivery day except Sundays.

Here’s what you can do:

Ensure your food and drink products are in food/drink categories, even if you don’t use those categories in your store.

Next, add this code snippet to your child theme’s functions.php file:

/**
  * Modify allowed days based on cart items.
  *
  * @param array $allowed_days
  * @param bool  $minmax
  *  * @return mixed
  */
function iconic_wds_modify_allowed_days( $allowed_days, $minmax ) { 
    // No need to do anything is Sunday is unavailable, and don't 
    // modify min/max settings. 
    if ( $minmax || false === $allowed_days[0] ) { 
        return $allowed_days; 
    } 

    // Check if any food items are in the cart. 
    // @todo modify categories. 
    $in_cart = iconic_check_for_cart_item_in_category( array( 'food' ) ); 

    // If no, return normal settings. 
    if ( ! $in_cart ) { 
        return $allowed_days; 
    } 

    // Otherwise, disable all days except Sunday. 
    foreach ( $allowed_days as $day => $allowed ) { 
        if ( 0 !== $day ) { 
            $allowed_days[ $day ] = false; 
        } 
    } 

    return $allowed_days; 
} 

add_filter( 'iconic_wds_allowed_days', 'iconic_wds_modify_allowed_days', 10, 2 ); 

/**
 * Check cart for product in category.
 *
 * @param array $categories Categories.
 *
 * @return bool
 */
function iconic_check_for_cart_item_in_category( $categories = array() ) {
	if ( empty( $categories ) || empty( WC()->cart ) ) {
		return false;
	}

	// Set our flag to be false until we find a product in that category.
	$has_item = false;

	// Check each cart item for our category.
	foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
		$product    = $cart_item['data'];
		$product_id = $product->is_type( 'variation' ) ? $product->get_parent_id() : $product->get_id();

		if ( has_term( $categories, 'product_cat', $product_id ) ) {
			$has_item = true;

			// Break because we only need one "true" to matter here.
			break;
		}
	}

	return $has_item;
}

There are 2 main functions in this code snippet, iconic_wds_modify_allowed_days() and iconic_check_for_cart_item_in_category().

The first function is modifying the days available for delivery, and the second is a helper function which we use to check if there are any products from the “food” category in the cart.

If there are products in the “food” category, we set every day except Sunday to false meaning it’s not a delivery day. Otherwise, we return the days as normal.

Notes:

  • iconic_wds_modify_allowed_days() should return an array of delivery days. There are 7 items in the array, one for each day of the week. The key/index is the day of the week, starting from 0 which is Sunday.
  • Each item in the allowed days array has a true or false value assigned to it. True meaning it’s an allowed day, and false meaning it isn’t.
  • You can modify the line after @todo to add more categories to the array, like so: $in_cart = iconic_check_for_cart_item_in_category( array( 'food', 'appetizers', 'party-wear' ) );
  • This example can be adapted to check for any product data, like meta, product type, status, etc.

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.