'', 'end_date' => '', 'booking_period' => 'custom', 'current_accomodation' => 'all', 'current_status' => ['processing', 'on-hold', 'completed', 'pending', 'blocked'], 'allowed_status' => ['processing', 'on-hold', 'completed', 'pending', 'blocked'], ); public function __construct() { $this->plugin_settings = get_option( 'eshb_settings', [] ); // Setup calendar settings $today_date = gmdate("Y-m-d"); $default_end_date = gmdate('Y-m-d', strtotime('+14 days')); // use defaults $start_date = $today_date; $end_date = $default_end_date; $current_status = $this->calendar_settings['current_status']; $current_accomodation = $this->calendar_settings['current_accomodation']; $booking_period = $this->calendar_settings['booking_period']; // Verify nonce for form processing if (isset($_POST['nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), ESHB_Helper::generate_secure_nonce_action('booking_calendar_nonce'))) { // Sanitize and validate GET parameters $start_date = !empty($_POST['start-date']) ? sanitize_text_field(wp_unslash($_POST['start-date'])) : $today_date; $end_date = !empty($_POST['end-date']) ? sanitize_text_field(wp_unslash($_POST['end-date'])) : $default_end_date; $current_status = !empty($_POST['booking-status']) ? [sanitize_text_field(wp_unslash($_POST['booking-status']))] : $this->calendar_settings['current_status']; $current_accomodation = !empty($_POST['accomodation-id']) ? sanitize_text_field(wp_unslash($_POST['accomodation-id'])) : $this->calendar_settings['current_accomodation']; $booking_period = !empty($_POST['booking-period']) ? sanitize_text_field(wp_unslash($_POST['booking-period'])) : $this->calendar_settings['booking_period']; } if ($booking_period != 'custom') { // Current date $start_date = gmdate('Y-m-01'); $end_date = gmdate('Y-m-t'); if (!empty($_POST['action-prev-period']) || !empty($_POST['action-next-period'])){ $start_date = !empty($_POST['start-date']) ? sanitize_text_field(wp_unslash($_POST['start-date'])) : $start_date; $end_date = !empty($_POST['end-date']) ? sanitize_text_field(wp_unslash($_POST['end-date'])) : $end_date; } if ($booking_period == 'month') { if (!empty($_POST['action-prev-period'])) { $date = $start_date; $start_date = gmdate('Y-m-01', strtotime('-1 month', strtotime($date))); $end_date = gmdate('Y-m-t', strtotime('-1 month', strtotime($date))); } if (!empty($_POST['action-next-period'])) { $date = $start_date; $start_date = gmdate('Y-m-01', strtotime('+1 month', strtotime($date))); $end_date = gmdate('Y-m-t', strtotime('+1 month', strtotime($date))); } } elseif ($booking_period == 'quarter') { // Default: current quarter $current_month = gmdate('n'); $quarter_start_month = floor(($current_month - 1) / 3) * 3 + 1; $start_date = gmdate('Y-' . str_pad($quarter_start_month, 2, '0', STR_PAD_LEFT) . '-01'); $end_date = gmdate('Y-m-t', strtotime("+2 months", strtotime($start_date))); // end of third month if (!empty($_POST['action-prev-period'])) { $start_date = !empty($_POST['start-date']) ? sanitize_text_field(wp_unslash($_POST['start-date'])) : $start_date; $end_date = !empty($_POST['end-date']) ? sanitize_text_field(wp_unslash($_POST['end-date'])) : $end_date; $start_date = gmdate('Y-m-01', strtotime('-3 months', strtotime($start_date))); $end_date = gmdate('Y-m-t', strtotime('+2 months', strtotime($start_date))); } if (!empty($_POST['action-next-period'])) { $start_date = !empty($_POST['start-date']) ? sanitize_text_field(wp_unslash($_POST['start-date'])) : $start_date; $end_date = !empty($_POST['end-date']) ? sanitize_text_field(wp_unslash($_POST['end-date'])) : $end_date; $start_date = gmdate('Y-m-01', strtotime('+3 months', strtotime($start_date))); $end_date = gmdate('Y-m-t', strtotime('+2 months', strtotime($start_date))); } } elseif ($booking_period == 'year') { // Default to full current year $start_date = gmdate('Y-01-01'); $end_date = gmdate('Y-12-31'); if (!empty($_POST['action-prev-period'])) { $start_date = !empty($_POST['start-date']) ? sanitize_text_field(wp_unslash($_POST['start-date'])) : $start_date; $end_date = !empty($_POST['end-date']) ? sanitize_text_field(wp_unslash($_POST['end-date'])) : $end_date; $start_date = gmdate('Y-01-01', strtotime('-1 year', strtotime($start_date))); $end_date = gmdate('Y-12-31', strtotime('-1 year', strtotime($end_date))); } if (!empty($_POST['action-next-period'])) { $start_date = !empty($_POST['start-date']) ? sanitize_text_field(wp_unslash($_POST['start-date'])) : $start_date; $end_date = !empty($_POST['end-date']) ? sanitize_text_field(wp_unslash($_POST['end-date'])) : $end_date; $start_date = gmdate('Y-01-01', strtotime('+1 year', strtotime($start_date))); $end_date = gmdate('Y-12-31', strtotime('+1 year', strtotime($end_date))); } } } $this->calendar_settings = array_merge( $this->calendar_settings, [ 'start' => $start_date, 'end' => $end_date, 'current_status' => $current_status, 'current_accomodation' => $current_accomodation, ] ); $this->calendar = [ 'name' => 'Booking Calendar', 'settings' => $this->calendar_settings, 'dates' => $this->get_dates_from_range($this->calendar_settings['start'], $this->calendar_settings['end']), 'accomodations' => $this->accomodations, ]; // Set all accomodations & bookings $this->set_all_accomodations(); $this->set_all_bookings(); } public function get_dates_from_range($start_date, $end_date) { $dates = array(); $start = new DateTime($start_date); $end = new DateTime($end_date); $end = $end->modify('+1 day'); // Include end date while ($start < $end) { $dates[] = $start->format('Y-m-d'); $start->modify('+1 day'); } return $dates; } public function set_all_accomodations () { // Fetch all accomodations $accomodation_posts = get_posts([ 'post_type' => 'eshb_accomodation', 'posts_per_page' => -1, 'post_status' => 'publish', 'orderby' => 'ID', 'order' => 'DESC', ]); foreach ($accomodation_posts as $post) { $accomodation_id = $post->ID; $metaboxes = get_post_meta($accomodation_id, 'eshb_accomodation_metaboxes', true); $total_rooms = isset($metaboxes['total_rooms']) ? floatval($metaboxes['total_rooms']) : 0; $this->accomodations[] = [ 'id' => $accomodation_id, 'name' => $post->post_title, 'type' => $post->post_type, 'status' => $post->post_status, 'total_rooms' => $total_rooms, ]; } } public function set_all_bookings (){ $plugin_settings = $this->plugin_settings; $booked_type = $plugin_settings['booking-type']; $bookings = []; $booking_posts = get_posts([ 'post_type' => 'eshb_booking', 'posts_per_page' => -1, 'post_status' => ['publish', 'deposit-payment', 'pending', 'processing', 'on-hold', 'completed'], 'orderby' => 'title', 'order' => 'ASC', ]); foreach ($booking_posts as $post) { $booking_id = $post->ID; $metaboxes = get_post_meta($booking_id, 'eshb_booking_metaboxes', true); $accomodation_id = floatval($metaboxes['booking_accomodation_id'] ?? 0); $order_id = $metaboxes['order_id'] ?? ''; $check_in = $metaboxes['booking_start_date'] ?? ''; $check_out = $metaboxes['booking_end_date'] ?? ''; $booked_dates = $this->get_dates_from_range($check_in, $check_out); if (count($booked_dates) > 1) { array_pop($booked_dates); } $booking_status = $metaboxes['booking_status'] ?? ''; $customer = ''; if (class_exists('WooCommerce') && wc_get_order($order_id)) { $order = wc_get_order($order_id); $customer = trim($order->get_billing_first_name() . ' ' . $order->get_billing_last_name()); } $customer = apply_filters( 'eshb_customer_data_in_calendar', $customer, $order_id, $booked_type); if (in_array($booking_status, ['processing', 'on-hold'])) { $booking_status = 'blocked'; } if(in_array($booking_status, $this->calendar_settings['current_status'])){ $bookings[] = [ 'id' => $booking_id, 'check_in' => $check_in, 'check_out' => $check_out, 'status' => $booking_status, 'accomodation_id' => $accomodation_id, 'customer' => $customer, 'source_type' => 'internal', ]; } } $bookings = apply_filters('eshb_modify_calendar_booking_data', $bookings, $this->calendar_settings); $this->bookings = array_merge($this->bookings, $bookings); } private function get_bookings_for_accomodation($accomodation_id) { return array_filter($this->bookings, function($booking) use ($accomodation_id) { return intval($booking['accomodation_id']) === intval($accomodation_id); }); } public function render_booking_cells($dates, $accomodations, $accomodation_limit = 0) { if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), ESHB_Helper::generate_secure_nonce_action('booking_calendar_nonce') ) ) { $filtered_accomodation_id = ''; } if ($accomodation_limit > 0) { $accomodations = array_slice($accomodations, 0, $accomodation_limit); } $filtered_accomodation_id = !empty($_REQUEST['accomodation-id']) ? sanitize_text_field(wp_unslash($_REQUEST['accomodation-id'])): ''; if(!empty($filtered_accomodation_id)){ $accomodations = array_filter($accomodations, function($accomodation) use ($filtered_accomodation_id) { return $accomodation['id'] == $filtered_accomodation_id; }); } $html = ''; $dates_map = array_flip($dates); $total_dates = count($dates); // Group bookings by accomodation id for faster access $bookings_by_accomodation = []; foreach ($this->bookings as $booking) { if (!isset($booking['accomodation_id'])) continue; $acc_id = $booking['accomodation_id']; $bookings_by_accomodation[$acc_id][] = $booking; } foreach ($accomodations as $accomodation) { $accomodation_id = $accomodation['id']; if ( function_exists( 'pll_get_post' )) { $default_lang = pll_default_language(); $main_post_id = pll_get_post( $accomodation_id, $default_lang ) ? pll_get_post( $accomodation_id, $default_lang ) : $accomodation_id ; $accomodation_id = $main_post_id; }elseif ( function_exists( 'apply_filters' ) && function_exists( 'icl_object_id' ) ) { $accomodation_id = apply_filters( 'wpml_original_element_id', NULL, $accomodation_id, 'post_post' ); } $accomodation_name = $accomodation['name']; $bookings = isset($bookings_by_accomodation[$accomodation_id]) ? $bookings_by_accomodation[$accomodation_id] : []; // Group bookings by date range $grouped_bookings = []; foreach ($bookings as $booking) { $key = $booking['check_in'] . '|' . $booking['check_out']; $grouped_bookings[$key][] = $booking; } $html .= '
'. esc_html__('Accomodations', 'easy-hotel') .' | ';
foreach ($dates as $date) {
$wp_date_format = get_option('date_format');
$formatted_date = DateTime::createFromFormat('Y-m-d', $date)->format($wp_date_format);
$html .= '';
$html .= ' ';
$html .= esc_html( DateTime::createFromFormat('Y-m-d', $date)->format('j') ) . ' ';
$html .= ''; $html .= esc_html( DateTime::createFromFormat('Y-m-d', $date)->format('M'), DateTime::createFromFormat('Y-m-d', $date)->format('F'). ' abbreviation') . ' '; $html .= '' . DateTime::createFromFormat('Y-m-d', $date)->format('Y').' '; $html .= '' . DateTime::createFromFormat('Y-m-d', $date)->format('D') . ''; $html .= ' | ';
}
$html .= '
|---|---|
'. esc_html__('Accomodations', 'easy-hotel') .' | ';
foreach ($dates as $date) {
$wp_date_format = get_option('date_format');
$formatted_date = DateTime::createFromFormat('Y-m-d', $date)->format($wp_date_format);
$html .= '';
$html .= ' ';
$html .= esc_html( DateTime::createFromFormat('Y-m-d', $date)->format('j') ) . ' ';
$html .= ''; $html .= esc_html( DateTime::createFromFormat('Y-m-d', $date)->format('M'), DateTime::createFromFormat('Y-m-d', $date)->format('F'). ' abbreviation' ) . ' '; $html .= '' . DateTime::createFromFormat('Y-m-d', $date)->format('Y').' '; $html .= '' . DateTime::createFromFormat('Y-m-d', $date)->format('D') . ''; $html .= ' | ';
}
$html .= '