PluginProbe
Easy Hotel – Powerful Hotel Booking / 2.0.4
Easy Hotel – Powerful Hotel Booking v2.0.4
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.4, at admin/includes/classes/class.search.php

451 lines 20.1 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 $booking_accomodation_id = ESHB_Helper::get_main_post_id_for_translated($booking_accomodation_id);
170
171 if ($accomodation_id == $booking_accomodation_id) {
172
173 // Convert dates to DateTime objects
174 $start_date = new DateTime($booking_start_date);
175 $end_date = new DateTime($booking_end_date);
176 $booked_id = get_the_ID();
177 $booking_metas = get_post_meta($booked_id, 'eshb_booking_metaboxes', true);
178 $booked_room_quantity = isset($booking_metas['room_quantity']) ? intval($booking_metas['room_quantity']) : 1;
179 $booking_start_time = isset($booking_metas['booking_start_time']) ? intval($booking_metas['booking_start_time']) : '';
180 $booking_end_time = isset($booking_metas['booking_end_time']) ? intval($booking_metas['booking_end_time']) : '';
181
182 $checked_in_out_dates['checked_in'][] = $booking_start_date;
183 $checked_in_out_dates['checked_out'][] = $booking_end_date;
184
185 // NEW: Clone end date and subtract 1 day to exclude checkout day
186 if($booking_start_date !== $booking_end_date) {
187 $actual_end_date = (clone $end_date)->modify('-1 day');
188 }else{
189 $actual_end_date = (clone $end_date)->modify('+1 day');
190 }
191
192
193 $period = new DatePeriod($start_date, new DateInterval('P1D'), $actual_end_date->modify('+1 day'));
194
195 foreach ($period as $date) {
196 $formatted_date = $date->format('Y-m-d');
197
198 if (!isset($total_room_bookings_per_date[$formatted_date])) {
199 $total_room_bookings_per_date[$formatted_date] = 0;
200 }
201
202 $total_room_bookings_per_date[$formatted_date] += $booked_room_quantity;
203 }
204
205 if($booking_start_date === $booking_end_date) {
206 array_pop($total_room_bookings_per_date);
207 }
208
209 }
210 }
211 }
212 }
213
214
215 $total_booked_rooms_in_date_ranges = 0;
216 $dates = [];
217
218 // Determine which dates should be disabled (fully booked)
219 foreach ($total_room_bookings_per_date as $date => $total_booked_rooms) {
220
221 // allow external plugins to modify available slots
222 $available_slots = apply_filters(
223 'eshb_available_slots_in_booked_dates_loop',
224 false,
225 $date,
226 $total_booked_rooms,
227 $accomodation_id
228 );
229
230
231 if($available_slots) {
232 $total_booked_rooms = 0;
233 }
234
235 if ($allowed_total_rooms <= $total_booked_rooms) {
236 $date = new DateTime($date);
237 $booked_dates[] = $date->format('Y, m, d');
238 array_push($dates, array('dates' => $date, 'total_booked_rooms_in_date_ranges' => $total_booked_rooms));
239 }
240
241 }
242
243
244 // Apply filter hook to allow external modifications
245 $booked_dates = apply_filters('eshb_modify_booked_dates', $booked_dates, $accomodation_id);
246
247 $checked_in_out_dates = apply_filters('eshb_modify_checked_in_out_dates', $checked_in_out_dates, $accomodation_id);
248
249 $all_dates = [
250 'checked_in_out_dates' => $checked_in_out_dates,
251 'booked_dates' => $booked_dates,
252 'holiday_dates' => $finally_holidays,
253 'allowed_check_in_day' => '',
254 'single_day' => false,
255 'min_nights' => $min_max_nights_settings['required_min_nights'],
256 'max_nights' => $min_max_nights_settings['required_max_nights'],
257 'total_room_bookings_per_date' => $total_room_bookings_per_date,
258 ];
259
260 $all_dates = apply_filters('eshb_get_disabled_dates_in_search', $all_dates, $accomodation_id, $accomodation_metas);
261
262
263 if(isset($_POST['action']) && $_POST['action'] == 'eshb_get_disabled_dates_by_accomodation_id'){
264 wp_send_json_success($all_dates);
265 wp_die();
266 }else{
267 return $all_dates;
268 }
269
270 }
271
272 public function eshb_generate_dates_from_date_ranges($start_date, $end_date){
273 // $start_date = '2025, 05, 16'; // Format: YYYY, MM, DD
274 // $end_date = '2025, 05, 26';
275
276 $start = DateTime::createFromFormat('Y, m, d', $start_date);
277 $end = DateTime::createFromFormat('Y, m, d', $end_date);
278 $end->modify('+1 day'); // Include the end date in the range
279
280 $interval = new DateInterval('P1D'); // 1-day interval
281 $daterange = new DatePeriod($start, $interval, $end);
282
283 $dates_array = [];
284
285 foreach ($daterange as $date) {
286 $dates_array[] = $date->format('Y, m, d');
287 }
288 return $dates_array;
289 }
290
291 public function eshb_get_available_accomodation_ids($start_date, $end_date, $adult_quantity = 0, $children_quantity = 0, $rooms_quantity = 0) {
292 $available_accomodation_ids = [];
293
294 if ($start_date && $end_date) {
295
296 // Step 1: Get all accommodation IDs
297 $accomodations_args = array(
298 'post_type' => 'eshb_accomodation',
299 'posts_per_page' => -1,
300 'fields' => 'ids',
301 );
302
303 $accomodations = new WP_Query($accomodations_args);
304
305 if ($accomodations->have_posts()) {
306 $accomodation_ids = $accomodations->posts;
307
308 // Step 2: Get all bookings with overlapping dates
309 $bookings_args = array(
310 'post_type' => 'eshb_booking',
311 'posts_per_page' => -1,
312 'post_status' => ['publish', 'deposit-payment', 'pending', 'processing', 'on-hold', 'completed'],
313 'fields' => 'ids',
314 );
315
316 $bookings = new WP_Query($bookings_args);
317 $accommodation_bookings = array(); // [accommodation_id => total_booked_rooms]
318 $booked_accomodation_ids = array();
319
320 if ($bookings->have_posts()) {
321 while ($bookings->have_posts()) {
322 $bookings->the_post();
323
324 $meta_values = get_post_meta(get_the_ID(), 'eshb_booking_metaboxes', true);
325 if (!is_array($meta_values)) continue;
326
327 $booking_accomodation_id = intval($meta_values['booking_accomodation_id']);
328 $booking_start_date = $meta_values['booking_start_date'];
329 $booking_end_date = $meta_values['booking_end_date'];
330 $booking_room_quantity = isset($meta_values['room_quantity']) ? intval($meta_values['room_quantity']) : 1;
331 $booking_status = isset($meta_values['booking_status']) ? $meta_values['booking_status'] : '';
332 $valid_statuses = array('deposit-payment', 'pending', 'processing', 'on-hold', 'completed');
333
334 // Only count if booking status is valid and dates overlap
335 if (
336 in_array($booking_status, $valid_statuses) &&
337 $start_date <= $booking_end_date &&
338 $end_date >= $booking_start_date
339 ) {
340 if (!isset($accommodation_bookings[$booking_accomodation_id])) {
341 $accommodation_bookings[$booking_accomodation_id] = 0;
342 }
343
344 $accommodation_bookings[$booking_accomodation_id] += $booking_room_quantity;
345 }
346 }
347 wp_reset_postdata();
348
349 // Step 3: Mark accommodations as fully booked
350 foreach ($accommodation_bookings as $accommodation_id => $booked_rooms) {
351 $accomodation_metaboxes = get_post_meta($accommodation_id, 'eshb_accomodation_metaboxes', true);
352 $total_rooms = !empty($accomodation_metaboxes['total_rooms']) ? intval($accomodation_metaboxes['total_rooms']) : 1;
353
354 if ($booked_rooms >= $total_rooms) {
355 $booked_accomodation_ids[] = $accommodation_id;
356 }
357 }
358
359 // Step 4: Exclude fully booked accommodations
360 $available_accomodation_ids = array_diff($accomodation_ids, $booked_accomodation_ids);
361 } else {
362 // No bookings, all accommodations are available
363 $available_accomodation_ids = $accomodation_ids;
364 }
365
366 // Step 5: Filter by requested capacity
367 if (!empty($available_accomodation_ids)) {
368 foreach ($available_accomodation_ids as $key => $available_accomodation_id) {
369 $accomodation_metaboxes = get_post_meta($available_accomodation_id, 'eshb_accomodation_metaboxes', true);
370
371 $total_capacity = !empty($accomodation_metaboxes['total_capacity']) ? intval($accomodation_metaboxes['total_capacity']) : 1;
372 $adult_capacity = !empty($accomodation_metaboxes['adult_capacity']) ? intval($accomodation_metaboxes['adult_capacity']) : 0;
373 $children_capacity = !empty($accomodation_metaboxes['children_capacity']) ? intval($accomodation_metaboxes['children_capacity']) : 0;
374 $total_rooms = !empty($accomodation_metaboxes['total_rooms']) ? intval($accomodation_metaboxes['total_rooms']) : 1;
375 if(empty($adult_capacity)) {
376 $adult_capacity = $total_capacity;
377 }
378 if(empty($children_capacity)) {
379 $children_capacity = $total_capacity;
380 }
381
382 if (
383 $adult_quantity > $adult_capacity ||
384 $children_quantity > $children_capacity ||
385 $rooms_quantity > $total_rooms
386 ) {
387 unset($available_accomodation_ids[$key]);
388 }
389 }
390 }
391 }
392 }
393
394 return $available_accomodation_ids;
395 }
396
397 public function eshb_register_page_template($templates) {
398 $templates['easy-hotel-search.php'] = 'Easy Hotel Search';
399 $templates['easy-hotel-search-result.php'] = 'Easy Hotel Search Result';
400 return $templates;
401 }
402
403 public function eshb_load_template($template) {
404
405 global $post;
406
407 if (is_page() && $post->post_type == 'page') {
408 $template_meta = get_post_meta($post->ID, '_wp_page_template', true);
409
410
411 if ($template_meta == 'easy-hotel-search.php') {
412
413 $plugin_template = ESHB_PL_PATH . '/public/templates/easy-hotel-search.php';
414 $theme_template = get_stylesheet_directory() . '/easy-hotel-booking/easy-hotel-search.php';
415 $child_theme_template = get_template_directory() . '/easy-hotel-booking/easy-hotel-search.php';
416
417 if (file_exists($theme_template)) {
418 $template = $theme_template;
419 } elseif (file_exists($child_theme_template)) {
420 $template = $child_theme_template;
421 } else {
422 $template = $plugin_template;
423 }
424
425 }
426
427 if ($template_meta == 'easy-hotel-search-result.php') {
428
429 $plugin_template = ESHB_PL_PATH . '/public/templates/easy-hotel-search-result.php';
430 $theme_template = get_stylesheet_directory() . '/easy-hotel-booking/easy-hotel-search-result.php';
431 $child_theme_template = get_template_directory() . '/easy-hotel-booking/easy-hotel-search-result.php';
432
433 if (file_exists($theme_template)) {
434 $template = $theme_template;
435 } elseif (file_exists($child_theme_template)) {
436 $template = $child_theme_template;
437 } else {
438 $template = $plugin_template;
439 }
440
441 }
442
443
444 }
445 return $template;
446 }
447
448 }
449
450
451 ESHB_Search::instance();