PluginProbe
Booking Calendar / 11.0
Booking Calendar v11.0
11.8.3 11.8.2 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 All 203 releases
booking / includes / _capacity / capacity.php

capacity.php in Booking Calendar 11.0, at includes/_capacity/capacity.php

1,985 lines 106.2 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 // <editor-fold defaultstate="collapsed" desc=" == SQL - Get Dates array from DB == " >
7
8 // -----------------------------------------------------------------------------------------------------------------
9 // SQL - Get Dates array from DB
10 // -----------------------------------------------------------------------------------------------------------------
11
12 /**
13 * Get SQL dates array from DB as: [ [0] => std_object( booking_date:'2023-08-08 10:00:01', approved:0, booking_id:45, type:1 ... ), [1] => std_object( ), ... ]
14 *
15 * @param array $params = array(
16 'approved' => 'all' | 0 | 1 default 'all'
17 , 'resource_id' => array, CSD, int if empty then default '1'
18 , 'additional_bk_types' => array, CSD, int OPTIONAL default array()
19 , 'skip_booking_id' => CSD default ''
20 )
21 *
22 * @return array Array ( [0] => stdClass Object ( [booking_date] => 2023-08-08 10:00:01
23 [approved] => 0
24 [date_res_type] =>
25 [booking_id] => 45
26 [form] => selectbox-one^rangetime2^10:00 - 12:00~text^selected_short_dates_hint2^...
27 [parent] => 0
28 [prioritet] => 20
29 [type] => 2
30 )
31 [1] => stdClass Object (
32 [booking_date] => 2023-08-08 10:00:01
33 [approved] => 0
34 [date_res_type] =>
35 [booking_id] => 46
36 [form] => selectbox-one^rangetime10^10:00 - 12:00~text^selected_short_dates_hint10^...
37 [parent] => 2
38 [prioritet] => 1
39 [type] => 10
40 ), ...
41 *
42 *
43 * Example:
44
45 $sql_dates_params = array(
46 'approved' => ( ( 'On' == get_bk_option( 'booking_is_show_pending_days_as_available' ) ) ? '1' : 'all' )
47 , 'resource_id' => $type_id
48 , 'skip_booking_id' => wpbc_get_booking_id__from_hash_in_url() // int | '' // Booking IDs to skip getting from DB
49 );
50 $dates_approve = wpbc__sql__get_booking_dates( $sql_dates_params );
51
52 */
53 function wpbc__sql__get_booking_dates( $params ){
54
55 //TODO: think about pre-caching SQL request for all booking resources - useful for [bookingselect shortcode ...] $params['resource_id'] = implode(',',range(1,17));
56
57 // <editor-fold defaultstate="collapsed" desc=" = CACHE - GET :: check if such request was cached and get it = " >
58
59 $params_for_cache = maybe_serialize( $params );
60 $cache_result = wpbc_cache__get( 'wpbc__sql__get_booking_dates', $params_for_cache );
61 if ( ! is_null( $cache_result ) ) {
62 return $cache_result;
63 }
64
65 // </editor-fold>
66
67 global $wpdb;
68
69 $defaults = array(
70 'dates_to_check' => 'CURDATE' // 'CURDATE' | 'ALL' | [ '2023-07-15' , '2023-07-21' ]
71 , 'approved' => 'all' // 'all' | 0 | 1
72 , 'resource_id' => '' // INT
73 , 'additional_bk_types' => array() // arrays only
74 , 'skip_booking_id' => '' // CSD '3,5'
75 , 'as_single_resource' => false // get dates as for 'single resource' or 'parent' resource including bookings in all 'child booking resources'
76 );
77 $params = wp_parse_args( $params, $defaults );
78
79
80 // Convert $params['additional_bk_types'] and $params['resource_id'] to one CSD variable or default '1' if all empty
81 $resource_id__arr = wpbc_get_unique_array_of_resources_id( $params['resource_id'], $params['additional_bk_types'] );
82 $resource_id__csd = implode( ',', $resource_id__arr );
83
84 // S a n i t i z e
85 $resource_id__csd = wpbc_sanitize_digit_or_csd( $resource_id__csd );
86 $params['skip_booking_id'] = wpbc_sanitize_digit_or_csd( $params['skip_booking_id'] );
87 $params['approved'] = ( 'all' == $params['approved'] ) ? 'all' : intval( $params['approved'] );
88
89
90 $sql_trash_bookings = ' AND bk.trash != 1 ';
91 $sql_skip_bookings = ( '' == $params['skip_booking_id'] ) ? '' : " AND dt.booking_id NOT IN ( {$params['skip_booking_id']} ) ";
92 $sql_approved_bookings = ( 'all' == $params['approved'] ) ? '' : " AND dt.approved = {$params['approved']} ";
93
94 $or__sql_child_bookings_4_parent = ( ! $params['as_single_resource'] ) ? " OR bt.parent IN ( {$resource_id__csd} ) " : '' ;
95
96 $where_dates = wpbc_get__sql_where__for__dates( $params );
97
98 /**
99 * Description:
100 * OR dt.type_id IN ( {$resource_id__csd} )
101 * It is means that sometimes bookings can be started in one booking resource,
102 * and in future dates can be finished in other 'child' booking resource(s).
103 * It's possible, when 'main' booking resource, where booking was started
104 * has future dates as 'unavailable' or booked
105 *
106 * OR dt.type_id IN ( {$resource_id__csd} )
107 * It's means that this booking belong to child booking resource, and do not belong to parent booking resource!
108 */
109
110 if ( class_exists('wpdev_bk_biz_l') ) {
111
112 $my_sql = "SELECT DISTINCT dt.booking_date, dt.approved, dt.type_id as date_res_type, dt.booking_id, bk.form, bt.parent, bt.prioritet, bt.booking_type_id as type
113 FROM {$wpdb->prefix}bookingdates as dt
114
115 INNER JOIN {$wpdb->prefix}booking as bk
116 ON bk.booking_id = dt.booking_id
117
118 INNER JOIN {$wpdb->prefix}bookingtypes as bt
119 ON bk.booking_type = bt.booking_type_id
120
121 WHERE 1 = 1
122 {$where_dates}
123 AND (
124 bk.booking_type IN ( {$resource_id__csd} )
125 OR dt.type_id IN ( {$resource_id__csd} )
126 {$or__sql_child_bookings_4_parent}
127 )
128 {$sql_approved_bookings}
129 {$sql_trash_bookings}
130 {$sql_skip_bookings}
131 ORDER BY dt.booking_date";
132
133 // Explanation:
134 // OR bt.parent IN ( ... ) -> Bookings from CHILD booking resources
135 // OR dt.type_id IN ( ... ) -> Dates from other booking resources, which belong to this booking resource
136
137 } else if ( class_exists('wpdev_bk_biz_m') ) { // Here we get form for booking details.
138
139 $my_sql = "SELECT DISTINCT dt.booking_date, dt.approved, dt.booking_id, bk.booking_type as type, bk.form
140 FROM {$wpdb->prefix}bookingdates as dt
141
142 INNER JOIN {$wpdb->prefix}booking as bk
143 ON bk.booking_id = dt.booking_id
144
145 WHERE 1 = 1
146 {$where_dates}
147 AND bk.booking_type IN ( {$resource_id__csd} )
148 {$sql_approved_bookings}
149 {$sql_trash_bookings}
150 {$sql_skip_bookings}
151 ORDER BY dt.booking_date";
152
153 } else { // Fast request only for dates
154 $my_sql = "SELECT DISTINCT dt.booking_date, dt.approved, dt.booking_id, bk.booking_type as type
155 FROM {$wpdb->prefix}bookingdates as dt
156
157 INNER JOIN {$wpdb->prefix}booking as bk
158 ON bk.booking_id = dt.booking_id
159
160 WHERE 1 = 1
161 {$where_dates}
162 AND bk.booking_type IN ( {$resource_id__csd} )
163 {$sql_approved_bookings}
164 {$sql_trash_bookings}
165 {$sql_skip_bookings}
166 ORDER BY dt.booking_date";
167 }
168
169
170
171 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
172 $sql__dates_obj__arr = $wpdb->get_results( $my_sql );
173
174
175 // <editor-fold defaultstate="collapsed" desc=" = CACHE - SAVE :: = " >
176 $cache_result = wpbc_cache__save( 'wpbc__sql__get_booking_dates', $params_for_cache, $sql__dates_obj__arr );
177 // </editor-fold>
178
179 return $sql__dates_obj__arr;
180 }
181
182
183 /**
184 * Get SQL WHERE condition for Dates
185 *
186 * @param array $params [ 'dates_to_check' => 'CURDATE' ] | [ 'dates_to_check' => 'ALL' ] | [ 'dates_to_check' => [ '2023-07-15' , '2023-07-21' ] ]
187 *
188 * @return string ' AND ( dt.booking_date >= C URDATE() ) '
189 */
190 function wpbc_get__sql_where__for__dates( $params ){
191
192 $defaults = array(
193 'dates_to_check' => 'CURDATE' // 'CURDATE' | 'ALL' | [ '2023-07-15' , '2023-07-21' ]
194 );
195 $params = wp_parse_args( $params, $defaults );
196
197
198 if ( 'ALL' == $params['dates_to_check'] ) { // All dates -> ''
199
200 return '';
201
202 } else if ( 'CURDATE' == $params['dates_to_check'] ) { // Current dates -> CURDATE
203
204 return ' AND ( dt.booking_date >= ' . wpbc_sql_date_math_expr_explicit('', 'curdate') . ' ) ' ;
205
206 } else if ( is_array( $params['dates_to_check'] ) ) { // Specific Date(s).
207
208 // FixIn: 10.14.9.1.
209
210 // Sanitize and validate all incoming dates first.
211 $dates_to_check = wpbc_sanitize_dates_to_check( $params['dates_to_check'] );
212
213 // If nothing valid left – do not add any date filter (or return empty string).
214 if ( empty( $dates_to_check ) ) {
215 return '';
216 }
217
218 global $wpdb;
219
220 $count_dates = count( $dates_to_check );
221
222 // Case 1: date range (2 items: start / end).
223 if ( 2 === $count_dates ) {
224 $start = $dates_to_check[0] . ' 00:00:00';
225 $end = $dates_to_check[1] . ' 23:59:59';
226
227 // %s will be properly escaped and quoted by $wpdb->prepare().
228 $dates_sql_str = $wpdb->prepare( ' ( ( dt.booking_date >= %s ) AND ( dt.booking_date <= %s ) ) ', $start, $end );
229
230 // Case 2: one date – from that day forward.
231 } else if ( 1 === $count_dates ) {
232
233 $start = $dates_to_check[0] . ' 00:00:00';
234
235 $dates_sql_str = $wpdb->prepare( ' ( dt.booking_date >= %s ) ', $start );
236
237 // Case 3: list of specific separate dates – OR between each day.
238 } else {
239
240 $conditions = array();
241 $values = array();
242
243 foreach ( $dates_to_check as $date ) {
244
245 $conditions[] = '( ( dt.booking_date >= %s ) AND ( dt.booking_date <= %s ) )';
246
247 $values[] = $date . ' 00:00:00';
248 $values[] = $date . ' 23:59:59';
249 }
250
251 $conditions_sql = implode( ' OR ', $conditions );
252
253 // $values is an array; $wpdb->prepare() will expand it safely.
254 $dates_sql_str = $wpdb->prepare( $conditions_sql, $values ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
255 }
256
257 return ' AND ( ' . $dates_sql_str . ' ) ';
258 }
259
260 // Default CURDATE
261 return ' AND ( dt.booking_date >= ' . wpbc_sql_date_math_expr_explicit('', 'curdate') . ' ) ';
262 }
263
264
265
266 /**
267 * Get array of "Booked Dates" as: ['2023-08-30'][ > resource_id < ][ > time_seconds_range < ] => booking_date_obj[ booking_id:45, approved:1, ...
268 *
269 * @param array $params array(
270 * 'approved' => 'all' // 'all' | 0 | 1
271 * , 'resource_id' => '1' // arrays | CSD | int
272 * , 'additional_bk_types' => array() OPTIONAL // arrays | CSD | int
273 * , 'skip_booking_id' => '' // CSD '3,5'
274 * )
275 *
276 * @return array [ [2023-08-09]: [ [3]: [ '43211 - 86392': object( 'booking_date' => 2023-08-09 12:00:01 ... ), ... ], ... ], [2023-08-10]: ... ]
277 *
278 * Explanation:
279 * [2023-08-09]: [
280 * [3]: [
281 * '43211 - 86392': object(
282 * [booking_date] => 2023-08-09 12:00:01
283 * [approved] => 0
284 * [date_res_type] =>
285 * [booking_id] => 65
286 * [form] => text^selected_short_dates_hint3^August 10...
287 * [parent] => 0
288 * [prioritet] => 30
289 * [type] => 3
290 * [__summary__booking] : [
291 *
292 * [sql__booking_dates__arr] : [
293 * [1691668811] => 2023-08-10 12:00:01
294 * [1691675992] => 2023-08-10 14:00:02
295 * ]
296 * [__dates_obj] => WPBC_BOOKING_DATE Object(
297 * [readable_dates]: [ '2023-08-10': [ 12:00:01 - 14:00:02 ] ]
298 * [is_debug] => 0
299 * )
300 * [__dates_obj__bm__extended] => WPBC_BOOKING_DATE_EXTENDED Object (
301 * [readable_dates] : [
302 * [2023-08-09] : [ 12:00:01 - 24:00:00 ]
303 * [2023-08-10] : [ 00:00:00 - 24:00:00 ]
304 * [2023-08-11] : [ 00:00:00 - 24:00:00 ]
305 * [2023-08-12] : [ 00:00:00 - 24:00:00 ]
306 * [2023-08-13] : [ 00:00:00 - 14:00:02 ]
307 * ]
308 * [is_debug] => 0
309 * [extended_dates_times_arr] : []
310 * [debug_dates_times_arr] : []
311 * )
312 * [sql__booking_dates__arr__extended] : [
313 * [1691582401] => 2023-08-09 12:00:01
314 * [1691625600] => 2023-08-10 00:00:00
315 * [1691712000] => 2023-08-11 00:00:00
316 * [1691798400] => 2023-08-12 00:00:00
317 * [1691935202] => 2023-08-13 14:00:02
318 * ]
319 *
320 * ]
321 * )
322 * '64811 - 86392': object(
323 * [booking_date] => 2023-08-09 18:00:01
324 * [approved] => 0
325 * [date_res_type] =>
326 * [booking_id] => 66
327 * ....
328 * )
329 *
330 * ]
331 *
332 * ]
333 *
334 * [2023-08-10]: [ ... ]
335 * ...
336 *
337 * Example 1:
338 * $booked_dates__per_resources__arr = wpbc_get__booked_dates__per_resources__arr( array( 'resource_id' => $type_id ) );
339 * Example 2:
340 * $booked_dates__per_resources__arr = wpbc_get__booked_dates__per_resources__arr(
341 * 'approved' => 'all' // 'all' | 0 | 1
342 * , 'resource_id' => '1' // arrays | CSD | int
343 * , 'additional_bk_types' => array() // arrays | CSD | int
344 * , 'skip_booking_id' => '' // int | '' // CSD
345 * );
346 *
347 *
348 *
349 *
350 * $booked_dates__resources__seconds__arr[ '2023-08-08' ][ 'resource_id' ][ 'time_seconds_range' ] = Booking Date Object()
351 *
352 * Seconds: [36011 - 43192] - [start_time_second - end_time_second]
353 * Seconds: [0] - FULL DAY Booking
354 *
355 * Day start at ( 10 + 1 ) second
356 * Day End at ( ( 24 * 60 * 60 ) - 10 + 2 ) second
357 *
358 * To prevent intersections:
359 * Each booking Start time has +10 seconds
360 * Each booking End time has -10 seconds
361 * So real time here [36011 - 43192] is [ 36001 - 43202 ]
362 *
363 * Full day booking end with 0
364 * Start time booking end with 1
365 * End time booking end with 2
366 */
367 function wpbc_get__booked_dates__per_resources__arr( $params ){
368
369 $defaults = array(
370 'dates_to_check' => 'CURDATE' // 'CURDATE' | 'ALL' | [ '2023-07-15' , '2023-07-21' ]
371 , 'approved' => ( ( get_bk_option( 'booking_is_show_pending_days_as_available' ) == 'On' ) ? '1' : 'all' ) // 'all' | 0 | 1
372 , 'resource_id' => '1' // arrays | CSD | int
373 , 'additional_bk_types' => array() // arrays | CSD | int // OPTIONAL
374 , 'skip_booking_id' => wpbc_get_booking_id__from_hash_in_url() // int | '' // CSD '3,5'
375 , 'as_single_resource' => false // get dates as for 'single resource' or 'parent' resource including bookings in all 'child booking resources'
376 , 'is_days_always_available' => ( ( 'On' == get_bk_option( 'booking_is_days_always_available' ) ) ? true : false )
377
378 , 'aggregate_params' => array() //Optional. It can contain: [ 'aggregate_resource_id_arr' => [ 4 ] , 'resource_id__with_children__arr' => [3,25] ]
379 );
380 $params_for_dates = wp_parse_args( $params, $defaults );
381
382
383 // $params_for_dates['is_days_always_available'] = in_array( $params_for_dates['resource_id'], array( '1' ) ); // Set some resources as always avavailable.
384
385 if ( $params_for_dates['is_days_always_available'] ) { // All bookings showing as available dates.
386 return array();
387 }
388
389
390 /**
391 * 1. SQL - get array of all booked dates for our booking resource(s): [ [0] => date_object{ [booking_date] => 2023-08-08 10:00:01, [approved] => 0, .. }, .. ]
392 *
393 * Example: [
394 [0] => stdClass Object ( [booking_date] => 2023-08-08 10:00:01
395 [approved] => 0
396 [date_res_type] =>
397 [booking_id] => 45
398 [form] => selectbox-one^rangetime2^10:00 - 12:00~text^selected_short_dates_hint2^...
399 [parent] => 0
400 [prioritet] => 20
401 [type] => 2
402 )
403 [1] => stdClass Object (
404 [booking_date] => 2023-08-08 10:00:01
405 [approved] => 0
406 [date_res_type] =>
407 [booking_id] => 46
408 [form] => selectbox-one^rangetime10^10:00 - 12:00~text^selected_short_dates_hint10^...
409 [parent] => 2
410 [prioritet] => 1
411 [type] => 10
412 ), ...
413 ]
414 */
415 $sql__b_dates__arr = wpbc__sql__get_booking_dates( $params_for_dates );
416
417
418 /**
419 * 2. From SQL dates into: [ > resource_id < ][ > booking_id < ] -> __summary__booking['sql__booking_dates__arr'] = [ [ '>seconds<' ]: '> SQL DATE <' , ... ]
420 * [1693303211] => 2023-08-29 10:00:01
421 * [1693353600] => 2023-08-30 00:00:00
422 * [1693483192] => 2023-08-31 12:00:02
423 * ]
424 */
425 $resources__booking_id__obj = wpbc_support__transform__into__resource_booking_dates__arr(
426 array( 'sql_dates_arr' => wpbc_clone_array_of_objects( $sql__b_dates__arr ) , 'is_sort__dates_arr' => true , 'is_apply__check_in_out__10s' => true ) );
427
428
429 /**
430 * 2.0 Transfer AGGREGATE resource bookings to Main resources
431 *
432 *
433 */
434 if ( ! empty( $params['aggregate_params'] ) ) {
435 $resources__booking_id__obj = wpbc_aggregate__merge_bookings__from_aggregate__in_source_resource__arr(
436 $resources__booking_id__obj,
437 $params['aggregate_params']['resource_id__with_children__arr'],
438 $params['aggregate_params']['aggregate_resource_id_arr']
439 );
440 }
441
442
443 /**
444 * 2.1 Get [ > resource_id < ][ > booking_id < ] -> __summary__booking[ '_readable_dates' ] = [ '2023-08-01': [ 0: "10:00:01 - 12:00:02" ], ...
445 * '2023-08-05': [ 0: "10:00:01 - 12:00:02" ], ...
446 * ]
447 */
448 $resources__booking_id__obj = wpbc__in_all_bookings__create_WPBC_BOOKING_DATE( $resources__booking_id__obj );
449
450
451 /**
452 * 2.2 Extend check in/out dates [ > resource_id < ][ > booking_id < ] -> __summary__booking[ 'sql__booking_dates__arr__extended' ]
453 */
454 if ( function_exists( 'wpbc__extend_availability__before_after__check_in_out' ) ) {
455
456 $resources__booking_id__obj = wpbc__extend_availability__before_after__check_in_out( $resources__booking_id__obj );
457 }
458
459
460 /**
461 * 3. Into: ['2024-01-28'][ > resource_id < ][ > booking_id < ][ > only_time_seconds < ] => obj( booking_date: "2024-01-28 10:00:01", ... )
462 *
463 * From: [ > resource_id < ][ > booking_id < ] => obj( booking_date: "2024-01-28 10:00:01", ['__summary__booking']['sql__booking_dates__arr'][] , ... )
464 */
465 $dt__res__bk__seconds__arr = wpbc_support__transform__into__date_resource_booking_timesec__arr(
466 array( 'resource_booking_dates_arr' => $resources__booking_id__obj , 'is_apply__check_in_out__10s' => true ) );
467
468
469 /**
470 * 4. Into: ['2023-08-30'][ > resource_id < ][ > time_seconds_range < ] => booking_date_obj[ booking_id:45, approved:1, ...
471 *
472 * , where 'time_seconds_range' can be: '0' | '36011 - 43192', ...
473 */
474 $dt__res__time_seconds_range__arr = wpbc_support__transform__into__date_resource_timesec_range__arr(
475 array( 'date_resource_booking_timesec_arr' => $dt__res__bk__seconds__arr , 'is_apply__check_in_out__10s' => true ) );
476
477 return $dt__res__time_seconds_range__arr;
478 }
479
480 // </editor-fold>
481
482
483 // -----------------------------------------------------------------------------------------------------------------
484 // Get Resource array filled by booked Dates
485 // -----------------------------------------------------------------------------------------------------------------
486
487
488 /**
489 * Get all dates STATUSES as: ['2023-08-30'][ 'summary']['status_for_day':'available', 'day_availability':3, [ > resource_id < ] => std_object( '_day_status':'full_day_booking', '__booked__times__details':[ '1 - 43192': std_object( booking_id:46, 'approved':0, ... ), '50300 - 63192': ], 'is_day_unavailable':1, ...
490 *
491 * @param int $single_or_parent__resource_id // 1 --- INT (currently it's works only for one resource (single or parent)
492 * array $params[ 'timeslots_to_check_intersect' ] // [ '10:00 - 12:00' ] if bookings intersect with all time slots in array, then the date unavailable, if empty array then it's skipped
493 *
494 * @return array {
495 * calendar_2: {
496 * id: 2
497 * dates: { "2023-07-21": {…}
498 * "2023-07-22": {
499 * ['summary']['status_for_bookings']: "pending"
500 * ['summary']['status_for_day']: "available"
501 * day_availability: 4
502 * max_capacity: 4
503 * statuses: Object { day: "check_in|check_in|available|available", bookings: "approved|pending||" }
504 *
505 * 2: Object { is_day_unavailable: false, _day_status: "check_in", check_in_out: "check_in", … }
506 * 10: Object { is_day_unavailable: false, _day_status: "check_in", check_in_out: "check_in", … }
507 * 11: Object { is_day_unavailable: false, _day_status: "available", pending_approved: [] }
508 * 12: Object { is_day_unavailable: false, _day_status: "available", pending_approved: [] }
509 * }
510 * , "2023-07-23": {…}
511 * , …
512 * }
513 * }
514 * calendar_5: {...}
515 * , ...
516 * }
517 *
518 *
519 * Important Dates properties:
520 *
521 * ['summary']['status_for_bookings']: "" | "pending" | "approved"
522 * ['summary']['status_for_day']: | 'available';
523 * | 'time_slots_booking';
524 * | 'full_day_booking';
525 * | 'season_filter';
526 * | 'resource_availability';
527 * | 'weekday_unavailable'; 'from_today_unavailable' | 'limit_available_from_today'
528 * | 'change_over';
529 * | 'check_in';
530 * | 'check_out';
531 * | 'change_over check_out' .... variations....
532 *
533 *
534 * @return array array(
535 'dates' => $availability_per_day like ['2023-08-17'] = ...
536 , 'resources_id_arr__in_dates' => $source__resource_id_arr like [ 1,10,11,12,14]
537 )
538 */
539 function wpbc_get_availability_per_days_arr( $params ) {
540
541 if ( 0 ) { // FixIn: 9.8.3.1 ?
542 wpbc_set_limit_php( 300 ); // Set 300 seconds for php execution.
543 }
544
545 $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 */
546 $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 */
547
548 $defaults = array(
549 'dates_to_check' => 'CURDATE', // v: 'CURDATE' | 'ALL' | arr: '2023-07-15' , '2023-07-21'.
550 'approved' => ( ( 'On' === get_bk_option( 'booking_is_show_pending_days_as_available' ) ) ? '1' : 'all' ), // v: 'all' | 0 | 1.
551 'resource_id' => '1', // Single or parent booking resource!!!! // arrays | CSD | int ???.
552 'additional_bk_types' => array(), // arrays | CSD | int // OPTIONAL -> aggregate_resource_id_arr ... it is array of booking resources from aggregate shortcode parameter.
553 'skip_booking_id' => wpbc_get_booking_id__from_hash_in_url(), // int | '' // CSD '3,5'.
554 'as_single_resource' => false, // get dates as for 'single resource' or 'parent' resource including bookings in all 'child booking resources'.
555 'max_days_count' => wpbc_get_max_visible_days_in_calendar(), // 365.
556 'timeslots_to_check_intersect' => array(), // arr: '12:20 - 12:55', '13:00 - 14:00' ) // TODO: ? do we really need it, because below we get it from function.
557 '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.
558 'custom_form' => '', // Required for checking all available time-slots and compare with booked time slots.
559 'force_check_from_today_unavailable' => false, // Optional admin tools can force relative availability checks inside explicit date ranges.
560 );
561
562 $params = wp_parse_args( $params, $defaults );
563
564 // FixIn: 10.7.1.2. //FixIn: 10.10.3.2.
565 if (
566 ( false !== strpos( $params['request_uri'], 'allow_past' ) ) ||
567 (
568 wpbc_is_new_booking_page_url( $params['request_uri'] ) &&
569 ( false !== strpos( $params['request_uri'], 'booking_hash' ) )
570 )
571 ) {
572 $params['dates_to_check'] = 'ALL';
573 }
574
575 // -----------------------------------------------------------------------------------------------------------------
576 // R e s o u r c e (s) D a t a
577 // -----------------------------------------------------------------------------------------------------------------
578 // Get array of booking resource ID [1, 13, 8, 6, 7] or default: [ 1 ]
579 $source__resource_id_arr = wpbc_get_unique_array_of_resources_id( $params['resource_id'] ); // [1, 13, 8, 6, 7]
580 //$source__resource_id_arr = wpbc_get_unique_array_of_resources_id( $params['resource_id'], $params['additional_bk_types'] ); // [1, 13, 8, 6, 7]
581 $first_resource_id = $source__resource_id_arr[0]; // First from the list, or 1 if not provided.
582
583 // Get here Obj. of booking resource (which can include CHILD booking resources)
584 $resources_obj = new WPBC_RESOURCE_SUPPORT( array(
585 'resource_id' => $source__resource_id_arr, //CSD | D
586 'as_single_resource' => $params['as_single_resource'] // If true, then skip child booking resources
587 ));
588 // Resource ID arr (Can be Parent and Child resource ID)
589 $resource_id__with_children__arr = $resources_obj->get_resource_id_arr(); // [ 2, 10, 11, 12 ]
590
591 // Get Maximum capacity of resource
592 $resource_obj = $resources_obj->get__booking_resource_obj( $first_resource_id );
593 $max_resource_capacity_int = empty( $resource_obj ) ? 1 : $resource_obj->capacity; // 1 | 4
594
595 // Get base cost of resource
596 $resource_base_cost = $resources_obj->get_resources_base_cost_arr(); // [ 0, 25, 100, 99]
597
598
599
600
601 // -----------------------------------------------------------------------------------------------------------------
602 // Get real AGGREGATE resource ID arr
603 // -----------------------------------------------------------------------------------------------------------------
604 $real_resource_id_arr = wpbc_get_unique_array_of_resources_id( $params['resource_id'] ); // [ 1 ]
605 if ( empty( $params['additional_bk_types'] ) ) {
606 $aggregate_resource_id_arr = array();
607 } else {
608 $aggregate_resource_id_arr = wpbc_get_unique_array_of_resources_id( $params['additional_bk_types'] ); // [1, 13, 8, 6, 7]
609 }
610 // Excluding from 'additional_bk_types' all resources in 'resource_id'
611 $aggregate_resource_id_arr = array_diff( $aggregate_resource_id_arr, $real_resource_id_arr ); // [ 13, 8, 6, 7 ]
612 $aggregate_resource_id_arr = array_values( $aggregate_resource_id_arr ); // reindex array, for ability to transfer array instead of obj to JS client side.
613
614 $params['aggregate_params'] = array(
615 'aggregate_resource_id_arr' => $aggregate_resource_id_arr,
616 'resource_id__with_children__arr' => $resource_id__with_children__arr
617 );
618
619 // -----------------------------------------------------------------------------------------------------------------
620 // B o o k i n g s
621 // -----------------------------------------------------------------------------------------------------------------
622 // Main function to get "Bookings": ['2023-08-30'][ > resource_id < ][ > time_seconds_range < ] => booking_date_obj[ booking_id:45, approved:1, ...
623 $bookings__in_dates = wpbc_get__booked_dates__per_resources__arr( $params );
624
625 // -----------------------------------------------------------------------------------------------------------------
626 // Time slots availability blocks.
627 // -----------------------------------------------------------------------------------------------------------------
628 $availability_timeslots__in_dates = array(); // FixIn: 10.16.1.
629
630
631
632 // -----------------------------------------------------------------------------------------------------------------
633 // Booking > Availability page
634 // -----------------------------------------------------------------------------------------------------------------
635 $search_dates = $params['dates_to_check']; // 'CURDATE' | 'ALL' | [ "2023-08-03" , "2023-08-04" , "2023-08-05" ]
636
637 //FixIn: 9.8.15.10 Aggregate or not Aggregate Booking > Availability ? aggregate_type = 'all' | 'bookings_only'
638 if ( ( ! empty( $params['aggregate_type'] ) ) && ( 'bookings_only' === $params['aggregate_type'] ) ) { // FixIn: 9.9.0.16.
639 $unavailable_dates__per_resources__arr = wpbc_for_resources_arr__get_unavailable_dates(
640 $resource_id__with_children__arr, // Only One Primary Resource !!
641 $search_dates
642 ); // [ 2: ['2023-08-01', '2023-08-02'], 10: ['2023-08-05', '2023-08-06'] ]
643 } else {
644 $unavailable_dates__per_resources__arr = wpbc_for_resources_arr__get_unavailable_dates(
645 wpbc_get_unique_array_of_resources_id( $resource_id__with_children__arr, $aggregate_resource_id_arr ), // Get unavailable dates for primary and aggregate booking resources
646 $search_dates
647 ); // [ 2: ['2023-08-01', '2023-08-02'], 10: ['2023-08-05', '2023-08-06'] ]
648 }
649 $unavailable_dates__per_resources__arr = wpbc_aggregate_merge_availability( $unavailable_dates__per_resources__arr,
650 $resource_id__with_children__arr,
651 $aggregate_resource_id_arr );
652 // FixIn: 10.16.1.
653 if ( function_exists( 'wpbc_availability_timeslots__get_intervals_for_resources' ) ) {
654 $availability_timeslots__resource_ids = wpbc_get_unique_array_of_resources_id( $resource_id__with_children__arr, $aggregate_resource_id_arr );
655 $availability_timeslots__in_dates = wpbc_availability_timeslots__get_intervals_for_resources(
656 array(
657 'resource_id' => $availability_timeslots__resource_ids,
658 'dates_to_check' => $search_dates,
659 'max_days_count' => $params['max_days_count'],
660 )
661 );
662
663 if ( function_exists( 'wpbc_availability_timeslots__aggregate_merge_intervals' ) ) {
664 $availability_timeslots__in_dates = wpbc_availability_timeslots__aggregate_merge_intervals(
665 $availability_timeslots__in_dates,
666 $resource_id__with_children__arr,
667 $aggregate_resource_id_arr
668 );
669 }
670 }
671
672 // -----------------------------------------------------------------------------------------------------------------
673 // Booking > Resources > Availability page
674 // -----------------------------------------------------------------------------------------------------------------
675 $season_filters_availability = array();
676 if ( class_exists('wpdev_bk_biz_m') ) {
677 foreach ( $resource_id__with_children__arr as $resource_id_for_season ) {
678 $season_filters_availability[ $resource_id_for_season ] = apply_bk_filter( 'get_available_days', $resource_id_for_season );
679 }
680 }
681
682
683
684
685 // -----------------------------------------------------------------------------------------------------------------
686 // P a r a m e t e r s f o r L O O P
687 // -----------------------------------------------------------------------------------------------------------------
688
689 // - Is this Booking > Add booking page ? --------------------------------------------------------------------------
690 $is_this_bap_page = wpbc_is_new_booking_page_url( $params['request_uri'] );
691 $is_this_hash_page = ( false !== strpos( $params['request_uri'], 'booking_hash' ) ) ? true : false; // Set it to TRUE for adding booking in past at Booking > Add booking page
692
693 // FixIn: 10.7.1.2.
694 if ( ! $is_this_hash_page ) {
695 $is_this_hash_page = ( false !== strpos( $params['request_uri'], 'allow_past' ) ) ? true : false;
696 }
697
698 if ( ( $is_this_bap_page ) && ( $is_this_hash_page ) ) { // Start days in calendar from = PAST
699 $params['dates_to_check'] = 'ALL';
700 }
701
702 if ( 'ALL' == $params['dates_to_check'] ) { // All dates -> ''
703
704 $start_day_number = - 1 * $params['max_days_count'];
705 //$today_inix_timestamp = strtotime( '-' . intval( $params['max_days_count'] ) . ' days' ); // - 300 days
706
707 // Get time, relative to Timezone from WordPress > Settings General page // FixIn: 9.9.0.17.
708 $start_date_unix = strtotime( '-' . intval( $params['max_days_count'] ) . ' days' ); // - 365 days
709 $date_with_wp_timezone = wpbc_datetime_localized__use_wp_timezone( gmdate( 'Y-m-d H:i:s', $start_date_unix ), 'Y-m-d 00:00:00' );
710 $today_inix_timestamp = strtotime( $date_with_wp_timezone );
711
712 } else if ( 'CURDATE' == $params['dates_to_check'] ) { // Current dates -> CURDATE
713
714 $start_day_number = 1;
715 // $today_inix_timestamp = strtotime( gmdate( 'Y-m-d 00:00:00', strtotime( 'now' ) ) ); // Today 00:00:00
716
717 // Get time, relative to Timezone from WordPress > Settings General page // FixIn: 9.9.0.17.
718 $start_date_unix = strtotime( 'now' );
719 $date_with_wp_timezone = wpbc_datetime_localized__use_wp_timezone( gmdate( 'Y-m-d H:i:s', $start_date_unix ), 'Y-m-d 00:00:00' );
720 $today_inix_timestamp = strtotime( $date_with_wp_timezone );
721
722 } else if ( is_array( $params['dates_to_check'] ) ) {
723
724 $start_day_number = 1;
725
726 $today_inix_timestamp = strtotime( $params['dates_to_check'][0] . ' 00:00:00' ); // '2023-09-03 00:00:00'
727
728 $dif_in_days = strtotime( $params['dates_to_check'][ ( count( $params['dates_to_check'] ) - 1 ) ] . ' 00:00:00' )
729 - strtotime( $params['dates_to_check'][0] . ' 00:00:00' );
730
731 $dif_in_days = $dif_in_days / ( 24 * 60 * 60 );
732 $params['max_days_count'] = ceil( $dif_in_days ) + 1;
733 }
734
735
736 // Get Time Slots from booking form for Each date: [ '2023-10-25' => [ '12:20 - 12:55', '13:00 - 14:00' ], '2023-10-26' => [ ... ], ... ]
737 $readable_timeslots_arr__in_dates_arr__to_check_intersect = wpbc_get_times_fields_configuration__by_dates(
738 $first_resource_id, // Resource ID (used in case of MultiUser version for getting specific form for regular users)
739 $params['custom_form'], // Form name for getting time slots configuration
740 $today_inix_timestamp, // start_date_unix_timestamp
741 ( $params['max_days_count'] - $start_day_number ) // days_count
742 );
743
744 // =================================================================================================================
745 // -- Here are GO
746 // =================================================================================================================
747 $availability_per_day = array();
748
749 for ( $day_num = $start_day_number; $day_num <= $params['max_days_count']; $day_num ++ ) {
750
751 $my_day_tag = gmdate( 'Y-m-d', $today_inix_timestamp ); // '2023-07-19'
752
753
754 //--------------------------------------------------------------------------------------------------------------
755 // Get Time-Slots from booking form to CHECK INTERSECT :: Convert readable time slot to time slot as seconds [ '12:20 - 12:55', '13:00 - 14:00' ] OR [] if not time slots
756 $as_seconds_timeslots_arr__to_check_intersect = wpbc_get__time_range_in_seconds_arr__for_date( $readable_timeslots_arr__in_dates_arr__to_check_intersect, $my_day_tag );
757 /*
758 // TODO: check this, if it's required ? // If empty, maybe get default 'timeslots_to_check_intersect' from root of this function parameters ????
759 if ( empty( $as_seconds_timeslots_arr__to_check_intersect ) ) {
760
761
762 if ( ! is_array( $params[ 'timeslots_to_check_intersect' ] ) ) { // Root parameters from this function
763 $params[ 'timeslots_to_check_intersect' ] = array( $params[ 'timeslots_to_check_intersect' ] );
764 }
765
766 $as_seconds_timeslots_arr__to_check_intersect = array();
767 foreach ( $params[ 'timeslots_to_check_intersect' ] as $time_slot_readable ) {
768 $as_seconds_timeslots_arr__to_check_intersect[] = wpbc_convert__readable_time_slot__to__time_range_in_seconds( $time_slot_readable );
769 }
770 }
771 */
772 //--------------------------------------------------------------------------------------------------------------
773
774
775 $availability_per_day[ $my_day_tag ] = array();
776
777 // Helpful tip. Definition here variables in such order, useful for having such order in _wpbc JS variable for showing it with _wpbc.bookings_in_calendars__get_all(); command
778 $availability_per_day[ $my_day_tag ]['day_availability'] = $max_resource_capacity_int; // 4
779 $availability_per_day[ $my_day_tag ]['max_capacity'] = $max_resource_capacity_int; // 4
780 $availability_per_day[ $my_day_tag ]['statuses'] = array();
781 $availability_per_day[ $my_day_tag ]['statuses']['day_status'] = array(); // per each child booking resource
782 $availability_per_day[ $my_day_tag ]['statuses']['bookings_status'] = array(); // per each child booking resource
783 $availability_per_day[ $my_day_tag ]['summary'] = array();
784 $availability_per_day[ $my_day_tag ]['summary']['status_for_day'] = ''; // available | time_slots_booking | full_day_booking | ...
785 $availability_per_day[ $my_day_tag ]['summary']['status_for_bookings'] = ''; // pending | approved | CO: pending_pending | pending_approved | approved_pending | approved_approved
786 $availability_per_day[ $my_day_tag ]['summary']['status_for_bookings_arr'] = array(); // Structured statuses array, e.g. array( 'approved', 'approved_approved' ).
787 $availability_per_day[ $my_day_tag ]['summary']['tooltip_times'] = '';
788 $availability_per_day[ $my_day_tag ]['summary']['tooltip_availability'] = '';
789 $availability_per_day[ $my_day_tag ]['summary']['tooltip_day_cost'] = '';
790 $availability_per_day[ $my_day_tag ]['summary']['tooltip_booking_details'] = '';
791
792
793 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
794 // R E S O U R C E S - S t a r t
795 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
796 foreach ( $resource_id__with_children__arr as $resource_id ) { // [1, 13, 8, 6, 7]
797
798 $availability_per_day[ $my_day_tag ][ $resource_id ] = new stdClass();
799 $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = false;
800 $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'available';
801 $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved = array();
802 $availability_per_day[ $my_day_tag ][ $resource_id ]->tooltips = array(
803 'resource_title' => $resources_obj->get_resource_title( $resource_id ),
804 'times' => '',
805 'details' => array()
806 );
807 $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots = array(
808 'in_seconds' => array(), // seconds
809 'readable24h' => array(), // readable 24H - for debug only
810 'merged_seconds' => array(), // seconds (reduced number of time_ranges)
811 'merged_readable' => array() // readable 12AM
812 );
813 // Day Cost / Rates ---------------------------------------------------------------------------------------
814 $fin_day_cost = wpbc_support_capacity__get_day_cost( $my_day_tag, $resource_id, $resource_base_cost[ $resource_id ] );
815 $availability_per_day[ $my_day_tag ][ $resource_id ]->date_cost_rate = $fin_day_cost;
816
817
818 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
819 // B O O K I N G S - S t a r t
820 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
821
822 if ( ( isset( $bookings__in_dates[ $my_day_tag ] ) )
823 && ( isset( $bookings__in_dates[ $my_day_tag ][ $resource_id ] ) ) ){
824
825 $this_date_bookings = $bookings__in_dates[ $my_day_tag ][ $resource_id ]; // [ [36011 - 86392] => stdClass Object( [approved] => 1 , ... ) ,... ]
826 ksort( $this_date_bookings );
827 $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details = $this_date_bookings;
828
829 } else {
830 $this_date_bookings = array();
831 }
832
833
834 /**
835 * If bookings exist then:
836 * 1. Removing some properties here to hide personal details,
837 * 2. Set Approved / Pending status of the bookings
838 * 3. By default, set "_day_status" as 'time_slots_booking' ( later we will change to 'full_day_booking', if applied )
839 */
840 if ( ! empty( $this_date_bookings ) ) {
841
842 // =====================================================================================================
843 // T i m e s - Start
844 // =====================================================================================================
845 foreach ( $this_date_bookings as $booked_times__key => $booked_times__value ) {
846
847 // By default, set "_day_status" as 'time_slots_booking' ( later we will change to 'full_day_booking', if applied )
848 $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'time_slots_booking';
849
850 // -------------------------------------------------------------------------------------------------
851 // Get Time-Slot
852 if ( false === strpos( $booked_times__key, '-' ) ) { // Full day ? - 0 == $booked_times__key
853 $time_range__seconds__arr = array( 0, 86400 ); // 24 * 60 * 60
854 } else {
855 $time_range__seconds__arr = wpbc_transform_timerange__s_range__in__seconds_arr( $booked_times__key ); // '43211 - 86392' into [43211, 86400]
856 }
857
858 // Real time: [43211, 86400]
859 $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots['in_seconds'][] = $time_range__seconds__arr;
860
861 // For DEBUG only -- Readable 24H: '10:00:01 - 12:30:02'
862 $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots['readable24h'][] = wpbc_transform_timerange__seconds_arr__in__24_hours_range( $time_range__seconds__arr );
863
864 // -------------------------------------------------------------------------------------------------
865 // Pending | Approved :: for correct order of all statuses - make it based on start time index / $time_range__seconds__arr[0] == 0 in situation of FULL day booking
866 $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved[ $time_range__seconds__arr[0] ] = ( '1' == $booked_times__value->approved ) ? 'approved' : 'pending';
867
868
869 // T O O L T I P :: Booking Details
870 $booked_time_title = ( ( 0 == $time_range__seconds__arr[0] ) && ( $time_range__seconds__arr[1] >= 86400 ) )
871 ? __( 'Full day', 'booking' )
872 : wpbc_transform_timerange__seconds_arr__in__formated_hours( $time_range__seconds__arr );
873 $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__tooltip__set_for_details( $availability_per_day, $my_day_tag, $resource_id,
874 $this_date_bookings, $booked_times__key, $resources_obj, $booked_time_title );
875
876 // Unset ...->form and other fields...
877 $this_date_bookings[ $booked_times__key ] = wpbc_support_capacity__unset_some_fields( $this_date_bookings[ $booked_times__key ] );
878
879 } // T i m e s - E n d Booked Times Loop - for current resource
880
881
882 // =====================================================================================================
883 // Merge intersected time intervals =
884 // =====================================================================================================
885 $merged_seconds_arr = wpbc_merge_intersected_intervals( $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots['in_seconds'] );
886
887 $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots['merged_seconds'] = $merged_seconds_arr;
888
889 foreach ( $merged_seconds_arr as $booked_time_slots__in_seconds ) {
890 $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots['merged_readable'][] = wpbc_transform_timerange__seconds_arr__in__formated_hours( $booked_time_slots__in_seconds );
891 }
892
893 // T O O L T I P :: Times
894 $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__tooltip_times__set_for_times( $availability_per_day, $my_day_tag, $resource_id, $resource_id__with_children__arr );
895
896 // =====================================================================================================
897 // End times
898 // =====================================================================================================
899
900
901 // For correct order of all booking statuses - we will make it based on start time index - Sort array starting from 1 second 00:00 to 12:00 to 23:00 etc...
902 ksort( $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved );
903
904 // array_keys( $booked_time_slots ) can be: [0] -> 'Full day' | ['36011 - 43192', '56011 - 86392'] -> '10:00 - 12:00', '15:55 - 24:00'
905 $booked_time_slots = array_keys( $this_date_bookings );
906
907
908 // =====================================================================================================
909 // Full day booking ----------------------------------------------------------------------------------- full_by_bookings
910 // =====================================================================================================
911 if ( in_array( '0', $booked_time_slots ) ) {
912
913 $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true;
914 $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'full_day_booking';
915
916 // Reset all other possible time slot statuses, in general they must not exist, but for some case
917 $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved = array();
918
919 // Pending or approved, for full day booking: $this_date_bookings['0']
920 $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved[] = ( '1' == $this_date_bookings['0']->approved ) ? 'approved' : 'pending';
921
922 // T O O L T I P :: Times - Full Day Booked
923 $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__tooltip_times__set_full_day( $availability_per_day, $my_day_tag, $resource_id
924 , $resource_id__with_children__arr, __( 'Full day', 'booking' ) );
925
926 } // end 'full day' if
927
928
929 // =====================================================================================================
930 // All time slots booked ? -----------------------------------------------------------------------------
931 // =====================================================================================================
932 if (
933 ( ! empty( $as_seconds_timeslots_arr__to_check_intersect ) ) // We need to check intersection with some time slot '36011 - 43192'
934 && ( ! $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable ) // And this date still free false
935 ){
936
937 $is_some_timeslot_available = wpbc_is_some_timeslot__available__in_arr( $as_seconds_timeslots_arr__to_check_intersect, $booked_time_slots );
938
939 // ------------------------------------------------------------------------------------------------- full_by_bookings
940 if ( ! $is_some_timeslot_available ) {
941 // All time slots booked !!!
942
943 $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true;
944 $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'full_day_booking';
945 $availability_per_day[ $my_day_tag ][ $resource_id ]->_booking_form_timeslots_unavailable = implode( '|', $params[ 'timeslots_to_check_intersect' ] );
946
947 // T O O L T I P :: Times - Full Day Booked
948 $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__tooltip_times__set_full_day( $availability_per_day, $my_day_tag, $resource_id
949 , $resource_id__with_children__arr, __( 'Full day', 'booking' ) );
950 } else {
951 // Some time slots available or there is no time slot passed in this function
952 }
953
954 } // end 'all time slots booked' if
955
956
957
958 // =====================================================================================================
959 // Change over days =
960 // =====================================================================================================
961 if (
962 ( function_exists( 'wpbc_is_booking_used_check_in_out_time' ) )
963 && ( wpbc_is_booking_used_check_in_out_time( $params[ 'request_uri' ], $resource_id ) )
964 && ( ! $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable ) // And this date still free false
965 ) {
966
967 /**
968 * "Change over days" - possible situations: check_in | check_out | change_over | ...
969 *
970 * $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = check_in
971 * | check_out
972 * | change_over
973 * | 'mixed'
974 * 'mixed' - e.g. 'change_over check_out' where several child resources and some is 'change_over' and others are 'check_out'
975 *
976 *
977 * Possible situations for change-over days:
978 *
979 * // A. If in $booked_time_slots array one of values (or in $this_date_bookings one of keys)
980 * // 1. Started with time that is ended with 1 second
981 * // 2. and Ended with '24:00' it is means '86392', like this: '28811 - 86392'
982 * // then it's means that we have 'check_in' time here
983 *
984 * // B. If in $booked_time_slots array one of values (or in $this_date_bookings one of keys)
985 * // 1. Started with '00:00' it is means '1'
986 * // 2. and Ended time that is ended with 2 second
987 * // like this: '1 - 32402'
988 * // then it's means that we have 'check_out' time here
989 *
990 * // C. If we have A. and B. then we have 'change_over' here
991 */
992
993 $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out = array();
994
995 foreach ( $this_date_bookings as $booked_times__key => $booked_times__value ) {
996
997 if ( false === strpos( $booked_times__key, '-' ) ) {
998 continue; // for situation with FULL day booking, here $booked_times__key = 0
999 }
1000
1001 $rangeA_arr = explode( '-', $booked_times__key );
1002 $rangeA_arr[0] = intval( trim( $rangeA_arr[0] ) );
1003 $rangeA_arr[1] = intval( trim( $rangeA_arr[1] ) );
1004
1005 // start time
1006 $is_starttime__check_in = $rangeA_arr[0] % 10; // 0, 1, 2
1007 $is_starttime__check_in = ( 1 == $is_starttime__check_in ) ? true : false;
1008
1009 // end time
1010 $is_endtime__check_out = $rangeA_arr[1] % 10;
1011 $is_endtime__check_out = ( 2 == $is_endtime__check_out ) ? true : false;
1012
1013
1014 if ( ( $is_starttime__check_in ) && ( WPBC_FULL_DAY_TIME_OUT == $rangeA_arr[1] ) ) { // A :: start_time - 86392 e.g. 14:00 - 24:00
1015 // only "check in" time here
1016 $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out[] = 'check_in';
1017
1018 } else if ( ( WPBC_FULL_DAY_TIME_IN == $rangeA_arr[0] ) && ( $is_endtime__check_out ) ) { // B :: 1 - end_time e.g. 00:00 - 10:00
1019 // only "check out" time here
1020 $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out[] = 'check_out';
1021 }
1022
1023 }
1024 $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out = array_unique( $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out );
1025 $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out = array_filter( $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out ); // All entries of array equal to FALSE (0, '', '0' ) will be removed.
1026
1027 if (
1028 ( in_array( 'check_in', $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out ) )
1029 && ( in_array( 'check_out', $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out ) )
1030 ) {
1031 $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out = array( 'change_over' ); // both check in / out times here
1032 $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true;
1033
1034 // Possible statuses: pending_pending | pending_approved | approved_pending | approved_approved
1035 $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved = array( implode( '_', $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved ) );
1036 }
1037
1038 $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out = implode( '|', $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out );
1039
1040 if ( ! empty( $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out ) ) {
1041 $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out;
1042 }
1043 } // end change-over if
1044
1045
1046 }
1047 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1048 // B O O K I N G S - E n d
1049 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1050 // FixIn: 10.16.1.
1051 if (
1052 function_exists( 'wpbc_availability_timeslots__apply_blocks_to_availability_obj' )
1053 && isset( $availability_timeslots__in_dates[ $my_day_tag ][ $resource_id ] )
1054 ) {
1055 $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_availability_timeslots__apply_blocks_to_availability_obj(
1056 $availability_per_day[ $my_day_tag ][ $resource_id ],
1057 $availability_timeslots__in_dates[ $my_day_tag ][ $resource_id ],
1058 $as_seconds_timeslots_arr__to_check_intersect
1059 );
1060 }
1061
1062 //==========================================================================================================
1063 // $availability_per_day[..]->_day_status = 'season_filter' | ...
1064 //==========================================================================================================
1065 // Booking > Resources > Availability page >>> 'season_filter'
1066 $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__day_status__season_filter( $availability_per_day, $my_day_tag, $resource_id, $season_filters_availability );
1067
1068 // Booking > Availability page >>> 'resource_availability'
1069 $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__day_status__resource_availability( $availability_per_day, $my_day_tag, $resource_id, $unavailable_dates__per_resources__arr );
1070
1071 if ( empty( $params['skip_general_availability'] ) ) {
1072 // Week Days unavailable >>> 'weekday_unavailable'
1073 $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__day_status__weekday_unavailable( $availability_per_day, $my_day_tag, $resource_id );
1074 }
1075
1076 // if ( ( ! $is_this_bap_page ) || ( ! $is_this_hash_page ) ) {
1077 if ( empty( $params['skip_general_availability'] ) && ( ! $is_this_bap_page ) && ( ! $is_this_hash_page ) ) {
1078 // Do not apply these settings at Booking > Add booking page, when we edit booking - e.g. exist 'booking_hash'
1079
1080 // Skip checking unavailable from today, if defined the calendar_dates_start='2025-02-10' calendar_dates_end='2025-12-31' in shortcode. // FixIn: 10.13.1.4.
1081 $is_skip_check__from_today_unavailable = false;
1082 if ( is_array( $params['dates_to_check'] ) && empty( $params['force_check_from_today_unavailable'] ) ) {
1083 if ( ( ( count( $params['dates_to_check'] ) ) > 0 ) && ( wpbc_is_date_less_than( $params['dates_to_check'][0], $my_day_tag ) ) ) {
1084 $is_skip_check__from_today_unavailable = true;
1085 }
1086 if ( ( ( count( $params['dates_to_check'] ) ) > 1 ) && ( wpbc_is_date_higher_than( $params['dates_to_check'][1], $my_day_tag ) ) ) {
1087 $is_skip_check__from_today_unavailable = true;
1088 }
1089 }
1090
1091 if ( ! $is_skip_check__from_today_unavailable ) {
1092
1093 // Unavailable days from today >>> 'from_today_unavailable'.
1094 $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__day_status__from_today_unavailable( $availability_per_day, $my_day_tag, $resource_id );
1095
1096 // Limit available days from today >>> 'limit_available_from_today'.
1097 $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__day_status__limit_available_from_today( $availability_per_day, $my_day_tag, $resource_id );
1098 }
1099 }
1100 //==========================================================================================================
1101
1102
1103 // T O O L T I P :: Times - Unavailable Day
1104 if ( in_array( $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status, array( 'season_filter',
1105 'resource_availability',
1106 'weekday_unavailable',
1107 'from_today_unavailable',
1108 'limit_available_from_today'
1109 ) )
1110 ){
1111 $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__tooltip_times__set_full_day( $availability_per_day, $my_day_tag, $resource_id
1112 , $resource_id__with_children__arr, __( 'Unavailable', 'booking' ) );
1113 }
1114
1115
1116 // =========================================================================================================
1117 // Entire D A Y statuses
1118 // =========================================================================================================
1119
1120 if ( $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable ) {
1121 // Set merged time interval as fully unavailable.
1122 $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots['merged_seconds'] = array( array( 0, 86400 ) ); // FixIn: 10.11.5.1.
1123 // Reduce DAY day_availability, if some season or days unavailable or full by bookings.
1124 --$availability_per_day[ $my_day_tag ]['day_availability'];
1125 }
1126
1127 // 'resource_availability' | 'weekday_unavailable' | 'from_today_unavailable' | 'limit_available_from_today' | 'season_filter' | 'full_day_booking' | 'time_slots_booking' | 'available'.
1128 $availability_per_day[ $my_day_tag ]['statuses']['day_status'][] = $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status;
1129
1130 // 'approved' | 'pending'.
1131 $availability_per_day[ $my_day_tag ]['statuses']['bookings_status'][] = implode( '|', $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved );
1132
1133 // Go to next child booking resource.
1134 }
1135
1136 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1137 // R E S O U R C E S - E n d
1138 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1139
1140
1141 // -------------------------------------------------------------------------------------------------------------
1142 // Day summary :
1143 // -------------------------------------------------------------------------------------------------------------
1144 $availability_per_day[ $my_day_tag ] = wpbc_update_summary_availability_per_this_day( $availability_per_day[ $my_day_tag ], $my_day_tag, $resource_id__with_children__arr );
1145
1146 // Go next day + 1 day
1147 $today_inix_timestamp += 24 * 60 * 60;
1148 }
1149
1150
1151 return array(
1152 'dates' => $availability_per_day
1153 , 'resources_id_arr__in_dates' => $resource_id__with_children__arr
1154 , 'aggregate_resource_id_arr' => $aggregate_resource_id_arr
1155 );
1156 }
1157
1158
1159 // <editor-fold defaultstate="collapsed" desc=" == S U P P O R T == " >
1160
1161
1162 // S U P P O R T
1163
1164 /**
1165 * Update Summary statuses for the Day
1166 *
1167 * @param $availability_per_this_day
1168 * @param $my_day_tag
1169 * @param $resource_id_arr
1170 *
1171 * @return mixed
1172 *
1173 *
1174 * Dates Status Concept Strategy ::
1175 *
1176 * Check date booking status based on 'all booking resources':
1177 * ( and as one common situation, when we have only 1 resource )
1178 *
1179 * | 'approved' - when all booking resources has approved FULL day bookings or some booking resource unavailable
1180 * | 'pending' - when at least one booking in one booking resource has pending status and there is no available booking resources
1181 * | 'times_partially_booked' - when at least one booking in one booking resource has time bookings and there is no available booking resources
1182 * and if all time slot approved then status approved
1183 * otherwise if at least one time slot booking has pending status then it has pending status
1184 *
1185 * if all 'time_slots' booked (it's time slot passed into function as parameter)
1186 * then such date in specific booking resource has pending or approved status, based on 'pending'|'approved' rule
1187 *
1188 * | 'check_in' - if activated 'change over days' and all bookings have 'check-in' status
1189 * | 'check_out' - if activated 'change over days' and all bookings have 'check-out' status
1190 * | if in booking resource exist both check in/out bookings, and activated 'change over days'
1191 * then such booking resource date has approved or pending status depends on from status of these bookings
1192 * | 'season_unavailable' - if all booking resources defined as unavailable at Booking > Resources > Availability page
1193 * | 'resource_unavailable' - if all booking resources defined as unavailable at Booking > Availability page
1194 * | 'other_unavailable' - if all booking resources defined as unavailable at Booking > Settings General page in "Availability" section
1195 *
1196 */
1197 function wpbc_update_summary_availability_per_this_day( $availability_per_this_day, $my_day_tag, $resource_id_arr ){
1198
1199 // -------------------------------------------------------------------------------------------------------------
1200 // Summary Tooltips
1201 // -------------------------------------------------------------------------------------------------------------
1202 $availability_per_this_day['summary']['tooltip_times'] = wpbc_support_capacity__tooltip__summary__times( $availability_per_this_day, $my_day_tag, $resource_id_arr );
1203 $availability_per_this_day['summary']['tooltip_booking_details'] = wpbc_support_capacity__tooltip__summary__booked_details( $availability_per_this_day, $my_day_tag, $resource_id_arr );
1204 $availability_per_this_day['summary']['tooltip_day_cost'] = wpbc_support_capacity__tooltip__summary__day_cost( $availability_per_this_day, $my_day_tag, $resource_id_arr );
1205 $availability_per_this_day['summary']['tooltip_availability'] = wpbc_support_capacity__tooltip__summary__availability( $availability_per_this_day, $my_day_tag, $resource_id_arr );
1206
1207
1208 $availability_per_this_day['summary']['hint__in_day__cost'] = wpbc_support_capacity__in_day_hint__summary__day_cost( $availability_per_this_day, $my_day_tag, $resource_id_arr );
1209 $availability_per_this_day['summary']['hint__in_day__availability'] = wpbc_support_capacity__in_day_hint__summary__availability( $availability_per_this_day, $my_day_tag, $resource_id_arr ); // FixIn: 10.6.4.1.
1210
1211 // -------------------------------------------------------------------------------------------------------------
1212 // ['summary']['status_for_day']
1213 // -------------------------------------------------------------------------------------------------------------
1214 $temp_status = array();
1215 foreach ( $availability_per_this_day['statuses']['day_status'] as $bookings_status_arr ) {
1216 $bookings_status_arr = explode( '|', $bookings_status_arr );
1217 foreach ( $bookings_status_arr as $bookings_status_element ) {
1218 $temp_status[] = $bookings_status_element;
1219 }
1220 }
1221 $temp_status = array_filter( $temp_status ); // All entries of array equal to FALSE (0, '', '0' ) will be removed.
1222 $temp_status = array_unique( $temp_status ); // Erase duplicates
1223 $availability_per_this_day['summary']['status_for_day'] = $temp_status;
1224
1225 /**
1226 * Possible day statuses (searched by value of _day_status):
1227 *
1228 * available
1229 * time_slots_booking
1230 * full_day_booking
1231 *
1232 * limit_available_from_today
1233 * from_today_unavailable
1234 * weekday_unavailable
1235 * resource_availability
1236 * season_filter
1237 *
1238 * change_over
1239 * check_out
1240 * check_in
1241 * 'mixed' from check_in/check_out/change_over
1242 */
1243
1244 // Priority: available > time_slots_booking > full_day_booking
1245 // > season_filter > resource_availability
1246 // > weekday_unavailable > from_today_unavailable > limit_available_from_today
1247
1248 // if at least one booking "available" then day has this status
1249 if ( in_array( 'available', $availability_per_this_day['summary']['status_for_day'] ) ) { $availability_per_this_day['summary']['status_for_day'] = 'available';
1250 } else if ( in_array( 'time_slots_booking', $availability_per_this_day['summary']['status_for_day'] ) ) { $availability_per_this_day['summary']['status_for_day'] = 'time_slots_booking';
1251 } else if ( ( ! in_array( 'check_out', $availability_per_this_day['summary']['status_for_day'] ) )
1252 && ( in_array( 'check_in', $availability_per_this_day['summary']['status_for_day'] ) ) ) { $availability_per_this_day['summary']['status_for_day'] = 'check_in';
1253 } else if ( ( ! in_array( 'check_in', $availability_per_this_day['summary']['status_for_day'] ) )
1254 && ( in_array( 'check_out', $availability_per_this_day['summary']['status_for_day'] ) ) ) { $availability_per_this_day['summary']['status_for_day'] = 'check_out';
1255 } else if ( in_array( 'full_day_booking', $availability_per_this_day['summary']['status_for_day'] ) ) { $availability_per_this_day['summary']['status_for_day'] = 'full_day_booking';
1256 } else if ( in_array( 'season_filter', $availability_per_this_day['summary']['status_for_day'] ) ) { $availability_per_this_day['summary']['status_for_day'] = 'season_filter';
1257 } else if ( in_array( 'resource_availability', $availability_per_this_day['summary']['status_for_day'] ) ) { $availability_per_this_day['summary']['status_for_day'] = 'resource_availability';
1258 } else if ( in_array( 'weekday_unavailable', $availability_per_this_day['summary']['status_for_day'] ) ) { $availability_per_this_day['summary']['status_for_day'] = 'weekday_unavailable';
1259 } else if ( in_array( 'from_today_unavailable', $availability_per_this_day['summary']['status_for_day'] ) ) { $availability_per_this_day['summary']['status_for_day'] = 'from_today_unavailable';
1260 } else if ( in_array( 'limit_available_from_today', $availability_per_this_day['summary']['status_for_day'])){ $availability_per_this_day['summary']['status_for_day'] = 'limit_available_from_today';
1261 } else {
1262 $availability_per_this_day['summary']['status_for_day'] = implode( ' ', $availability_per_this_day['summary']['status_for_day'] );
1263 }
1264
1265
1266 // -------------------------------------------------------------------------------------------------------------
1267 // ['summary']['status_for_bookings']
1268 // -------------------------------------------------------------------------------------------------------------
1269 $temp_status = array();
1270 foreach ( $availability_per_this_day['statuses']['bookings_status'] as $bookings_status_arr ) {
1271 $bookings_status_arr = explode( '|', $bookings_status_arr );
1272 foreach ( $bookings_status_arr as $bookings_status_element ) {
1273 $temp_status[] = $bookings_status_element;
1274 }
1275 }
1276 $temp_status = array_filter( $temp_status ); // All entries of array equal to FALSE (0, '', '0' ) will be removed.
1277 $temp_status = array_values( array_unique( $temp_status ) );
1278
1279 // Structured booking statuses contract. Keep numeric keys sequential so JSON encodes this as a JS array.
1280 $availability_per_this_day['summary']['status_for_bookings_arr'] = $temp_status;
1281
1282 // Priority: pending > approved > ''
1283
1284 // if at least one booking pending then day is pending
1285 if ( in_array( 'pending', $temp_status ) ) { $availability_per_this_day['summary']['status_for_bookings'] = 'pending';
1286 } else if ( in_array( 'pending_pending', $temp_status ) ) { $availability_per_this_day['summary']['status_for_bookings'] = 'pending_pending';
1287 // Usual situations for change over days: pending_pending | pending_approved | approved_pending | approved_approved
1288 } else {
1289 $availability_per_this_day['summary']['status_for_bookings'] = implode( ' ', $temp_status );
1290 }
1291
1292
1293 // -------------------------------------------------------------------------------------------------------------
1294 return $availability_per_this_day;
1295 }
1296
1297
1298 // T O O L T I P s
1299
1300 /**
1301 * Set tooltip summary -- Time-Slots
1302 *
1303 * @param $availability_per_this_day
1304 * @param $my_day_tag
1305 * @param $resource_id_arr
1306 *
1307 * @return string - tooltip content or ''
1308 */
1309 function wpbc_support_capacity__tooltip__summary__times( $availability_per_this_day, $my_day_tag, $resource_id_arr ){
1310
1311 $tooltip = '';
1312
1313 if ( 'On' != get_bk_option( 'booking_disable_timeslots_in_tooltip' ) ) { //FixIn: 9.5.0.2.2
1314
1315 $tooltip_title_word = get_bk_option( 'booking_highlight_timeslot_word' );
1316 $tooltip_title_word = wpbc_lang( $tooltip_title_word );
1317 $tooltip_title_word = ( empty( $tooltip_title_word ) )
1318 ? ''
1319 : '<div class="wpbc_tooltip_title">' . $tooltip_title_word . '</div>' . ' ';
1320
1321 $status_summary_tooltip_times = array();
1322 foreach ( $resource_id_arr as $resource_id ) {
1323 if ( ! empty( $availability_per_this_day[ $resource_id ]->tooltips['times'] ) ) {
1324 $status_summary_tooltip_times[] = $availability_per_this_day[ $resource_id ]->tooltips['times'];
1325 }
1326 }
1327
1328 if ( ! empty( $status_summary_tooltip_times ) ) {
1329
1330 $tooltip = '<div class="wpbc_tooltip_section tooltip__times">'
1331 . $tooltip_title_word
1332 . implode( '', $status_summary_tooltip_times )
1333 . '</div>';
1334 }
1335 }
1336
1337 return $tooltip;
1338 }
1339
1340 function wpbc_support_capacity__tooltip__summary__availability( $availability_per_this_day, $my_day_tag, $resource_id_arr ){
1341
1342 $tooltip = '';
1343
1344 if ( ( 'On' == get_bk_option( 'booking_is_show_availability_in_tooltips' ) ) && ( $availability_per_this_day['max_capacity'] > 1 ) ) {
1345
1346 $tooltip_title_word = get_bk_option( 'booking_highlight_availability_word' );
1347 $tooltip_title_word = wpbc_lang( $tooltip_title_word );
1348 $tooltip_title_word = ( empty( $tooltip_title_word ) )
1349 ? ''
1350 : '<div class="wpbc_tooltip_title">' . $tooltip_title_word . '</div>' . ' ';
1351
1352 $tooltip_content_header = '';
1353
1354 if ( ! empty( $availability_per_this_day['day_availability'] ) ) {
1355
1356 $tooltip = '<div class="wpbc_tooltip_section tooltip__availability">'
1357 . $tooltip_title_word
1358 . '<div class="wpbc_tooltip_resource_container">'
1359 . $tooltip_content_header
1360 . '<div class="wpbc_tooltip_item">'
1361 . $availability_per_this_day['day_availability']
1362 . '</div>'
1363 . '</div>'
1364 . '</div>';
1365 }
1366 }
1367 return $tooltip;
1368 }
1369
1370 function wpbc_support_capacity__tooltip__summary__day_cost( $availability_per_this_day, $my_day_tag, $resource_id_arr ){
1371
1372 $tooltip = '';
1373 if (
1374 ( ! empty( $availability_per_this_day['day_availability'] ) )
1375 && ( 'On' == get_bk_option( 'booking_is_show_cost_in_tooltips' ) )
1376 ){
1377
1378 $tooltip_title_word = get_bk_option( 'booking_highlight_cost_word' );
1379 $tooltip_title_word = wpbc_lang( $tooltip_title_word );
1380 $tooltip_title_word = ( empty( $tooltip_title_word ) )
1381 ? ''
1382 : '<div class="wpbc_tooltip_title">' . $tooltip_title_word . '</div>' . ' ';
1383
1384 if ( isset( $resource_id_arr[0] ) ) {
1385
1386 $id_of_first_resource = $resource_id_arr[0];
1387 $tooltip_content_header = '';
1388
1389 if ( ! empty( $availability_per_this_day[ $id_of_first_resource ]->date_cost_rate ) ) {
1390
1391 $cur_sym = get_bk_option( 'booking_cost_in_date_cell_currency' ); // in Booking > Settings General page in "Calendar" section
1392 //$cur_sym = wpbc_get_currency_symbol(); // in Booking > Settings > Payment page
1393
1394 $cost_text = wpbc_formate_cost_hint__no_html( $availability_per_this_day[ $id_of_first_resource ]->date_cost_rate, $cur_sym );
1395 $cost_text = html_entity_decode( $cost_text );
1396
1397 $tooltip = '<div class="wpbc_tooltip_section tooltip__day_cost">'
1398 . $tooltip_title_word
1399 . '<div class="wpbc_tooltip_resource_container">'
1400 . $tooltip_content_header
1401 . '<div class="wpbc_tooltip_item">'
1402 . $cost_text
1403 . '</div>'
1404 . '</div>'
1405 . '</div>';
1406 }
1407
1408 }
1409 }
1410 return $tooltip;
1411 }
1412
1413
1414 function wpbc_support_capacity__in_day_hint__summary__day_cost( $availability_per_this_day, $my_day_tag, $resource_id_arr ){
1415
1416 $tooltip = '';
1417 if (
1418 ( ! empty( $availability_per_this_day['day_availability'] ) )
1419 && ( 'On' == get_bk_option( 'booking_is_show_cost_in_date_cell' ) )
1420 ){
1421
1422 $id_of_first_resource = $resource_id_arr[0];
1423
1424 if ( ! empty( $availability_per_this_day[ $id_of_first_resource ]->date_cost_rate ) ) {
1425
1426 $cur_sym = get_bk_option( 'booking_cost_in_date_cell_currency' ); // in Booking > Settings General page in "Calendar" section
1427 //$cur_sym = wpbc_get_currency_symbol(); // in Booking > Settings > Payment page
1428
1429 $cost_text = $availability_per_this_day[ $id_of_first_resource ]->date_cost_rate;
1430 $cost_text = number_format( floatval( $cost_text ), wpbc_get_cost_decimals(), '.', '' );
1431 $cost_text = wp_strip_all_tags( wpbc_cost_show( $cost_text, array( 'currency' => 'CURRENCY_SYMBOL' ) ) );
1432 $cost_text = str_replace( array( 'CURRENCY_SYMBOL', '&' ), array( $cur_sym, '&amp;' ), $cost_text );
1433 $cost_text = html_entity_decode($cost_text);
1434
1435 $tooltip = '<span class="wpbc_in_date_hint__cost">' . $cost_text . '</span>';;
1436 }
1437 }
1438 return $tooltip;
1439 }
1440
1441 // FixIn: 10.6.4.1.
1442 /**
1443 * Get availability for in Day cells
1444 *
1445 * @param $availability_per_this_day
1446 * @param $my_day_tag
1447 * @param $resource_id_arr
1448 *
1449 * @return string
1450 */
1451 function wpbc_support_capacity__in_day_hint__summary__availability( $availability_per_this_day, $my_day_tag, $resource_id_arr ){
1452
1453 $tooltip = '';
1454
1455 if (
1456 ( 'On' == get_bk_option( 'booking_is_show_availability_in_date_cell' ) ) &&
1457 ( $availability_per_this_day['max_capacity'] > 1 )
1458 ) {
1459
1460 $tooltip_title_word = get_bk_option( 'booking_highlight_availability_word_in_date_cell' );
1461 $tooltip_title_word = wpbc_lang( $tooltip_title_word );
1462 $tooltip_title_word = ( empty( $tooltip_title_word ) )
1463 ? ''
1464 : '<span class="wpbc_in_date_hint__availability_title">' . $tooltip_title_word . '</span>';
1465
1466
1467 if ( ! empty( $availability_per_this_day['day_availability'] ) ) {
1468
1469 $tooltip = '<span class="wpbc_in_date_hint__availability">'
1470 . '<span class="wpbc_in_date_hint__availability_number">'
1471 . intval( $availability_per_this_day['day_availability'] )
1472 . '&nbsp;'
1473 . '</span>'
1474 . $tooltip_title_word
1475 . '</span>';
1476 $tooltip = html_entity_decode($tooltip);
1477 }
1478 }
1479 return $tooltip;
1480 }
1481
1482
1483
1484 /**
1485 * Set tooltip summary -- Booking Details
1486 *
1487 * @param $availability_per_this_day
1488 * @param $my_day_tag
1489 * @param $resource_id_arr
1490 *
1491 * @return string - tooltip content or ''
1492 */
1493 function wpbc_support_capacity__tooltip__summary__booked_details( $availability_per_this_day, $my_day_tag, $resource_id_arr ){
1494
1495 $tooltip = '';
1496
1497 if ( 'On' == get_bk_option( 'booking_is_show_booked_data_in_tooltips' ) ) { //FixIn: 9.5.0.2.2
1498
1499 $tooltip_title_word = '<div class="wpbc_tooltip_title">' . esc_html__('Booking details','booking') . '</div>';
1500
1501 $status_summary_tooltip_times = array();
1502 foreach ( $resource_id_arr as $resource_id ) {
1503 if ( ! empty( $availability_per_this_day[ $resource_id ]->tooltips['details'] ) ) {
1504
1505 if ( ! empty( $availability_per_this_day[ $resource_id ]->tooltips['resource_title'] ) ){
1506 $tooltip_content_header = '<div class="wpbc_tooltip_header">'
1507 . $availability_per_this_day[ $resource_id ]->tooltips['resource_title'] . ': '
1508 . '</div>';
1509 } else{
1510 $tooltip_content_header = '';
1511 }
1512
1513 $booking_details_text = '<div class="wpbc_tooltip_resource_container">'
1514 . $tooltip_content_header
1515 . implode( ' ', $availability_per_this_day[ $resource_id ]->tooltips['details'] )
1516 . '</div>';
1517
1518 $status_summary_tooltip_times[] = $booking_details_text;
1519 }
1520 }
1521
1522 if ( ! empty( $status_summary_tooltip_times ) ) {
1523
1524 $tooltip = '<div class="wpbc_tooltip_section tooltip__booking_details">'
1525 . $tooltip_title_word
1526 . implode( '', $status_summary_tooltip_times )
1527 . '</div>';
1528 }
1529 }
1530 return $tooltip;
1531 }
1532
1533 /**
1534 * Set Tooltip -- Booking Details
1535 *
1536 * @param $availability_per_day
1537 * @param $my_day_tag
1538 * @param $resource_id
1539 * @param $this_date_bookings
1540 * @param $booked_times__key
1541 * @param $resources_obj
1542 *
1543 * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ];
1544 */
1545 function wpbc_support_capacity__tooltip__set_for_details( $availability_per_day, $my_day_tag, $resource_id, $this_date_bookings, $booked_times__key, $resources_obj, $booked_time ) {
1546
1547 // Get booking details for tooltip, if needed
1548 if ( 'On' == get_bk_option( 'booking_is_show_booked_data_in_tooltips' ) ) {
1549
1550 $booking_id = $this_date_bookings[ $booked_times__key ]->booking_id;
1551 $this_booking_resource_id = $this_date_bookings[ $booked_times__key ]->type;
1552
1553 $booking_details_text = wpbc_support_capacity__get_booking_details(
1554 $this_date_bookings[ $booked_times__key ],
1555 $resources_obj->get__booking_resource_obj( $this_booking_resource_id )
1556 );
1557 $tooltip_text = '';
1558 $tooltip_text .= '<div class="wpbc_tooltip_item tooltip_booked_time">' . $booked_time . '</div>'; // Booked time
1559 $tooltip_text .= '<div class="wpbc_tooltip_item">' . $booking_details_text . '</div>'; // Booking details
1560
1561 $availability_per_day[ $my_day_tag ][ $resource_id ]->tooltips['details'][ $booking_id ] = $tooltip_text;
1562 }
1563
1564 return $availability_per_day[ $my_day_tag ][ $resource_id ];
1565 }
1566
1567 /**
1568 * Set Tooltip Times -- Time-Slots
1569 *
1570 * @param $availability_per_day
1571 * @param $my_day_tag
1572 * @param $resource_id
1573 * @param $resource_id_arr
1574 *
1575 * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ];
1576 */
1577 function wpbc_support_capacity__tooltip_times__set_for_times( $availability_per_day, $my_day_tag, $resource_id, $resource_id_arr ){
1578
1579 // Times Tooltip - time slot list --------------------------------------------------------------------
1580 $tooltip_content_header = '';
1581
1582 if ( count( $resource_id_arr ) > 1 ) {
1583
1584 $class_name = 'tooltip_items_count_' . count( $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots['merged_readable'] );
1585
1586 $tooltip_content_header = '<div class="wpbc_tooltip_header ' . $class_name . ' ">'
1587 . $availability_per_day[ $my_day_tag ][ $resource_id ]->tooltips['resource_title'] . ': '
1588 . '</div>';
1589 }
1590
1591 $tooltip_content_arr = array_map( function ( $item ) {
1592 return '<div class="wpbc_tooltip_item">' . $item . '</div>';
1593 }
1594 , $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots['merged_readable']
1595 );
1596
1597 $availability_per_day[ $my_day_tag ][ $resource_id ]->tooltips['times'] = '<div class="wpbc_tooltip_resource_container">'
1598 . $tooltip_content_header
1599 . implode( '', $tooltip_content_arr )
1600 . '</div>';
1601 return $availability_per_day[ $my_day_tag ][ $resource_id ];
1602 }
1603
1604 /**
1605 * Set Tooltip Times -- Full Day
1606 *
1607 * @param $availability_per_day
1608 * @param $my_day_tag
1609 * @param $resource_id
1610 * @param $resource_id_arr
1611 * @param $status_title
1612 *
1613 * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ];
1614 */
1615 function wpbc_support_capacity__tooltip_times__set_full_day( $availability_per_day, $my_day_tag, $resource_id, $resource_id_arr, $status_title ){
1616
1617 // Times Tooltip - FULL DAY --------------------------------------------------------------------
1618 $tooltip_content_header = '';
1619
1620 if ( count( $resource_id_arr ) > 1 ) {
1621
1622 $class_name = 'tooltip_items_count_1';
1623
1624 $tooltip_content_header = '<div class="wpbc_tooltip_header ' . $class_name . ' ">'
1625 . $availability_per_day[ $my_day_tag ][ $resource_id ]->tooltips['resource_title'] . ': '
1626 . '</div>';
1627 }
1628
1629 $tooltip_content_text = '<div class="wpbc_tooltip_item">' . $status_title . '</div>';
1630
1631 $availability_per_day[ $my_day_tag ][ $resource_id ]->tooltips['times'] = '<div class="wpbc_tooltip_resource_container">'
1632 . $tooltip_content_header
1633 . $tooltip_content_text
1634 . '</div>';
1635 return $availability_per_day[ $my_day_tag ][ $resource_id ];
1636 }
1637
1638
1639
1640 /**
1641 * Get parsed booking data, if required
1642 *
1643 * @param object $this_date_bookings
1644 * @param object $resource_obj
1645 *
1646 * @return string
1647 */
1648 function wpbc_support_capacity__get_booking_details( $this_date_bookings, $resource_obj ) {
1649
1650 if ( ( ! class_exists( 'wpdev_bk_biz_m' ) )
1651 || ( 'On' !== get_bk_option( 'booking_is_show_booked_data_in_tooltips' ) )
1652 ){
1653 return '';
1654 }
1655
1656 $booking_details_for_hint = '';
1657
1658 if ( isset( $this_date_bookings->form ) ) {
1659
1660 // Get shortcodes
1661 $booking_shortcodes_in_tooltips = get_bk_option( 'booking_booked_data_in_tooltips' ); // '[name] [secondname]'
1662
1663 $resource_id = $this_date_bookings->type;
1664
1665 // Get parsed booking data field values -- e.g.: [ "rangetime":"12:00 - 14:00", "secondname":"Smith",... ]
1666 $booking_data_arr = wpbc_get_parsed_booking_data_arr( $this_date_bookings->form, $resource_id, array( 'get' => 'value' ) );
1667 $booking_data_arr['booking_id'] = $this_date_bookings->booking_id;
1668 $booking_data_arr['resource_id'] = $resource_id;
1669 $booking_data_arr['resource_title'] = ( ! empty( $resource_obj ) ) ? wpbc_lang( $resource_obj->title ) : '';
1670
1671 // Replace existing shortcodes
1672 foreach ( $booking_data_arr as $replace_shortcode => $replace_value ) {
1673
1674 if ( is_null( $replace_value ) ) { $replace_value = ''; };
1675
1676 $replace_value = wpbc_replace__true_false__to__yes_no( $replace_value ); // FixIn: 9.8.9.1.
1677
1678 $booking_shortcodes_in_tooltips = str_replace( array(
1679 '[' . $replace_shortcode . ']'
1680 , '{' . $replace_shortcode . '}'
1681 )
1682 , $replace_value
1683 , $booking_shortcodes_in_tooltips
1684 );
1685 }
1686
1687 $booking_details_for_hint = $booking_shortcodes_in_tooltips;
1688
1689 // Remove all shortcodes, which is not replaced early.
1690 $booking_details_for_hint = preg_replace( '/[\[\{][a-zA-Z0-9.,_-]{0,}[\]\}]/', '', $booking_details_for_hint );
1691 }
1692
1693 return $booking_details_for_hint;
1694 }
1695
1696
1697 /**
1698 * Unset some fields from booking data for do not show personal data at front-end side
1699 *
1700 * @param object $this_date_bookings
1701 *
1702 * @return object
1703 */
1704 function wpbc_support_capacity__unset_some_fields( $this_date_bookings ) {
1705
1706 if ( isset( $this_date_bookings->form ) ) {
1707 unset( $this_date_bookings->form ); // Hide booking details
1708 }
1709
1710 if ( isset( $this_date_bookings->booking_date ) ) {
1711 unset( $this_date_bookings->booking_date ); // Confusing property of last end booking date, because we have 'sql summary booking dates arrays' for all dates and times
1712 }
1713
1714 return $this_date_bookings;
1715 }
1716
1717
1718 // D A Y S T A T U S U N A V A I L A B L E
1719
1720 /**
1721 * Set > _day_status = 'limit_available_from_today' depends on Booking > Settings General page ---> "Limit available days from today"
1722 *
1723 * @param $availability_per_day [ ... ]
1724 * @param $my_day_tag - '2023-08-08'
1725 * @param $resource_id - 2
1726 *
1727 * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ]
1728 */
1729 function wpbc_support_capacity__day_status__limit_available_from_today( $availability_per_day, $my_day_tag, $resource_id ){
1730
1731 // ----------------------------------------------------------------------------------------------------- // limit_available_from_today
1732 // 3. Limit available days from today
1733 if ( function_exists( 'wpbc_is_day_available__relative__limit_available_from_today' ) ) {
1734 if ( ! wpbc_is_day_available__relative__limit_available_from_today( $my_day_tag ) ) {
1735 // this date unavailable
1736 $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true;
1737 $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'limit_available_from_today';
1738
1739 if ( empty( $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details ) ) {
1740 $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details = array(); // Reset bookings details
1741 }
1742 }
1743 }
1744
1745 return $availability_per_day[ $my_day_tag ][ $resource_id ];
1746 }
1747
1748
1749 /**
1750 * Set > _day_status = 'from_today_unavailable' depends on Booking > Settings General page ---> "Unavailable days from today"
1751 *
1752 * @param $availability_per_day [ ... ]
1753 * @param $my_day_tag - '2023-08-08'
1754 * @param $resource_id - 2
1755 *
1756 * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ]
1757 */
1758 function wpbc_support_capacity__day_status__from_today_unavailable( $availability_per_day, $my_day_tag, $resource_id ){
1759
1760 // FixIn: 10.8.1.4.
1761
1762 // ----------------------------------------------------------------------------------------------------- // from_today_unavailable
1763 // 2. Unavailable days from today
1764 $unavailable_days_num_from_today = get_bk_option( 'booking_unavailable_days_num_from_today' );
1765
1766 // FixIn: 10.8.1.4.
1767 if ( ! empty( $unavailable_days_num_from_today ) ) {
1768 if ( 'm' === substr( $unavailable_days_num_from_today, - 1 ) ) {
1769 $start_date_unix = strtotime( '+' . ( intval( $unavailable_days_num_from_today ) - 1 ) . ' minutes' ); // + 0 days
1770 } else {
1771 $start_date_unix = strtotime( '+' . intval( $unavailable_days_num_from_today ) . ' days' ); // + 0 days
1772 }
1773 } else {
1774 $start_date_unix = strtotime( 'now' );
1775 }
1776
1777 $date_start__gmt = gmdate( 'Y-m-d H:i:s', $start_date_unix ); // '2025-01-25 12:50:10'
1778 $date_start__midnight__wp_timezone = wpbc_datetime_localized__use_wp_timezone( $date_start__gmt, 'Y-m-d 00:00:00' ); // Local Midnight.
1779
1780 // 'Today Midnight' - 'Calendar Day Cell' .
1781 $days_number = intval( ( strtotime( $date_start__midnight__wp_timezone ) - strtotime( $my_day_tag ) ) / 86400 );
1782
1783 if ( $days_number > 0 ) {
1784 // This date Unavailable.
1785 $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true;
1786 $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'from_today_unavailable';
1787
1788 if ( empty( $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details ) ) {
1789 $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details = array(); // Reset bookings details
1790 }
1791 }
1792
1793 return $availability_per_day[ $my_day_tag ][ $resource_id ];
1794 }
1795
1796
1797 /**
1798 * Set > _day_status = 'weekday_unavailable' depends on Booking > Settings General page ---> "Week Days unavailable"
1799 *
1800 * @param $availability_per_day [ ... ]
1801 * @param $my_day_tag - '2023-08-08'
1802 * @param $resource_id - 2
1803 *
1804 * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ]
1805 */
1806 function wpbc_support_capacity__day_status__weekday_unavailable( $availability_per_day, $my_day_tag, $resource_id ){
1807
1808 // 1. Week Days unavailable -------------------------------------------------------------------------------- // weekday_unavailable
1809 $unavailable_weekdays = array();
1810 foreach ( range( 0, 6 ) as $week_day_num ) {
1811 $unavailable_weekdays[ $week_day_num ] = ( 'On' == get_bk_option( 'booking_unavailable_day' . $week_day_num ) ) ? true : false;
1812 }
1813
1814 $this_day_week_num = gmdate( 'w', strtotime( $my_day_tag ) ); // 0 - 6
1815
1816 if ( $unavailable_weekdays[ $this_day_week_num ] ) {
1817 // this date unavailable
1818 $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true;
1819 $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'weekday_unavailable';
1820
1821 if ( empty( $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details ) ) {
1822 $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details = array(); // Reset bookings details
1823 }
1824 }
1825
1826 return $availability_per_day[ $my_day_tag ][ $resource_id ];
1827 }
1828
1829
1830 /**
1831 * Set > _day_status = 'resource_availability' depends on Booking > Availability page
1832 *
1833 * @param $availability_per_day [ ... ]
1834 * @param $my_day_tag - '2023-08-08'
1835 * @param $resource_id - 2
1836 * @param array $unavailable_dates__per_resources__arr - [ 2: ['2023-08-01', '2023-08-02'], 10: ['2023-08-05', '2023-08-06'] ]
1837 *
1838 * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ]
1839 */
1840 function wpbc_support_capacity__day_status__resource_availability( $availability_per_day, $my_day_tag, $resource_id, $unavailable_dates__per_resources__arr ){
1841
1842 // Booking > Availability page ----------------------------------------------------------------------------- // resource_availability
1843 /**
1844 * $unavailable_dates__per_resources__arr = Array ( [2] => Array( [0] => 2023-08-01
1845 [1] => 2023-08-02
1846 )
1847 [10] => Array( [0] => 2023-08-05
1848 [1] => 2023-08-06
1849 )
1850 )
1851 */
1852 if (
1853 ( isset( $unavailable_dates__per_resources__arr[ $resource_id ] ) )
1854 && ( in_array( $my_day_tag, $unavailable_dates__per_resources__arr[ $resource_id ] ) )
1855 ) {
1856
1857 $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true;
1858 $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'resource_availability';
1859
1860 if ( empty( $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details ) ) {
1861 $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details = array(); // Reset bookings details
1862 }
1863 }
1864
1865 return $availability_per_day[ $my_day_tag ][ $resource_id ];
1866 }
1867
1868
1869 /**
1870 * Set > _day_status = 'season_filter' depends on Booking > Resources > Availability page
1871 *
1872 * @param $availability_per_day [ ... ]
1873 * @param $my_day_tag - '2023-08-08'
1874 * @param $resource_id - 2
1875 * @param array $season_filters_availability - [...]
1876 *
1877 * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ]
1878 */
1879 function wpbc_support_capacity__day_status__season_filter( $availability_per_day, $my_day_tag, $resource_id, $season_filters_availability ){
1880
1881 if ( function_exists( 'wpbc_is_this_day_available_in_season_filters' ) ) { // BM and higher
1882
1883 $is_date_available = wpbc_is_this_day_available_in_season_filters( $my_day_tag, $resource_id, $season_filters_availability[ $resource_id ] ); // Get availability
1884 if ( ! $is_date_available ) {
1885
1886 $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true;
1887 $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'season_filter';
1888
1889 if ( empty( $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details ) ) {
1890 $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details = array(); // Reset bookings details
1891 }
1892 }
1893 }
1894
1895 return $availability_per_day[ $my_day_tag ][ $resource_id ];
1896 }
1897
1898
1899 // D A Y C O S T
1900
1901 /**
1902 * Get day cost depend on Rates
1903 * @param $my_day_tag - '2023-08-08'
1904 * @param $resource_id - 2
1905 * @param $base_cost - 25
1906 *
1907 * @return int|string
1908 */
1909 function wpbc_support_capacity__get_day_cost( $my_day_tag, $resource_id, $base_cost ) {
1910
1911 $fin_day_cost = 0;
1912 if ( function_exists( 'wpbc_get_1_day_cost_apply_rates' ) ) {
1913
1914 list( $year, $month, $day ) = explode( '-', $my_day_tag );
1915
1916 $day = intval( $day );
1917 $month = intval( $month );
1918 $year = intval( $year );
1919
1920 $fin_day_cost = wpbc_get_1_day_cost_apply_rates( $resource_id, $base_cost, $day, $month, $year );
1921 }
1922
1923 return $fin_day_cost;
1924 }
1925
1926
1927 // </editor-fold>
1928
1929
1930
1931 //TODO: M I G R A T E to 9.8
1932 // .
1933 // instead of this: <script type="text/javascript"> wpbc_settings.set_option( 'pending_days_selectable', true ); </script>
1934 // use this: <script type="text/javascript"> _wpbc.calendar__set_param_value( " . intval( $resource_id ) . ", 'pending_days_selectable' , true ); </script>
1935 // Booking Calendar - JavaScript Settings
1936 // Example or redefine some settings:
1937 // <script type="text/javascript"> wpbc_settings.set_option( 'pending_days_selectable', true ); </script>
1938 // [booking type=1]
1939 // .
1940 // .
1941 // 1. Define parameters for calendar(s):
1942 // _wpbc.calendar__set_parameters( " . intval( $resource_id ) . ", {'days_select_mode': 'single'} );
1943 // _wpbc.calendar__set_parameters( " . intval( $resource_id ) . ", {'days_select_mode': 'multiple'} );
1944 // _wpbc.calendar__set_parameters( " . intval( $resource_id ) . ", {'days_select_mode': 'fixed'} );
1945 // _wpbc.calendar__set_parameters( " . intval( $resource_id ) . ", {'fixed__days_num' : 7 } );
1946 // _wpbc.calendar__set_parameters( " . intval( $resource_id ) . ", {'fixed__week_days__start': [-1] } ); // { -1 - Any | 0 - Su, 1 - Mo, 2 - Tu, 3 - We, 4 - Th, 5 - Fr, 6 - Sat }
1947 // _wpbc.calendar__set_parameters( " . intval( $resource_id ) . ", {'days_select_mode': 'dynamic'} );
1948 // _wpbc.calendar__set_param_value( " . intval( $resource_id ) . ", 'dynamic__days_min' , 7 );
1949 // _wpbc.calendar__set_param_value( " . intval( $resource_id ) . ", 'dynamic__days_max' , 14 );
1950 // _wpbc.calendar__set_param_value( " . intval( $resource_id ) . ", 'dynamic__days_specific' , [] ); // Example [5,7]
1951 // _wpbc.calendar__set_param_value( " . intval( $resource_id ) . ", 'dynamic__week_days__start' , [-1] ); // { -1 - Any | 0 - Su, 1 - Mo, 2 - Tu, 3 - We, 4 - Th, 5 - Fr, 6 - Sat }
1952 // JavaScript functions changes:
1953 // wpbc_unselect_all_days( resource_id ) -> wpbc_calendar__unselect_all_dates( resource_id )
1954 // showErrorMessage( element , errorMessage , isScrollStop ); -> wpbc_front_end__show_message__warning( jq_node, message );
1955 // showMessageUnderElement( element , errorMessage , message_type); -> wpbc_front_end__show_message__warning_under_element( jq_node, message );
1956 // makeScroll( object_name ); -> wpbc_do_scroll( jq_node );
1957 // .
1958 // JavaScript hooks changes:
1959 // jQuery( ".booking_form_div" ).trigger( "date_selected", [ resource_id, date ] );
1960 // become
1961 // jQuery( ".booking_form_div" ).trigger( "date_selected", [ resource_id, mouse_clicked_dates, all_selected_dates_arr ] );
1962 // where:
1963 // mouse_clicked_dates Can be: "05.10.2023 - 07.10.2023" | "10.10.2023 - 10.10.2023" |
1964 // all_selected_dates_arr Can be: [ "2023-10-05", "2023-10-06", "2023-10-07", … ]
1965 // PHP actions:
1966 // from: make_bk_action('wpdev_booking_post_inserted', $booking_id, $bktype, $str_dates__dd_mm_yyyy, array($start_time, $end_time ) , $formdata );
1967 // removed!
1968 // . // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
1969 // from: apply_filters('wpdev_booking_form_content', $form , $resource_id);
1970 // to: apply_filters( 'wpbc_booking_form_html__update__append_change_over_times', $form, $resource_id );
1971 // .
1972 // Removed PHP actions:
1973 // . 'show_payment_forms__for_ajax'
1974 // * make_bk_action('wpbc_ add_new_booking' , array(
1975 // * 'bktype' => 1
1976 // * , 'dates' => '27.08.2014, 28.08.2014, 29.08.2014'
1977 // * , 'form' => 'selectbox-one^rangetime1^10:00 - 12:00~text^name1^Jo~text^secondname1^Smith~email^email1^smith@gmail.com~text^phone1^678676678~text^address1^Linkoln Street~text^city1^London~text^postcode1^78788~selectbox-one^country1^GB~selectbox-one^visitors1^1~selectbox-one^children1^1~textarea^details1^Rooms with sea view~checkbox^term_and_condition1[]^I Accept term and conditions'
1978 // * , 'is_send_emeils' => 0
1979 // * // , 'booking_form_type' => ''
1980 // * // , 'wpdev_active_locale' => 'en_US'
1981 // * ) );
1982 // .
1983 // add_bk_filter('wpbc_add_new_booking_filter' , 'wpbc_add_new_booking' );
1984 // TODO: recheck hooks in wpbc-dev-api.php
1985