问题
I am building pizza delivery website with WooCommerce. In fact when customer is checking out, he can select when he want to have food delivered.
The select box should contain 15 minute intervals ranging from the current time and clearing all past hours. The first option I want is to be "As soon as possible", and then the next option is an hour later (rounded to nearest 15mins), and then 15 mins each time.
Our delivery hours are as below:
- Monday: Closed
- Tuesday - Friday 11:30 - 14:00 & 17:00 - 22:00
- Sat & Sun : 13:00 - 22:00
I succesfully WooCommerce action/hook, but I can't disable all time slots before the current time.
add_action('woocommerce_before_order_notes', 'wps_add_select_checkout_field');
function wps_add_select_checkout_field( $checkout ) {
woocommerce_form_field( 'lieferzeit', array(
'type' => 'select',
'class' => array( 'wps-drop' ),
'label' => __( '<div class="gew"><span class="gew-lz">Gewünschte Lieferzeit</span></div>'),
'options' => array(
'asap' => __( 'So schnell wie möglich', 'wps' ),
'12:00' => __( '12:00', 'wps' ),
'12:30' => __( '12:30', 'wps' ),
'13:00' => __( '13:00', 'wps' ),
'13:30' => __( '13:30', 'wps' ),
'14:00' => __( '14:00', 'wps' ),
'17:30' => __( '17:30', 'wps' ),
'18:00' => __( '18:00', 'wps' ),
'18:30' => __( '18:30', 'wps' ),
'19:00' => __( '19:00', 'wps' ),
'19:30' => __( '19:30', 'wps' ),
'20:00' => __( '20:00', 'wps' ),
'20:30' => __( '20:30', 'wps' ),
'21:00' => __( '21:00', 'wps' ),
'21:30' => __( '21:30', 'wps' ),
'22:00' => __( '22:00', 'wps' ),
)
),
$checkout->get_value( 'lieferzeit' ));
}
add_action('woocommerce_checkout_update_order_meta', 'wps_select_checkout_field_update_order_meta');
function wps_select_checkout_field_update_order_meta( $order_id ) {
if ($_POST['lieferzeit']) update_post_meta( $order_id, 'lieferzeit', esc_attr($_POST['lieferzeit']));
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'wps_select_checkout_field_display_admin_order_meta', 10, 1 );
function wps_select_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Delivery option').':</strong> ' . get_post_meta( $order->id, 'lieferzeit', true ) . '</p>';
}
add_filter('woocommerce_email_order_meta_keys', 'wps_select_order_meta_keys');
function wps_select_order_meta_keys( $keys ) {
$keys['lieferzeit:'] = 'lieferzeit';
return $keys;
}
回答1:
For your question about the select field you can use the following
Via the $store_times
array you can set the opening and closing hours as well as the hours of the break.
If the store is closed all day, leave all settings for that day empty (see monday)
function action_woocommerce_before_order_notes( $checkout ) {
// Open, break and close time
$store_times = array(
array( // Sunday (NO break)
'open' => '13:00',
'break_s' => '',
'break_e' => '',
'close' => '22:00',
),
array( // Monday (closed, so everything is empty)
'open' => '',
'break_s' => '',
'break_e' => '',
'close' => '',
),
array( // Tuesday
'open' => '11:30',
'break_s' => '14:00',
'break_e' => '17:00',
'close' => '22:00',
),
array( // Wednesday
'open' => '11:30',
'break_s' => '14:00',
'break_e' => '17:00',
'close' => '22:00',
),
array( // Thursday
'open' => '11:30',
'break_s' => '14:00',
'break_e' => '17:00',
'close' => '23:30',
),
array( // Friday
'open' => '11:30',
'break_s' => '14:00',
'break_e' => '17:00',
'close' => '22:00',
),
array( // Saturday
'open' => '13:00',
'break_s' => '',
'break_e' => '',
'close' => '22:00',
),
);
// Current time
$current_time = current_time( 'timestamp' );
// Current day, 0 for Sunday, 6 for Saturday
$current_day = date( 'w', $current_time );
// Get values for the current day
$open_time = strtotime( $store_times[ $current_day][ 'open' ] );
$break_start = strtotime( $store_times[ $current_day][ 'break_s' ] );
$break_end = strtotime( $store_times[ $current_day][ 'break_e' ] );
$close_time = strtotime( $store_times[ $current_day][ 'close' ] );
// Open time is empty or before/passed open/close time, so the store is closed
if ( empty ( $open_time ) || ( $current_time > $close_time || $current_time <= $open_time ) ) {
// Default value
$options['closed'] = __( 'Closed', 'woocommerce');
} else {
// Default value
$options[''] = __( 'As soon as possible', 'woocommerce');
// As soon as possible
$asa_possible = strtotime( '+1 hour', $current_time );
// Round to next 15 minutes (15 * 60 seconds)
$asa_possible = ceil( $asa_possible / ( 15 * 60 ) ) * ( 15 * 60);
// Add a new option every 15 minutes
while( $asa_possible <= $close_time && $asa_possible >= $open_time ) {
// Generate value
$value = date( 'H:i', $asa_possible );
// NOT between break start & break end
if ( $value <= date( 'H:i', $break_start ) || $value >= date( 'H:i', $break_end ) ) {
// Push to array
$options[$value] = $value;
}
// Add 15 minutes to the variable in this while loop
$asa_possible = strtotime( '+15 minutes', $asa_possible );
}
}
// Add field
woocommerce_form_field( 'delivery_time', array(
'type' => 'select',
'class' => array( 'wps-drop' ),
'label' => __('Desired delivery time', 'woocommerce' ),
'options' => $options,
), $checkout->get_value( 'delivery_time' ) );
}
add_action( 'woocommerce_before_order_notes', 'action_woocommerce_before_order_notes', 10, 1 );
来源:https://stackoverflow.com/questions/64378146/add-a-select-field-with-time-intervals-based-on-opening-closing-and-breaks-time