PluginProbe
Booking Calendar / 11.8.3
Booking Calendar v11.8.3
11.8.3 11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 10.11 10.11.2 All 203 releases
← All changes | includes/_capacity/capacity.php +88 -18 10.15.711.8.3 View file →
@@ -554,9 +554,11 @@
554 554 'as_single_resource' => false, // get dates as for 'single resource' or 'parent' resource including bookings in all 'child booking resources'.
555 555 'max_days_count' => wpbc_get_max_visible_days_in_calendar(), // 365.
556 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 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 + 'allow_past' => false,
558 559 'custom_form' => '', // Required for checking all available time-slots and compare with booked time slots.
560 + 'force_check_from_today_unavailable' => false, // Optional admin tools can force relative availability checks inside explicit date ranges.
559 561 );
560 562
561 563 $params = wp_parse_args( $params, $defaults );
562 564
@@ -561,11 +563,12 @@
561 563 $params = wp_parse_args( $params, $defaults );
562 564
563 565 // FixIn: 10.7.1.2. //FixIn: 10.10.3.2.
564 566 if (
567 + ( ! empty( $params['allow_past'] ) ) ||
565 568 ( false !== strpos( $params['request_uri'], 'allow_past' ) ) ||
566 569 (
567 - ( false !== strpos( $params['request_uri'], 'page=wpbc-new' ) ) &&
570 + wpbc_is_new_booking_page_url( $params['request_uri'] ) &&
568 571 ( false !== strpos( $params['request_uri'], 'booking_hash' ) )
569 572 )
570 573 ) {
571 574 $params['dates_to_check'] = 'ALL';
@@ -685,14 +688,14 @@
685 688 // P a r a m e t e r s f o r L O O P
686 689 // -----------------------------------------------------------------------------------------------------------------
687 690
688 691 // - Is this Booking > Add booking page ? --------------------------------------------------------------------------
689 - $is_this_bap_page = ( false !== strpos( $params['request_uri'], 'page=wpbc-new' ) ) ? true : false;
692 + $is_this_bap_page = wpbc_is_new_booking_page_url( $params['request_uri'] );
690 693 $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 694
692 695 // FixIn: 10.7.1.2.
693 696 if ( ! $is_this_hash_page ) {
694 - $is_this_hash_page = ( false !== strpos( $params['request_uri'], 'allow_past' ) ) ? true : false;
697 + $is_this_hash_page = ( ( ! empty( $params['allow_past'] ) ) || ( false !== strpos( $params['request_uri'], 'allow_past' ) ) ) ? true : false;
695 698 }
696 699
697 700 if ( ( $is_this_bap_page ) && ( $is_this_hash_page ) ) { // Start days in calendar from = PAST
698 701 $params['dates_to_check'] = 'ALL';
@@ -721,12 +724,12 @@
721 724 } else if ( is_array( $params['dates_to_check'] ) ) {
722 725
723 726 $start_day_number = 1;
724 727
725 - $today_inix_timestamp = strtotime( $params['dates_to_check'][0] . ' 00:00:00' ); // '2023-09-03 00:00:00'
728 + $today_inix_timestamp = strtotime( $params['dates_to_check'][0] . ' 00:00:00 UTC' ); // '2023-09-03 00:00:00'
726 729
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' );
730 + $dif_in_days = strtotime( $params['dates_to_check'][ ( count( $params['dates_to_check'] ) - 1 ) ] . ' 00:00:00 UTC' )
731 + - strtotime( $params['dates_to_check'][0] . ' 00:00:00 UTC' );
729 732
730 733 $dif_in_days = $dif_in_days / ( 24 * 60 * 60 );
731 734 $params['max_days_count'] = ceil( $dif_in_days ) + 1;
732 735 }
@@ -781,8 +784,9 @@
781 784 $availability_per_day[ $my_day_tag ]['statuses']['bookings_status'] = array(); // per each child booking resource
782 785 $availability_per_day[ $my_day_tag ]['summary'] = array();
783 786 $availability_per_day[ $my_day_tag ]['summary']['status_for_day'] = ''; // available | time_slots_booking | full_day_booking | ...
784 787 $availability_per_day[ $my_day_tag ]['summary']['status_for_bookings'] = ''; // pending | approved | CO: pending_pending | pending_approved | approved_pending | approved_approved
788 + $availability_per_day[ $my_day_tag ]['summary']['status_for_bookings_arr'] = array(); // Structured statuses array, e.g. array( 'approved', 'approved_approved' ).
785 789 $availability_per_day[ $my_day_tag ]['summary']['tooltip_times'] = '';
786 790 $availability_per_day[ $my_day_tag ]['summary']['tooltip_availability'] = '';
787 791 $availability_per_day[ $my_day_tag ]['summary']['tooltip_day_cost'] = '';
788 792 $availability_per_day[ $my_day_tag ]['summary']['tooltip_booking_details'] = '';
@@ -955,11 +959,20 @@
955 959
956 960 // =====================================================================================================
957 961 // Change over days =
958 962 // =====================================================================================================
963 + $is_booking_used_check_in_out_time = null;
964 + if ( function_exists( 'wpbc_settings_calendar__preview_is_changeover_enabled' ) ) {
965 + $is_booking_used_check_in_out_time = wpbc_settings_calendar__preview_is_changeover_enabled( $resource_id, $params['request_uri'] );
966 + }
967 + if ( null === $is_booking_used_check_in_out_time ) {
968 + $is_booking_used_check_in_out_time = (
969 + ( function_exists( 'wpbc_is_booking_used_check_in_out_time' ) )
970 + && ( wpbc_is_booking_used_check_in_out_time( $params['request_uri'], $resource_id ) )
971 + );
972 + }
959 973 if (
960 - ( function_exists( 'wpbc_is_booking_used_check_in_out_time' ) )
961 - && ( wpbc_is_booking_used_check_in_out_time( $params[ 'request_uri' ] ) )
974 + $is_booking_used_check_in_out_time
962 975 && ( ! $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable ) // And this date still free false
963 976 ) {
964 977
965 978 /**
@@ -1044,8 +1057,36 @@
1044 1057 }
1045 1058 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1046 1059 // B O O K I N G S - E n d
1047 1060 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1061 + // Working Time applies only to time-based booking forms: rangetime, start/end, or start/duration.
1062 + $working_time__timeslots_to_check_intersect = $as_seconds_timeslots_arr__to_check_intersect;
1063 + if ( empty( $working_time__timeslots_to_check_intersect ) && ! empty( $params['timeslots_to_check_intersect'] ) ) {
1064 + if ( ! is_array( $params['timeslots_to_check_intersect'] ) ) {
1065 + $params['timeslots_to_check_intersect'] = array( $params['timeslots_to_check_intersect'] );
1066 + }
1067 + $working_time__timeslots_to_check_intersect = array();
1068 + foreach ( $params['timeslots_to_check_intersect'] as $time_slot_readable ) {
1069 + $working_time__timeslots_to_check_intersect[] = wpbc_convert__readable_time_slot__to__time_range_in_seconds( $time_slot_readable );
1070 + }
1071 + }
1072 +
1073 + if (
1074 + ! empty( $working_time__timeslots_to_check_intersect )
1075 + && function_exists( 'wpbc_working_time__get_non_working_intervals_for_date' )
1076 + && function_exists( 'wpbc_availability_timeslots__apply_blocks_to_availability_obj' )
1077 + ) {
1078 + $working_time__blocked_intervals = wpbc_working_time__get_non_working_intervals_for_date( $resource_id, $my_day_tag );
1079 +
1080 + if ( ! empty( $working_time__blocked_intervals ) ) {
1081 + $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_availability_timeslots__apply_blocks_to_availability_obj(
1082 + $availability_per_day[ $my_day_tag ][ $resource_id ],
1083 + $working_time__blocked_intervals,
1084 + $working_time__timeslots_to_check_intersect
1085 + );
1086 + }
1087 + }
1088 +
1048 1089 // FixIn: 10.16.1.
1049 1090 if (
1050 1091 function_exists( 'wpbc_availability_timeslots__apply_blocks_to_availability_obj' )
1051 1092 && isset( $availability_timeslots__in_dates[ $my_day_tag ][ $resource_id ] )
@@ -1065,18 +1106,20 @@
1065 1106
1066 1107 // Booking > Availability page >>> 'resource_availability'
1067 1108 $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 1109
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 );
1110 + if ( empty( $params['skip_general_availability'] ) ) {
1111 + // Week Days unavailable >>> 'weekday_unavailable'
1112 + $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__day_status__weekday_unavailable( $availability_per_day, $my_day_tag, $resource_id );
1113 + }
1071 1114
1072 1115 // if ( ( ! $is_this_bap_page ) || ( ! $is_this_hash_page ) ) {
1073 - if ( ( ! $is_this_bap_page ) && ( ! $is_this_hash_page ) ) {
1116 + if ( empty( $params['skip_general_availability'] ) && ( ! $is_this_bap_page ) && ( ! $is_this_hash_page ) ) {
1074 1117 // Do not apply these settings at Booking > Add booking page, when we edit booking - e.g. exist 'booking_hash'
1075 1118
1076 1119 // 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 1120 $is_skip_check__from_today_unavailable = false;
1078 - if ( is_array( $params['dates_to_check'] ) ) {
1121 + if ( is_array( $params['dates_to_check'] ) && empty( $params['force_check_from_today_unavailable'] ) ) {
1079 1122 if ( ( ( count( $params['dates_to_check'] ) ) > 0 ) && ( wpbc_is_date_less_than( $params['dates_to_check'][0], $my_day_tag ) ) ) {
1080 1123 $is_skip_check__from_today_unavailable = true;
1081 1124 }
1082 1125 if ( ( ( count( $params['dates_to_check'] ) ) > 1 ) && ( wpbc_is_date_higher_than( $params['dates_to_check'][1], $my_day_tag ) ) ) {
@@ -1214,8 +1257,9 @@
1214 1257 $temp_status[] = $bookings_status_element;
1215 1258 }
1216 1259 }
1217 1260 $temp_status = array_filter( $temp_status ); // All entries of array equal to FALSE (0, '', '0' ) will be removed.
1261 + $temp_status_counts = array_count_values( $temp_status );
1218 1262 $temp_status = array_unique( $temp_status ); // Erase duplicates
1219 1263 $availability_per_this_day['summary']['status_for_day'] = $temp_status;
1220 1264
1221 1265 /**
@@ -1240,10 +1284,34 @@
1240 1284 // Priority: available > time_slots_booking > full_day_booking
1241 1285 // > season_filter > resource_availability
1242 1286 // > weekday_unavailable > from_today_unavailable > limit_available_from_today
1243 1287
1244 - // if at least one booking "available" then day has this status
1288 + // Capacity resources can be available even when every child has a check-in/out or full-day status.
1289 + $max_capacity = isset( $availability_per_this_day['max_capacity'] ) ? intval( $availability_per_this_day['max_capacity'] ) : 1;
1290 + $blocking_statuses = array(
1291 + 'full_day_booking',
1292 + 'season_filter',
1293 + 'resource_availability',
1294 + 'weekday_unavailable',
1295 + 'from_today_unavailable',
1296 + 'limit_available_from_today',
1297 + 'change_over',
1298 + );
1299 + $blocked_capacity = 0;
1300 + foreach ( $blocking_statuses as $blocking_status ) {
1301 + $blocked_capacity += isset( $temp_status_counts[ $blocking_status ] ) ? intval( $temp_status_counts[ $blocking_status ] ) : 0;
1302 + }
1303 + $booked_capacity__before_check_in = $blocked_capacity + ( isset( $temp_status_counts['check_out'] ) ? intval( $temp_status_counts['check_out'] ) : 0 );
1304 + $booked_capacity__after_check_in = $blocked_capacity + ( isset( $temp_status_counts['check_in'] ) ? intval( $temp_status_counts['check_in'] ) : 0 );
1305 + $is_capacity_available_during_change_over = (
1306 + ( $max_capacity > 1 )
1307 + && ( $max_capacity > max( $booked_capacity__before_check_in, $booked_capacity__after_check_in ) )
1308 + && ( ! in_array( 'time_slots_booking', $availability_per_this_day['summary']['status_for_day'] ) )
1309 + );
1310 +
1311 + // if at least one resource is available then day has this status
1245 1312 if ( in_array( 'available', $availability_per_this_day['summary']['status_for_day'] ) ) { $availability_per_this_day['summary']['status_for_day'] = 'available';
1313 + } else if ( $is_capacity_available_during_change_over ) { $availability_per_this_day['summary']['status_for_day'] = 'available';
1246 1314 } 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 1315 } else if ( ( ! in_array( 'check_out', $availability_per_this_day['summary']['status_for_day'] ) )
1248 1316 && ( in_array( 'check_in', $availability_per_this_day['summary']['status_for_day'] ) ) ) { $availability_per_this_day['summary']['status_for_day'] = 'check_in';
1249 1317 } else if ( ( ! in_array( 'check_in', $availability_per_this_day['summary']['status_for_day'] ) )
@@ -1269,19 +1337,21 @@
1269 1337 $temp_status[] = $bookings_status_element;
1270 1338 }
1271 1339 }
1272 1340 $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;
1341 + $temp_status = array_values( array_unique( $temp_status ) );
1275 1342
1343 + // Structured booking statuses contract. Keep numeric keys sequential so JSON encodes this as a JS array.
1344 + $availability_per_this_day['summary']['status_for_bookings_arr'] = $temp_status;
1345 +
1276 1346 // Priority: pending > approved > ''
1277 1347
1278 1348 // 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';
1349 + if ( in_array( 'pending', $temp_status ) ) { $availability_per_this_day['summary']['status_for_bookings'] = 'pending';
1350 + } else if ( in_array( 'pending_pending', $temp_status ) ) { $availability_per_this_day['summary']['status_for_bookings'] = 'pending_pending';
1281 1351 // Usual situations for change over days: pending_pending | pending_approved | approved_pending | approved_approved
1282 1352 } else {
1283 - $availability_per_this_day['summary']['status_for_bookings'] = implode( ' ', $availability_per_this_day['summary']['status_for_bookings'] );
1353 + $availability_per_this_day['summary']['status_for_bookings'] = implode( ' ', $temp_status );
1284 1354 }
1285 1355
1286 1356
1287 1357 // -------------------------------------------------------------------------------------------------------------