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

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

1,979 lines 105.8 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 );
560
561 $params = wp_parse_args( $params, $defaults );
562
563 // FixIn: 10.7.1.2. //FixIn: 10.10.3.2.
564 if (
565 ( false !== strpos( $params['request_uri'], 'allow_past' ) ) ||
566 (
567 ( false !== strpos( $params['request_uri'], 'page=wpbc-new' ) ) &&
568 ( false !== strpos( $params['request_uri'], 'booking_hash' ) )
569 )
570 ) {
571 $params['dates_to_check'] = 'ALL';
572 }
573
574 // -----------------------------------------------------------------------------------------------------------------
575 // R e s o u r c e (s) D a t a
576 // -----------------------------------------------------------------------------------------------------------------
577 // Get array of booking resource ID [1, 13, 8, 6, 7] or default: [ 1 ]
578 $source__resource_id_arr = wpbc_get_unique_array_of_resources_id( $params['resource_id'] ); // [1, 13, 8, 6, 7]
579 //$source__resource_id_arr = wpbc_get_unique_array_of_resources_id( $params['resource_id'], $params['additional_bk_types'] ); // [1, 13, 8, 6, 7]
580 $first_resource_id = $source__resource_id_arr[0]; // First from the list, or 1 if not provided.
581
582 // Get here Obj. of booking resource (which can include CHILD booking resources)
583 $resources_obj = new WPBC_RESOURCE_SUPPORT( array(
584 'resource_id' => $source__resource_id_arr, //CSD | D
585 'as_single_resource' => $params['as_single_resource'] // If true, then skip child booking resources
586 ));
587 // Resource ID arr (Can be Parent and Child resource ID)
588 $resource_id__with_children__arr = $resources_obj->get_resource_id_arr(); // [ 2, 10, 11, 12 ]
589
590 // Get Maximum capacity of resource
591 $resource_obj = $resources_obj->get__booking_resource_obj( $first_resource_id );
592 $max_resource_capacity_int = empty( $resource_obj ) ? 1 : $resource_obj->capacity; // 1 | 4
593
594 // Get base cost of resource
595 $resource_base_cost = $resources_obj->get_resources_base_cost_arr(); // [ 0, 25, 100, 99]
596
597
598
599
600 // -----------------------------------------------------------------------------------------------------------------
601 // Get real AGGREGATE resource ID arr
602 // -----------------------------------------------------------------------------------------------------------------
603 $real_resource_id_arr = wpbc_get_unique_array_of_resources_id( $params['resource_id'] ); // [ 1 ]
604 if ( empty( $params['additional_bk_types'] ) ) {
605 $aggregate_resource_id_arr = array();
606 } else {
607 $aggregate_resource_id_arr = wpbc_get_unique_array_of_resources_id( $params['additional_bk_types'] ); // [1, 13, 8, 6, 7]
608 }
609 // Excluding from 'additional_bk_types' all resources in 'resource_id'
610 $aggregate_resource_id_arr = array_diff( $aggregate_resource_id_arr, $real_resource_id_arr ); // [ 13, 8, 6, 7 ]
611 $aggregate_resource_id_arr = array_values( $aggregate_resource_id_arr ); // reindex array, for ability to transfer array instead of obj to JS client side.
612
613 $params['aggregate_params'] = array(
614 'aggregate_resource_id_arr' => $aggregate_resource_id_arr,
615 'resource_id__with_children__arr' => $resource_id__with_children__arr
616 );
617
618 // -----------------------------------------------------------------------------------------------------------------
619 // B o o k i n g s
620 // -----------------------------------------------------------------------------------------------------------------
621 // Main function to get "Bookings": ['2023-08-30'][ > resource_id < ][ > time_seconds_range < ] => booking_date_obj[ booking_id:45, approved:1, ...
622 $bookings__in_dates = wpbc_get__booked_dates__per_resources__arr( $params );
623
624 // -----------------------------------------------------------------------------------------------------------------
625 // Time slots availability blocks.
626 // -----------------------------------------------------------------------------------------------------------------
627 $availability_timeslots__in_dates = array(); // FixIn: 10.16.1.
628
629
630
631 // -----------------------------------------------------------------------------------------------------------------
632 // Booking > Availability page
633 // -----------------------------------------------------------------------------------------------------------------
634 $search_dates = $params['dates_to_check']; // 'CURDATE' | 'ALL' | [ "2023-08-03" , "2023-08-04" , "2023-08-05" ]
635
636 //FixIn: 9.8.15.10 Aggregate or not Aggregate Booking > Availability ? aggregate_type = 'all' | 'bookings_only'
637 if ( ( ! empty( $params['aggregate_type'] ) ) && ( 'bookings_only' === $params['aggregate_type'] ) ) { // FixIn: 9.9.0.16.
638 $unavailable_dates__per_resources__arr = wpbc_for_resources_arr__get_unavailable_dates(
639 $resource_id__with_children__arr, // Only One Primary Resource !!
640 $search_dates
641 ); // [ 2: ['2023-08-01', '2023-08-02'], 10: ['2023-08-05', '2023-08-06'] ]
642 } else {
643 $unavailable_dates__per_resources__arr = wpbc_for_resources_arr__get_unavailable_dates(
644 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
645 $search_dates
646 ); // [ 2: ['2023-08-01', '2023-08-02'], 10: ['2023-08-05', '2023-08-06'] ]
647 }
648 $unavailable_dates__per_resources__arr = wpbc_aggregate_merge_availability( $unavailable_dates__per_resources__arr,
649 $resource_id__with_children__arr,
650 $aggregate_resource_id_arr );
651 // FixIn: 10.16.1.
652 if ( function_exists( 'wpbc_availability_timeslots__get_intervals_for_resources' ) ) {
653 $availability_timeslots__resource_ids = wpbc_get_unique_array_of_resources_id( $resource_id__with_children__arr, $aggregate_resource_id_arr );
654 $availability_timeslots__in_dates = wpbc_availability_timeslots__get_intervals_for_resources(
655 array(
656 'resource_id' => $availability_timeslots__resource_ids,
657 'dates_to_check' => $search_dates,
658 'max_days_count' => $params['max_days_count'],
659 )
660 );
661
662 if ( function_exists( 'wpbc_availability_timeslots__aggregate_merge_intervals' ) ) {
663 $availability_timeslots__in_dates = wpbc_availability_timeslots__aggregate_merge_intervals(
664 $availability_timeslots__in_dates,
665 $resource_id__with_children__arr,
666 $aggregate_resource_id_arr
667 );
668 }
669 }
670
671 // -----------------------------------------------------------------------------------------------------------------
672 // Booking > Resources > Availability page
673 // -----------------------------------------------------------------------------------------------------------------
674 $season_filters_availability = array();
675 if ( class_exists('wpdev_bk_biz_m') ) {
676 foreach ( $resource_id__with_children__arr as $resource_id_for_season ) {
677 $season_filters_availability[ $resource_id_for_season ] = apply_bk_filter( 'get_available_days', $resource_id_for_season );
678 }
679 }
680
681
682
683
684 // -----------------------------------------------------------------------------------------------------------------
685 // P a r a m e t e r s f o r L O O P
686 // -----------------------------------------------------------------------------------------------------------------
687
688 // - Is this Booking > Add booking page ? --------------------------------------------------------------------------
689 $is_this_bap_page = ( false !== strpos( $params['request_uri'], 'page=wpbc-new' ) ) ? true : false;
690 $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
691
692 // FixIn: 10.7.1.2.
693 if ( ! $is_this_hash_page ) {
694 $is_this_hash_page = ( false !== strpos( $params['request_uri'], 'allow_past' ) ) ? true : false;
695 }
696
697 if ( ( $is_this_bap_page ) && ( $is_this_hash_page ) ) { // Start days in calendar from = PAST
698 $params['dates_to_check'] = 'ALL';
699 }
700
701 if ( 'ALL' == $params['dates_to_check'] ) { // All dates -> ''
702
703 $start_day_number = - 1 * $params['max_days_count'];
704 //$today_inix_timestamp = strtotime( '-' . intval( $params['max_days_count'] ) . ' days' ); // - 300 days
705
706 // Get time, relative to Timezone from WordPress > Settings General page // FixIn: 9.9.0.17.
707 $start_date_unix = strtotime( '-' . intval( $params['max_days_count'] ) . ' days' ); // - 365 days
708 $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' );
709 $today_inix_timestamp = strtotime( $date_with_wp_timezone );
710
711 } else if ( 'CURDATE' == $params['dates_to_check'] ) { // Current dates -> CURDATE
712
713 $start_day_number = 1;
714 // $today_inix_timestamp = strtotime( gmdate( 'Y-m-d 00:00:00', strtotime( 'now' ) ) ); // Today 00:00:00
715
716 // Get time, relative to Timezone from WordPress > Settings General page // FixIn: 9.9.0.17.
717 $start_date_unix = strtotime( 'now' );
718 $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' );
719 $today_inix_timestamp = strtotime( $date_with_wp_timezone );
720
721 } else if ( is_array( $params['dates_to_check'] ) ) {
722
723 $start_day_number = 1;
724
725 $today_inix_timestamp = strtotime( $params['dates_to_check'][0] . ' 00:00:00' ); // '2023-09-03 00:00:00'
726
727 $dif_in_days = strtotime( $params['dates_to_check'][ ( count( $params['dates_to_check'] ) - 1 ) ] . ' 00:00:00' )
728 - strtotime( $params['dates_to_check'][0] . ' 00:00:00' );
729
730 $dif_in_days = $dif_in_days / ( 24 * 60 * 60 );
731 $params['max_days_count'] = ceil( $dif_in_days ) + 1;
732 }
733
734
735 // Get Time Slots from booking form for Each date: [ '2023-10-25' => [ '12:20 - 12:55', '13:00 - 14:00' ], '2023-10-26' => [ ... ], ... ]
736 $readable_timeslots_arr__in_dates_arr__to_check_intersect = wpbc_get_times_fields_configuration__by_dates(
737 $first_resource_id, // Resource ID (used in case of MultiUser version for getting specific form for regular users)
738 $params['custom_form'], // Form name for getting time slots configuration
739 $today_inix_timestamp, // start_date_unix_timestamp
740 ( $params['max_days_count'] - $start_day_number ) // days_count
741 );
742
743 // =================================================================================================================
744 // -- Here are GO
745 // =================================================================================================================
746 $availability_per_day = array();
747
748 for ( $day_num = $start_day_number; $day_num <= $params['max_days_count']; $day_num ++ ) {
749
750 $my_day_tag = gmdate( 'Y-m-d', $today_inix_timestamp ); // '2023-07-19'
751
752
753 //--------------------------------------------------------------------------------------------------------------
754 // 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
755 $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 );
756 /*
757 // TODO: check this, if it's required ? // If empty, maybe get default 'timeslots_to_check_intersect' from root of this function parameters ????
758 if ( empty( $as_seconds_timeslots_arr__to_check_intersect ) ) {
759
760
761 if ( ! is_array( $params[ 'timeslots_to_check_intersect' ] ) ) { // Root parameters from this function
762 $params[ 'timeslots_to_check_intersect' ] = array( $params[ 'timeslots_to_check_intersect' ] );
763 }
764
765 $as_seconds_timeslots_arr__to_check_intersect = array();
766 foreach ( $params[ 'timeslots_to_check_intersect' ] as $time_slot_readable ) {
767 $as_seconds_timeslots_arr__to_check_intersect[] = wpbc_convert__readable_time_slot__to__time_range_in_seconds( $time_slot_readable );
768 }
769 }
770 */
771 //--------------------------------------------------------------------------------------------------------------
772
773
774 $availability_per_day[ $my_day_tag ] = array();
775
776 // 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
777 $availability_per_day[ $my_day_tag ]['day_availability'] = $max_resource_capacity_int; // 4
778 $availability_per_day[ $my_day_tag ]['max_capacity'] = $max_resource_capacity_int; // 4
779 $availability_per_day[ $my_day_tag ]['statuses'] = array();
780 $availability_per_day[ $my_day_tag ]['statuses']['day_status'] = array(); // per each child booking resource
781 $availability_per_day[ $my_day_tag ]['statuses']['bookings_status'] = array(); // per each child booking resource
782 $availability_per_day[ $my_day_tag ]['summary'] = array();
783 $availability_per_day[ $my_day_tag ]['summary']['status_for_day'] = ''; // available | time_slots_booking | full_day_booking | ...
784 $availability_per_day[ $my_day_tag ]['summary']['status_for_bookings'] = ''; // pending | approved | CO: pending_pending | pending_approved | approved_pending | approved_approved
785 $availability_per_day[ $my_day_tag ]['summary']['tooltip_times'] = '';
786 $availability_per_day[ $my_day_tag ]['summary']['tooltip_availability'] = '';
787 $availability_per_day[ $my_day_tag ]['summary']['tooltip_day_cost'] = '';
788 $availability_per_day[ $my_day_tag ]['summary']['tooltip_booking_details'] = '';
789
790
791 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
792 // R E S O U R C E S - S t a r t
793 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
794 foreach ( $resource_id__with_children__arr as $resource_id ) { // [1, 13, 8, 6, 7]
795
796 $availability_per_day[ $my_day_tag ][ $resource_id ] = new stdClass();
797 $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = false;
798 $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'available';
799 $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved = array();
800 $availability_per_day[ $my_day_tag ][ $resource_id ]->tooltips = array(
801 'resource_title' => $resources_obj->get_resource_title( $resource_id ),
802 'times' => '',
803 'details' => array()
804 );
805 $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots = array(
806 'in_seconds' => array(), // seconds
807 'readable24h' => array(), // readable 24H - for debug only
808 'merged_seconds' => array(), // seconds (reduced number of time_ranges)
809 'merged_readable' => array() // readable 12AM
810 );
811 // Day Cost / Rates ---------------------------------------------------------------------------------------
812 $fin_day_cost = wpbc_support_capacity__get_day_cost( $my_day_tag, $resource_id, $resource_base_cost[ $resource_id ] );
813 $availability_per_day[ $my_day_tag ][ $resource_id ]->date_cost_rate = $fin_day_cost;
814
815
816 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
817 // B O O K I N G S - S t a r t
818 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
819
820 if ( ( isset( $bookings__in_dates[ $my_day_tag ] ) )
821 && ( isset( $bookings__in_dates[ $my_day_tag ][ $resource_id ] ) ) ){
822
823 $this_date_bookings = $bookings__in_dates[ $my_day_tag ][ $resource_id ]; // [ [36011 - 86392] => stdClass Object( [approved] => 1 , ... ) ,... ]
824 ksort( $this_date_bookings );
825 $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details = $this_date_bookings;
826
827 } else {
828 $this_date_bookings = array();
829 }
830
831
832 /**
833 * If bookings exist then:
834 * 1. Removing some properties here to hide personal details,
835 * 2. Set Approved / Pending status of the bookings
836 * 3. By default, set "_day_status" as 'time_slots_booking' ( later we will change to 'full_day_booking', if applied )
837 */
838 if ( ! empty( $this_date_bookings ) ) {
839
840 // =====================================================================================================
841 // T i m e s - Start
842 // =====================================================================================================
843 foreach ( $this_date_bookings as $booked_times__key => $booked_times__value ) {
844
845 // By default, set "_day_status" as 'time_slots_booking' ( later we will change to 'full_day_booking', if applied )
846 $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'time_slots_booking';
847
848 // -------------------------------------------------------------------------------------------------
849 // Get Time-Slot
850 if ( false === strpos( $booked_times__key, '-' ) ) { // Full day ? - 0 == $booked_times__key
851 $time_range__seconds__arr = array( 0, 86400 ); // 24 * 60 * 60
852 } else {
853 $time_range__seconds__arr = wpbc_transform_timerange__s_range__in__seconds_arr( $booked_times__key ); // '43211 - 86392' into [43211, 86400]
854 }
855
856 // Real time: [43211, 86400]
857 $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots['in_seconds'][] = $time_range__seconds__arr;
858
859 // For DEBUG only -- Readable 24H: '10:00:01 - 12:30:02'
860 $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 );
861
862 // -------------------------------------------------------------------------------------------------
863 // 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
864 $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved[ $time_range__seconds__arr[0] ] = ( '1' == $booked_times__value->approved ) ? 'approved' : 'pending';
865
866
867 // T O O L T I P :: Booking Details
868 $booked_time_title = ( ( 0 == $time_range__seconds__arr[0] ) && ( $time_range__seconds__arr[1] >= 86400 ) )
869 ? __( 'Full day', 'booking' )
870 : wpbc_transform_timerange__seconds_arr__in__formated_hours( $time_range__seconds__arr );
871 $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__tooltip__set_for_details( $availability_per_day, $my_day_tag, $resource_id,
872 $this_date_bookings, $booked_times__key, $resources_obj, $booked_time_title );
873
874 // Unset ...->form and other fields...
875 $this_date_bookings[ $booked_times__key ] = wpbc_support_capacity__unset_some_fields( $this_date_bookings[ $booked_times__key ] );
876
877 } // T i m e s - E n d Booked Times Loop - for current resource
878
879
880 // =====================================================================================================
881 // Merge intersected time intervals =
882 // =====================================================================================================
883 $merged_seconds_arr = wpbc_merge_intersected_intervals( $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots['in_seconds'] );
884
885 $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots['merged_seconds'] = $merged_seconds_arr;
886
887 foreach ( $merged_seconds_arr as $booked_time_slots__in_seconds ) {
888 $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 );
889 }
890
891 // T O O L T I P :: Times
892 $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 );
893
894 // =====================================================================================================
895 // End times
896 // =====================================================================================================
897
898
899 // 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...
900 ksort( $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved );
901
902 // array_keys( $booked_time_slots ) can be: [0] -> 'Full day' | ['36011 - 43192', '56011 - 86392'] -> '10:00 - 12:00', '15:55 - 24:00'
903 $booked_time_slots = array_keys( $this_date_bookings );
904
905
906 // =====================================================================================================
907 // Full day booking ----------------------------------------------------------------------------------- full_by_bookings
908 // =====================================================================================================
909 if ( in_array( '0', $booked_time_slots ) ) {
910
911 $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true;
912 $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'full_day_booking';
913
914 // Reset all other possible time slot statuses, in general they must not exist, but for some case
915 $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved = array();
916
917 // Pending or approved, for full day booking: $this_date_bookings['0']
918 $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved[] = ( '1' == $this_date_bookings['0']->approved ) ? 'approved' : 'pending';
919
920 // T O O L T I P :: Times - Full Day Booked
921 $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__tooltip_times__set_full_day( $availability_per_day, $my_day_tag, $resource_id
922 , $resource_id__with_children__arr, __( 'Full day', 'booking' ) );
923
924 } // end 'full day' if
925
926
927 // =====================================================================================================
928 // All time slots booked ? -----------------------------------------------------------------------------
929 // =====================================================================================================
930 if (
931 ( ! empty( $as_seconds_timeslots_arr__to_check_intersect ) ) // We need to check intersection with some time slot '36011 - 43192'
932 && ( ! $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable ) // And this date still free false
933 ){
934
935 $is_some_timeslot_available = wpbc_is_some_timeslot__available__in_arr( $as_seconds_timeslots_arr__to_check_intersect, $booked_time_slots );
936
937 // ------------------------------------------------------------------------------------------------- full_by_bookings
938 if ( ! $is_some_timeslot_available ) {
939 // All time slots booked !!!
940
941 $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true;
942 $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'full_day_booking';
943 $availability_per_day[ $my_day_tag ][ $resource_id ]->_booking_form_timeslots_unavailable = implode( '|', $params[ 'timeslots_to_check_intersect' ] );
944
945 // T O O L T I P :: Times - Full Day Booked
946 $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__tooltip_times__set_full_day( $availability_per_day, $my_day_tag, $resource_id
947 , $resource_id__with_children__arr, __( 'Full day', 'booking' ) );
948 } else {
949 // Some time slots available or there is no time slot passed in this function
950 }
951
952 } // end 'all time slots booked' if
953
954
955
956 // =====================================================================================================
957 // Change over days =
958 // =====================================================================================================
959 if (
960 ( function_exists( 'wpbc_is_booking_used_check_in_out_time' ) )
961 && ( wpbc_is_booking_used_check_in_out_time( $params[ 'request_uri' ] ) )
962 && ( ! $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable ) // And this date still free false
963 ) {
964
965 /**
966 * "Change over days" - possible situations: check_in | check_out | change_over | ...
967 *
968 * $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = check_in
969 * | check_out
970 * | change_over
971 * | 'mixed'
972 * 'mixed' - e.g. 'change_over check_out' where several child resources and some is 'change_over' and others are 'check_out'
973 *
974 *
975 * Possible situations for change-over days:
976 *
977 * // A. If in $booked_time_slots array one of values (or in $this_date_bookings one of keys)
978 * // 1. Started with time that is ended with 1 second
979 * // 2. and Ended with '24:00' it is means '86392', like this: '28811 - 86392'
980 * // then it's means that we have 'check_in' time here
981 *
982 * // B. If in $booked_time_slots array one of values (or in $this_date_bookings one of keys)
983 * // 1. Started with '00:00' it is means '1'
984 * // 2. and Ended time that is ended with 2 second
985 * // like this: '1 - 32402'
986 * // then it's means that we have 'check_out' time here
987 *
988 * // C. If we have A. and B. then we have 'change_over' here
989 */
990
991 $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out = array();
992
993 foreach ( $this_date_bookings as $booked_times__key => $booked_times__value ) {
994
995 if ( false === strpos( $booked_times__key, '-' ) ) {
996 continue; // for situation with FULL day booking, here $booked_times__key = 0
997 }
998
999 $rangeA_arr = explode( '-', $booked_times__key );
1000 $rangeA_arr[0] = intval( trim( $rangeA_arr[0] ) );
1001 $rangeA_arr[1] = intval( trim( $rangeA_arr[1] ) );
1002
1003 // start time
1004 $is_starttime__check_in = $rangeA_arr[0] % 10; // 0, 1, 2
1005 $is_starttime__check_in = ( 1 == $is_starttime__check_in ) ? true : false;
1006
1007 // end time
1008 $is_endtime__check_out = $rangeA_arr[1] % 10;
1009 $is_endtime__check_out = ( 2 == $is_endtime__check_out ) ? true : false;
1010
1011
1012 if ( ( $is_starttime__check_in ) && ( WPBC_FULL_DAY_TIME_OUT == $rangeA_arr[1] ) ) { // A :: start_time - 86392 e.g. 14:00 - 24:00
1013 // only "check in" time here
1014 $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out[] = 'check_in';
1015
1016 } else if ( ( WPBC_FULL_DAY_TIME_IN == $rangeA_arr[0] ) && ( $is_endtime__check_out ) ) { // B :: 1 - end_time e.g. 00:00 - 10:00
1017 // only "check out" time here
1018 $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out[] = 'check_out';
1019 }
1020
1021 }
1022 $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out = array_unique( $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out );
1023 $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.
1024
1025 if (
1026 ( in_array( 'check_in', $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out ) )
1027 && ( in_array( 'check_out', $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out ) )
1028 ) {
1029 $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out = array( 'change_over' ); // both check in / out times here
1030 $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true;
1031
1032 // Possible statuses: pending_pending | pending_approved | approved_pending | approved_approved
1033 $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved = array( implode( '_', $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved ) );
1034 }
1035
1036 $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out = implode( '|', $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out );
1037
1038 if ( ! empty( $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out ) ) {
1039 $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out;
1040 }
1041 } // end change-over if
1042
1043
1044 }
1045 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1046 // B O O K I N G S - E n d
1047 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1048 // FixIn: 10.16.1.
1049 if (
1050 function_exists( 'wpbc_availability_timeslots__apply_blocks_to_availability_obj' )
1051 && isset( $availability_timeslots__in_dates[ $my_day_tag ][ $resource_id ] )
1052 ) {
1053 $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_availability_timeslots__apply_blocks_to_availability_obj(
1054 $availability_per_day[ $my_day_tag ][ $resource_id ],
1055 $availability_timeslots__in_dates[ $my_day_tag ][ $resource_id ],
1056 $as_seconds_timeslots_arr__to_check_intersect
1057 );
1058 }
1059
1060 //==========================================================================================================
1061 // $availability_per_day[..]->_day_status = 'season_filter' | ...
1062 //==========================================================================================================
1063 // Booking > Resources > Availability page >>> 'season_filter'
1064 $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 );
1065
1066 // Booking > Availability page >>> 'resource_availability'
1067 $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 );
1068
1069 // Week Days unavailable >>> 'weekday_unavailable'
1070 $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__day_status__weekday_unavailable( $availability_per_day, $my_day_tag, $resource_id );
1071
1072 // if ( ( ! $is_this_bap_page ) || ( ! $is_this_hash_page ) ) {
1073 if ( ( ! $is_this_bap_page ) && ( ! $is_this_hash_page ) ) {
1074 // Do not apply these settings at Booking > Add booking page, when we edit booking - e.g. exist 'booking_hash'
1075
1076 // 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.
1077 $is_skip_check__from_today_unavailable = false;
1078 if ( is_array( $params['dates_to_check'] ) ) {
1079 if ( ( ( count( $params['dates_to_check'] ) ) > 0 ) && ( wpbc_is_date_less_than( $params['dates_to_check'][0], $my_day_tag ) ) ) {
1080 $is_skip_check__from_today_unavailable = true;
1081 }
1082 if ( ( ( count( $params['dates_to_check'] ) ) > 1 ) && ( wpbc_is_date_higher_than( $params['dates_to_check'][1], $my_day_tag ) ) ) {
1083 $is_skip_check__from_today_unavailable = true;
1084 }
1085 }
1086
1087 if ( ! $is_skip_check__from_today_unavailable ) {
1088
1089 // Unavailable days from today >>> 'from_today_unavailable'.
1090 $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__day_status__from_today_unavailable( $availability_per_day, $my_day_tag, $resource_id );
1091
1092 // Limit available days from today >>> 'limit_available_from_today'.
1093 $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 );
1094 }
1095 }
1096 //==========================================================================================================
1097
1098
1099 // T O O L T I P :: Times - Unavailable Day
1100 if ( in_array( $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status, array( 'season_filter',
1101 'resource_availability',
1102 'weekday_unavailable',
1103 'from_today_unavailable',
1104 'limit_available_from_today'
1105 ) )
1106 ){
1107 $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__tooltip_times__set_full_day( $availability_per_day, $my_day_tag, $resource_id
1108 , $resource_id__with_children__arr, __( 'Unavailable', 'booking' ) );
1109 }
1110
1111
1112 // =========================================================================================================
1113 // Entire D A Y statuses
1114 // =========================================================================================================
1115
1116 if ( $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable ) {
1117 // Set merged time interval as fully unavailable.
1118 $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots['merged_seconds'] = array( array( 0, 86400 ) ); // FixIn: 10.11.5.1.
1119 // Reduce DAY day_availability, if some season or days unavailable or full by bookings.
1120 --$availability_per_day[ $my_day_tag ]['day_availability'];
1121 }
1122
1123 // 'resource_availability' | 'weekday_unavailable' | 'from_today_unavailable' | 'limit_available_from_today' | 'season_filter' | 'full_day_booking' | 'time_slots_booking' | 'available'.
1124 $availability_per_day[ $my_day_tag ]['statuses']['day_status'][] = $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status;
1125
1126 // 'approved' | 'pending'.
1127 $availability_per_day[ $my_day_tag ]['statuses']['bookings_status'][] = implode( '|', $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved );
1128
1129 // Go to next child booking resource.
1130 }
1131
1132 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1133 // R E S O U R C E S - E n d
1134 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1135
1136
1137 // -------------------------------------------------------------------------------------------------------------
1138 // Day summary :
1139 // -------------------------------------------------------------------------------------------------------------
1140 $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 );
1141
1142 // Go next day + 1 day
1143 $today_inix_timestamp += 24 * 60 * 60;
1144 }
1145
1146
1147 return array(
1148 'dates' => $availability_per_day
1149 , 'resources_id_arr__in_dates' => $resource_id__with_children__arr
1150 , 'aggregate_resource_id_arr' => $aggregate_resource_id_arr
1151 );
1152 }
1153
1154
1155 // <editor-fold defaultstate="collapsed" desc=" == S U P P O R T == " >
1156
1157
1158 // S U P P O R T
1159
1160 /**
1161 * Update Summary statuses for the Day
1162 *
1163 * @param $availability_per_this_day
1164 * @param $my_day_tag
1165 * @param $resource_id_arr
1166 *
1167 * @return mixed
1168 *
1169 *
1170 * Dates Status Concept Strategy ::
1171 *
1172 * Check date booking status based on 'all booking resources':
1173 * ( and as one common situation, when we have only 1 resource )
1174 *
1175 * | 'approved' - when all booking resources has approved FULL day bookings or some booking resource unavailable
1176 * | 'pending' - when at least one booking in one booking resource has pending status and there is no available booking resources
1177 * | 'times_partially_booked' - when at least one booking in one booking resource has time bookings and there is no available booking resources
1178 * and if all time slot approved then status approved
1179 * otherwise if at least one time slot booking has pending status then it has pending status
1180 *
1181 * if all 'time_slots' booked (it's time slot passed into function as parameter)
1182 * then such date in specific booking resource has pending or approved status, based on 'pending'|'approved' rule
1183 *
1184 * | 'check_in' - if activated 'change over days' and all bookings have 'check-in' status
1185 * | 'check_out' - if activated 'change over days' and all bookings have 'check-out' status
1186 * | if in booking resource exist both check in/out bookings, and activated 'change over days'
1187 * then such booking resource date has approved or pending status depends on from status of these bookings
1188 * | 'season_unavailable' - if all booking resources defined as unavailable at Booking > Resources > Availability page
1189 * | 'resource_unavailable' - if all booking resources defined as unavailable at Booking > Availability page
1190 * | 'other_unavailable' - if all booking resources defined as unavailable at Booking > Settings General page in "Availability" section
1191 *
1192 */
1193 function wpbc_update_summary_availability_per_this_day( $availability_per_this_day, $my_day_tag, $resource_id_arr ){
1194
1195 // -------------------------------------------------------------------------------------------------------------
1196 // Summary Tooltips
1197 // -------------------------------------------------------------------------------------------------------------
1198 $availability_per_this_day['summary']['tooltip_times'] = wpbc_support_capacity__tooltip__summary__times( $availability_per_this_day, $my_day_tag, $resource_id_arr );
1199 $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 );
1200 $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 );
1201 $availability_per_this_day['summary']['tooltip_availability'] = wpbc_support_capacity__tooltip__summary__availability( $availability_per_this_day, $my_day_tag, $resource_id_arr );
1202
1203
1204 $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 );
1205 $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.
1206
1207 // -------------------------------------------------------------------------------------------------------------
1208 // ['summary']['status_for_day']
1209 // -------------------------------------------------------------------------------------------------------------
1210 $temp_status = array();
1211 foreach ( $availability_per_this_day['statuses']['day_status'] as $bookings_status_arr ) {
1212 $bookings_status_arr = explode( '|', $bookings_status_arr );
1213 foreach ( $bookings_status_arr as $bookings_status_element ) {
1214 $temp_status[] = $bookings_status_element;
1215 }
1216 }
1217 $temp_status = array_filter( $temp_status ); // All entries of array equal to FALSE (0, '', '0' ) will be removed.
1218 $temp_status = array_unique( $temp_status ); // Erase duplicates
1219 $availability_per_this_day['summary']['status_for_day'] = $temp_status;
1220
1221 /**
1222 * Possible day statuses (searched by value of _day_status):
1223 *
1224 * available
1225 * time_slots_booking
1226 * full_day_booking
1227 *
1228 * limit_available_from_today
1229 * from_today_unavailable
1230 * weekday_unavailable
1231 * resource_availability
1232 * season_filter
1233 *
1234 * change_over
1235 * check_out
1236 * check_in
1237 * 'mixed' from check_in/check_out/change_over
1238 */
1239
1240 // Priority: available > time_slots_booking > full_day_booking
1241 // > season_filter > resource_availability
1242 // > weekday_unavailable > from_today_unavailable > limit_available_from_today
1243
1244 // if at least one booking "available" then day has this status
1245 if ( in_array( 'available', $availability_per_this_day['summary']['status_for_day'] ) ) { $availability_per_this_day['summary']['status_for_day'] = 'available';
1246 } 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';
1247 } else if ( ( ! in_array( 'check_out', $availability_per_this_day['summary']['status_for_day'] ) )
1248 && ( in_array( 'check_in', $availability_per_this_day['summary']['status_for_day'] ) ) ) { $availability_per_this_day['summary']['status_for_day'] = 'check_in';
1249 } else if ( ( ! in_array( 'check_in', $availability_per_this_day['summary']['status_for_day'] ) )
1250 && ( in_array( 'check_out', $availability_per_this_day['summary']['status_for_day'] ) ) ) { $availability_per_this_day['summary']['status_for_day'] = 'check_out';
1251 } 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';
1252 } else if ( in_array( 'season_filter', $availability_per_this_day['summary']['status_for_day'] ) ) { $availability_per_this_day['summary']['status_for_day'] = 'season_filter';
1253 } else if ( in_array( 'resource_availability', $availability_per_this_day['summary']['status_for_day'] ) ) { $availability_per_this_day['summary']['status_for_day'] = 'resource_availability';
1254 } else if ( in_array( 'weekday_unavailable', $availability_per_this_day['summary']['status_for_day'] ) ) { $availability_per_this_day['summary']['status_for_day'] = 'weekday_unavailable';
1255 } 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';
1256 } 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';
1257 } else {
1258 $availability_per_this_day['summary']['status_for_day'] = implode( ' ', $availability_per_this_day['summary']['status_for_day'] );
1259 }
1260
1261
1262 // -------------------------------------------------------------------------------------------------------------
1263 // ['summary']['status_for_bookings']
1264 // -------------------------------------------------------------------------------------------------------------
1265 $temp_status = array();
1266 foreach ( $availability_per_this_day['statuses']['bookings_status'] as $bookings_status_arr ) {
1267 $bookings_status_arr = explode( '|', $bookings_status_arr );
1268 foreach ( $bookings_status_arr as $bookings_status_element ) {
1269 $temp_status[] = $bookings_status_element;
1270 }
1271 }
1272 $temp_status = array_filter( $temp_status ); // All entries of array equal to FALSE (0, '', '0' ) will be removed.
1273 $temp_status = array_unique( $temp_status );
1274 $availability_per_this_day['summary']['status_for_bookings'] = $temp_status;
1275
1276 // Priority: pending > approved > ''
1277
1278 // if at least one booking pending then day is pending
1279 if ( in_array( 'pending', $availability_per_this_day['summary']['status_for_bookings'] ) ) { $availability_per_this_day['summary']['status_for_bookings'] = 'pending';
1280 } else if ( in_array( 'pending_pending', $availability_per_this_day['summary']['status_for_bookings'] ) ) { $availability_per_this_day['summary']['status_for_bookings'] = 'pending_pending';
1281 // Usual situations for change over days: pending_pending | pending_approved | approved_pending | approved_approved
1282 } else {
1283 $availability_per_this_day['summary']['status_for_bookings'] = implode( ' ', $availability_per_this_day['summary']['status_for_bookings'] );
1284 }
1285
1286
1287 // -------------------------------------------------------------------------------------------------------------
1288 return $availability_per_this_day;
1289 }
1290
1291
1292 // T O O L T I P s
1293
1294 /**
1295 * Set tooltip summary -- Time-Slots
1296 *
1297 * @param $availability_per_this_day
1298 * @param $my_day_tag
1299 * @param $resource_id_arr
1300 *
1301 * @return string - tooltip content or ''
1302 */
1303 function wpbc_support_capacity__tooltip__summary__times( $availability_per_this_day, $my_day_tag, $resource_id_arr ){
1304
1305 $tooltip = '';
1306
1307 if ( 'On' != get_bk_option( 'booking_disable_timeslots_in_tooltip' ) ) { //FixIn: 9.5.0.2.2
1308
1309 $tooltip_title_word = get_bk_option( 'booking_highlight_timeslot_word' );
1310 $tooltip_title_word = wpbc_lang( $tooltip_title_word );
1311 $tooltip_title_word = ( empty( $tooltip_title_word ) )
1312 ? ''
1313 : '<div class="wpbc_tooltip_title">' . $tooltip_title_word . '</div>' . ' ';
1314
1315 $status_summary_tooltip_times = array();
1316 foreach ( $resource_id_arr as $resource_id ) {
1317 if ( ! empty( $availability_per_this_day[ $resource_id ]->tooltips['times'] ) ) {
1318 $status_summary_tooltip_times[] = $availability_per_this_day[ $resource_id ]->tooltips['times'];
1319 }
1320 }
1321
1322 if ( ! empty( $status_summary_tooltip_times ) ) {
1323
1324 $tooltip = '<div class="wpbc_tooltip_section tooltip__times">'
1325 . $tooltip_title_word
1326 . implode( '', $status_summary_tooltip_times )
1327 . '</div>';
1328 }
1329 }
1330
1331 return $tooltip;
1332 }
1333
1334 function wpbc_support_capacity__tooltip__summary__availability( $availability_per_this_day, $my_day_tag, $resource_id_arr ){
1335
1336 $tooltip = '';
1337
1338 if ( ( 'On' == get_bk_option( 'booking_is_show_availability_in_tooltips' ) ) && ( $availability_per_this_day['max_capacity'] > 1 ) ) {
1339
1340 $tooltip_title_word = get_bk_option( 'booking_highlight_availability_word' );
1341 $tooltip_title_word = wpbc_lang( $tooltip_title_word );
1342 $tooltip_title_word = ( empty( $tooltip_title_word ) )
1343 ? ''
1344 : '<div class="wpbc_tooltip_title">' . $tooltip_title_word . '</div>' . ' ';
1345
1346 $tooltip_content_header = '';
1347
1348 if ( ! empty( $availability_per_this_day['day_availability'] ) ) {
1349
1350 $tooltip = '<div class="wpbc_tooltip_section tooltip__availability">'
1351 . $tooltip_title_word
1352 . '<div class="wpbc_tooltip_resource_container">'
1353 . $tooltip_content_header
1354 . '<div class="wpbc_tooltip_item">'
1355 . $availability_per_this_day['day_availability']
1356 . '</div>'
1357 . '</div>'
1358 . '</div>';
1359 }
1360 }
1361 return $tooltip;
1362 }
1363
1364 function wpbc_support_capacity__tooltip__summary__day_cost( $availability_per_this_day, $my_day_tag, $resource_id_arr ){
1365
1366 $tooltip = '';
1367 if (
1368 ( ! empty( $availability_per_this_day['day_availability'] ) )
1369 && ( 'On' == get_bk_option( 'booking_is_show_cost_in_tooltips' ) )
1370 ){
1371
1372 $tooltip_title_word = get_bk_option( 'booking_highlight_cost_word' );
1373 $tooltip_title_word = wpbc_lang( $tooltip_title_word );
1374 $tooltip_title_word = ( empty( $tooltip_title_word ) )
1375 ? ''
1376 : '<div class="wpbc_tooltip_title">' . $tooltip_title_word . '</div>' . ' ';
1377
1378 if ( isset( $resource_id_arr[0] ) ) {
1379
1380 $id_of_first_resource = $resource_id_arr[0];
1381 $tooltip_content_header = '';
1382
1383 if ( ! empty( $availability_per_this_day[ $id_of_first_resource ]->date_cost_rate ) ) {
1384
1385 $cur_sym = get_bk_option( 'booking_cost_in_date_cell_currency' ); // in Booking > Settings General page in "Calendar" section
1386 //$cur_sym = wpbc_get_currency_symbol(); // in Booking > Settings > Payment page
1387
1388 $cost_text = wpbc_formate_cost_hint__no_html( $availability_per_this_day[ $id_of_first_resource ]->date_cost_rate, $cur_sym );
1389 $cost_text = html_entity_decode( $cost_text );
1390
1391 $tooltip = '<div class="wpbc_tooltip_section tooltip__day_cost">'
1392 . $tooltip_title_word
1393 . '<div class="wpbc_tooltip_resource_container">'
1394 . $tooltip_content_header
1395 . '<div class="wpbc_tooltip_item">'
1396 . $cost_text
1397 . '</div>'
1398 . '</div>'
1399 . '</div>';
1400 }
1401
1402 }
1403 }
1404 return $tooltip;
1405 }
1406
1407
1408 function wpbc_support_capacity__in_day_hint__summary__day_cost( $availability_per_this_day, $my_day_tag, $resource_id_arr ){
1409
1410 $tooltip = '';
1411 if (
1412 ( ! empty( $availability_per_this_day['day_availability'] ) )
1413 && ( 'On' == get_bk_option( 'booking_is_show_cost_in_date_cell' ) )
1414 ){
1415
1416 $id_of_first_resource = $resource_id_arr[0];
1417
1418 if ( ! empty( $availability_per_this_day[ $id_of_first_resource ]->date_cost_rate ) ) {
1419
1420 $cur_sym = get_bk_option( 'booking_cost_in_date_cell_currency' ); // in Booking > Settings General page in "Calendar" section
1421 //$cur_sym = wpbc_get_currency_symbol(); // in Booking > Settings > Payment page
1422
1423 $cost_text = $availability_per_this_day[ $id_of_first_resource ]->date_cost_rate;
1424 $cost_text = number_format( floatval( $cost_text ), wpbc_get_cost_decimals(), '.', '' );
1425 $cost_text = wp_strip_all_tags( wpbc_cost_show( $cost_text, array( 'currency' => 'CURRENCY_SYMBOL' ) ) );
1426 $cost_text = str_replace( array( 'CURRENCY_SYMBOL', '&' ), array( $cur_sym, '&amp;' ), $cost_text );
1427 $cost_text = html_entity_decode($cost_text);
1428
1429 $tooltip = '<span class="wpbc_in_date_hint__cost">' . $cost_text . '</span>';;
1430 }
1431 }
1432 return $tooltip;
1433 }
1434
1435 // FixIn: 10.6.4.1.
1436 /**
1437 * Get availability for in Day cells
1438 *
1439 * @param $availability_per_this_day
1440 * @param $my_day_tag
1441 * @param $resource_id_arr
1442 *
1443 * @return string
1444 */
1445 function wpbc_support_capacity__in_day_hint__summary__availability( $availability_per_this_day, $my_day_tag, $resource_id_arr ){
1446
1447 $tooltip = '';
1448
1449 if (
1450 ( 'On' == get_bk_option( 'booking_is_show_availability_in_date_cell' ) ) &&
1451 ( $availability_per_this_day['max_capacity'] > 1 )
1452 ) {
1453
1454 $tooltip_title_word = get_bk_option( 'booking_highlight_availability_word_in_date_cell' );
1455 $tooltip_title_word = wpbc_lang( $tooltip_title_word );
1456 $tooltip_title_word = ( empty( $tooltip_title_word ) )
1457 ? ''
1458 : '<span class="wpbc_in_date_hint__availability_title">' . $tooltip_title_word . '</span>';
1459
1460
1461 if ( ! empty( $availability_per_this_day['day_availability'] ) ) {
1462
1463 $tooltip = '<span class="wpbc_in_date_hint__availability">'
1464 . '<span class="wpbc_in_date_hint__availability_number">'
1465 . intval( $availability_per_this_day['day_availability'] )
1466 . '&nbsp;'
1467 . '</span>'
1468 . $tooltip_title_word
1469 . '</span>';
1470 $tooltip = html_entity_decode($tooltip);
1471 }
1472 }
1473 return $tooltip;
1474 }
1475
1476
1477
1478 /**
1479 * Set tooltip summary -- Booking Details
1480 *
1481 * @param $availability_per_this_day
1482 * @param $my_day_tag
1483 * @param $resource_id_arr
1484 *
1485 * @return string - tooltip content or ''
1486 */
1487 function wpbc_support_capacity__tooltip__summary__booked_details( $availability_per_this_day, $my_day_tag, $resource_id_arr ){
1488
1489 $tooltip = '';
1490
1491 if ( 'On' == get_bk_option( 'booking_is_show_booked_data_in_tooltips' ) ) { //FixIn: 9.5.0.2.2
1492
1493 $tooltip_title_word = '<div class="wpbc_tooltip_title">' . esc_html__('Booking details','booking') . '</div>';
1494
1495 $status_summary_tooltip_times = array();
1496 foreach ( $resource_id_arr as $resource_id ) {
1497 if ( ! empty( $availability_per_this_day[ $resource_id ]->tooltips['details'] ) ) {
1498
1499 if ( ! empty( $availability_per_this_day[ $resource_id ]->tooltips['resource_title'] ) ){
1500 $tooltip_content_header = '<div class="wpbc_tooltip_header">'
1501 . $availability_per_this_day[ $resource_id ]->tooltips['resource_title'] . ': '
1502 . '</div>';
1503 } else{
1504 $tooltip_content_header = '';
1505 }
1506
1507 $booking_details_text = '<div class="wpbc_tooltip_resource_container">'
1508 . $tooltip_content_header
1509 . implode( ' ', $availability_per_this_day[ $resource_id ]->tooltips['details'] )
1510 . '</div>';
1511
1512 $status_summary_tooltip_times[] = $booking_details_text;
1513 }
1514 }
1515
1516 if ( ! empty( $status_summary_tooltip_times ) ) {
1517
1518 $tooltip = '<div class="wpbc_tooltip_section tooltip__booking_details">'
1519 . $tooltip_title_word
1520 . implode( '', $status_summary_tooltip_times )
1521 . '</div>';
1522 }
1523 }
1524 return $tooltip;
1525 }
1526
1527 /**
1528 * Set Tooltip -- Booking Details
1529 *
1530 * @param $availability_per_day
1531 * @param $my_day_tag
1532 * @param $resource_id
1533 * @param $this_date_bookings
1534 * @param $booked_times__key
1535 * @param $resources_obj
1536 *
1537 * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ];
1538 */
1539 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 ) {
1540
1541 // Get booking details for tooltip, if needed
1542 if ( 'On' == get_bk_option( 'booking_is_show_booked_data_in_tooltips' ) ) {
1543
1544 $booking_id = $this_date_bookings[ $booked_times__key ]->booking_id;
1545 $this_booking_resource_id = $this_date_bookings[ $booked_times__key ]->type;
1546
1547 $booking_details_text = wpbc_support_capacity__get_booking_details(
1548 $this_date_bookings[ $booked_times__key ],
1549 $resources_obj->get__booking_resource_obj( $this_booking_resource_id )
1550 );
1551 $tooltip_text = '';
1552 $tooltip_text .= '<div class="wpbc_tooltip_item tooltip_booked_time">' . $booked_time . '</div>'; // Booked time
1553 $tooltip_text .= '<div class="wpbc_tooltip_item">' . $booking_details_text . '</div>'; // Booking details
1554
1555 $availability_per_day[ $my_day_tag ][ $resource_id ]->tooltips['details'][ $booking_id ] = $tooltip_text;
1556 }
1557
1558 return $availability_per_day[ $my_day_tag ][ $resource_id ];
1559 }
1560
1561 /**
1562 * Set Tooltip Times -- Time-Slots
1563 *
1564 * @param $availability_per_day
1565 * @param $my_day_tag
1566 * @param $resource_id
1567 * @param $resource_id_arr
1568 *
1569 * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ];
1570 */
1571 function wpbc_support_capacity__tooltip_times__set_for_times( $availability_per_day, $my_day_tag, $resource_id, $resource_id_arr ){
1572
1573 // Times Tooltip - time slot list --------------------------------------------------------------------
1574 $tooltip_content_header = '';
1575
1576 if ( count( $resource_id_arr ) > 1 ) {
1577
1578 $class_name = 'tooltip_items_count_' . count( $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots['merged_readable'] );
1579
1580 $tooltip_content_header = '<div class="wpbc_tooltip_header ' . $class_name . ' ">'
1581 . $availability_per_day[ $my_day_tag ][ $resource_id ]->tooltips['resource_title'] . ': '
1582 . '</div>';
1583 }
1584
1585 $tooltip_content_arr = array_map( function ( $item ) {
1586 return '<div class="wpbc_tooltip_item">' . $item . '</div>';
1587 }
1588 , $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots['merged_readable']
1589 );
1590
1591 $availability_per_day[ $my_day_tag ][ $resource_id ]->tooltips['times'] = '<div class="wpbc_tooltip_resource_container">'
1592 . $tooltip_content_header
1593 . implode( '', $tooltip_content_arr )
1594 . '</div>';
1595 return $availability_per_day[ $my_day_tag ][ $resource_id ];
1596 }
1597
1598 /**
1599 * Set Tooltip Times -- Full Day
1600 *
1601 * @param $availability_per_day
1602 * @param $my_day_tag
1603 * @param $resource_id
1604 * @param $resource_id_arr
1605 * @param $status_title
1606 *
1607 * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ];
1608 */
1609 function wpbc_support_capacity__tooltip_times__set_full_day( $availability_per_day, $my_day_tag, $resource_id, $resource_id_arr, $status_title ){
1610
1611 // Times Tooltip - FULL DAY --------------------------------------------------------------------
1612 $tooltip_content_header = '';
1613
1614 if ( count( $resource_id_arr ) > 1 ) {
1615
1616 $class_name = 'tooltip_items_count_1';
1617
1618 $tooltip_content_header = '<div class="wpbc_tooltip_header ' . $class_name . ' ">'
1619 . $availability_per_day[ $my_day_tag ][ $resource_id ]->tooltips['resource_title'] . ': '
1620 . '</div>';
1621 }
1622
1623 $tooltip_content_text = '<div class="wpbc_tooltip_item">' . $status_title . '</div>';
1624
1625 $availability_per_day[ $my_day_tag ][ $resource_id ]->tooltips['times'] = '<div class="wpbc_tooltip_resource_container">'
1626 . $tooltip_content_header
1627 . $tooltip_content_text
1628 . '</div>';
1629 return $availability_per_day[ $my_day_tag ][ $resource_id ];
1630 }
1631
1632
1633
1634 /**
1635 * Get parsed booking data, if required
1636 *
1637 * @param object $this_date_bookings
1638 * @param object $resource_obj
1639 *
1640 * @return string
1641 */
1642 function wpbc_support_capacity__get_booking_details( $this_date_bookings, $resource_obj ) {
1643
1644 if ( ( ! class_exists( 'wpdev_bk_biz_m' ) )
1645 || ( 'On' !== get_bk_option( 'booking_is_show_booked_data_in_tooltips' ) )
1646 ){
1647 return '';
1648 }
1649
1650 $booking_details_for_hint = '';
1651
1652 if ( isset( $this_date_bookings->form ) ) {
1653
1654 // Get shortcodes
1655 $booking_shortcodes_in_tooltips = get_bk_option( 'booking_booked_data_in_tooltips' ); // '[name] [secondname]'
1656
1657 $resource_id = $this_date_bookings->type;
1658
1659 // Get parsed booking data field values -- e.g.: [ "rangetime":"12:00 - 14:00", "secondname":"Smith",... ]
1660 $booking_data_arr = wpbc_get_parsed_booking_data_arr( $this_date_bookings->form, $resource_id, array( 'get' => 'value' ) );
1661 $booking_data_arr['booking_id'] = $this_date_bookings->booking_id;
1662 $booking_data_arr['resource_id'] = $resource_id;
1663 $booking_data_arr['resource_title'] = ( ! empty( $resource_obj ) ) ? wpbc_lang( $resource_obj->title ) : '';
1664
1665 // Replace existing shortcodes
1666 foreach ( $booking_data_arr as $replace_shortcode => $replace_value ) {
1667
1668 if ( is_null( $replace_value ) ) { $replace_value = ''; };
1669
1670 $replace_value = wpbc_replace__true_false__to__yes_no( $replace_value ); // FixIn: 9.8.9.1.
1671
1672 $booking_shortcodes_in_tooltips = str_replace( array(
1673 '[' . $replace_shortcode . ']'
1674 , '{' . $replace_shortcode . '}'
1675 )
1676 , $replace_value
1677 , $booking_shortcodes_in_tooltips
1678 );
1679 }
1680
1681 $booking_details_for_hint = $booking_shortcodes_in_tooltips;
1682
1683 // Remove all shortcodes, which is not replaced early.
1684 $booking_details_for_hint = preg_replace( '/[\[\{][a-zA-Z0-9.,_-]{0,}[\]\}]/', '', $booking_details_for_hint );
1685 }
1686
1687 return $booking_details_for_hint;
1688 }
1689
1690
1691 /**
1692 * Unset some fields from booking data for do not show personal data at front-end side
1693 *
1694 * @param object $this_date_bookings
1695 *
1696 * @return object
1697 */
1698 function wpbc_support_capacity__unset_some_fields( $this_date_bookings ) {
1699
1700 if ( isset( $this_date_bookings->form ) ) {
1701 unset( $this_date_bookings->form ); // Hide booking details
1702 }
1703
1704 if ( isset( $this_date_bookings->booking_date ) ) {
1705 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
1706 }
1707
1708 return $this_date_bookings;
1709 }
1710
1711
1712 // D A Y S T A T U S U N A V A I L A B L E
1713
1714 /**
1715 * Set > _day_status = 'limit_available_from_today' depends on Booking > Settings General page ---> "Limit available days from today"
1716 *
1717 * @param $availability_per_day [ ... ]
1718 * @param $my_day_tag - '2023-08-08'
1719 * @param $resource_id - 2
1720 *
1721 * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ]
1722 */
1723 function wpbc_support_capacity__day_status__limit_available_from_today( $availability_per_day, $my_day_tag, $resource_id ){
1724
1725 // ----------------------------------------------------------------------------------------------------- // limit_available_from_today
1726 // 3. Limit available days from today
1727 if ( function_exists( 'wpbc_is_day_available__relative__limit_available_from_today' ) ) {
1728 if ( ! wpbc_is_day_available__relative__limit_available_from_today( $my_day_tag ) ) {
1729 // this date unavailable
1730 $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true;
1731 $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'limit_available_from_today';
1732
1733 if ( empty( $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details ) ) {
1734 $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details = array(); // Reset bookings details
1735 }
1736 }
1737 }
1738
1739 return $availability_per_day[ $my_day_tag ][ $resource_id ];
1740 }
1741
1742
1743 /**
1744 * Set > _day_status = 'from_today_unavailable' depends on Booking > Settings General page ---> "Unavailable days from today"
1745 *
1746 * @param $availability_per_day [ ... ]
1747 * @param $my_day_tag - '2023-08-08'
1748 * @param $resource_id - 2
1749 *
1750 * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ]
1751 */
1752 function wpbc_support_capacity__day_status__from_today_unavailable( $availability_per_day, $my_day_tag, $resource_id ){
1753
1754 // FixIn: 10.8.1.4.
1755
1756 // ----------------------------------------------------------------------------------------------------- // from_today_unavailable
1757 // 2. Unavailable days from today
1758 $unavailable_days_num_from_today = get_bk_option( 'booking_unavailable_days_num_from_today' );
1759
1760 // FixIn: 10.8.1.4.
1761 if ( ! empty( $unavailable_days_num_from_today ) ) {
1762 if ( 'm' === substr( $unavailable_days_num_from_today, - 1 ) ) {
1763 $start_date_unix = strtotime( '+' . ( intval( $unavailable_days_num_from_today ) - 1 ) . ' minutes' ); // + 0 days
1764 } else {
1765 $start_date_unix = strtotime( '+' . intval( $unavailable_days_num_from_today ) . ' days' ); // + 0 days
1766 }
1767 } else {
1768 $start_date_unix = strtotime( 'now' );
1769 }
1770
1771 $date_start__gmt = gmdate( 'Y-m-d H:i:s', $start_date_unix ); // '2025-01-25 12:50:10'
1772 $date_start__midnight__wp_timezone = wpbc_datetime_localized__use_wp_timezone( $date_start__gmt, 'Y-m-d 00:00:00' ); // Local Midnight.
1773
1774 // 'Today Midnight' - 'Calendar Day Cell' .
1775 $days_number = intval( ( strtotime( $date_start__midnight__wp_timezone ) - strtotime( $my_day_tag ) ) / 86400 );
1776
1777 if ( $days_number > 0 ) {
1778 // This date Unavailable.
1779 $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true;
1780 $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'from_today_unavailable';
1781
1782 if ( empty( $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details ) ) {
1783 $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details = array(); // Reset bookings details
1784 }
1785 }
1786
1787 return $availability_per_day[ $my_day_tag ][ $resource_id ];
1788 }
1789
1790
1791 /**
1792 * Set > _day_status = 'weekday_unavailable' depends on Booking > Settings General page ---> "Week Days unavailable"
1793 *
1794 * @param $availability_per_day [ ... ]
1795 * @param $my_day_tag - '2023-08-08'
1796 * @param $resource_id - 2
1797 *
1798 * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ]
1799 */
1800 function wpbc_support_capacity__day_status__weekday_unavailable( $availability_per_day, $my_day_tag, $resource_id ){
1801
1802 // 1. Week Days unavailable -------------------------------------------------------------------------------- // weekday_unavailable
1803 $unavailable_weekdays = array();
1804 foreach ( range( 0, 6 ) as $week_day_num ) {
1805 $unavailable_weekdays[ $week_day_num ] = ( 'On' == get_bk_option( 'booking_unavailable_day' . $week_day_num ) ) ? true : false;
1806 }
1807
1808 $this_day_week_num = gmdate( 'w', strtotime( $my_day_tag ) ); // 0 - 6
1809
1810 if ( $unavailable_weekdays[ $this_day_week_num ] ) {
1811 // this date unavailable
1812 $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true;
1813 $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'weekday_unavailable';
1814
1815 if ( empty( $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details ) ) {
1816 $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details = array(); // Reset bookings details
1817 }
1818 }
1819
1820 return $availability_per_day[ $my_day_tag ][ $resource_id ];
1821 }
1822
1823
1824 /**
1825 * Set > _day_status = 'resource_availability' depends on Booking > Availability page
1826 *
1827 * @param $availability_per_day [ ... ]
1828 * @param $my_day_tag - '2023-08-08'
1829 * @param $resource_id - 2
1830 * @param array $unavailable_dates__per_resources__arr - [ 2: ['2023-08-01', '2023-08-02'], 10: ['2023-08-05', '2023-08-06'] ]
1831 *
1832 * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ]
1833 */
1834 function wpbc_support_capacity__day_status__resource_availability( $availability_per_day, $my_day_tag, $resource_id, $unavailable_dates__per_resources__arr ){
1835
1836 // Booking > Availability page ----------------------------------------------------------------------------- // resource_availability
1837 /**
1838 * $unavailable_dates__per_resources__arr = Array ( [2] => Array( [0] => 2023-08-01
1839 [1] => 2023-08-02
1840 )
1841 [10] => Array( [0] => 2023-08-05
1842 [1] => 2023-08-06
1843 )
1844 )
1845 */
1846 if (
1847 ( isset( $unavailable_dates__per_resources__arr[ $resource_id ] ) )
1848 && ( in_array( $my_day_tag, $unavailable_dates__per_resources__arr[ $resource_id ] ) )
1849 ) {
1850
1851 $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true;
1852 $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'resource_availability';
1853
1854 if ( empty( $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details ) ) {
1855 $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details = array(); // Reset bookings details
1856 }
1857 }
1858
1859 return $availability_per_day[ $my_day_tag ][ $resource_id ];
1860 }
1861
1862
1863 /**
1864 * Set > _day_status = 'season_filter' depends on Booking > Resources > Availability page
1865 *
1866 * @param $availability_per_day [ ... ]
1867 * @param $my_day_tag - '2023-08-08'
1868 * @param $resource_id - 2
1869 * @param array $season_filters_availability - [...]
1870 *
1871 * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ]
1872 */
1873 function wpbc_support_capacity__day_status__season_filter( $availability_per_day, $my_day_tag, $resource_id, $season_filters_availability ){
1874
1875 if ( function_exists( 'wpbc_is_this_day_available_in_season_filters' ) ) { // BM and higher
1876
1877 $is_date_available = wpbc_is_this_day_available_in_season_filters( $my_day_tag, $resource_id, $season_filters_availability[ $resource_id ] ); // Get availability
1878 if ( ! $is_date_available ) {
1879
1880 $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true;
1881 $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'season_filter';
1882
1883 if ( empty( $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details ) ) {
1884 $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details = array(); // Reset bookings details
1885 }
1886 }
1887 }
1888
1889 return $availability_per_day[ $my_day_tag ][ $resource_id ];
1890 }
1891
1892
1893 // D A Y C O S T
1894
1895 /**
1896 * Get day cost depend on Rates
1897 * @param $my_day_tag - '2023-08-08'
1898 * @param $resource_id - 2
1899 * @param $base_cost - 25
1900 *
1901 * @return int|string
1902 */
1903 function wpbc_support_capacity__get_day_cost( $my_day_tag, $resource_id, $base_cost ) {
1904
1905 $fin_day_cost = 0;
1906 if ( function_exists( 'wpbc_get_1_day_cost_apply_rates' ) ) {
1907
1908 list( $year, $month, $day ) = explode( '-', $my_day_tag );
1909
1910 $day = intval( $day );
1911 $month = intval( $month );
1912 $year = intval( $year );
1913
1914 $fin_day_cost = wpbc_get_1_day_cost_apply_rates( $resource_id, $base_cost, $day, $month, $year );
1915 }
1916
1917 return $fin_day_cost;
1918 }
1919
1920
1921 // </editor-fold>
1922
1923
1924
1925 //TODO: M I G R A T E to 9.8
1926 // .
1927 // instead of this: <script type="text/javascript"> wpbc_settings.set_option( 'pending_days_selectable', true ); </script>
1928 // use this: <script type="text/javascript"> _wpbc.calendar__set_param_value( " . intval( $resource_id ) . ", 'pending_days_selectable' , true ); </script>
1929 // Booking Calendar - JavaScript Settings
1930 // Example or redefine some settings:
1931 // <script type="text/javascript"> wpbc_settings.set_option( 'pending_days_selectable', true ); </script>
1932 // [booking type=1]
1933 // .
1934 // .
1935 // 1. Define parameters for calendar(s):
1936 // _wpbc.calendar__set_parameters( " . intval( $resource_id ) . ", {'days_select_mode': 'single'} );
1937 // _wpbc.calendar__set_parameters( " . intval( $resource_id ) . ", {'days_select_mode': 'multiple'} );
1938 // _wpbc.calendar__set_parameters( " . intval( $resource_id ) . ", {'days_select_mode': 'fixed'} );
1939 // _wpbc.calendar__set_parameters( " . intval( $resource_id ) . ", {'fixed__days_num' : 7 } );
1940 // _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 }
1941 // _wpbc.calendar__set_parameters( " . intval( $resource_id ) . ", {'days_select_mode': 'dynamic'} );
1942 // _wpbc.calendar__set_param_value( " . intval( $resource_id ) . ", 'dynamic__days_min' , 7 );
1943 // _wpbc.calendar__set_param_value( " . intval( $resource_id ) . ", 'dynamic__days_max' , 14 );
1944 // _wpbc.calendar__set_param_value( " . intval( $resource_id ) . ", 'dynamic__days_specific' , [] ); // Example [5,7]
1945 // _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 }
1946 // JavaScript functions changes:
1947 // wpbc_unselect_all_days( resource_id ) -> wpbc_calendar__unselect_all_dates( resource_id )
1948 // showErrorMessage( element , errorMessage , isScrollStop ); -> wpbc_front_end__show_message__warning( jq_node, message );
1949 // showMessageUnderElement( element , errorMessage , message_type); -> wpbc_front_end__show_message__warning_under_element( jq_node, message );
1950 // makeScroll( object_name ); -> wpbc_do_scroll( jq_node );
1951 // .
1952 // JavaScript hooks changes:
1953 // jQuery( ".booking_form_div" ).trigger( "date_selected", [ resource_id, date ] );
1954 // become
1955 // jQuery( ".booking_form_div" ).trigger( "date_selected", [ resource_id, mouse_clicked_dates, all_selected_dates_arr ] );
1956 // where:
1957 // mouse_clicked_dates Can be: "05.10.2023 - 07.10.2023" | "10.10.2023 - 10.10.2023" |
1958 // all_selected_dates_arr Can be: [ "2023-10-05", "2023-10-06", "2023-10-07", … ]
1959 // PHP actions:
1960 // from: make_bk_action('wpdev_booking_post_inserted', $booking_id, $bktype, $str_dates__dd_mm_yyyy, array($start_time, $end_time ) , $formdata );
1961 // removed!
1962 // . // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
1963 // from: apply_filters('wpdev_booking_form_content', $form , $resource_id);
1964 // to: apply_filters( 'wpbc_booking_form_html__update__append_change_over_times', $form, $resource_id );
1965 // .
1966 // Removed PHP actions:
1967 // . 'show_payment_forms__for_ajax'
1968 // * make_bk_action('wpbc_ add_new_booking' , array(
1969 // * 'bktype' => 1
1970 // * , 'dates' => '27.08.2014, 28.08.2014, 29.08.2014'
1971 // * , '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'
1972 // * , 'is_send_emeils' => 0
1973 // * // , 'booking_form_type' => ''
1974 // * // , 'wpdev_active_locale' => 'en_US'
1975 // * ) );
1976 // .
1977 // add_bk_filter('wpbc_add_new_booking_filter' , 'wpbc_add_new_booking' );
1978 // TODO: recheck hooks in wpbc-dev-api.php
1979