/**
* Bowbells Florist — delivery date chooser on the block-based checkout.
*
* Paste into the theme's functions.php (Appearance -> Theme File Editor).
* No JavaScript, no block.json, no build step, no new plugin files.
*
* Uses WooCommerce's Additional Checkout Fields API (WC 8.9+), which is the
* supported way to add a field to the *block* checkout. The field saves to the
* order and shows on the admin order screen automatically.
*/
/**
* Build the list of selectable delivery dates.
*
* Mirrors the shop's real rules: deliveries Monday-Saturday only (no Sundays),
* same-day only if the order is placed before the 2pm cutoff.
*/
function bowbells_delivery_date_options() {
$tz = wp_timezone();
$now = new DateTimeImmutable( 'now', $tz );
$date = new DateTimeImmutable( 'today', $tz );
// Past the 2pm cutoff, the earliest possible date is tomorrow.
if ( (int) $now->format( 'G' ) >= 14 ) {
$date = $date->modify( '+1 day' );
}
$options = array();
// Offer the next 18 delivery days (~3 weeks of Mon-Sat).
while ( count( $options ) < 18 ) {
if ( 'Sun' !== $date->format( 'D' ) ) {
$options[] = array(
'value' => $date->format( 'Y-m-d' ),
'label' => $date->format( 'l j F Y' ),
);
}
$date = $date->modify( '+1 day' );
}
return $options;
}
/**
* Register the field on the block checkout.
*/
function bowbells_register_delivery_date_field() {
if ( ! function_exists( 'woocommerce_register_additional_checkout_field' ) ) {
return;
}
woocommerce_register_additional_checkout_field(
array(
'id' => 'bowbells/delivery-date',
'label' => __( 'Preferred delivery or collection date', 'bowbells' ),
'location' => 'order',
'type' => 'select',
'required' => true,
'options' => bowbells_delivery_date_options(),
)
);
}
add_action( 'woocommerce_init', 'bowbells_register_delivery_date_field' );
/**
* Re-validate server-side: reject a date the customer should not have been
* able to pick (stale page left open overnight, or a tampered request).
*
* NOTE: confirm this hook's signature against the WooCommerce version actually
* running on the site before relying on it -- the callback arguments for
* `woocommerce_validate_additional_field` have changed across releases.
*/
function bowbells_validate_delivery_date( $errors, $field_key, $field_value ) {
if ( 'bowbells/delivery-date' !== $field_key ) {
return $errors;
}
$allowed = wp_list_pluck( bowbells_delivery_date_options(), 'value' );
if ( ! in_array( $field_value, $allowed, true ) ) {
$errors->add(
'invalid_delivery_date',
__( 'Sorry, that delivery date is no longer available. Please choose another.', 'bowbells' )
);
}
return $errors;
}
add_action( 'woocommerce_validate_additional_field', 'bowbells_validate_delivery_date', 10, 3 );