$post_type, 'post_status' => 'publish', // Only fetch published pages 'title' => $page_title, 'posts_per_page' => 1, // Limit to one result ); // Run the query $query = new WP_Query( $args ); // Check if any post is found if ( $query->have_posts() ) { return $query->posts[0]; // Return the first found page } // Return false if no page is found return false; } public function eshb_get_disabled_dates_by_accomodation_id($accomodation_id, $start_date = '', $end_date = '') { // Verify nonce for security if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), ESHB_Helper::generate_secure_nonce_action('eshb_global_nonce_action'))) { wp_send_json_error(['message' => 'Invalid nonce']); die(); } if (isset($_POST['accomodation_id'])) { $accomodation_id = sanitize_text_field(wp_unslash($_POST['accomodation_id'])); } $eshb_settings = get_option('eshb_settings', []); $booked_dates = []; $total_room_bookings_per_date = []; // Track room bookings per date $total_booked_slots_hours = 0; $total_slots_hours = false; // Get total rooms allowed for this accommodation $accomodation_metas = get_post_meta($accomodation_id, 'eshb_accomodation_metaboxes', true); $is_single_day_plugin_active = get_option('eshb_single_day_activated'); $pricing_periodicity = false; if ($is_single_day_plugin_active) { $pricing_periodicity = !empty($accomodation_metas['pricing_periodicity']) ? $accomodation_metas['pricing_periodicity'] : false; $eshb_single_day_settings = get_option( 'eshb_single_day_settings', []); $slots_start_time = $eshb_single_day_settings['start_time']; $slots_end_time = $eshb_single_day_settings['end_time']; $total_slots_hours = ESHB_Helper::eshb_calculate_time_diff('', '', $slots_start_time, $slots_end_time); } $holidays = isset($eshb_settings['holidays']) ? $eshb_settings['holidays'] : []; $finally_holidays = []; if ( ! empty( $holidays ) ) { foreach ( $holidays as $holiday ) { $accommodation_ids = $holiday['accomodation-ids'] ?? []; $holiday_date = $holiday['holiday-date'] ?? null; // Check if holiday is applicable for all or specific accommodation $is_applicable = empty($accommodation_ids) || (is_array($accommodation_ids) && in_array($accomodation_id, $accommodation_ids)); if ( $is_applicable && $holiday_date ) { if ( is_array($holiday_date) && isset($holiday_date['from'], $holiday_date['to']) ) { $start = DateTime::createFromFormat('Y-m-d', $holiday_date['from']); $end = DateTime::createFromFormat('Y-m-d', $holiday_date['to']); if ( $start && $end ) { $end->modify('+1 day'); // Include end date $interval = new DateInterval('P1D'); $dateRange = new DatePeriod($start, $interval, $end); foreach ( $dateRange as $date ) { $finally_holidays[] = $date->format('Y-m-d'); } } } else { $finally_holidays[] = $holiday_date; } } } } $allowed_total_rooms = isset($accomodation_metas['total_rooms']) ? intval($accomodation_metas['total_rooms']) : 0; $total_rooms = isset($accomodation_metas['total_rooms']) ? intval($accomodation_metas['total_rooms']) : 1; $available_rooms = isset($accomodation_metas['available_rooms']) ? intval($accomodation_metas['available_rooms']) : $total_rooms; $min_max_nights_settings = [ 'required_min_nights' => 1, 'required_max_nights' => 999, ]; $min_max_nights_settings = apply_filters('eshb_min_max_nights_settings_before_search', $min_max_nights_settings, $accomodation_id, $accomodation_metas); // Get min stay night by session $min_stay_night_by_session = ESHB_Helper::get_eshb_min_stay_night_by_session($accomodation_id, $start_date, $end_date); if(class_exists('ESHB_ADVANCED_PRICING') && $min_stay_night_by_session > 0){ $min_max_nights_settings['required_min_nights'] = $min_stay_night_by_session; } // Find all bookings for this accommodation $bookings_args = [ 'post_type' => 'eshb_booking', 'posts_per_page' => -1, 'post_status' => ['publish', 'deposit-payment', 'pending', 'processing', 'on-hold', 'completed'], 'fields' => 'ids', ]; $bookings = new WP_Query($bookings_args); $checked_in_out_dates = []; if ($bookings->have_posts()) { while ($bookings->have_posts()) { $bookings->the_post(); $meta_values = get_post_meta(get_the_ID(), 'eshb_booking_metaboxes', true); $booking_status = isset($meta_values['booking_status']) ? $meta_values['booking_status'] : ''; $completed_booking_status_maps = array( 'pending', 'deposit-payment', 'processing', 'on-hold', 'completed' ); // Ensure required keys exist if (is_array($meta_values) && in_array($booking_status, $completed_booking_status_maps) && isset($meta_values['booking_accomodation_id'], $meta_values['booking_start_date'], $meta_values['booking_end_date'])) { $booking_accomodation_id = intval($meta_values['booking_accomodation_id']); $booking_start_date = $meta_values['booking_start_date']; $booking_end_date = $meta_values['booking_end_date']; $accommodation_metaboxes = get_post_meta($booking_accomodation_id, 'eshb_accomodation_metaboxes', true); $total_rooms = $accommodation_metaboxes['total_rooms'] ?? 1; $booked_accomodation_ids = []; $accomodation_id = ESHB_Helper::get_main_post_id_for_translated($accomodation_id); if ($accomodation_id == $booking_accomodation_id) { // Convert dates to DateTime objects $start_date = new DateTime($booking_start_date); $end_date = new DateTime($booking_end_date); $booked_id = get_the_ID(); $booking_metas = get_post_meta($booked_id, 'eshb_booking_metaboxes', true); $booked_room_quantity = isset($booking_metas['room_quantity']) ? intval($booking_metas['room_quantity']) : 1; $booking_start_time = isset($booking_metas['booking_start_time']) ? intval($booking_metas['booking_start_time']) : ''; $booking_end_time = isset($booking_metas['booking_end_time']) ? intval($booking_metas['booking_end_time']) : ''; $checked_in_out_dates['checked_in'][] = $booking_start_date; $checked_in_out_dates['checked_out'][] = $booking_end_date; // NEW: Clone end date and subtract 1 day to exclude checkout day if($booking_start_date !== $booking_end_date) { $actual_end_date = (clone $end_date)->modify('-1 day'); }else{ $actual_end_date = (clone $end_date)->modify('+1 day'); } $period = new DatePeriod($start_date, new DateInterval('P1D'), $actual_end_date->modify('+1 day')); foreach ($period as $date) { $formatted_date = $date->format('Y-m-d'); if (!isset($total_room_bookings_per_date[$formatted_date])) { $total_room_bookings_per_date[$formatted_date] = 0; } $total_room_bookings_per_date[$formatted_date] += $booked_room_quantity; } if($booking_start_date === $booking_end_date) { array_pop($total_room_bookings_per_date); } } } } } $total_booked_rooms_in_date_ranges = 0; $dates = []; // Determine which dates should be disabled (fully booked) foreach ($total_room_bookings_per_date as $date => $total_booked_rooms) { // allow external plugins to modify available slots $available_slots = apply_filters( 'eshb_available_slots_in_booked_dates_loop', false, $date, $total_booked_rooms, $accomodation_id ); if($available_slots) { $total_booked_rooms = 0; } if ($allowed_total_rooms <= $total_booked_rooms) { $date = new DateTime($date); $booked_dates[] = $date->format('Y, m, d'); array_push($dates, array('dates' => $date, 'total_booked_rooms_in_date_ranges' => $total_booked_rooms)); } } // Apply filter hook to allow external modifications $booked_dates = apply_filters('eshb_modify_booked_dates', $booked_dates, $accomodation_id); $checked_in_out_dates = apply_filters('eshb_modify_checked_in_out_dates', $checked_in_out_dates, $accomodation_id); $all_dates = [ 'checked_in_out_dates' => $checked_in_out_dates, 'booked_dates' => $booked_dates, 'holiday_dates' => $finally_holidays, 'allowed_check_in_day' => '', 'single_day' => false, 'min_nights' => $min_max_nights_settings['required_min_nights'], 'max_nights' => $min_max_nights_settings['required_max_nights'], 'total_room_bookings_per_date' => $total_room_bookings_per_date, ]; $all_dates = apply_filters('eshb_get_disabled_dates_in_search', $all_dates, $accomodation_id, $accomodation_metas); if(isset($_POST['action']) && $_POST['action'] == 'eshb_get_disabled_dates_by_accomodation_id'){ wp_send_json_success($all_dates); wp_die(); }else{ return $all_dates; } } public function eshb_generate_dates_from_date_ranges($start_date, $end_date){ // $start_date = '2025, 05, 16'; // Format: YYYY, MM, DD // $end_date = '2025, 05, 26'; $start = DateTime::createFromFormat('Y, m, d', $start_date); $end = DateTime::createFromFormat('Y, m, d', $end_date); $end->modify('+1 day'); // Include the end date in the range $interval = new DateInterval('P1D'); // 1-day interval $daterange = new DatePeriod($start, $interval, $end); $dates_array = []; foreach ($daterange as $date) { $dates_array[] = $date->format('Y, m, d'); } return $dates_array; } public function eshb_get_available_accomodation_ids($start_date, $end_date, $adult_quantity = 0, $children_quantity = 0, $rooms_quantity = 0) { $available_accomodation_ids = []; if ($start_date && $end_date) { // Step 1: Get all accommodation IDs $accomodations_args = array( 'post_type' => 'eshb_accomodation', 'posts_per_page' => -1, 'fields' => 'ids', ); $accomodations = new WP_Query($accomodations_args); if ($accomodations->have_posts()) { $accomodation_ids = $accomodations->posts; // Step 2: Get all bookings with overlapping dates $bookings_args = array( 'post_type' => 'eshb_booking', 'posts_per_page' => -1, 'post_status' => ['publish', 'deposit-payment', 'pending', 'processing', 'on-hold', 'completed'], 'fields' => 'ids', ); $bookings = new WP_Query($bookings_args); $accommodation_bookings = array(); // [accommodation_id => total_booked_rooms] $booked_accomodation_ids = array(); if ($bookings->have_posts()) { while ($bookings->have_posts()) { $bookings->the_post(); $meta_values = get_post_meta(get_the_ID(), 'eshb_booking_metaboxes', true); if (!is_array($meta_values)) continue; $booking_accomodation_id = intval($meta_values['booking_accomodation_id']); $booking_start_date = $meta_values['booking_start_date']; $booking_end_date = $meta_values['booking_end_date']; $booking_room_quantity = isset($meta_values['room_quantity']) ? intval($meta_values['room_quantity']) : 1; $booking_status = isset($meta_values['booking_status']) ? $meta_values['booking_status'] : ''; $valid_statuses = array('deposit-payment', 'pending', 'processing', 'on-hold', 'completed'); // Only count if booking status is valid and dates overlap if ( in_array($booking_status, $valid_statuses) && $start_date <= $booking_end_date && $end_date >= $booking_start_date ) { if (!isset($accommodation_bookings[$booking_accomodation_id])) { $accommodation_bookings[$booking_accomodation_id] = 0; } $accommodation_bookings[$booking_accomodation_id] += $booking_room_quantity; } } wp_reset_postdata(); // Step 3: Mark accommodations as fully booked foreach ($accommodation_bookings as $accommodation_id => $booked_rooms) { $accomodation_metaboxes = get_post_meta($accommodation_id, 'eshb_accomodation_metaboxes', true); $total_rooms = !empty($accomodation_metaboxes['total_rooms']) ? intval($accomodation_metaboxes['total_rooms']) : 1; if ($booked_rooms >= $total_rooms) { $booked_accomodation_ids[] = $accommodation_id; } } // Step 4: Exclude fully booked accommodations $available_accomodation_ids = array_diff($accomodation_ids, $booked_accomodation_ids); } else { // No bookings, all accommodations are available $available_accomodation_ids = $accomodation_ids; } // Step 5: Filter by requested capacity if (!empty($available_accomodation_ids)) { foreach ($available_accomodation_ids as $key => $available_accomodation_id) { $accomodation_metaboxes = get_post_meta($available_accomodation_id, 'eshb_accomodation_metaboxes', true); $total_capacity = !empty($accomodation_metaboxes['total_capacity']) ? intval($accomodation_metaboxes['total_capacity']) : 1; $adult_capacity = !empty($accomodation_metaboxes['adult_capacity']) ? intval($accomodation_metaboxes['adult_capacity']) : 0; $children_capacity = !empty($accomodation_metaboxes['children_capacity']) ? intval($accomodation_metaboxes['children_capacity']) : 0; $total_rooms = !empty($accomodation_metaboxes['total_rooms']) ? intval($accomodation_metaboxes['total_rooms']) : 1; if(empty($adult_capacity)) { $adult_capacity = $total_capacity; } if(empty($children_capacity)) { $children_capacity = $total_capacity; } if ( $adult_quantity > $adult_capacity || $children_quantity > $children_capacity || $rooms_quantity > $total_rooms ) { unset($available_accomodation_ids[$key]); } } } } } return $available_accomodation_ids; } public function eshb_register_page_template($templates) { $templates['easy-hotel-search.php'] = 'Easy Hotel Search'; $templates['easy-hotel-search-result.php'] = 'Easy Hotel Search Result'; return $templates; } public function eshb_load_template($template) { global $post; if (is_page() && $post->post_type == 'page') { $template_meta = get_post_meta($post->ID, '_wp_page_template', true); if ($template_meta == 'easy-hotel-search.php') { $plugin_template = ESHB_PL_PATH . '/public/templates/easy-hotel-search.php'; $theme_template = get_stylesheet_directory() . '/easy-hotel-booking/easy-hotel-search.php'; $child_theme_template = get_template_directory() . '/easy-hotel-booking/easy-hotel-search.php'; if (file_exists($theme_template)) { $template = $theme_template; } elseif (file_exists($child_theme_template)) { $template = $child_theme_template; } else { $template = $plugin_template; } } if ($template_meta == 'easy-hotel-search-result.php') { $plugin_template = ESHB_PL_PATH . '/public/templates/easy-hotel-search-result.php'; $theme_template = get_stylesheet_directory() . '/easy-hotel-booking/easy-hotel-search-result.php'; $child_theme_template = get_template_directory() . '/easy-hotel-booking/easy-hotel-search-result.php'; if (file_exists($theme_template)) { $template = $theme_template; } elseif (file_exists($child_theme_template)) { $template = $child_theme_template; } else { $template = $plugin_template; } } } return $template; } } ESHB_Search::instance();