PluginProbe
Booking Calendar / 11.8
Booking Calendar v11.8
11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 10.11 10.11.2 10.11.3 10.11.4 All 201 releases
booking / includes / _capacity / where_to_save.php

where_to_save.php in Booking Calendar 11.8, at includes/_capacity/where_to_save.php

519 lines 26.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly // FixIn: 9.8.0.4.
4
5 // ---------------------------------------------------------------------------------------------------------------------
6 // Check where to save the booking
7 // ---------------------------------------------------------------------------------------------------------------------
8
9 /**
10 * Check if these dates contain marker '2981-01-13', which is means that this booking was submited without dates - as Contact Form.
11 *
12 * @param array|string $dates_sql_arr - array of SQL dates.
13 *
14 * @return bool
15 */
16 function wpbc_is_these_dates__for__no_dates( $dates_sql_arr ){
17
18 // FixIn: 2981-01-13 13 Jan 2981.
19
20 if ( is_array( $dates_sql_arr ) ) {
21 foreach ( $dates_sql_arr as $date_ymd ) {
22 if ( '2981-01-13' === gmdate( 'Y-m-d', mysql2date( 'U', $date_ymd ) ) ) {
23 return true;
24 }
25 }
26 } elseif ( '2981-01-13' === gmdate( 'Y-m-d', mysql2date( 'U', $dates_sql_arr ) ) ) {
27 return true;
28 }
29
30 return false;
31 }
32
33
34 /**
35 * Get booking resources for each selected date, where we can save the booking, or false if we can not save it
36 *
37 * @param array $params = [
38 * 'resource_id' => 2
39 * 'skip_booking_id' => '', | 125 if edit booking
40 * 'dates_only_sql_arr' => [ "2023-10-18", "2023-10-25", "2023-11-25" ]
41 * 'time_as_seconds_arr' => [ 36000, 39600 ]
42 * 'how_many_items_to_book' => 1
43 * 'request_uri' => 'http://beta/resource-id2/' // Optional default -> DOING_AJAX ? $_SERVER['HTTP_REFERER'] : $_SERVER['REQUEST_URI']
44 * 'as_single_resource' => false, // Optional default false
45 * 'is_use_booking_recurrent_time' => false // Optional default ( 'On' === get_bk_option( 'booking_recurrent_time' ) )
46 * ]
47 * @return array = [ 'result' => 'ok', 'main__resource_id' => 2, 'resources_in_dates' => [ '2023-09-23':[2,10,11], '2023-09-24':[2,10,11] ], 'time_to_book' => [ "00:00:00", "24:00:00" ] ]
48 * Note. 'main__resource_id' - it's first booking resource in the list, basically needed for saving in wp_booking DB table.
49 * OR
50 * = [ 'result' => 'error', 'message' => 'Booking can not be saved ...' ]
51 */
52 function wpbc__where_to_save_booking( $local_params ){
53
54 $server_request_uri = ( ( isset( $_SERVER['REQUEST_URI'] ) ) ? sanitize_text_field( $_SERVER['REQUEST_URI'] ) : '' ); /* phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.MissingUnslash */ /* FixIn: sanitize_unslash */
55 $server_http_referer_uri = ( ( isset( $_SERVER['HTTP_REFERER'] ) ) ? sanitize_text_field( $_SERVER['HTTP_REFERER'] ) : '' ); /* phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.MissingUnslash */ /* FixIn: sanitize_unslash */
56 $defaults = array(
57 'request_uri' => ( ( ( defined( 'DOING_AJAX' ) ) && ( DOING_AJAX ) ) ? $server_http_referer_uri : $server_request_uri ), // front-end: $server_request_uri | ajax: $server_http_referer_uri // It different in Ajax requests. It's used for change-over days to detect for exception at specific pages
58 'allow_past' => false,
59 'as_single_resource' => false,
60 'is_use_booking_recurrent_time' => ( 'On' === get_bk_option( 'booking_recurrent_time' ) ),
61 'time_override_source' => '',
62 'aggregate_resource_id_arr' => array(),
63 'custom_form' => '' //FixIn: 10.0.0.10 // Required for checking all available time-slots and compare with booked time slots
64 );
65 $local_params = wp_parse_args( $local_params, $defaults );
66
67 $time_as_seconds_arr = $local_params['time_as_seconds_arr'];
68 $time_as_seconds_arr[0] = ( 0 != $time_as_seconds_arr[0] ) ? $time_as_seconds_arr[0] + 1 : $time_as_seconds_arr[0]; // +1 s. -- set check in time with ended 1 second
69 $time_as_seconds_arr[1] = ( ( 24 * 60 * 60 ) != $time_as_seconds_arr[1] ) ? $time_as_seconds_arr[1] + 2 : $time_as_seconds_arr[1]; // +2 s. -- set check out time with ended 2 seconds
70 if ( ( 0 != $time_as_seconds_arr[0] ) && ( ( 24 * 60 * 60 ) == $time_as_seconds_arr[1] ) ) {
71 //FixIn: 10.0.0.49 - in case if we have start time != 00:00 and end time as 24:00 then set end time as 23:59:52
72 $time_as_seconds_arr[1] += - 8;
73 }
74 $local_params['time_as_his_arr'] = array(
75 wpbc_transform__seconds__in__24_hours_his( $time_as_seconds_arr[0] ),
76 wpbc_transform__seconds__in__24_hours_his( $time_as_seconds_arr[1] )
77 );
78 // FixIn: 2981-01-13 13 Jan 2981
79 $availability_per_days_arr__params = array();
80 if ( ( ! empty( $local_params['dates_only_sql_arr'] ) ) && ( is_array( $local_params['dates_only_sql_arr'] ) ) && ( '2981-01-13' === $local_params['dates_only_sql_arr'][0] ) ) {
81 $availability_per_days_arr__params['is_days_always_available'] = true;
82 }
83 // If we are using the unavailable before/after booking dates, then we need to extend "$local_params['dates_only_sql_arr']" to such dates.
84 if ( function_exists( 'wpbc__extend_checking_dates_range__if_used__extra_seconds__before_after' ) ) {
85 $maybe_extended__dates_to_check_arr = wpbc__extend_checking_dates_range__if_used__extra_seconds__before_after( $local_params['dates_only_sql_arr'] );
86 } else {
87 $maybe_extended__dates_to_check_arr = $local_params['dates_only_sql_arr'];
88 }
89 // [ "dates": [ "2023-11-05": [ "day_availability":4, ... "2": [ "is_day_unavailable":false, ...]], '2023-11-06':[...] ] ,"resources_id_arr__in_dates":[2,12,10,11]}
90
91 $availability_per_days = wpbc_get_availability_per_days_arr( wp_parse_args( array(
92 'resource_id' => $local_params['resource_id'],
93 'skip_booking_id' => $local_params['skip_booking_id'],
94 'dates_to_check' => $maybe_extended__dates_to_check_arr,
95 'request_uri' => $local_params['request_uri'],
96 'allow_past' => ! empty( $local_params['allow_past'] ),
97 'as_single_resource' => $local_params['as_single_resource'], // default FALSE :: get dates as for 'single resource' or 'parent' resource including bookings in all 'child booking resources' .
98 'additional_bk_types' => $local_params['aggregate_resource_id_arr'],
99 'aggregate_type' => empty( $local_params['aggregate_type'] ) ? 'bookings_only' : $local_params['aggregate_type'], //TODO: this parameter does not transfer during saving, so here will be always default value 'bookings_only' // FixIn: 10.0.0.7.
100 'custom_form' => $local_params['custom_form'], // FixIn: 10.0.0.10.
101 ) , $availability_per_days_arr__params ) );
102
103 // A contact form has no calendar and uses one synthetic date only to satisfy the booking storage schema.
104 // Keep its requested resource, because calendar availability rules do not apply to a no-date submission.
105 $is_no_dates_booking = ( is_array( $local_params['dates_only_sql_arr'] ) && ( 1 === count( $local_params['dates_only_sql_arr'] ) ) &&
106 wpbc_is_these_dates__for__no_dates( $local_params['dates_only_sql_arr'] ) );
107 if ( $is_no_dates_booking ) {
108 $requested_resource_id = absint( $local_params['resource_id'] );
109 $loaded_resource_ids = isset( $availability_per_days['resources_id_arr__in_dates'] ) ? array_map( 'absint', (array) $availability_per_days['resources_id_arr__in_dates'] ) : array();
110
111 if ( ( 0 === $requested_resource_id ) || ! in_array( $requested_resource_id, $loaded_resource_ids, true ) ) {
112 return array(
113 'result' => 'error',
114 'message' => 'Wrong ID of booking resource: ' . $requested_resource_id,
115 );
116 }
117
118 $storage_resource_ids = array_values(
119 array_unique( array_merge( array( $requested_resource_id ), $loaded_resource_ids ) )
120 );
121 $resources_in_dates = array_fill_keys(
122 array_values( $local_params['dates_only_sql_arr'] ),
123 $storage_resource_ids
124 );
125
126 return array(
127 'result' => 'ok',
128 'resources_in_dates' => $resources_in_dates,
129 'time_to_book' => $local_params['time_as_his_arr'],
130 'main__resource_id' => $requested_resource_id,
131 );
132 }
133
134 // Get value of how many booking resources to book
135 $how_many_items_to_book = $local_params['how_many_items_to_book'];
136
137 // -------------------------------------------------------------------------------------------------------------
138 // [ 2023-10-18: [ 0:[ resource_id: 2, is_available: true, booked__seconds: [], booked__readable: [], time_to_book__seconds: [ 36030, 39570 ], time_to_book__readable: "10:00:00", "11:00:00" ] ], 1: [...], 2: [...], 3: [...] ], 2023-10-25: [...], 2023-11-25: [...] ]
139 $available_slots = wpbc__get_available_slots__for_selected_dates_times__bl( array(
140 'dates_sql__arr' => $local_params['dates_only_sql_arr'],
141 'time_as_seconds_arr' => $local_params['time_as_seconds_arr'],
142 'is_use_booking_recurrent_time' => $local_params['is_use_booking_recurrent_time'],
143 'time_override_source' => $local_params['time_override_source'],
144 'availability_per_days' => $availability_per_days
145 ) );
146
147 $main__resource_id = 0;
148 // == In SAME 'child' booking resources ============================================================
149 if ( class_exists( 'wpdev_bk_biz_l' ) && ( 'On' === get_bk_option( 'booking_is_dissbale_booking_for_different_sub_resources' ) ) ) {
150
151 $availability_in_same_child_resources = $availability_per_days['resources_id_arr__in_dates'];
152
153 foreach ( $availability_per_days['resources_id_arr__in_dates'] as $child_resource_id ) {
154 foreach ( $local_params['dates_only_sql_arr'] as $day_sql_key ) {
155 foreach ( $available_slots[ $day_sql_key ] as $available_slot ) {
156 if (
157 ( $child_resource_id == $available_slot['resource_id'] )
158 && ( ! $available_slot['is_available'] )
159 ){
160 $availability_in_same_child_resources = array_diff( $availability_in_same_child_resources, array( $child_resource_id ) ); // Remove $child_resource_id from array
161 break;
162 }
163 }
164 }
165 }
166
167 // Reset indexes in this array for ability to get first [0] element in this arr.
168 $availability_in_same_child_resources = array_values( $availability_in_same_child_resources );
169 $main__resource_id = ( ! empty( $availability_in_same_child_resources ) ) ? $availability_in_same_child_resources[0] : 0;
170
171 // [ 2, 12, 11 ] <- ID of child booking resources, where we can save our booking in the same child booking resource!
172 if ( count( $availability_in_same_child_resources ) >= $how_many_items_to_book ) {
173
174 $availability_in_same_child_resources_by_dates = array();
175 foreach ( $local_params['dates_only_sql_arr'] as $day_sql_key ) {
176 $availability_in_same_child_resources_by_dates[ $day_sql_key ] = $availability_in_same_child_resources;
177 }
178 // Good Save it
179 return array(
180 'result' => 'ok',
181 'resources_in_dates' => $availability_in_same_child_resources_by_dates, // [ 2023-09-23 = [ 2, 10, 11 ], 2023-09-24 = [ 2, 10, 11 ]
182 'time_to_book' => $local_params['time_as_his_arr'], // [ "00:00:00", "24:00:00" ]
183 'main__resource_id' => $main__resource_id
184 );
185 } else {
186 // Bad not save
187 return array(
188 'result' => 'error',
189 'message' => wpbc_frontend_messages__get( 'message_dates_times_unavailable', array(), $local_params['resource_id'] )
190 . ' <br> '
191 . wpbc_frontend_messages__get( 'message_cannot_save_in_one_resource', array(), $local_params['resource_id'] )
192 . ' <br> '
193 . wpbc_frontend_messages__get( 'message_choose_alternative_dates', array(), $local_params['resource_id'] )
194 . ' <a href="javascript:void(0)" onclick="'
195 .'jQuery( this ).next().toggle();'
196 .'jQuery( this).hide();'
197 .'jQuery( this ).parents(\'.wpbc_alert_message\').parent().on(\'hide\',function(even){jQuery(this).show();});'
198 .'">'
199 . __( 'Show more details', 'booking' )
200 . '</a>'
201 . ' <div style="display:none;">'
202 . '<p><hr><code>'
203 . wp_json_encode( $available_slots )
204 . '</code></p>'
205 . '</div>'
206 . ' <div style="display:none;">' . wp_json_encode( $available_slots ) . '</div>'
207 );
208 }
209
210 } else {
211
212 // == In ANY 'child' booking resources =========================================================
213
214 $availability_in_any_child_resources = array();
215 foreach ( $available_slots as $day_sql_key => $available_slot ) { // '2023-09-10': [], '2023-09-14': [],
216 $availability_in_any_child_resources[ $day_sql_key ] = array();
217 foreach ( $available_slot as $ind => $slot_value ) { // [ 0:{ resource_id: 2, is_available: false,...} , .... ]
218 if ( $slot_value['is_available'] ) {
219 if ( empty( $main__resource_id ) ) {
220 $main__resource_id = $slot_value['resource_id'];
221 }
222 $availability_in_any_child_resources[ $day_sql_key ][] = $slot_value['resource_id'];
223 }
224 }
225 }
226 /**
227 * { "2023-09-10": [ 2, 10, 11 ] <- available ID of child resources in this date
228 "2023-09-14": [ 4 ] <- available ID of child resources in this date
229 }
230 */
231
232 foreach ( $availability_in_any_child_resources as $day_sql_key2 => $available_res_in_day_arr ) {
233 if ( count( $available_res_in_day_arr ) < $how_many_items_to_book ) {
234 // Bad not save
235 // We can not store booking in this date day_sql_key2, number of available child booking resources less than required
236 return array(
237 'result' => 'error',
238 'message' => wpbc_frontend_messages__get( 'message_dates_times_unavailable', array(), $local_params['resource_id'] )
239 . ' <br> '
240 . wpbc_frontend_messages__get( 'message_choose_alternative_dates', array(), $local_params['resource_id'] )
241 . ' <a href="javascript:void(0)" onclick="'
242 .'jQuery( this ).next().toggle();'
243 .'jQuery( this).hide();'
244 .'jQuery( this ).parents(\'.wpbc_alert_message\').parent().on(\'hide\',function(even){jQuery(this).show();});'
245 .'">'
246 . __( 'Show more details', 'booking' )
247 . '</a>'
248 . ' <div style="display:none;">'
249 . '<p><strong>'
250 /* translators: 1: ... */
251 . sprintf( __( 'Booking can not be saved in this date %1$s, number of available (single or child) booking resource(s) (%2$d) less than required (%3$d).', 'booking' )
252 , $day_sql_key2, count( $available_res_in_day_arr ), $how_many_items_to_book )
253 . '</strong><hr><code>'
254 . wp_json_encode( $available_slots )
255 // . wp_json_encode( $local_params, $availability_per_days )
256 . '</code></p>'
257 . '</div>'
258
259 );
260 }
261 }
262
263 // Good Save it
264 return array(
265 'result' => 'ok',
266 'resources_in_dates' => $availability_in_any_child_resources, // [ 2023-09-23 = [ 2, 10, 11 ], 2023-09-24 = [ 2, 10, 11 ]
267 'time_to_book' => $local_params['time_as_his_arr'], // [ "00:00:00", "24:00:00" ]
268 'main__resource_id' => $main__resource_id
269 );
270 }
271 }
272
273
274 /**
275 * Get available slots per each date in each slot (child resource). It's checking times as well.
276 *
277 * @param $params [
278 * dates_sql__arr = [ "2023-10-18", "2023-10-25", "2023-11-25" ]
279 * time_as_seconds_arr = [ 36030, 39570 ]
280 * availability_per_days = [ dates = [...], resources_id_arr__in_dates = [...] ]
281 * ]
282 *
283 * @return array [
284 * 2023-10-18 = [
285 * 0 = [
286 * resource_id = 2
287 * is_available = true
288 * booked__seconds = []
289 * booked__readable = []
290 * time_to_book__seconds = [ 36030, 39570 ]
291 * time_to_book__readable = "10:00:00", "11:00:00" ]
292 * ]
293 * 1 = [...]
294 * 2 = [...]
295 * 3 = [...]
296 * ]
297 * 2023-10-25 = [...]
298 * 2023-11-25 = [...]
299 * ]
300 */
301 function wpbc__get_available_slots__for_selected_dates_times__bl( $params ) {
302
303 $defaults = array(
304 'dates_sql__arr' => array(),
305 'time_as_seconds_arr' => array(),
306 'availability_per_days' => array(),
307 'time_override_source' => '',
308 'is_use_booking_recurrent_time' => ( 'On' === get_bk_option( 'booking_recurrent_time' ) )
309 );
310 $params = wp_parse_args( $params, $defaults );
311
312 $time_as_seconds_arr = $params['time_as_seconds_arr'];
313
314 // Shift time interval in 30 seconds
315 $shift__30sec = array( 30, 30 );
316 $time_as_seconds_arr[ 0 ] = $time_as_seconds_arr[ 0 ] + $shift__30sec[0];
317 $time_as_seconds_arr[ 1 ] = $time_as_seconds_arr[ 1 ] - $shift__30sec[1];
318
319 $available_resources_arr = array();
320
321 foreach ( $params['dates_sql__arr'] as $sql_class_day_number => $sql_class_day ) {
322 $available_resources_arr[ $sql_class_day ] = array();
323 $date_shift__30sec = $shift__30sec;
324
325 if ( isset( $params['availability_per_days']['dates'][ $sql_class_day ] ) ) {
326
327 $this_date_time_as_seconds_arr = $time_as_seconds_arr;
328
329 //TODO: debug this checking in biz_l.js 2023-09-05 16:40 --- If we are using not time slot but the check in/out times ?
330
331 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
332 // Duplicated part of code, as in ../do_search.php //FixIn: 2024-05-12_11:58
333 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
334 if (
335 ( ! $params['is_use_booking_recurrent_time'] )
336 && ( count( $params['dates_sql__arr'] ) > 1 )
337 ) {
338 if ( 0 == $sql_class_day_number ) { // check in
339 $this_date_time_as_seconds_arr[1] = 24 * 60 * 60;
340 $date_shift__30sec[1] = 0;
341 } else if ( ( count( $params['dates_sql__arr'] ) - 1 ) == $sql_class_day_number ) { // check out
342 $this_date_time_as_seconds_arr[0] = 0;
343 $date_shift__30sec[0] = 0;
344 } else {
345 $this_date_time_as_seconds_arr = array( 0, 24 * 60 * 60 );
346 $date_shift__30sec = array( 0, 0 );
347 }
348 }
349 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
350
351 $date_bookings_obj = $params['availability_per_days']['dates'][ $sql_class_day ];
352
353 foreach ( $params['availability_per_days']['resources_id_arr__in_dates'] as $child_resource_id ) {
354
355 $merged_seconds_arr = wpbc_get__booking_obj__merged_seconds_arr( $date_bookings_obj[ $child_resource_id ], $params['time_override_source'] );
356
357 $is_intersect = wpbc_is_intersect__merged_seconds_arr__and__seconds_arr( $merged_seconds_arr['merged_seconds'], $this_date_time_as_seconds_arr );
358
359 $this_date_available_resource = array(
360 'resource_id' => $child_resource_id,
361 'is_available' => (! $is_intersect),
362 'booked__seconds' => $merged_seconds_arr['merged_seconds'],
363 'booked__readable' => $merged_seconds_arr['merged_readable'],
364 'time_to_book__seconds' => $this_date_time_as_seconds_arr,
365 'time_to_book__readable'=> array()
366 );
367 $this_date_available_resource['time_to_book__readable'][] = wpbc_transform__seconds__in__24_hours_his(
368 (
369 ( ( $this_date_time_as_seconds_arr[0] - $date_shift__30sec[0] ) < 0 )
370 ? 0
371 : ( $this_date_time_as_seconds_arr[0] - $date_shift__30sec[0] )
372 )
373 );
374 $this_date_available_resource['time_to_book__readable'][] = wpbc_transform__seconds__in__24_hours_his(
375 (
376 ( ( $this_date_time_as_seconds_arr[1] + $date_shift__30sec[1] ) > 86400 )
377 ? 86400
378 : ( $this_date_time_as_seconds_arr[1] + $date_shift__30sec[1] )
379 )
380 );
381
382 $available_resources_arr[ $sql_class_day ][] = $this_date_available_resource;
383 }
384 }
385 }
386
387 return $available_resources_arr;
388 }
389
390
391 /**
392 * Get Merged Seconds Array from object -> $params['availability_per_days']['dates'][ $sql_class_day ][ $child_resource_id ]
393 *
394 * @param $date_booking_obj - date_bookings_obj from $params['availability_per_days']['dates']
395 *
396 * @return array - [
397 * 'merged_seconds' => $merged_seconds,
398 * 'merged_readable' => $merged_readable
399 * ]
400 */
401 function wpbc_get__booking_obj__merged_seconds_arr( $date_booking_obj, $time_override_source = '' ) {
402
403 $is_times_availability_full_day_status = (
404 ( 'times_availability' === $time_override_source )
405 && ( ! empty( $date_booking_obj->is_day_unavailable ) )
406 && ( ! empty( $date_booking_obj->_day_status ) )
407 && ( 'full_day_booking' === $date_booking_obj->_day_status )
408 );
409
410 if ( $is_times_availability_full_day_status ) {
411 $merged_seconds_arr = wpbc_get__booking_obj__booked_details_seconds_arr( $date_booking_obj );
412 if ( ! empty( $merged_seconds_arr['merged_seconds'] ) ) {
413 return $merged_seconds_arr;
414 }
415 }
416
417 if ( $date_booking_obj->is_day_unavailable ){
418 $merged_seconds = array( array( 0, 24 * 60 * 60 ) ); // Unavailable
419 $merged_readable = array( wpbc_transform_timerange__seconds_arr__in__formated_hours( array( 0, 24 * 60 * 60 ) ) );
420 } else {
421 $merged_seconds = $date_booking_obj->booked_time_slots['merged_seconds']; // [ [ 25211, 27002 ], [ 36011, 86400 ] ] // Time slots or Available
422 $merged_readable = $date_booking_obj->booked_time_slots['merged_readable'];
423 }
424
425 return array(
426 'merged_seconds' => $merged_seconds,
427 'merged_readable' => $merged_readable
428 );
429 }
430
431
432 /**
433 * Rebuild real booked intervals from details after capacity marks the whole day unavailable.
434 *
435 * @param object $date_booking_obj Availability object for a date/resource.
436 *
437 * @return array
438 */
439 function wpbc_get__booking_obj__booked_details_seconds_arr( $date_booking_obj ) {
440
441 $seconds_arr = array();
442 $readable_arr = array();
443
444 if ( empty( $date_booking_obj->__booked__times__details ) || ! is_array( $date_booking_obj->__booked__times__details ) ) {
445 return array(
446 'merged_seconds' => array(),
447 'merged_readable' => array(),
448 );
449 }
450
451 foreach ( $date_booking_obj->__booked__times__details as $time_key => $details ) {
452 if ( '0' === (string) $time_key || false === strpos( (string) $time_key, '-' ) ) {
453 $seconds_arr[] = array( 0, 24 * 60 * 60 );
454 } else {
455 $seconds_arr[] = wpbc_transform_timerange__s_range__in__seconds_arr( $time_key );
456 }
457 }
458
459 $seconds_arr = wpbc_merge_intersected_intervals( $seconds_arr );
460
461 foreach ( $seconds_arr as $booked_time_slots__in_seconds ) {
462 $readable_arr[] = wpbc_transform_timerange__seconds_arr__in__formated_hours( $booked_time_slots__in_seconds );
463 }
464
465 return array(
466 'merged_seconds' => $seconds_arr,
467 'merged_readable' => $readable_arr,
468 );
469 }
470
471
472 /**
473 * Check if merged_seconds in $params['availability_per_days']['dates'][ $sql_class_day ][ $child_resource_id ] intersect with $time_as_seconds_arr
474 *
475 * @param $merged_seconds - [ [ 0, 86400 ] ]
476
477 * @param $this_date_time_as_seconds_arr - [ 36030, 39570 ] | [ 0, 24*60*60 ]
478 *
479 * @return bool
480 */
481 function wpbc_is_intersect__merged_seconds_arr__and__seconds_arr( $merged_seconds, $this_date_time_as_seconds_arr ) {
482
483 $is_intersect = wpbc_is_intersect__range_time_interval(
484 array(
485 array(
486 intval( $this_date_time_as_seconds_arr[ 0 ] ) + 20
487 , intval( $this_date_time_as_seconds_arr[ 1 ] ) - 20
488 )
489 )
490 , $merged_seconds );
491 return $is_intersect;
492 }
493
494
495 /**
496 * Is these array of intervals intersected ? - overlay of Math function
497 *
498 * @param array $time_interval_A array( array( 21600, 23400 ) )
499 * @param array $time_interval_B array( array( 25211, 27002 ), array( 36011, 86400 ) )
500 *
501 * @return bool
502 */
503 function wpbc_is_intersect__range_time_interval( $time_interval_A, $time_interval_B ){
504
505 for ( $i = 0; $i < count($time_interval_A); $i++ ){
506
507 for ( $j = 0; $j < count($time_interval_B); $j++ ){
508
509 $is_intersect = wpbc_is__intervals__intersected( $time_interval_A[ $i ], $time_interval_B[ $j ] );
510
511 if ( $is_intersect ){
512 return true;
513 }
514 }
515 }
516
517 return false;
518 }
519