PluginProbe
Easy Hotel – Powerful Hotel Booking / 2.0.2
Easy Hotel – Powerful Hotel Booking v2.0.2
2.0.8 2.0.7 2.0.6 2.0.5 2.0.4 2.0.3 2.0.2 2.0.1 2.0.0 1.9.9 1.9.8 1.9.7 1.9.6 1.9.5 1.9.4 1.9.3 1.9.2 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 All 110 releases
easy-hotel / admin / includes / classes / class.search.php

class.search.php in Easy Hotel – Powerful Hotel Booking 2.0.2, at admin/includes/classes/class.search.php

450 lines 19.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
3 class ESHB_Search {
4
5 private static $_instance = null;
6
7 public static function instance() {
8
9 if ( is_null( self::$_instance ) ) {
10 self::$_instance = new self();
11 }
12 return self::$_instance;
13
14 }
15
16 public function __construct() {
17
18 add_action( 'plugins_loaded', [ $this, 'init' ] );
19 add_action( "wp_ajax_nopriv_eshb_get_disabled_dates_by_accomodation_id", array ( $this, 'eshb_get_disabled_dates_by_accomodation_id' ) );
20 add_action( "wp_ajax_eshb_get_disabled_dates_by_accomodation_id", array ( $this, 'eshb_get_disabled_dates_by_accomodation_id' ) );
21
22 }
23
24 public function init() {
25 // Add Plugin actions
26 add_filter('theme_page_templates', [$this, 'eshb_register_page_template']);
27 add_filter('template_include', [$this, 'eshb_load_template']);
28 }
29
30 public function eshb_search_page_by_title( $page_title, $post_type = 'page' ) {
31 // Set up the arguments for WP_Query
32 $args = array(
33 'post_type' => $post_type,
34 'post_status' => 'publish', // Only fetch published pages
35 'title' => $page_title,
36 'posts_per_page' => 1, // Limit to one result
37 );
38
39 // Run the query
40 $query = new WP_Query( $args );
41
42 // Check if any post is found
43 if ( $query->have_posts() ) {
44 return $query->posts[0]; // Return the first found page
45 }
46
47 // Return false if no page is found
48 return false;
49 }
50
51 public function eshb_get_disabled_dates_by_accomodation_id($accomodation_id, $start_date = '', $end_date = '') {
52
53 // Verify nonce for security
54 if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), ESHB_Helper::generate_secure_nonce_action('eshb_global_nonce_action'))) {
55 wp_send_json_error(['message' => 'Invalid nonce']);
56 die();
57 }
58
59 if (isset($_POST['accomodation_id'])) {
60 $accomodation_id = sanitize_text_field(wp_unslash($_POST['accomodation_id']));
61 }
62
63 $eshb_settings = get_option('eshb_settings', []);
64 $booked_dates = [];
65 $total_room_bookings_per_date = []; // Track room bookings per date
66 $total_booked_slots_hours = 0;
67 $total_slots_hours = false;
68
69 // Get total rooms allowed for this accommodation
70 $accomodation_metas = get_post_meta($accomodation_id, 'eshb_accomodation_metaboxes', true);
71
72 $is_single_day_plugin_active = get_option('eshb_single_day_activated');
73 $pricing_periodicity = false;
74 if ($is_single_day_plugin_active) {
75 $pricing_periodicity = !empty($accomodation_metas['pricing_periodicity']) ? $accomodation_metas['pricing_periodicity'] : false;
76 $eshb_single_day_settings = get_option( 'eshb_single_day_settings', []);
77 $slots_start_time = $eshb_single_day_settings['start_time'];
78 $slots_end_time = $eshb_single_day_settings['end_time'];
79 $total_slots_hours = ESHB_Helper::eshb_calculate_time_diff('', '', $slots_start_time, $slots_end_time);
80 }
81
82 $holidays = isset($eshb_settings['holidays']) ? $eshb_settings['holidays'] : [];
83 $finally_holidays = [];
84
85 if ( ! empty( $holidays ) ) {
86 foreach ( $holidays as $holiday ) {
87 $accommodation_ids = $holiday['accomodation-ids'] ?? [];
88 $holiday_date = $holiday['holiday-date'] ?? null;
89
90 // Check if holiday is applicable for all or specific accommodation
91 $is_applicable = empty($accommodation_ids) || (is_array($accommodation_ids) && in_array($accomodation_id, $accommodation_ids));
92
93 if ( $is_applicable && $holiday_date ) {
94 if ( is_array($holiday_date) && isset($holiday_date['from'], $holiday_date['to']) ) {
95 $start = DateTime::createFromFormat('Y-m-d', $holiday_date['from']);
96 $end = DateTime::createFromFormat('Y-m-d', $holiday_date['to']);
97 if ( $start && $end ) {
98 $end->modify('+1 day'); // Include end date
99 $interval = new DateInterval('P1D');
100 $dateRange = new DatePeriod($start, $interval, $end);
101
102 foreach ( $dateRange as $date ) {
103 $finally_holidays[] = $date->format('Y-m-d');
104 }
105 }
106 } else {
107 $finally_holidays[] = $holiday_date;
108 }
109 }
110 }
111 }
112
113
114
115 $allowed_total_rooms = isset($accomodation_metas['total_rooms']) ? intval($accomodation_metas['total_rooms']) : 0;
116 $total_rooms = isset($accomodation_metas['total_rooms']) ? intval($accomodation_metas['total_rooms']) : 1;
117 $available_rooms = isset($accomodation_metas['available_rooms']) ? intval($accomodation_metas['available_rooms']) : $total_rooms;
118
119 $min_max_nights_settings = [
120 'required_min_nights' => 1,
121 'required_max_nights' => 999,
122 ];
123
124 $min_max_nights_settings = apply_filters('eshb_min_max_nights_settings_before_search', $min_max_nights_settings, $accomodation_id, $accomodation_metas);
125
126 // Get min stay night by session
127 $min_stay_night_by_session = ESHB_Helper::get_eshb_min_stay_night_by_session($accomodation_id, $start_date, $end_date);
128 if(class_exists('ESHB_ADVANCED_PRICING') && $min_stay_night_by_session > 0){
129 $min_max_nights_settings['required_min_nights'] = $min_stay_night_by_session;
130 }
131
132 // Find all bookings for this accommodation
133 $bookings_args = [
134 'post_type' => 'eshb_booking',
135 'posts_per_page' => -1,
136 'post_status' => ['publish', 'deposit-payment', 'pending', 'processing', 'on-hold', 'completed'],
137 'fields' => 'ids',
138 ];
139
140 $bookings = new WP_Query($bookings_args);
141 $checked_in_out_dates = [];
142
143 if ($bookings->have_posts()) {
144 while ($bookings->have_posts()) {
145 $bookings->the_post();
146 $meta_values = get_post_meta(get_the_ID(), 'eshb_booking_metaboxes', true);
147 $booking_status = isset($meta_values['booking_status']) ? $meta_values['booking_status'] : '';
148
149 $completed_booking_status_maps = array(
150 'pending',
151 'deposit-payment',
152 'processing',
153 'on-hold',
154 'completed'
155 );
156
157 // Ensure required keys exist
158 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'])) {
159
160 $booking_accomodation_id = intval($meta_values['booking_accomodation_id']);
161 $booking_start_date = $meta_values['booking_start_date'];
162 $booking_end_date = $meta_values['booking_end_date'];
163 $accommodation_metaboxes = get_post_meta($booking_accomodation_id, 'eshb_accomodation_metaboxes', true);
164 $total_rooms = $accommodation_metaboxes['total_rooms'] ?? 1;
165
166 $booked_accomodation_ids = [];
167 $accomodation_id = ESHB_Helper::get_main_post_id_for_translated($accomodation_id);
168
169
170 if ($accomodation_id == $booking_accomodation_id) {
171
172 // Convert dates to DateTime objects
173 $start_date = new DateTime($booking_start_date);
174 $end_date = new DateTime($booking_end_date);
175 $booked_id = get_the_ID();
176 $booking_metas = get_post_meta($booked_id, 'eshb_booking_metaboxes', true);
177 $booked_room_quantity = isset($booking_metas['room_quantity']) ? intval($booking_metas['room_quantity']) : 1;
178 $booking_start_time = isset($booking_metas['booking_start_time']) ? intval($booking_metas['booking_start_time']) : '';
179 $booking_end_time = isset($booking_metas['booking_end_time']) ? intval($booking_metas['booking_end_time']) : '';
180
181 $checked_in_out_dates['checked_in'][] = $booking_start_date;
182 $checked_in_out_dates['checked_out'][] = $booking_end_date;
183
184 // NEW: Clone end date and subtract 1 day to exclude checkout day
185 if($booking_start_date !== $booking_end_date) {
186 $actual_end_date = (clone $end_date)->modify('-1 day');
187 }else{
188 $actual_end_date = (clone $end_date)->modify('+1 day');
189 }
190
191
192 $period = new DatePeriod($start_date, new DateInterval('P1D'), $actual_end_date->modify('+1 day'));
193
194 foreach ($period as $date) {
195 $formatted_date = $date->format('Y-m-d');
196
197 if (!isset($total_room_bookings_per_date[$formatted_date])) {
198 $total_room_bookings_per_date[$formatted_date] = 0;
199 }
200
201 $total_room_bookings_per_date[$formatted_date] += $booked_room_quantity;
202 }
203
204 if($booking_start_date === $booking_end_date) {
205 array_pop($total_room_bookings_per_date);
206 }
207
208 }
209 }
210 }
211 }
212
213
214 $total_booked_rooms_in_date_ranges = 0;
215 $dates = [];
216
217 // Determine which dates should be disabled (fully booked)
218 foreach ($total_room_bookings_per_date as $date => $total_booked_rooms) {
219
220 // allow external plugins to modify available slots
221 $available_slots = apply_filters(
222 'eshb_available_slots_in_booked_dates_loop',
223 false,
224 $date,
225 $total_booked_rooms,
226 $accomodation_id
227 );
228
229
230 if($available_slots) {
231 $total_booked_rooms = 0;
232 }
233
234 if ($allowed_total_rooms <= $total_booked_rooms) {
235 $date = new DateTime($date);
236 $booked_dates[] = $date->format('Y, m, d');
237 array_push($dates, array('dates' => $date, 'total_booked_rooms_in_date_ranges' => $total_booked_rooms));
238 }
239
240 }
241
242
243 // Apply filter hook to allow external modifications
244 $booked_dates = apply_filters('eshb_modify_booked_dates', $booked_dates, $accomodation_id);
245
246 $checked_in_out_dates = apply_filters('eshb_modify_checked_in_out_dates', $checked_in_out_dates, $accomodation_id);
247
248 $all_dates = [
249 'checked_in_out_dates' => $checked_in_out_dates,
250 'booked_dates' => $booked_dates,
251 'holiday_dates' => $finally_holidays,
252 'allowed_check_in_day' => '',
253 'single_day' => false,
254 'min_nights' => $min_max_nights_settings['required_min_nights'],
255 'max_nights' => $min_max_nights_settings['required_max_nights'],
256 'total_room_bookings_per_date' => $total_room_bookings_per_date,
257 ];
258
259 $all_dates = apply_filters('eshb_get_disabled_dates_in_search', $all_dates, $accomodation_id, $accomodation_metas);
260
261
262 if(isset($_POST['action']) && $_POST['action'] == 'eshb_get_disabled_dates_by_accomodation_id'){
263 wp_send_json_success($all_dates);
264 wp_die();
265 }else{
266 return $all_dates;
267 }
268
269 }
270
271 public function eshb_generate_dates_from_date_ranges($start_date, $end_date){
272 // $start_date = '2025, 05, 16'; // Format: YYYY, MM, DD
273 // $end_date = '2025, 05, 26';
274
275 $start = DateTime::createFromFormat('Y, m, d', $start_date);
276 $end = DateTime::createFromFormat('Y, m, d', $end_date);
277 $end->modify('+1 day'); // Include the end date in the range
278
279 $interval = new DateInterval('P1D'); // 1-day interval
280 $daterange = new DatePeriod($start, $interval, $end);
281
282 $dates_array = [];
283
284 foreach ($daterange as $date) {
285 $dates_array[] = $date->format('Y, m, d');
286 }
287 return $dates_array;
288 }
289
290 public function eshb_get_available_accomodation_ids($start_date, $end_date, $adult_quantity = 0, $children_quantity = 0, $rooms_quantity = 0) {
291 $available_accomodation_ids = [];
292
293 if ($start_date && $end_date) {
294
295 // Step 1: Get all accommodation IDs
296 $accomodations_args = array(
297 'post_type' => 'eshb_accomodation',
298 'posts_per_page' => -1,
299 'fields' => 'ids',
300 );
301
302 $accomodations = new WP_Query($accomodations_args);
303
304 if ($accomodations->have_posts()) {
305 $accomodation_ids = $accomodations->posts;
306
307 // Step 2: Get all bookings with overlapping dates
308 $bookings_args = array(
309 'post_type' => 'eshb_booking',
310 'posts_per_page' => -1,
311 'post_status' => ['publish', 'deposit-payment', 'pending', 'processing', 'on-hold', 'completed'],
312 'fields' => 'ids',
313 );
314
315 $bookings = new WP_Query($bookings_args);
316 $accommodation_bookings = array(); // [accommodation_id => total_booked_rooms]
317 $booked_accomodation_ids = array();
318
319 if ($bookings->have_posts()) {
320 while ($bookings->have_posts()) {
321 $bookings->the_post();
322
323 $meta_values = get_post_meta(get_the_ID(), 'eshb_booking_metaboxes', true);
324 if (!is_array($meta_values)) continue;
325
326 $booking_accomodation_id = intval($meta_values['booking_accomodation_id']);
327 $booking_start_date = $meta_values['booking_start_date'];
328 $booking_end_date = $meta_values['booking_end_date'];
329 $booking_room_quantity = isset($meta_values['room_quantity']) ? intval($meta_values['room_quantity']) : 1;
330 $booking_status = isset($meta_values['booking_status']) ? $meta_values['booking_status'] : '';
331 $valid_statuses = array('deposit-payment', 'pending', 'processing', 'on-hold', 'completed');
332
333 // Only count if booking status is valid and dates overlap
334 if (
335 in_array($booking_status, $valid_statuses) &&
336 $start_date <= $booking_end_date &&
337 $end_date >= $booking_start_date
338 ) {
339 if (!isset($accommodation_bookings[$booking_accomodation_id])) {
340 $accommodation_bookings[$booking_accomodation_id] = 0;
341 }
342
343 $accommodation_bookings[$booking_accomodation_id] += $booking_room_quantity;
344 }
345 }
346 wp_reset_postdata();
347
348 // Step 3: Mark accommodations as fully booked
349 foreach ($accommodation_bookings as $accommodation_id => $booked_rooms) {
350 $accomodation_metaboxes = get_post_meta($accommodation_id, 'eshb_accomodation_metaboxes', true);
351 $total_rooms = !empty($accomodation_metaboxes['total_rooms']) ? intval($accomodation_metaboxes['total_rooms']) : 1;
352
353 if ($booked_rooms >= $total_rooms) {
354 $booked_accomodation_ids[] = $accommodation_id;
355 }
356 }
357
358 // Step 4: Exclude fully booked accommodations
359 $available_accomodation_ids = array_diff($accomodation_ids, $booked_accomodation_ids);
360 } else {
361 // No bookings, all accommodations are available
362 $available_accomodation_ids = $accomodation_ids;
363 }
364
365 // Step 5: Filter by requested capacity
366 if (!empty($available_accomodation_ids)) {
367 foreach ($available_accomodation_ids as $key => $available_accomodation_id) {
368 $accomodation_metaboxes = get_post_meta($available_accomodation_id, 'eshb_accomodation_metaboxes', true);
369
370 $total_capacity = !empty($accomodation_metaboxes['total_capacity']) ? intval($accomodation_metaboxes['total_capacity']) : 1;
371 $adult_capacity = !empty($accomodation_metaboxes['adult_capacity']) ? intval($accomodation_metaboxes['adult_capacity']) : 0;
372 $children_capacity = !empty($accomodation_metaboxes['children_capacity']) ? intval($accomodation_metaboxes['children_capacity']) : 0;
373 $total_rooms = !empty($accomodation_metaboxes['total_rooms']) ? intval($accomodation_metaboxes['total_rooms']) : 1;
374 if(empty($adult_capacity)) {
375 $adult_capacity = $total_capacity;
376 }
377 if(empty($children_capacity)) {
378 $children_capacity = $total_capacity;
379 }
380
381 if (
382 $adult_quantity > $adult_capacity ||
383 $children_quantity > $children_capacity ||
384 $rooms_quantity > $total_rooms
385 ) {
386 unset($available_accomodation_ids[$key]);
387 }
388 }
389 }
390 }
391 }
392
393 return $available_accomodation_ids;
394 }
395
396 public function eshb_register_page_template($templates) {
397 $templates['easy-hotel-search.php'] = 'Easy Hotel Search';
398 $templates['easy-hotel-search-result.php'] = 'Easy Hotel Search Result';
399 return $templates;
400 }
401
402 public function eshb_load_template($template) {
403
404 global $post;
405
406 if (is_page() && $post->post_type == 'page') {
407 $template_meta = get_post_meta($post->ID, '_wp_page_template', true);
408
409
410 if ($template_meta == 'easy-hotel-search.php') {
411
412 $plugin_template = ESHB_PL_PATH . '/public/templates/easy-hotel-search.php';
413 $theme_template = get_stylesheet_directory() . '/easy-hotel-booking/easy-hotel-search.php';
414 $child_theme_template = get_template_directory() . '/easy-hotel-booking/easy-hotel-search.php';
415
416 if (file_exists($theme_template)) {
417 $template = $theme_template;
418 } elseif (file_exists($child_theme_template)) {
419 $template = $child_theme_template;
420 } else {
421 $template = $plugin_template;
422 }
423
424 }
425
426 if ($template_meta == 'easy-hotel-search-result.php') {
427
428 $plugin_template = ESHB_PL_PATH . '/public/templates/easy-hotel-search-result.php';
429 $theme_template = get_stylesheet_directory() . '/easy-hotel-booking/easy-hotel-search-result.php';
430 $child_theme_template = get_template_directory() . '/easy-hotel-booking/easy-hotel-search-result.php';
431
432 if (file_exists($theme_template)) {
433 $template = $theme_template;
434 } elseif (file_exists($child_theme_template)) {
435 $template = $child_theme_template;
436 } else {
437 $template = $plugin_template;
438 }
439
440 }
441
442
443 }
444 return $template;
445 }
446
447 }
448
449
450 ESHB_Search::instance();