Home / Admin / Woo SITE WIDE – Restaurant Hours + backend
Duplicate Snippet

Embed Snippet on Your Site

Woo SITE WIDE – Restaurant Hours + backend

Restaurant Hours, Shop Control & Checkout Disable (Enhanced with Vacations, Custom Notices, Dynamic Data, Close Button, Time Until Open, Admin Timezone & Shipping/Payment Disable)
Gestiona los horarios del restaurante (con múltiples sesiones en español)
deshabilita la tienda WooCommerce cuando está cerrada.
Además, limita los pedidos por hora
muestra un aviso dinámico con el horario de hoy y datos dinámicos utilizando la zona horaria seleccionada.
Cuando la tienda está cerrada, se deshabilitan métodos de envío y pago específicos (según se configure en el administrador).
Incluye configuración de aviso personalizado para los estados abierto y cerrado, con marcadores dinámicos, y un botón de cerrar.

Code Preview
php
<?php
/*
Plugin Name: Restaurant Hours, Shop Control & Checkout Disable (Enhanced with Vacations, Custom Notices, Dynamic Data, Close Button, Time Until Open, Admin Timezone & Shipping/Payment Disable)
Description: Gestiona los horarios del restaurante (con múltiples sesiones en español) y deshabilita la tienda WooCommerce cuando está cerrada. Además, limita los pedidos por hora y muestra un aviso dinámico con el horario de hoy y datos dinámicos utilizando la zona horaria seleccionada. Cuando la tienda está cerrada, se deshabilitan métodos de envío y pago específicos (según se configure en el administrador). Incluye configuración de aviso personalizado para los estados abierto y cerrado, con marcadores dinámicos, y un botón de cerrar.
Version: 2.5
Author: AzZar0
Www: staging28.Bokfood.es/calc
*/
/* ============================================================
   1. SETTINGS REGISTRATION & SANITIZATION CALLBACKS
   ============================================================ */
/**
 * Sanitize the hours array.
 */
function rha_sanitize_hours( $input ) {
    $sanitized = array();
    if ( is_array( $input ) ) {
        foreach ( $input as $day => $sessions ) {
            $sanitized[ $day ] = array();
            if ( is_array( $sessions ) ) {
                foreach ( $sessions as $session ) {
                    $open  = isset( $session['open'] ) ? sanitize_text_field( $session['open'] ) : '';
                    $close = isset( $session['close'] ) ? sanitize_text_field( $session['close'] ) : '';
                    $sanitized[ $day ][] = array( 'open' => $open, 'close' => $close );
                }
            }
        }
    }
    return $sanitized;
}
/**
 * Sanitize the maximum orders per hour.
 */
function rha_sanitize_max_orders( $input ) {
    return absint( $input );
}
/**
 * Sanitize the vacation entries.
 */
function rha_sanitize_vacations( $input ) {
    $vacations = array();
    $lines = explode("\n", $input);
    foreach ( $lines as $line ) {
        $line = trim( $line );
        if ( empty( $line ) ) {
            continue;
        }
        if ( preg_match( '/^(\d{4}-\d{2}-\d{2})(?:\s*-\s*(\d{4}-\d{2}-\d{2}))?$/', $line, $matches ) ) {
            $start = $matches[1];
            $end   = ( isset( $matches[2] ) && ! empty( $matches[2] ) ) ? $matches[2] : $start;
            $vacations[] = array( 'start' => $start, 'end' => $end );
        }
    }
    return $vacations;
}
/**
 * Sanitize the custom notice text.
 */
function rha_sanitize_notice_text( $input ) {
    return wp_kses_post( $input );
}
/**
 * Sanitize the timezone selection.
 */
function rha_sanitize_timezone( $input ) {
    return sanitize_text_field( $input );
}
/**
 * Sanitize an array of selected shipping method IDs.
 */
function rha_sanitize_shipping_methods( $input ) {
    if ( is_array( $input ) ) {
        return array_map( 'sanitize_text_field', $input );
    }
    return array();
}
/**
 * Sanitize an array of selected payment method IDs.
 */
function rha_sanitize_payment_methods( $input ) {
    if ( is_array( $input ) ) {
        return array_map( 'sanitize_text_field', $input );
    }
    return array();
}
/**
 * Register plugin settings.
 */
function rha_register_settings() {
    register_setting( 'rha_settings_group', 'rha_hours', array( 'sanitize_callback' => 'rha_sanitize_hours' ) );
    register_setting( 'rha_settings_group', 'rha_max_orders_per_hour', array( 'sanitize_callback' => 'rha_sanitize_max_orders' ) );
    register_setting( 'rha_settings_group', 'rha_vacations', array( 'sanitize_callback' => 'rha_sanitize_vacations' ) );
    // Register two notice texts: one for open and one for closed.
    register_setting( 'rha_settings_group', 'rha_notice_open_text', array( 'sanitize_callback' => 'rha_sanitize_notice_text' ) );
    register_setting( 'rha_settings_group', 'rha_notice_closed_text', array( 'sanitize_callback' => 'rha_sanitize_notice_text' ) );
    register_setting( 'rha_settings_group', 'rha_timezone', array( 'sanitize_callback' => 'rha_sanitize_timezone' ) );
    register_setting( 'rha_settings_group', 'rha_disable_shipping_methods', array( 'sanitize_callback' => 'rha_sanitize_shipping_methods' ) );
    register_setting( 'rha_settings_group', 'rha_disable_payment_methods', array( 'sanitize_callback' => 'rha_sanitize_payment_methods' ) );
}
add_action( 'admin_init', 'rha_register_settings' );
/* ============================================================
   2. ADMIN MENU & SETTINGS PAGE
   ============================================================ */
/**
 * Add the plugin settings page to the WordPress dashboard.
 */
function rha_add_admin_menu() {
    add_menu_page(
        'Restaurant Hours and Services',
        'Restaurant Hours',
        'manage_options',
        'rha-settings',
        'rha_settings_page',
        'dashicons-clock'
    );
}
add_action( 'admin_menu', 'rha_add_admin_menu' );
/**
 * Render the settings page.
 *
 * Note: Default hours are left unset so the administrator must define them.
 */
function rha_settings_page() {
    $default_hours = array();
    $hours    = get_option( 'rha_hours', $default_hours );
    $max_orders = get_option( 'rha_max_orders_per_hour', 10 );
    $vacations_setting = get_option( 'rha_vacations', array() );
    $notice_open_text = get_option( 'rha_notice_open_text', '' );
    $notice_closed_text = get_option( 'rha_notice_closed_text', '' );
    $timezone = get_option( 'rha_timezone', '' );
    $disable_shipping = get_option( 'rha_disable_shipping_methods', array() );
    $disable_payment = get_option( 'rha_disable_payment_methods', array() );
    $days     = array( 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado', 'Domingo' );
    $vacations_text = '';
    if ( is_array( $vacations_setting ) && ! empty( $vacations_setting ) ) {
        $lines = array();
        foreach ( $vacations_setting as $vac ) {
            $lines[] = $vac['start'] . ( ($vac['start'] !== $vac['end']) ? ' - ' . $vac['end'] : '' );
        }
        $vacations_text = implode("\n", $lines);
    }
    ?>
    <div class="wrap">
        <h1>Restaurant Hours and Services</h1>
        <style>
            .rha-settings-table {
                width: 100%;
                max-width: 800px;
                border-collapse: collapse;
            }
            .rha-settings-table th,
            .rha-settings-table td {
                padding: 10px;
                vertical-align: top;
                border-bottom: 1px solid #ddd;
            }
            @media screen and (max-width: 600px) {
                .rha-settings-table, .rha-settings-table th, .rha-settings-table td {
                    display: block;
                    width: 100%;
                }
                .rha-settings-table th {
                    margin-top: 10px;
                }
            }
            .rha-clock-icon {
                vertical-align: middle;
                margin-right: 5px;
            }
            .rha-session-group {
                display: flex;
                gap: 20px;
                flex-wrap: wrap;
            }
            .rha-session {
                flex: 1;
                min-width: 200px;
            }
            .rha-session label {
                font-weight: bold;
                display: block;
                margin-bottom: 2px;
            }
        </style>
        <form method="post" action="options.php">
            <?php 
                settings_fields( 'rha_settings_group' );
                do_settings_sections( 'rha_settings_group' );
            ?>
            <table class="rha-settings-table">
                <?php foreach ( $days as $day ) :
                    $day_hours   = isset( $hours[ $day ] ) ? $hours[ $day ] : array( array( 'open' => '', 'close' => '' ) );
                    $first_slot  = isset( $day_hours[0] ) ? $day_hours[0] : array( 'open' => '', 'close' => '' );
                    $second_slot = isset( $day_hours[1] ) ? $day_hours[1] : array( 'open' => '', 'close' => '' );
                    ?>
                    <tr>
                        <th scope="row">
                            <span class="dashicons dashicons-clock rha-clock-icon"></span>
                            <?php echo esc_html( $day ); ?>
                        </th>
                        <td>
                            <div class="rha-session-group">
                                <div class="rha-session">
                                    <label>Sesión 1</label>
                                    <label>Apertura:</label>
                                    <input type="time" name="rha_hours[<?php echo esc_attr( $day ); ?>][0][open]" value="<?php echo esc_attr( $first_slot['open'] ); ?>" />
                                    <label>Cierre:</label>
                                    <input type="time" name="rha_hours[<?php echo esc_attr( $day ); ?>][0][close]" value="<?php echo esc_attr( $first_slot['close'] ); ?>" />
                                </div>
                                <div class="rha-session">
                                    <label>Sesión 2</label>
                                    <label>Apertura:</label>
                                    <input type="time" name="rha_hours[<?php echo esc_attr( $day ); ?>][1][open]" value="<?php echo esc_attr( $second_slot['open'] ); ?>" />
                                    <label>Cierre:</label>
                                    <input type="time" name="rha_hours[<?php echo esc_attr( $day ); ?>][1][close]" value="<?php echo esc_attr( $second_slot['close'] ); ?>" />
                                </div>
                            </div>
                        </td>
                    </tr>
                <?php endforeach; ?>
                <tr>
                    <th scope="row">Vacaciones / Festivos</th>
                    <td>
                        <textarea name="rha_vacations" rows="4" cols="50"><?php echo esc_textarea( $vacations_text ); ?></textarea>
                        <p class="description">
                            Ingrese cada vacaciones o festivo en una línea. Para un rango, use <code>YYYY-MM-DD - YYYY-MM-DD</code>. Para un solo día, ingrese <code>YYYY-MM-DD</code>.
                        </p>
                    </td>
                </tr>
                <tr>
                    <th scope="row">Pedidos máximos por hora</th>
                    <td>
                        <input type="number" name="rha_max_orders_per_hour" value="<?php echo esc_attr( $max_orders ); ?>" min="1" />
                        <p class="description">Establece el número máximo de pedidos permitidos por hora.</p>
                    </td>
                </tr>
                <tr>
                    <th scope="row">Texto de Aviso cuando está ABIERTO</th>
                    <td>
                        <?php
                        wp_editor( $notice_open_text, 'rha_notice_open_text', array(
                            'textarea_name' => 'rha_notice_open_text',
                            'textarea_rows' => 5,
                        ) );
                        ?>
                        <p class="description">
                            Ingrese el texto para cuando la tienda está abierta. Puedes usar los siguientes marcadores:
                            <code>{hours_left}</code> y <code>{today_hours}</code>
                        </p>
                    </td>
                </tr>
                <tr>
                    <th scope="row">Texto de Aviso cuando está CERRADO</th>
                    <td>
                        <?php
                        wp_editor( $notice_closed_text, 'rha_notice_closed_text', array(
                            'textarea_name' => 'rha_notice_closed_text',
                            'textarea_rows' => 5,
                        ) );
                        ?>
                        <p class="description">
                            Ingrese el texto para cuando la tienda está cerrada. Puedes usar los siguientes marcadores:
                            <code>{time_until_open}</code> y <code>{today_hours}</code>
                        </p>
                    </td>
                </tr>
                <tr>
                    <th scope="row">Timezone</th>
                    <td>
                        <select name="rha_timezone">
                            <?php 
                            $timezones = timezone_identifiers_list();
                            foreach( $timezones as $tz ): ?>
                                <option value="<?php echo esc_attr( $tz ); ?>" <?php selected( $timezone, $tz ); ?>><?php echo esc_html( $tz ); ?></option>
                            <?php endforeach; ?>
                        </select>
                        <p class="description">Seleccione la zona horaria para el cálculo de horarios.</p>
                    </td>
                </tr>
                <tr>
                    <th scope="row">Deshabilitar Métodos de Envío</th>
                    <td>
                        <?php 
                        // Retrieve available shipping methods (if WooCommerce shipping is active).
                        $available_shipping = array();
                        if ( class_exists( 'WC_Shipping' ) ) {
                            $methods = WC()->shipping()->get_shipping_methods();
                            foreach( $methods as $method ) {
                                $available_shipping[ $method->id ] = $method->get_method_title();
                            }
                        }
                        ?>
                        <select name="rha_disable_shipping_methods[]" multiple style="min-width: 300px;">
                            <?php foreach ( $available_shipping as $id => $title ) : ?>
                                <option value="<?php echo esc_attr( $id ); ?>" <?php echo ( is_array( $disable_shipping ) && in_array( $id, $disable_shipping ) ) ? 'selected' : ''; ?>>
                                    <?php echo esc_html( $title ); ?>
                                </option>
                            <?php endforeach; ?>
                        </select>
                        <p class="description">Seleccione los métodos de envío que se deshabilitarán cuando la tienda esté cerrada.</p>
                    </td>
                </tr>
                <tr>
                    <th scope="row">Deshabilitar Métodos de Pago</th>
                    <td>
                        <?php 
                        // Retrieve available payment gateways.
                        $available_payments = array();
                        if ( class_exists( 'WC_Payment_Gateways' ) ) {
                            $gateways = WC()->payment_gateways->get_available_payment_gateways();
                            foreach( $gateways as $gateway ) {
                                $available_payments[ $gateway->id ] = $gateway->get_title();
                            }
                        }
                        ?>
                        <select name="rha_disable_payment_methods[]" multiple style="min-width: 300px;">
                            <?php foreach ( $available_payments as $id => $title ) : ?>
                                <option value="<?php echo esc_attr( $id ); ?>" <?php echo ( is_array( $disable_payment ) && in_array( $id, $disable_payment ) ) ? 'selected' : ''; ?>>
                                    <?php echo esc_html( $title ); ?>
                                </option>
                            <?php endforeach; ?>
                        </select>
                        <p class="description">Seleccione los métodos de pago que se deshabilitarán cuando la tienda esté cerrada.</p>
                    </td>
                </tr>
            </table>
            <?php submit_button(); ?>
        </form>
    </div>
    <?php
}
/* ============================================================
   3. FRONTEND SHORTCODE FOR DISPLAYING HOURS
   ============================================================ */
function rha_display_hours_services() {
    $hours = get_option( 'rha_hours' );
    
    $output = '<div class="restaurant-hours"><h2>Horarios del Restaurante</h2><ul>';
    if ( is_array( $hours ) ) {
        foreach ( $hours as $day => $slots ) {
            $output .= '<li><span class="dashicons dashicons-clock rha-frontend-clock"></span><strong>' . esc_html( $day ) . ':</strong> ';
            if ( is_array( $slots ) ) {
                $slot_output = array();
                foreach ( $slots as $slot ) {
                    if ( ! empty( $slot['open'] ) && ! empty( $slot['close'] ) ) {
                        $slot_output[] = esc_html( $slot['open'] ) . ' – ' . esc_html( $slot['close'] );
                    }
                }
                $output .= empty( $slot_output ) ? 'Cerrado' : implode( '<br>', $slot_output );
            } else {
                $output .= 'Cerrado';
            }
            $output .= '</li>';
        }
    }
    $output .= '</ul></div>';
    
    return $output;
}
add_shortcode( 'restaurant_hours_services', 'rha_display_hours_services' );
/* ============================================================
   4. HELPER FUNCTIONS & SHOP CONTROL LOGIC (Using WP Timezone)
   ============================================================ */
/**
 * Retrieve today's open hours as a formatted string.
 */
function rha_get_today_hours() {
    $days_mapping = array(
        'Monday'    => 'Lunes',
        'Tuesday'   => 'Martes',
        'Wednesday' => 'Miércoles',
        'Thursday'  => 'Jueves',
        'Friday'    => 'Viernes',
        'Saturday'  => 'Sábado',
        'Sunday'    => 'Domingo'
    );
    $current_timestamp = current_time( 'timestamp' );
    $current_day_en = wp_date( 'l', $current_timestamp );
    $current_day = isset( $days_mapping[ $current_day_en ] ) ? $days_mapping[ $current_day_en ] : $current_day_en;
    $hours = get_option( 'rha_hours' );
    $session_texts = array();
    
    if ( isset( $hours[ $current_day ] ) && is_array( $hours[ $current_day ] ) ) {
        foreach ( $hours[ $current_day ] as $slot ) {
            if ( ! empty( $slot['open'] ) && ! empty( $slot['close'] ) ) {
                $session_texts[] = $slot['open'] . ' – ' . $slot['close'];
            }
        }
    }
    return empty( $session_texts ) ? 'Cerrado' : implode( ' / ', $session_texts );
}
/**
 * Calculate the remaining time left to order in the current session.
 */
function rha_get_hours_left() {
    $current_timestamp = current_time( 'timestamp' );
    $today_date = wp_date( 'Y-m-d', $current_timestamp );
    $hours = get_option( 'rha_hours' );
    $days_mapping = array(
        'Monday'    => 'Lunes',
        'Tuesday'   => 'Martes',
        'Wednesday' => 'Miércoles',
        'Thursday'  => 'Jueves',
        'Friday'    => 'Viernes',
        'Saturday'  => 'Sábado',
        'Sunday'    => 'Domingo'
    );
    $current_day_en = wp_date( 'l', $current_timestamp );
    $current_day = isset( $days_mapping[ $current_day_en ] ) ? $days_mapping[ $current_day_en ] : $current_day_en;
    
    if ( isset( $hours[ $current_day ] ) && is_array( $hours[ $current_day ] ) ) {
        foreach ( $hours[ $current_day ] as $slot ) {
            if ( ! empty( $slot['open'] ) && ! empty( $slot['close'] ) ) {
                $open_timestamp  = strtotime( $today_date . ' ' . $slot['open'] );
                $close_timestamp = strtotime( $today_date . ' ' . $slot['close'] );
                if ( $current_timestamp >= $open_timestamp && $current_timestamp <= $close_timestamp ) {
                    $diff = $close_timestamp - $current_timestamp;
                    $hours_left = floor( $diff / 3600 );
                    $minutes_left = floor( ( $diff % 3600 ) / 60 );
                    return sprintf( "%d hours %d minutes", $hours_left, $minutes_left );
                }
            }
        }
    }
    return false;
}
/**
 * Calculate the time until the next opening session.
 */
function rha_get_time_until_open() {
    $tz = get_option( 'rha_timezone', wp_timezone()->getName() );
    $timezone = new DateTimeZone( $tz );
    $current_timestamp = current_time( 'timestamp' );
    $current_dt = new DateTime("@$current_timestamp");
    $current_dt->setTimezone( $timezone );
    
    $hours = get_option( 'rha_hours', array() );
    $days_mapping = array(
        'Monday'    => 'Lunes',
        'Tuesday'   => 'Martes',
        'Wednesday' => 'Miércoles',
        'Thursday'  => 'Jueves',
        'Friday'    => 'Viernes',
        'Saturday'  => 'Sábado',
        'Sunday'    => 'Domingo'
    );
    for ( $i = 0; $i < 7; $i++ ) {
        $dt = clone $current_dt;
        if ( $i > 0 ) {
            $dt->modify("+$i day");
        }
        $date_str = $dt->format('Y-m-d');
        $day_en = $dt->format('l');
        $day_spanish = isset( $days_mapping[ $day_en ] ) ? $days_mapping[ $day_en ] : $day_en;
        
        if ( isset( $hours[ $day_spanish ] ) && is_array( $hours[ $day_spanish ] ) ) {
            foreach ( $hours[ $day_spanish ] as $session ) {
                if ( ! empty( $session['open'] ) ) {
                    $open_dt = new DateTime( $date_str . ' ' . $session['open'], $timezone );
                    if ( $i == 0 && $open_dt <= $current_dt ) {
                        continue;
                    }
                    $diff = $open_dt->getTimestamp() - $current_dt->getTimestamp();
                    $hours_left = floor( $diff / 3600 );
                    $minutes_left = floor( ( $diff % 3600 ) / 60 );
                    return sprintf( "%d hours %d minutes", $hours_left, $minutes_left );
                }
            }
        }
    }
    return false;
}
/**
 * Check if the shop is currently open using WP timezone.
 */
function rha_is_shop_open() {
    $current_timestamp = current_time( 'timestamp' );
    $current_date = wp_date( 'Y-m-d', $current_timestamp );
    $vacations = get_option( 'rha_vacations', array() );
    if ( is_array( $vacations ) ) {
        foreach ( $vacations as $vacation ) {
            if ( $current_date >= $vacation['start'] && $current_date <= $vacation['end'] ) {
                return false;
            }
        }
    }
    
    $days_mapping = array(
        'Monday'    => 'Lunes',
        'Tuesday'   => 'Martes',
        'Wednesday' => 'Miércoles',
        'Thursday'  => 'Jueves',
        'Friday'    => 'Viernes',
        'Saturday'  => 'Sábado',
        'Sunday'    => 'Domingo'
    );
    $current_day_en = wp_date( 'l', $current_timestamp );
    $current_day = isset( $days_mapping[ $current_day_en ] ) ? $days_mapping[ $current_day_en ] : $current_day_en;
    $current_time = current_time( 'H:i' );
    
    $hours = get_option( 'rha_hours' );
    if ( isset( $hours[ $current_day ] ) && is_array( $hours[ $current_day ] ) ) {
        foreach ( $hours[ $current_day ] as $slot ) {
            if ( ! empty( $slot['open'] ) && ! empty( $slot['close'] ) ) {
                if ( $current_time >= $slot['open'] && $current_time <= $slot['close'] ) {
                    return true;
                }
            }
        }
    }
    return false;
}
/* ============================================================
   5. SHOP STATUS NOTICE & STYLE (Using WP Timezone)
   ============================================================ */
/**
 * Output a dynamic shop status notice on the front-end using WP timezone.
 */
function rha_shop_status_notice() {
    $today_hours  = rha_get_today_hours();
    
    if ( rha_is_shop_open() ) {
        $hours_left = rha_get_hours_left();
        $custom_notice = get_option( 'rha_notice_open_text', '' );
        // Prepare placeholders for the open state.
        $placeholders = array(
            '{hours_left}' => $hours_left,
            '{today_hours}' => $today_hours,
        );
        // Replace placeholders in the custom notice.
        $message = strtr( $custom_notice, $placeholders );
        // Fallback default message.
        if ( empty( trim($message) ) ) {
            $message = "¡Estamos abiertos! Horas restantes para pedir: " . $hours_left . ". Horarios de hoy: " . $today_hours . ".";
        }
        $class = "rha-open";
    } else {
        $time_until_open = rha_get_time_until_open();
        $custom_notice = get_option( 'rha_notice_closed_text', '' );
        // Prepare placeholders for the closed state.
        $placeholders = array(
            '{time_until_open}' => $time_until_open,
            '{today_hours}' => $today_hours,
        );
        $message = strtr( $custom_notice, $placeholders );
        if ( empty( trim($message) ) ) {
            if ( $time_until_open ) {
                $message = "La tienda está cerrada. Tiempo hasta abrir: " . $time_until_open . ". Horarios de hoy: " . $today_hours . ".";
            } else {
                $message = "La tienda está cerrada. Horarios de hoy: " . $today_hours . ".";
            }
        }
        $class = "rha-closed";
    }
    
    // Render the message without extra formatting so it uses the theme's default style.
    $notice_html = '<div class="rha-shop-notice ' . esc_attr( $class ) . '">';
    $notice_html .= '<span class="rha-close-notice">X</span>';
    $notice_html .= wp_kses_post( $message );
    $notice_html .= '</div>';
    
    echo $notice_html;
    ?>
    <script>
    document.addEventListener("DOMContentLoaded", function() {
        var notice = document.querySelector(".rha-shop-notice");
        var closeButton = document.querySelector(".rha-close-notice");
        if (closeButton) {
            closeButton.addEventListener("click", function() {
                notice.style.display = "none";
            });
        }
        // Hide the notice after 7 seconds.
        setTimeout(function() {
            if (notice) {
                notice.style.display = "none";
            }
        }, 7000);
    });
    </script>
    <?php
}
add_action( 'wp_footer', 'rha_shop_status_notice' );
/**
 * Disable purchasing if the shop is closed.
 */
function rha_disable_purchase_if_closed( $purchasable, $product ) {
    if ( ! rha_is_shop_open() ) {
        return false;
    }
    return $purchasable;
}
add_filter( 'woocommerce_is_purchasable', 'rha_disable_purchase_if_closed', 10, 2 );
/**
 * Remove Add-to-Cart buttons when the shop is closed.
 */
function rha_remove_add_to_cart() {
    if ( ! rha_is_shop_open() ) {
        remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );
        remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
    }
}
add_action( 'wp', 'rha_remove_add_to_cart' );
/* ============================================================
   6. DISABLE SHIPPING & PAYMENT METHODS WHEN CLOSED
   ============================================================ */
/**
 * Filter shipping methods to remove those that are set to be disabled when the shop is closed.
 */
function rha_filter_shipping_methods_when_closed( $rates, $package ) {
    if ( ! rha_is_shop_open() ) {
        $disabled_shipping = get_option( 'rha_disable_shipping_methods', array() );
        if ( ! empty( $disabled_shipping ) && is_array( $disabled_shipping ) ) {
            foreach ( $rates as $rate_id => $rate ) {
                if ( in_array( $rate->method_id, $disabled_shipping ) ) {
                    unset( $rates[ $rate_id ] );
                }
            }
        }
    }
    return $rates;
}
add_filter( 'woocommerce_package_rates', 'rha_filter_shipping_methods_when_closed', 10, 2 );
/**
 * Filter payment gateways to remove those that are set to be disabled when the shop is closed.
 */
function rha_filter_payment_gateways_when_closed( $gateways ) {
    if ( ! rha_is_shop_open() ) {
        $disabled_payment = get_option( 'rha_disable_payment_methods', array() );
        if ( ! empty( $disabled_payment ) && is_array( $disabled_payment ) ) {
            foreach ( $gateways as $gateway_id => $gateway ) {
                if ( in_array( $gateway_id, $disabled_payment ) ) {
                    unset( $gateways[ $gateway_id ] );
                }
            }
        }
    }
    return $gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'rha_filter_payment_gateways_when_closed' );
/* ============================================================
   7. INLINE STYLES & DASHICONS ENQUEUE
   ============================================================ */
/**
 * Inline CSS styles.
 */
function rha_shop_notice_styles() {
    ?>
    <style>
    .rha-shop-notice {
        position: fixed;
        bottom: 120px;
        left: 50%;
        transform: translateX(-50%);
        width: 75%;
        padding: 20px;
        text-align: center;
        border: 1px solid #ccc;
        border-radius: 10px;
        box-shadow: 0 -2px 5px rgba(0,0,0,0.1);
        animation: slideUp 0.5s ease-out;
        z-index: 9999;
    }
    @keyframes slideUp {
        from { transform: translateY(100%); }
        to { transform: translateY(0); }
    }
    .rha-close-notice {
        position: absolute;
        top: 5px;
        right: 10px;
        cursor: pointer;
        font-weight: normal;
        color: #000;
    }
    .rha-shop-notice a {
        color: inherit;
        text-decoration: underline;
        font-weight: normal;
    }
    .rha-shop-notice.rha-open {
        background-color: #d4edda;
        color: #155724;
    }
    .rha-shop-notice.rha-closed {
        background-color: #f8d7da;
        color: #721c24;
    }
    .rha-frontend-clock {
        padding: 12px;
        vertical-align: middle;
        margin-right: 5px;
    }
    </style>
    <?php
}
add_action( 'wp_head', 'rha_shop_notice_styles' );
function rha_enqueue_dashicons() {
    wp_enqueue_style( 'dashicons' );
}
add_action( 'wp_enqueue_scripts', 'rha_enqueue_dashicons' );
'; return $output; } add_shortcode( 'restaurant_hours_services', 'rha_display_hours_services' ); /* ============================================================ 4. HELPER FUNCTIONS & SHOP CONTROL LOGIC (Using WP Timezone) ============================================================ */ /** * Retrieve today's open hours as a formatted string. */ function rha_get_today_hours() { $days_mapping = array( 'Monday' => 'Lunes', 'Tuesday' => 'Martes', 'Wednesday' => 'Miércoles', 'Thursday' => 'Jueves', 'Friday' => 'Viernes', 'Saturday' => 'Sábado', 'Sunday' => 'Domingo' ); $current_timestamp = current_time( 'timestamp' ); $current_day_en = wp_date( 'l', $current_timestamp ); $current_day = isset( $days_mapping[ $current_day_en ] ) ? $days_mapping[ $current_day_en ] : $current_day_en; $hours = get_option( 'rha_hours' ); $session_texts = array(); if ( isset( $hours[ $current_day ] ) && is_array( $hours[ $current_day ] ) ) { foreach ( $hours[ $current_day ] as $slot ) { if ( ! empty( $slot['open'] ) && ! empty( $slot['close'] ) ) { $session_texts[] = $slot['open'] . ' – ' . $slot['close']; } } } return empty( $session_texts ) ? 'Cerrado' : implode( ' / ', $session_texts ); } /** * Calculate the remaining time left to order in the current session. */ function rha_get_hours_left() { $current_timestamp = current_time( 'timestamp' ); $today_date = wp_date( 'Y-m-d', $current_timestamp ); $hours = get_option( 'rha_hours' ); $days_mapping = array( 'Monday' => 'Lunes', 'Tuesday' => 'Martes', 'Wednesday' => 'Miércoles', 'Thursday' => 'Jueves', 'Friday' => 'Viernes', 'Saturday' => 'Sábado', 'Sunday' => 'Domingo' ); $current_day_en = wp_date( 'l', $current_timestamp ); $current_day = isset( $days_mapping[ $current_day_en ] ) ? $days_mapping[ $current_day_en ] : $current_day_en; if ( isset( $hours[ $current_day ] ) && is_array( $hours[ $current_day ] ) ) { foreach ( $hours[ $current_day ] as $slot ) { if ( ! empty( $slot['open'] ) && ! empty( $slot['close'] ) ) { $open_timestamp = strtotime( $today_date . ' ' . $slot['open'] ); $close_timestamp = strtotime( $today_date . ' ' . $slot['close'] ); if ( $current_timestamp >= $open_timestamp && $current_timestamp <= $close_timestamp ) { $diff = $close_timestamp - $current_timestamp; $hours_left = floor( $diff / 3600 ); $minutes_left = floor( ( $diff % 3600 ) / 60 ); return sprintf( "%d hours %d minutes", $hours_left, $minutes_left ); } } } } return false; } /** * Calculate the time until the next opening session. */ function rha_get_time_until_open() { $tz = get_option( 'rha_timezone', wp_timezone()->getName() ); $timezone = new DateTimeZone( $tz ); $current_timestamp = current_time( 'timestamp' ); $current_dt = new DateTime("@$current_timestamp"); $current_dt->setTimezone( $timezone ); $hours = get_option( 'rha_hours', array() ); $days_mapping = array( 'Monday' => 'Lunes', 'Tuesday' => 'Martes', 'Wednesday' => 'Miércoles', 'Thursday' => 'Jueves', 'Friday' => 'Viernes', 'Saturday' => 'Sábado', 'Sunday' => 'Domingo' ); for ( $i = 0; $i < 7; $i++ ) { $dt = clone $current_dt; if ( $i > 0 ) { $dt->modify("+$i day"); } $date_str = $dt->format('Y-m-d'); $day_en = $dt->format('l'); $day_spanish = isset( $days_mapping[ $day_en ] ) ? $days_mapping[ $day_en ] : $day_en; if ( isset( $hours[ $day_spanish ] ) && is_array( $hours[ $day_spanish ] ) ) { foreach ( $hours[ $day_spanish ] as $session ) { if ( ! empty( $session['open'] ) ) { $open_dt = new DateTime( $date_str . ' ' . $session['open'], $timezone ); if ( $i == 0 && $open_dt <= $current_dt ) { continue; } $diff = $open_dt->getTimestamp() - $current_dt->getTimestamp(); $hours_left = floor( $diff / 3600 ); $minutes_left = floor( ( $diff % 3600 ) / 60 ); return sprintf( "%d hours %d minutes", $hours_left, $minutes_left ); } } } } return false; } /** * Check if the shop is currently open using WP timezone. */ function rha_is_shop_open() { $current_timestamp = current_time( 'timestamp' ); $current_date = wp_date( 'Y-m-d', $current_timestamp ); $vacations = get_option( 'rha_vacations', array() ); if ( is_array( $vacations ) ) { foreach ( $vacations as $vacation ) { if ( $current_date >= $vacation['start'] && $current_date <= $vacation['end'] ) { return false; } } } $days_mapping = array( 'Monday' => 'Lunes', 'Tuesday' => 'Martes', 'Wednesday' => 'Miércoles', 'Thursday' => 'Jueves', 'Friday' => 'Viernes', 'Saturday' => 'Sábado', 'Sunday' => 'Domingo' ); $current_day_en = wp_date( 'l', $current_timestamp ); $current_day = isset( $days_mapping[ $current_day_en ] ) ? $days_mapping[ $current_day_en ] : $current_day_en; $current_time = current_time( 'H:i' ); $hours = get_option( 'rha_hours' ); if ( isset( $hours[ $current_day ] ) && is_array( $hours[ $current_day ] ) ) { foreach ( $hours[ $current_day ] as $slot ) { if ( ! empty( $slot['open'] ) && ! empty( $slot['close'] ) ) { if ( $current_time >= $slot['open'] && $current_time <= $slot['close'] ) { return true; } } } } return false; } /* ============================================================ 5. SHOP STATUS NOTICE & STYLE (Using WP Timezone) ============================================================ */ /** * Output a dynamic shop status notice on the front-end using WP timezone. */ function rha_shop_status_notice() { $today_hours = rha_get_today_hours(); if ( rha_is_shop_open() ) { $hours_left = rha_get_hours_left(); $custom_notice = get_option( 'rha_notice_open_text', '' ); // Prepare placeholders for the open state. $placeholders = array( '{hours_left}' => $hours_left, '{today_hours}' => $today_hours, ); // Replace placeholders in the custom notice. $message = strtr( $custom_notice, $placeholders ); // Fallback default message. if ( empty( trim($message) ) ) { $message = "¡Estamos abiertos! Horas restantes para pedir: " . $hours_left . ". Horarios de hoy: " . $today_hours . "."; } $class = "rha-open"; } else { $time_until_open = rha_get_time_until_open(); $custom_notice = get_option( 'rha_notice_closed_text', '' ); // Prepare placeholders for the closed state. $placeholders = array( '{time_until_open}' => $time_until_open, '{today_hours}' => $today_hours, ); $message = strtr( $custom_notice, $placeholders ); if ( empty( trim($message) ) ) { if ( $time_until_open ) { $message = "La tienda está cerrada. Tiempo hasta abrir: " . $time_until_open . ". Horarios de hoy: " . $today_hours . "."; } else { $message = "La tienda está cerrada. Horarios de hoy: " . $today_hours . "."; } } $class = "rha-closed"; } // Render the message without extra formatting so it uses the theme's default style. $notice_html = '
'; $notice_html .= 'X'; $notice_html .= wp_kses_post( $message ); $notice_html .= '
'; echo $notice_html; ?> $rate ) { if ( in_array( $rate->method_id, $disabled_shipping ) ) { unset( $rates[ $rate_id ] ); } } } } return $rates; } add_filter( 'woocommerce_package_rates', 'rha_filter_shipping_methods_when_closed', 10, 2 ); /** * Filter payment gateways to remove those that are set to be disabled when the shop is closed. */ function rha_filter_payment_gateways_when_closed( $gateways ) { if ( ! rha_is_shop_open() ) { $disabled_payment = get_option( 'rha_disable_payment_methods', array() ); if ( ! empty( $disabled_payment ) && is_array( $disabled_payment ) ) { foreach ( $gateways as $gateway_id => $gateway ) { if ( in_array( $gateway_id, $disabled_payment ) ) { unset( $gateways[ $gateway_id ] ); } } } } return $gateways; } add_filter( 'woocommerce_available_payment_gateways', 'rha_filter_payment_gateways_when_closed' ); /* ============================================================ 7. INLINE STYLES & DASHICONS ENQUEUE ============================================================ */ /** * Inline CSS styles. */ function rha_shop_notice_styles() { ?>

Comments

Add a Comment