FileMaster
Search
Toggle Dark Mode
Home
/
.
/
wp-content
/
plugins
/
booking
/
includes
/
_capacity
Edit File: capacity.php
<?php if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly // FixIn: 9.8.0.4. // <editor-fold defaultstate="collapsed" desc=" == SQL - Get Dates array from DB == " > // ----------------------------------------------------------------------------------------------------------------- // SQL - Get Dates array from DB // ----------------------------------------------------------------------------------------------------------------- /** * 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( ), ... ] * * @param array $params = array( 'approved' => 'all' | 0 | 1 default 'all' , 'resource_id' => array, CSD, int if empty then default '1' , 'additional_bk_types' => array, CSD, int OPTIONAL default array() , 'skip_booking_id' => CSD default '' ) * * @return array Array ( [0] => stdClass Object ( [booking_date] => 2023-08-08 10:00:01 [approved] => 0 [date_res_type] => [booking_id] => 45 [form] => selectbox-one^rangetime2^10:00 - 12:00~text^selected_short_dates_hint2^... [parent] => 0 [prioritet] => 20 [type] => 2 ) [1] => stdClass Object ( [booking_date] => 2023-08-08 10:00:01 [approved] => 0 [date_res_type] => [booking_id] => 46 [form] => selectbox-one^rangetime10^10:00 - 12:00~text^selected_short_dates_hint10^... [parent] => 2 [prioritet] => 1 [type] => 10 ), ... * * * Example: $sql_dates_params = array( 'approved' => ( ( 'On' == get_bk_option( 'booking_is_show_pending_days_as_available' ) ) ? '1' : 'all' ) , 'resource_id' => $type_id , 'skip_booking_id' => wpbc_get_booking_id__from_hash_in_url() // int | '' // Booking IDs to skip getting from DB ); $dates_approve = wpbc__sql__get_booking_dates( $sql_dates_params ); */ function wpbc__sql__get_booking_dates( $params ){ //TODO: think about pre-caching SQL request for all booking resources - useful for [bookingselect shortcode ...] $params['resource_id'] = implode(',',range(1,17)); // <editor-fold defaultstate="collapsed" desc=" = CACHE - GET :: check if such request was cached and get it = " > $params_for_cache = maybe_serialize( $params ); $cache_result = wpbc_cache__get( 'wpbc__sql__get_booking_dates', $params_for_cache ); if ( ! is_null( $cache_result ) ) { return $cache_result; } // </editor-fold> global $wpdb; $defaults = array( 'dates_to_check' => 'CURDATE' // 'CURDATE' | 'ALL' | [ '2023-07-15' , '2023-07-21' ] , 'approved' => 'all' // 'all' | 0 | 1 , 'resource_id' => '' // INT , 'additional_bk_types' => array() // arrays only , 'skip_booking_id' => '' // CSD '3,5' , 'as_single_resource' => false // get dates as for 'single resource' or 'parent' resource including bookings in all 'child booking resources' ); $params = wp_parse_args( $params, $defaults ); // Convert $params['additional_bk_types'] and $params['resource_id'] to one CSD variable or default '1' if all empty $resource_id__arr = wpbc_get_unique_array_of_resources_id( $params['resource_id'], $params['additional_bk_types'] ); $resource_id__csd = implode( ',', $resource_id__arr ); // S a n i t i z e $resource_id__csd = wpbc_sanitize_digit_or_csd( $resource_id__csd ); $params['skip_booking_id'] = wpbc_sanitize_digit_or_csd( $params['skip_booking_id'] ); $params['approved'] = ( 'all' == $params['approved'] ) ? 'all' : intval( $params['approved'] ); $sql_trash_bookings = ' AND bk.trash != 1 '; $sql_skip_bookings = ( '' == $params['skip_booking_id'] ) ? '' : " AND dt.booking_id NOT IN ( {$params['skip_booking_id']} ) "; $sql_approved_bookings = ( 'all' == $params['approved'] ) ? '' : " AND dt.approved = {$params['approved']} "; $or__sql_child_bookings_4_parent = ( ! $params['as_single_resource'] ) ? " OR bt.parent IN ( {$resource_id__csd} ) " : '' ; $where_dates = wpbc_get__sql_where__for__dates( $params ); /** * Description: * OR dt.type_id IN ( {$resource_id__csd} ) * It is means that sometimes bookings can be started in one booking resource, * and in future dates can be finished in other 'child' booking resource(s). * It's possible, when 'main' booking resource, where booking was started * has future dates as 'unavailable' or booked * * OR dt.type_id IN ( {$resource_id__csd} ) * It's means that this booking belong to child booking resource, and do not belong to parent booking resource! */ if ( class_exists('wpdev_bk_biz_l') ) { $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 FROM {$wpdb->prefix}bookingdates as dt INNER JOIN {$wpdb->prefix}booking as bk ON bk.booking_id = dt.booking_id INNER JOIN {$wpdb->prefix}bookingtypes as bt ON bk.booking_type = bt.booking_type_id WHERE 1 = 1 {$where_dates} AND ( bk.booking_type IN ( {$resource_id__csd} ) OR dt.type_id IN ( {$resource_id__csd} ) {$or__sql_child_bookings_4_parent} ) {$sql_approved_bookings} {$sql_trash_bookings} {$sql_skip_bookings} ORDER BY dt.booking_date"; // Explanation: // OR bt.parent IN ( ... ) -> Bookings from CHILD booking resources // OR dt.type_id IN ( ... ) -> Dates from other booking resources, which belong to this booking resource } else if ( class_exists('wpdev_bk_biz_m') ) { // Here we get form for booking details. $my_sql = "SELECT DISTINCT dt.booking_date, dt.approved, dt.booking_id, bk.booking_type as type, bk.form FROM {$wpdb->prefix}bookingdates as dt INNER JOIN {$wpdb->prefix}booking as bk ON bk.booking_id = dt.booking_id WHERE 1 = 1 {$where_dates} AND bk.booking_type IN ( {$resource_id__csd} ) {$sql_approved_bookings} {$sql_trash_bookings} {$sql_skip_bookings} ORDER BY dt.booking_date"; } else { // Fast request only for dates $my_sql = "SELECT DISTINCT dt.booking_date, dt.approved, dt.booking_id, bk.booking_type as type FROM {$wpdb->prefix}bookingdates as dt INNER JOIN {$wpdb->prefix}booking as bk ON bk.booking_id = dt.booking_id WHERE 1 = 1 {$where_dates} AND bk.booking_type IN ( {$resource_id__csd} ) {$sql_approved_bookings} {$sql_trash_bookings} {$sql_skip_bookings} ORDER BY dt.booking_date"; } // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared $sql__dates_obj__arr = $wpdb->get_results( $my_sql ); // <editor-fold defaultstate="collapsed" desc=" = CACHE - SAVE :: = " > $cache_result = wpbc_cache__save( 'wpbc__sql__get_booking_dates', $params_for_cache, $sql__dates_obj__arr ); // </editor-fold> return $sql__dates_obj__arr; } /** * Get SQL WHERE condition for Dates * * @param array $params [ 'dates_to_check' => 'CURDATE' ] | [ 'dates_to_check' => 'ALL' ] | [ 'dates_to_check' => [ '2023-07-15' , '2023-07-21' ] ] * * @return string ' AND ( dt.booking_date >= C URDATE() ) ' */ function wpbc_get__sql_where__for__dates( $params ){ $defaults = array( 'dates_to_check' => 'CURDATE' // 'CURDATE' | 'ALL' | [ '2023-07-15' , '2023-07-21' ] ); $params = wp_parse_args( $params, $defaults ); if ( 'ALL' == $params['dates_to_check'] ) { // All dates -> '' return ''; } else if ( 'CURDATE' == $params['dates_to_check'] ) { // Current dates -> CURDATE return ' AND ( dt.booking_date >= ' . wpbc_sql_date_math_expr_explicit('', 'curdate') . ' ) ' ; } else if ( is_array( $params['dates_to_check'] ) ) { // Specific Date(s) -> [ '2023-07-15' , '2023-07-21' ] // FixIn: 10.13.1.4. -situation, where in shortcode defined - [booking calendar_dates_start='2025-01-01' calendar_dates_end='2025-12-31' ...] if ( 2 === count( $params['dates_to_check'] ) ) { $dates_sql_str = " ( ( dt.booking_date >= '{$params['dates_to_check'][0]} 00:00:00' ) AND ( dt.booking_date <= '{$params['dates_to_check'][1]} 23:59:59' ) )"; } else if ( 1 === count( $params['dates_to_check'] ) ) { $dates_sql_str = " ( dt.booking_date >= '{$params['dates_to_check'][0]} 00:00:00' ) "; } else { // Check booking dates inside of the each specific dates. I do not sure that this situation possible ?????? $dates_sql_array = array(); for( $i = 0; $i < count( $params['dates_to_check'] ); $i++) { $dates_sql_array[] = "( ( dt.booking_date >= '{$params['dates_to_check'][$i]} 00:00:00' ) AND ( dt.booking_date <= '{$params['dates_to_check'][$i]} 23:59:59' ) )"; } $dates_sql_str = implode( ' OR ', $dates_sql_array ); } return " AND ( {$dates_sql_str} ) " ; } // Default CURDATE return ' AND ( dt.booking_date >= ' . wpbc_sql_date_math_expr_explicit('', 'curdate') . ' ) '; } /** * Get array of "Booked Dates" as: ['2023-08-30'][ > resource_id < ][ > time_seconds_range < ] => booking_date_obj[ booking_id:45, approved:1, ... * * @param array $params array( * 'approved' => 'all' // 'all' | 0 | 1 * , 'resource_id' => '1' // arrays | CSD | int * , 'additional_bk_types' => array() OPTIONAL // arrays | CSD | int * , 'skip_booking_id' => '' // CSD '3,5' * ) * * @return array [ [2023-08-09]: [ [3]: [ '43211 - 86392': object( 'booking_date' => 2023-08-09 12:00:01 ... ), ... ], ... ], [2023-08-10]: ... ] * * Explanation: * [2023-08-09]: [ * [3]: [ * '43211 - 86392': object( * [booking_date] => 2023-08-09 12:00:01 * [approved] => 0 * [date_res_type] => * [booking_id] => 65 * [form] => text^selected_short_dates_hint3^August 10... * [parent] => 0 * [prioritet] => 30 * [type] => 3 * [__summary__booking] : [ * * [sql__booking_dates__arr] : [ * [1691668811] => 2023-08-10 12:00:01 * [1691675992] => 2023-08-10 14:00:02 * ] * [__dates_obj] => WPBC_BOOKING_DATE Object( * [readable_dates]: [ '2023-08-10': [ 12:00:01 - 14:00:02 ] ] * [is_debug] => 0 * ) * [__dates_obj__bm__extended] => WPBC_BOOKING_DATE_EXTENDED Object ( * [readable_dates] : [ * [2023-08-09] : [ 12:00:01 - 24:00:00 ] * [2023-08-10] : [ 00:00:00 - 24:00:00 ] * [2023-08-11] : [ 00:00:00 - 24:00:00 ] * [2023-08-12] : [ 00:00:00 - 24:00:00 ] * [2023-08-13] : [ 00:00:00 - 14:00:02 ] * ] * [is_debug] => 0 * [extended_dates_times_arr] : [] * [debug_dates_times_arr] : [] * ) * [sql__booking_dates__arr__extended] : [ * [1691582401] => 2023-08-09 12:00:01 * [1691625600] => 2023-08-10 00:00:00 * [1691712000] => 2023-08-11 00:00:00 * [1691798400] => 2023-08-12 00:00:00 * [1691935202] => 2023-08-13 14:00:02 * ] * * ] * ) * '64811 - 86392': object( * [booking_date] => 2023-08-09 18:00:01 * [approved] => 0 * [date_res_type] => * [booking_id] => 66 * .... * ) * * ] * * ] * * [2023-08-10]: [ ... ] * ... * * Example 1: * $booked_dates__per_resources__arr = wpbc_get__booked_dates__per_resources__arr( array( 'resource_id' => $type_id ) ); * Example 2: * $booked_dates__per_resources__arr = wpbc_get__booked_dates__per_resources__arr( * 'approved' => 'all' // 'all' | 0 | 1 * , 'resource_id' => '1' // arrays | CSD | int * , 'additional_bk_types' => array() // arrays | CSD | int * , 'skip_booking_id' => '' // int | '' // CSD * ); * * * * * $booked_dates__resources__seconds__arr[ '2023-08-08' ][ 'resource_id' ][ 'time_seconds_range' ] = Booking Date Object() * * Seconds: [36011 - 43192] - [start_time_second - end_time_second] * Seconds: [0] - FULL DAY Booking * * Day start at ( 10 + 1 ) second * Day End at ( ( 24 * 60 * 60 ) - 10 + 2 ) second * * To prevent intersections: * Each booking Start time has +10 seconds * Each booking End time has -10 seconds * So real time here [36011 - 43192] is [ 36001 - 43202 ] * * Full day booking end with 0 * Start time booking end with 1 * End time booking end with 2 */ function wpbc_get__booked_dates__per_resources__arr( $params ){ $defaults = array( 'dates_to_check' => 'CURDATE' // 'CURDATE' | 'ALL' | [ '2023-07-15' , '2023-07-21' ] , 'approved' => ( ( get_bk_option( 'booking_is_show_pending_days_as_available' ) == 'On' ) ? '1' : 'all' ) // 'all' | 0 | 1 , 'resource_id' => '1' // arrays | CSD | int , 'additional_bk_types' => array() // arrays | CSD | int // OPTIONAL , 'skip_booking_id' => wpbc_get_booking_id__from_hash_in_url() // int | '' // CSD '3,5' , 'as_single_resource' => false // get dates as for 'single resource' or 'parent' resource including bookings in all 'child booking resources' , 'is_days_always_available' => ( ( 'On' == get_bk_option( 'booking_is_days_always_available' ) ) ? true : false ) , 'aggregate_params' => array() //Optional. It can contain: [ 'aggregate_resource_id_arr' => [ 4 ] , 'resource_id__with_children__arr' => [3,25] ] ); $params_for_dates = wp_parse_args( $params, $defaults ); // $params_for_dates['is_days_always_available'] = in_array( $params_for_dates['resource_id'], array( '1' ) ); // Set some resources as always avavailable. if ( $params_for_dates['is_days_always_available'] ) { // All bookings showing as available dates. return array(); } /** * 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, .. }, .. ] * * Example: [ [0] => stdClass Object ( [booking_date] => 2023-08-08 10:00:01 [approved] => 0 [date_res_type] => [booking_id] => 45 [form] => selectbox-one^rangetime2^10:00 - 12:00~text^selected_short_dates_hint2^... [parent] => 0 [prioritet] => 20 [type] => 2 ) [1] => stdClass Object ( [booking_date] => 2023-08-08 10:00:01 [approved] => 0 [date_res_type] => [booking_id] => 46 [form] => selectbox-one^rangetime10^10:00 - 12:00~text^selected_short_dates_hint10^... [parent] => 2 [prioritet] => 1 [type] => 10 ), ... ] */ $sql__b_dates__arr = wpbc__sql__get_booking_dates( $params_for_dates ); /** * 2. From SQL dates into: [ > resource_id < ][ > booking_id < ] -> __summary__booking['sql__booking_dates__arr'] = [ [ '>seconds<' ]: '> SQL DATE <' , ... ] * [1693303211] => 2023-08-29 10:00:01 * [1693353600] => 2023-08-30 00:00:00 * [1693483192] => 2023-08-31 12:00:02 * ] */ $resources__booking_id__obj = wpbc_support__transform__into__resource_booking_dates__arr( 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 ) ); /** * 2.0 Transfer AGGREGATE resource bookings to Main resources * * */ if ( ! empty( $params['aggregate_params'] ) ) { $resources__booking_id__obj = wpbc_aggregate__merge_bookings__from_aggregate__in_source_resource__arr( $resources__booking_id__obj, $params['aggregate_params']['resource_id__with_children__arr'], $params['aggregate_params']['aggregate_resource_id_arr'] ); } /** * 2.1 Get [ > resource_id < ][ > booking_id < ] -> __summary__booking[ '_readable_dates' ] = [ '2023-08-01': [ 0: "10:00:01 - 12:00:02" ], ... * '2023-08-05': [ 0: "10:00:01 - 12:00:02" ], ... * ] */ $resources__booking_id__obj = wpbc__in_all_bookings__create_WPBC_BOOKING_DATE( $resources__booking_id__obj ); /** * 2.2 Extend check in/out dates [ > resource_id < ][ > booking_id < ] -> __summary__booking[ 'sql__booking_dates__arr__extended' ] */ if ( function_exists( 'wpbc__extend_availability__before_after__check_in_out' ) ) { $resources__booking_id__obj = wpbc__extend_availability__before_after__check_in_out( $resources__booking_id__obj ); } /** * 3. Into: ['2024-01-28'][ > resource_id < ][ > booking_id < ][ > only_time_seconds < ] => obj( booking_date: "2024-01-28 10:00:01", ... ) * * From: [ > resource_id < ][ > booking_id < ] => obj( booking_date: "2024-01-28 10:00:01", ['__summary__booking']['sql__booking_dates__arr'][] , ... ) */ $dt__res__bk__seconds__arr = wpbc_support__transform__into__date_resource_booking_timesec__arr( array( 'resource_booking_dates_arr' => $resources__booking_id__obj , 'is_apply__check_in_out__10s' => true ) ); /** * 4. Into: ['2023-08-30'][ > resource_id < ][ > time_seconds_range < ] => booking_date_obj[ booking_id:45, approved:1, ... * * , where 'time_seconds_range' can be: '0' | '36011 - 43192', ... */ $dt__res__time_seconds_range__arr = wpbc_support__transform__into__date_resource_timesec_range__arr( array( 'date_resource_booking_timesec_arr' => $dt__res__bk__seconds__arr , 'is_apply__check_in_out__10s' => true ) ); return $dt__res__time_seconds_range__arr; } // </editor-fold> // ----------------------------------------------------------------------------------------------------------------- // Get Resource array filled by booked Dates // ----------------------------------------------------------------------------------------------------------------- /** * 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, ... * * @param int $single_or_parent__resource_id // 1 --- INT (currently it's works only for one resource (single or parent) * 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 * * @return array { * calendar_2: { * id: 2 * dates: { "2023-07-21": {…} * "2023-07-22": { * ['summary']['status_for_bookings']: "pending" * ['summary']['status_for_day']: "available" * day_availability: 4 * max_capacity: 4 * statuses: Object { day: "check_in|check_in|available|available", bookings: "approved|pending||" } * * 2: Object { is_day_unavailable: false, _day_status: "check_in", check_in_out: "check_in", … } * 10: Object { is_day_unavailable: false, _day_status: "check_in", check_in_out: "check_in", … } * 11: Object { is_day_unavailable: false, _day_status: "available", pending_approved: [] } * 12: Object { is_day_unavailable: false, _day_status: "available", pending_approved: [] } * } * , "2023-07-23": {…} * , … * } * } * calendar_5: {...} * , ... * } * * * Important Dates properties: * * ['summary']['status_for_bookings']: "" | "pending" | "approved" * ['summary']['status_for_day']: | 'available'; * | 'time_slots_booking'; * | 'full_day_booking'; * | 'season_filter'; * | 'resource_availability'; * | 'weekday_unavailable'; 'from_today_unavailable' | 'limit_available_from_today' * | 'change_over'; * | 'check_in'; * | 'check_out'; * | 'change_over check_out' .... variations.... * * * @return array array( 'dates' => $availability_per_day like ['2023-08-17'] = ... , 'resources_id_arr__in_dates' => $source__resource_id_arr like [ 1,10,11,12,14] ) */ function wpbc_get_availability_per_days_arr( $params ) { if ( 0 ) { // FixIn: 9.8.3.1 ? wpbc_set_limit_php( 300 ); // Set 300 seconds for php execution. } $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 */ $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 */ $defaults = array( 'dates_to_check' => 'CURDATE', // v: 'CURDATE' | 'ALL' | arr: '2023-07-15' , '2023-07-21'. 'approved' => ( ( 'On' === get_bk_option( 'booking_is_show_pending_days_as_available' ) ) ? '1' : 'all' ), // v: 'all' | 0 | 1. 'resource_id' => '1', // Single or parent booking resource!!!! // arrays | CSD | int ???. 'additional_bk_types' => array(), // arrays | CSD | int // OPTIONAL -> aggregate_resource_id_arr ... it is array of booking resources from aggregate shortcode parameter. 'skip_booking_id' => wpbc_get_booking_id__from_hash_in_url(), // int | '' // CSD '3,5'. 'as_single_resource' => false, // get dates as for 'single resource' or 'parent' resource including bookings in all 'child booking resources'. 'max_days_count' => wpbc_get_max_visible_days_in_calendar(), // 365. '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. '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. 'custom_form' => '', // Required for checking all available time-slots and compare with booked time slots. ); $params = wp_parse_args( $params, $defaults ); // FixIn: 10.7.1.2. //FixIn: 10.10.3.2. if ( ( false !== strpos( $params['request_uri'], 'allow_past' ) ) || ( ( false !== strpos( $params['request_uri'], 'page=wpbc-new' ) ) && ( false !== strpos( $params['request_uri'], 'booking_hash' ) ) ) ) { $params['dates_to_check'] = 'ALL'; } // ----------------------------------------------------------------------------------------------------------------- // R e s o u r c e (s) D a t a // ----------------------------------------------------------------------------------------------------------------- // Get array of booking resource ID [1, 13, 8, 6, 7] or default: [ 1 ] $source__resource_id_arr = wpbc_get_unique_array_of_resources_id( $params['resource_id'] ); // [1, 13, 8, 6, 7] //$source__resource_id_arr = wpbc_get_unique_array_of_resources_id( $params['resource_id'], $params['additional_bk_types'] ); // [1, 13, 8, 6, 7] $first_resource_id = $source__resource_id_arr[0]; // First from the list, or 1 if not provided. // Get here Obj. of booking resource (which can include CHILD booking resources) $resources_obj = new WPBC_RESOURCE_SUPPORT( array( 'resource_id' => $source__resource_id_arr, //CSD | D 'as_single_resource' => $params['as_single_resource'] // If true, then skip child booking resources )); // Resource ID arr (Can be Parent and Child resource ID) $resource_id__with_children__arr = $resources_obj->get_resource_id_arr(); // [ 2, 10, 11, 12 ] // Get Maximum capacity of resource $resource_obj = $resources_obj->get__booking_resource_obj( $first_resource_id ); $max_resource_capacity_int = empty( $resource_obj ) ? 1 : $resource_obj->capacity; // 1 | 4 // Get base cost of resource $resource_base_cost = $resources_obj->get_resources_base_cost_arr(); // [ 0, 25, 100, 99] // ----------------------------------------------------------------------------------------------------------------- // Get real AGGREGATE resource ID arr // ----------------------------------------------------------------------------------------------------------------- $real_resource_id_arr = wpbc_get_unique_array_of_resources_id( $params['resource_id'] ); // [ 1 ] if ( empty( $params['additional_bk_types'] ) ) { $aggregate_resource_id_arr = array(); } else { $aggregate_resource_id_arr = wpbc_get_unique_array_of_resources_id( $params['additional_bk_types'] ); // [1, 13, 8, 6, 7] } // Excluding from 'additional_bk_types' all resources in 'resource_id' $aggregate_resource_id_arr = array_diff( $aggregate_resource_id_arr, $real_resource_id_arr ); // [ 13, 8, 6, 7 ] $aggregate_resource_id_arr = array_values( $aggregate_resource_id_arr ); // reindex array, for ability to transfer array instead of obj to JS client side. $params['aggregate_params'] = array( 'aggregate_resource_id_arr' => $aggregate_resource_id_arr, 'resource_id__with_children__arr' => $resource_id__with_children__arr ); // ----------------------------------------------------------------------------------------------------------------- // B o o k i n g s // ----------------------------------------------------------------------------------------------------------------- // Main function to get "Bookings": ['2023-08-30'][ > resource_id < ][ > time_seconds_range < ] => booking_date_obj[ booking_id:45, approved:1, ... $bookings__in_dates = wpbc_get__booked_dates__per_resources__arr( $params ); // ----------------------------------------------------------------------------------------------------------------- // Booking > Availability page // ----------------------------------------------------------------------------------------------------------------- $search_dates = $params['dates_to_check']; // 'CURDATE' | 'ALL' | [ "2023-08-03" , "2023-08-04" , "2023-08-05" ] //FixIn: 9.8.15.10 Aggregate or not Aggregate Booking > Availability ? aggregate_type = 'all' | 'bookings_only' if ( ( ! empty( $params['aggregate_type'] ) ) && ( 'bookings_only' === $params['aggregate_type'] ) ) { // FixIn: 9.9.0.16. $unavailable_dates__per_resources__arr = wpbc_for_resources_arr__get_unavailable_dates( $resource_id__with_children__arr, // Only One Primary Resource !! $search_dates ); // [ 2: ['2023-08-01', '2023-08-02'], 10: ['2023-08-05', '2023-08-06'] ] } else { $unavailable_dates__per_resources__arr = wpbc_for_resources_arr__get_unavailable_dates( 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 $search_dates ); // [ 2: ['2023-08-01', '2023-08-02'], 10: ['2023-08-05', '2023-08-06'] ] } $unavailable_dates__per_resources__arr = wpbc_aggregate_merge_availability( $unavailable_dates__per_resources__arr, $resource_id__with_children__arr, $aggregate_resource_id_arr ); // ----------------------------------------------------------------------------------------------------------------- // Booking > Resources > Availability page // ----------------------------------------------------------------------------------------------------------------- $season_filters_availability = array(); if ( class_exists('wpdev_bk_biz_m') ) { foreach ( $resource_id__with_children__arr as $resource_id_for_season ) { $season_filters_availability[ $resource_id_for_season ] = apply_bk_filter( 'get_available_days', $resource_id_for_season ); } } // ----------------------------------------------------------------------------------------------------------------- // P a r a m e t e r s f o r L O O P // ----------------------------------------------------------------------------------------------------------------- // - Is this Booking > Add booking page ? -------------------------------------------------------------------------- $is_this_bap_page = ( false !== strpos( $params['request_uri'], 'page=wpbc-new' ) ) ? true : false; $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 // FixIn: 10.7.1.2. if ( ! $is_this_hash_page ) { $is_this_hash_page = ( false !== strpos( $params['request_uri'], 'allow_past' ) ) ? true : false; } if ( ( $is_this_bap_page ) && ( $is_this_hash_page ) ) { // Start days in calendar from = PAST $params['dates_to_check'] = 'ALL'; } if ( 'ALL' == $params['dates_to_check'] ) { // All dates -> '' $start_day_number = - 1 * $params['max_days_count']; //$today_inix_timestamp = strtotime( '-' . intval( $params['max_days_count'] ) . ' days' ); // - 300 days // Get time, relative to Timezone from WordPress > Settings General page // FixIn: 9.9.0.17. $start_date_unix = strtotime( '-' . intval( $params['max_days_count'] ) . ' days' ); // - 365 days $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' ); $today_inix_timestamp = strtotime( $date_with_wp_timezone ); } else if ( 'CURDATE' == $params['dates_to_check'] ) { // Current dates -> CURDATE $start_day_number = 1; // $today_inix_timestamp = strtotime( gmdate( 'Y-m-d 00:00:00', strtotime( 'now' ) ) ); // Today 00:00:00 // Get time, relative to Timezone from WordPress > Settings General page // FixIn: 9.9.0.17. $start_date_unix = strtotime( 'now' ); $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' ); $today_inix_timestamp = strtotime( $date_with_wp_timezone ); } else if ( is_array( $params['dates_to_check'] ) ) { $start_day_number = 1; $today_inix_timestamp = strtotime( $params['dates_to_check'][0] . ' 00:00:00' ); // '2023-09-03 00:00:00' $dif_in_days = strtotime( $params['dates_to_check'][ ( count( $params['dates_to_check'] ) - 1 ) ] . ' 00:00:00' ) - strtotime( $params['dates_to_check'][0] . ' 00:00:00' ); $dif_in_days = $dif_in_days / ( 24 * 60 * 60 ); $params['max_days_count'] = ceil( $dif_in_days ) + 1; } // Get Time Slots from booking form for Each date: [ '2023-10-25' => [ '12:20 - 12:55', '13:00 - 14:00' ], '2023-10-26' => [ ... ], ... ] $readable_timeslots_arr__in_dates_arr__to_check_intersect = wpbc_get_times_fields_configuration__by_dates( $first_resource_id, // Resource ID (used in case of MultiUser version for getting specific form for regular users) $params['custom_form'], // Form name for getting time slots configuration $today_inix_timestamp, // start_date_unix_timestamp ( $params['max_days_count'] - $start_day_number ) // days_count ); // ================================================================================================================= // -- Here are GO // ================================================================================================================= $availability_per_day = array(); for ( $day_num = $start_day_number; $day_num <= $params['max_days_count']; $day_num ++ ) { $my_day_tag = gmdate( 'Y-m-d', $today_inix_timestamp ); // '2023-07-19' //-------------------------------------------------------------------------------------------------------------- // 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 $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 ); /* // TODO: check this, if it's required ? // If empty, maybe get default 'timeslots_to_check_intersect' from root of this function parameters ???? if ( empty( $as_seconds_timeslots_arr__to_check_intersect ) ) { if ( ! is_array( $params[ 'timeslots_to_check_intersect' ] ) ) { // Root parameters from this function $params[ 'timeslots_to_check_intersect' ] = array( $params[ 'timeslots_to_check_intersect' ] ); } $as_seconds_timeslots_arr__to_check_intersect = array(); foreach ( $params[ 'timeslots_to_check_intersect' ] as $time_slot_readable ) { $as_seconds_timeslots_arr__to_check_intersect[] = wpbc_convert__readable_time_slot__to__time_range_in_seconds( $time_slot_readable ); } } */ //-------------------------------------------------------------------------------------------------------------- $availability_per_day[ $my_day_tag ] = array(); // 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 $availability_per_day[ $my_day_tag ]['day_availability'] = $max_resource_capacity_int; // 4 $availability_per_day[ $my_day_tag ]['max_capacity'] = $max_resource_capacity_int; // 4 $availability_per_day[ $my_day_tag ]['statuses'] = array(); $availability_per_day[ $my_day_tag ]['statuses']['day_status'] = array(); // per each child booking resource $availability_per_day[ $my_day_tag ]['statuses']['bookings_status'] = array(); // per each child booking resource $availability_per_day[ $my_day_tag ]['summary'] = array(); $availability_per_day[ $my_day_tag ]['summary']['status_for_day'] = ''; // available | time_slots_booking | full_day_booking | ... $availability_per_day[ $my_day_tag ]['summary']['status_for_bookings'] = ''; // pending | approved | CO: pending_pending | pending_approved | approved_pending | approved_approved $availability_per_day[ $my_day_tag ]['summary']['tooltip_times'] = ''; $availability_per_day[ $my_day_tag ]['summary']['tooltip_availability'] = ''; $availability_per_day[ $my_day_tag ]['summary']['tooltip_day_cost'] = ''; $availability_per_day[ $my_day_tag ]['summary']['tooltip_booking_details'] = ''; // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // R E S O U R C E S - S t a r t // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ foreach ( $resource_id__with_children__arr as $resource_id ) { // [1, 13, 8, 6, 7] $availability_per_day[ $my_day_tag ][ $resource_id ] = new stdClass(); $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = false; $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'available'; $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved = array(); $availability_per_day[ $my_day_tag ][ $resource_id ]->tooltips = array( 'resource_title' => $resources_obj->get_resource_title( $resource_id ), 'times' => '', 'details' => array() ); $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots = array( 'in_seconds' => array(), // seconds 'readable24h' => array(), // readable 24H - for debug only 'merged_seconds' => array(), // seconds (reduced number of time_ranges) 'merged_readable' => array() // readable 12AM ); // Day Cost / Rates --------------------------------------------------------------------------------------- $fin_day_cost = wpbc_support_capacity__get_day_cost( $my_day_tag, $resource_id, $resource_base_cost[ $resource_id ] ); $availability_per_day[ $my_day_tag ][ $resource_id ]->date_cost_rate = $fin_day_cost; // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // B O O K I N G S - S t a r t // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if ( ( isset( $bookings__in_dates[ $my_day_tag ] ) ) && ( isset( $bookings__in_dates[ $my_day_tag ][ $resource_id ] ) ) ){ $this_date_bookings = $bookings__in_dates[ $my_day_tag ][ $resource_id ]; // [ [36011 - 86392] => stdClass Object( [approved] => 1 , ... ) ,... ] ksort( $this_date_bookings ); $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details = $this_date_bookings; } else { $this_date_bookings = array(); } /** * If bookings exist then: * 1. Removing some properties here to hide personal details, * 2. Set Approved / Pending status of the bookings * 3. By default, set "_day_status" as 'time_slots_booking' ( later we will change to 'full_day_booking', if applied ) */ if ( ! empty( $this_date_bookings ) ) { // ===================================================================================================== // T i m e s - Start // ===================================================================================================== foreach ( $this_date_bookings as $booked_times__key => $booked_times__value ) { // By default, set "_day_status" as 'time_slots_booking' ( later we will change to 'full_day_booking', if applied ) $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'time_slots_booking'; // ------------------------------------------------------------------------------------------------- // Get Time-Slot if ( false === strpos( $booked_times__key, '-' ) ) { // Full day ? - 0 == $booked_times__key $time_range__seconds__arr = array( 0, 86400 ); // 24 * 60 * 60 } else { $time_range__seconds__arr = wpbc_transform_timerange__s_range__in__seconds_arr( $booked_times__key ); // '43211 - 86392' into [43211, 86400] } // Real time: [43211, 86400] $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots['in_seconds'][] = $time_range__seconds__arr; // For DEBUG only -- Readable 24H: '10:00:01 - 12:30:02' $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 ); // ------------------------------------------------------------------------------------------------- // 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 $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved[ $time_range__seconds__arr[0] ] = ( '1' == $booked_times__value->approved ) ? 'approved' : 'pending'; // T O O L T I P :: Booking Details $booked_time_title = ( ( 0 == $time_range__seconds__arr[0] ) && ( $time_range__seconds__arr[1] >= 86400 ) ) ? __( 'Full day', 'booking' ) : wpbc_transform_timerange__seconds_arr__in__formated_hours( $time_range__seconds__arr ); $availability_per_day[ $my_day_tag ][ $resource_id ] = 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_title ); // Unset ...->form and other fields... $this_date_bookings[ $booked_times__key ] = wpbc_support_capacity__unset_some_fields( $this_date_bookings[ $booked_times__key ] ); } // T i m e s - E n d Booked Times Loop - for current resource // ===================================================================================================== // Merge intersected time intervals = // ===================================================================================================== $merged_seconds_arr = wpbc_merge_intersected_intervals( $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots['in_seconds'] ); $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots['merged_seconds'] = $merged_seconds_arr; foreach ( $merged_seconds_arr as $booked_time_slots__in_seconds ) { $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 ); } // T O O L T I P :: Times $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 ); // ===================================================================================================== // End times // ===================================================================================================== // 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... ksort( $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved ); // array_keys( $booked_time_slots ) can be: [0] -> 'Full day' | ['36011 - 43192', '56011 - 86392'] -> '10:00 - 12:00', '15:55 - 24:00' $booked_time_slots = array_keys( $this_date_bookings ); // ===================================================================================================== // Full day booking ----------------------------------------------------------------------------------- full_by_bookings // ===================================================================================================== if ( in_array( '0', $booked_time_slots ) ) { $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true; $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'full_day_booking'; // Reset all other possible time slot statuses, in general they must not exist, but for some case $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved = array(); // Pending or approved, for full day booking: $this_date_bookings['0'] $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved[] = ( '1' == $this_date_bookings['0']->approved ) ? 'approved' : 'pending'; // T O O L T I P :: Times - Full Day Booked $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__tooltip_times__set_full_day( $availability_per_day, $my_day_tag, $resource_id , $resource_id__with_children__arr, __( 'Full day', 'booking' ) ); } // end 'full day' if // ===================================================================================================== // All time slots booked ? ----------------------------------------------------------------------------- // ===================================================================================================== if ( ( ! empty( $as_seconds_timeslots_arr__to_check_intersect ) ) // We need to check intersection with some time slot '36011 - 43192' && ( ! $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable ) // And this date still free false ){ $is_some_timeslot_available = wpbc_is_some_timeslot__available__in_arr( $as_seconds_timeslots_arr__to_check_intersect, $booked_time_slots ); // ------------------------------------------------------------------------------------------------- full_by_bookings if ( ! $is_some_timeslot_available ) { // All time slots booked !!! $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true; $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'full_day_booking'; $availability_per_day[ $my_day_tag ][ $resource_id ]->_booking_form_timeslots_unavailable = implode( '|', $params[ 'timeslots_to_check_intersect' ] ); // T O O L T I P :: Times - Full Day Booked $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__tooltip_times__set_full_day( $availability_per_day, $my_day_tag, $resource_id , $resource_id__with_children__arr, __( 'Full day', 'booking' ) ); } else { // Some time slots available or there is no time slot passed in this function } } // end 'all time slots booked' if // ===================================================================================================== // Change over days = // ===================================================================================================== if ( ( function_exists( 'wpbc_is_booking_used_check_in_out_time' ) ) && ( wpbc_is_booking_used_check_in_out_time( $params[ 'request_uri' ] ) ) && ( ! $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable ) // And this date still free false ) { /** * "Change over days" - possible situations: check_in | check_out | change_over | ... * * $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = check_in * | check_out * | change_over * | 'mixed' * 'mixed' - e.g. 'change_over check_out' where several child resources and some is 'change_over' and others are 'check_out' * * * Possible situations for change-over days: * * // A. If in $booked_time_slots array one of values (or in $this_date_bookings one of keys) * // 1. Started with time that is ended with 1 second * // 2. and Ended with '24:00' it is means '86392', like this: '28811 - 86392' * // then it's means that we have 'check_in' time here * * // B. If in $booked_time_slots array one of values (or in $this_date_bookings one of keys) * // 1. Started with '00:00' it is means '1' * // 2. and Ended time that is ended with 2 second * // like this: '1 - 32402' * // then it's means that we have 'check_out' time here * * // C. If we have A. and B. then we have 'change_over' here */ $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out = array(); foreach ( $this_date_bookings as $booked_times__key => $booked_times__value ) { if ( false === strpos( $booked_times__key, '-' ) ) { continue; // for situation with FULL day booking, here $booked_times__key = 0 } $rangeA_arr = explode( '-', $booked_times__key ); $rangeA_arr[0] = intval( trim( $rangeA_arr[0] ) ); $rangeA_arr[1] = intval( trim( $rangeA_arr[1] ) ); // start time $is_starttime__check_in = $rangeA_arr[0] % 10; // 0, 1, 2 $is_starttime__check_in = ( 1 == $is_starttime__check_in ) ? true : false; // end time $is_endtime__check_out = $rangeA_arr[1] % 10; $is_endtime__check_out = ( 2 == $is_endtime__check_out ) ? true : false; if ( ( $is_starttime__check_in ) && ( WPBC_FULL_DAY_TIME_OUT == $rangeA_arr[1] ) ) { // A :: start_time - 86392 e.g. 14:00 - 24:00 // only "check in" time here $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out[] = 'check_in'; } else if ( ( WPBC_FULL_DAY_TIME_IN == $rangeA_arr[0] ) && ( $is_endtime__check_out ) ) { // B :: 1 - end_time e.g. 00:00 - 10:00 // only "check out" time here $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out[] = 'check_out'; } } $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out = array_unique( $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out ); $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. if ( ( in_array( 'check_in', $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out ) ) && ( in_array( 'check_out', $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out ) ) ) { $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out = array( 'change_over' ); // both check in / out times here $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true; // Possible statuses: pending_pending | pending_approved | approved_pending | approved_approved $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved = array( implode( '_', $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved ) ); } $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out = implode( '|', $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out ); if ( ! empty( $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out ) ) { $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = $availability_per_day[ $my_day_tag ][ $resource_id ]->check_in_out; } } // end change-over if } // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // B O O K I N G S - E n d // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //========================================================================================================== // $availability_per_day[..]->_day_status = 'season_filter' | ... //========================================================================================================== // Booking > Resources > Availability page >>> 'season_filter' $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 ); // Booking > Availability page >>> 'resource_availability' $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 ); // Week Days unavailable >>> 'weekday_unavailable' $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__day_status__weekday_unavailable( $availability_per_day, $my_day_tag, $resource_id ); // if ( ( ! $is_this_bap_page ) || ( ! $is_this_hash_page ) ) { if ( ( ! $is_this_bap_page ) && ( ! $is_this_hash_page ) ) { // Do not apply these settings at Booking > Add booking page, when we edit booking - e.g. exist 'booking_hash' // 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. $is_skip_check__from_today_unavailable = false; if ( is_array( $params['dates_to_check'] ) ) { if ( ( ( count( $params['dates_to_check'] ) ) > 0 ) && ( wpbc_is_date_less_than( $params['dates_to_check'][0], $my_day_tag ) ) ) { $is_skip_check__from_today_unavailable = true; } if ( ( ( count( $params['dates_to_check'] ) ) > 1 ) && ( wpbc_is_date_higher_than( $params['dates_to_check'][1], $my_day_tag ) ) ) { $is_skip_check__from_today_unavailable = true; } } if ( ! $is_skip_check__from_today_unavailable ) { // Unavailable days from today >>> 'from_today_unavailable'. $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__day_status__from_today_unavailable( $availability_per_day, $my_day_tag, $resource_id ); // Limit available days from today >>> 'limit_available_from_today'. $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 ); } } //========================================================================================================== // T O O L T I P :: Times - Unavailable Day if ( in_array( $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status, array( 'season_filter', 'resource_availability', 'weekday_unavailable', 'from_today_unavailable', 'limit_available_from_today' ) ) ){ $availability_per_day[ $my_day_tag ][ $resource_id ] = wpbc_support_capacity__tooltip_times__set_full_day( $availability_per_day, $my_day_tag, $resource_id , $resource_id__with_children__arr, __( 'Unavailable', 'booking' ) ); } // ========================================================================================================= // Entire D A Y statuses // ========================================================================================================= if ( $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable ) { // Set merged time interval as fully unavailable. $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots['merged_seconds'] = array( array( 0, 86400 ) ); // FixIn: 10.11.5.1. // Reduce DAY day_availability, if some season or days unavailable or full by bookings. --$availability_per_day[ $my_day_tag ]['day_availability']; } // 'resource_availability' | 'weekday_unavailable' | 'from_today_unavailable' | 'limit_available_from_today' | 'season_filter' | 'full_day_booking' | 'time_slots_booking' | 'available'. $availability_per_day[ $my_day_tag ]['statuses']['day_status'][] = $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status; // 'approved' | 'pending'. $availability_per_day[ $my_day_tag ]['statuses']['bookings_status'][] = implode( '|', $availability_per_day[ $my_day_tag ][ $resource_id ]->pending_approved ); // Go to next child booking resource. } // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // R E S O U R C E S - E n d // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // ------------------------------------------------------------------------------------------------------------- // Day summary : // ------------------------------------------------------------------------------------------------------------- $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 ); // Go next day + 1 day $today_inix_timestamp += 24 * 60 * 60; } return array( 'dates' => $availability_per_day , 'resources_id_arr__in_dates' => $resource_id__with_children__arr , 'aggregate_resource_id_arr' => $aggregate_resource_id_arr ); } // <editor-fold defaultstate="collapsed" desc=" == S U P P O R T == " > // S U P P O R T /** * Update Summary statuses for the Day * * @param $availability_per_this_day * @param $my_day_tag * @param $resource_id_arr * * @return mixed * * * Dates Status Concept Strategy :: * * Check date booking status based on 'all booking resources': * ( and as one common situation, when we have only 1 resource ) * * | 'approved' - when all booking resources has approved FULL day bookings or some booking resource unavailable * | 'pending' - when at least one booking in one booking resource has pending status and there is no available booking resources * | 'times_partially_booked' - when at least one booking in one booking resource has time bookings and there is no available booking resources * and if all time slot approved then status approved * otherwise if at least one time slot booking has pending status then it has pending status * * if all 'time_slots' booked (it's time slot passed into function as parameter) * then such date in specific booking resource has pending or approved status, based on 'pending'|'approved' rule * * | 'check_in' - if activated 'change over days' and all bookings have 'check-in' status * | 'check_out' - if activated 'change over days' and all bookings have 'check-out' status * | if in booking resource exist both check in/out bookings, and activated 'change over days' * then such booking resource date has approved or pending status depends on from status of these bookings * | 'season_unavailable' - if all booking resources defined as unavailable at Booking > Resources > Availability page * | 'resource_unavailable' - if all booking resources defined as unavailable at Booking > Availability page * | 'other_unavailable' - if all booking resources defined as unavailable at Booking > Settings General page in "Availability" section * */ function wpbc_update_summary_availability_per_this_day( $availability_per_this_day, $my_day_tag, $resource_id_arr ){ // ------------------------------------------------------------------------------------------------------------- // Summary Tooltips // ------------------------------------------------------------------------------------------------------------- $availability_per_this_day['summary']['tooltip_times'] = wpbc_support_capacity__tooltip__summary__times( $availability_per_this_day, $my_day_tag, $resource_id_arr ); $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 ); $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 ); $availability_per_this_day['summary']['tooltip_availability'] = wpbc_support_capacity__tooltip__summary__availability( $availability_per_this_day, $my_day_tag, $resource_id_arr ); $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 ); $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. // ------------------------------------------------------------------------------------------------------------- // ['summary']['status_for_day'] // ------------------------------------------------------------------------------------------------------------- $temp_status = array(); foreach ( $availability_per_this_day['statuses']['day_status'] as $bookings_status_arr ) { $bookings_status_arr = explode( '|', $bookings_status_arr ); foreach ( $bookings_status_arr as $bookings_status_element ) { $temp_status[] = $bookings_status_element; } } $temp_status = array_filter( $temp_status ); // All entries of array equal to FALSE (0, '', '0' ) will be removed. $temp_status = array_unique( $temp_status ); // Erase duplicates $availability_per_this_day['summary']['status_for_day'] = $temp_status; /** * Possible day statuses (searched by value of _day_status): * * available * time_slots_booking * full_day_booking * * limit_available_from_today * from_today_unavailable * weekday_unavailable * resource_availability * season_filter * * change_over * check_out * check_in * 'mixed' from check_in/check_out/change_over */ // Priority: available > time_slots_booking > full_day_booking // > season_filter > resource_availability // > weekday_unavailable > from_today_unavailable > limit_available_from_today // if at least one booking "available" then day has this status if ( in_array( 'available', $availability_per_this_day['summary']['status_for_day'] ) ) { $availability_per_this_day['summary']['status_for_day'] = 'available'; } 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'; } else if ( ( ! in_array( 'check_out', $availability_per_this_day['summary']['status_for_day'] ) ) && ( in_array( 'check_in', $availability_per_this_day['summary']['status_for_day'] ) ) ) { $availability_per_this_day['summary']['status_for_day'] = 'check_in'; } else if ( ( ! in_array( 'check_in', $availability_per_this_day['summary']['status_for_day'] ) ) && ( in_array( 'check_out', $availability_per_this_day['summary']['status_for_day'] ) ) ) { $availability_per_this_day['summary']['status_for_day'] = 'check_out'; } 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'; } else if ( in_array( 'season_filter', $availability_per_this_day['summary']['status_for_day'] ) ) { $availability_per_this_day['summary']['status_for_day'] = 'season_filter'; } else if ( in_array( 'resource_availability', $availability_per_this_day['summary']['status_for_day'] ) ) { $availability_per_this_day['summary']['status_for_day'] = 'resource_availability'; } else if ( in_array( 'weekday_unavailable', $availability_per_this_day['summary']['status_for_day'] ) ) { $availability_per_this_day['summary']['status_for_day'] = 'weekday_unavailable'; } 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'; } 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'; } else { $availability_per_this_day['summary']['status_for_day'] = implode( ' ', $availability_per_this_day['summary']['status_for_day'] ); } // ------------------------------------------------------------------------------------------------------------- // ['summary']['status_for_bookings'] // ------------------------------------------------------------------------------------------------------------- $temp_status = array(); foreach ( $availability_per_this_day['statuses']['bookings_status'] as $bookings_status_arr ) { $bookings_status_arr = explode( '|', $bookings_status_arr ); foreach ( $bookings_status_arr as $bookings_status_element ) { $temp_status[] = $bookings_status_element; } } $temp_status = array_filter( $temp_status ); // All entries of array equal to FALSE (0, '', '0' ) will be removed. $temp_status = array_unique( $temp_status ); $availability_per_this_day['summary']['status_for_bookings'] = $temp_status; // Priority: pending > approved > '' // if at least one booking pending then day is pending if ( in_array( 'pending', $availability_per_this_day['summary']['status_for_bookings'] ) ) { $availability_per_this_day['summary']['status_for_bookings'] = 'pending'; } else if ( in_array( 'pending_pending', $availability_per_this_day['summary']['status_for_bookings'] ) ) { $availability_per_this_day['summary']['status_for_bookings'] = 'pending_pending'; // Usual situations for change over days: pending_pending | pending_approved | approved_pending | approved_approved } else { $availability_per_this_day['summary']['status_for_bookings'] = implode( ' ', $availability_per_this_day['summary']['status_for_bookings'] ); } // ------------------------------------------------------------------------------------------------------------- return $availability_per_this_day; } // T O O L T I P s /** * Set tooltip summary -- Time-Slots * * @param $availability_per_this_day * @param $my_day_tag * @param $resource_id_arr * * @return string - tooltip content or '' */ function wpbc_support_capacity__tooltip__summary__times( $availability_per_this_day, $my_day_tag, $resource_id_arr ){ $tooltip = ''; if ( 'On' != get_bk_option( 'booking_disable_timeslots_in_tooltip' ) ) { //FixIn: 9.5.0.2.2 $tooltip_title_word = get_bk_option( 'booking_highlight_timeslot_word' ); $tooltip_title_word = wpbc_lang( $tooltip_title_word ); $tooltip_title_word = ( empty( $tooltip_title_word ) ) ? '' : '<div class="wpbc_tooltip_title">' . $tooltip_title_word . '</div>' . ' '; $status_summary_tooltip_times = array(); foreach ( $resource_id_arr as $resource_id ) { if ( ! empty( $availability_per_this_day[ $resource_id ]->tooltips['times'] ) ) { $status_summary_tooltip_times[] = $availability_per_this_day[ $resource_id ]->tooltips['times']; } } if ( ! empty( $status_summary_tooltip_times ) ) { $tooltip = '<div class="wpbc_tooltip_section tooltip__times">' . $tooltip_title_word . implode( '', $status_summary_tooltip_times ) . '</div>'; } } return $tooltip; } function wpbc_support_capacity__tooltip__summary__availability( $availability_per_this_day, $my_day_tag, $resource_id_arr ){ $tooltip = ''; if ( ( 'On' == get_bk_option( 'booking_is_show_availability_in_tooltips' ) ) && ( $availability_per_this_day['max_capacity'] > 1 ) ) { $tooltip_title_word = get_bk_option( 'booking_highlight_availability_word' ); $tooltip_title_word = wpbc_lang( $tooltip_title_word ); $tooltip_title_word = ( empty( $tooltip_title_word ) ) ? '' : '<div class="wpbc_tooltip_title">' . $tooltip_title_word . '</div>' . ' '; $tooltip_content_header = ''; if ( ! empty( $availability_per_this_day['day_availability'] ) ) { $tooltip = '<div class="wpbc_tooltip_section tooltip__availability">' . $tooltip_title_word . '<div class="wpbc_tooltip_resource_container">' . $tooltip_content_header . '<div class="wpbc_tooltip_item">' . $availability_per_this_day['day_availability'] . '</div>' . '</div>' . '</div>'; } } return $tooltip; } function wpbc_support_capacity__tooltip__summary__day_cost( $availability_per_this_day, $my_day_tag, $resource_id_arr ){ $tooltip = ''; if ( ( ! empty( $availability_per_this_day['day_availability'] ) ) && ( 'On' == get_bk_option( 'booking_is_show_cost_in_tooltips' ) ) ){ $tooltip_title_word = get_bk_option( 'booking_highlight_cost_word' ); $tooltip_title_word = wpbc_lang( $tooltip_title_word ); $tooltip_title_word = ( empty( $tooltip_title_word ) ) ? '' : '<div class="wpbc_tooltip_title">' . $tooltip_title_word . '</div>' . ' '; $id_of_first_resource = $resource_id_arr[0]; $tooltip_content_header = ''; if ( ! empty( $availability_per_this_day[ $id_of_first_resource ]->date_cost_rate ) ) { $cur_sym = get_bk_option( 'booking_cost_in_date_cell_currency' ); // in Booking > Settings General page in "Calendar" section //$cur_sym = wpbc_get_currency_symbol(); // in Booking > Settings > Payment page $cost_text = wpbc_formate_cost_hint__no_html( $availability_per_this_day[ $id_of_first_resource ]->date_cost_rate, $cur_sym ); $cost_text = html_entity_decode( $cost_text ); $tooltip = '<div class="wpbc_tooltip_section tooltip__day_cost">' . $tooltip_title_word . '<div class="wpbc_tooltip_resource_container">' . $tooltip_content_header . '<div class="wpbc_tooltip_item">' . $cost_text . '</div>' . '</div>' . '</div>'; } } return $tooltip; } function wpbc_support_capacity__in_day_hint__summary__day_cost( $availability_per_this_day, $my_day_tag, $resource_id_arr ){ $tooltip = ''; if ( ( ! empty( $availability_per_this_day['day_availability'] ) ) && ( 'On' == get_bk_option( 'booking_is_show_cost_in_date_cell' ) ) ){ $id_of_first_resource = $resource_id_arr[0]; if ( ! empty( $availability_per_this_day[ $id_of_first_resource ]->date_cost_rate ) ) { $cur_sym = get_bk_option( 'booking_cost_in_date_cell_currency' ); // in Booking > Settings General page in "Calendar" section //$cur_sym = wpbc_get_currency_symbol(); // in Booking > Settings > Payment page $cost_text = $availability_per_this_day[ $id_of_first_resource ]->date_cost_rate; $cost_text = number_format( floatval( $cost_text ), wpbc_get_cost_decimals(), '.', '' ); $cost_text = wp_strip_all_tags( wpbc_cost_show( $cost_text, array( 'currency' => 'CURRENCY_SYMBOL' ) ) ); $cost_text = str_replace( array( 'CURRENCY_SYMBOL', '&' ), array( $cur_sym, '&' ), $cost_text ); $cost_text = html_entity_decode($cost_text); $tooltip = '<span class="wpbc_in_date_hint__cost">' . $cost_text . '</span>';; } } return $tooltip; } // FixIn: 10.6.4.1. /** * Get availability for in Day cells * * @param $availability_per_this_day * @param $my_day_tag * @param $resource_id_arr * * @return string */ function wpbc_support_capacity__in_day_hint__summary__availability( $availability_per_this_day, $my_day_tag, $resource_id_arr ){ $tooltip = ''; if ( ( 'On' == get_bk_option( 'booking_is_show_availability_in_date_cell' ) ) && ( $availability_per_this_day['max_capacity'] > 1 ) ) { $tooltip_title_word = get_bk_option( 'booking_highlight_availability_word_in_date_cell' ); $tooltip_title_word = wpbc_lang( $tooltip_title_word ); $tooltip_title_word = ( empty( $tooltip_title_word ) ) ? '' : '<span class="wpbc_in_date_hint__availability_title">' . $tooltip_title_word . '</span>'; if ( ! empty( $availability_per_this_day['day_availability'] ) ) { $tooltip = '<span class="wpbc_in_date_hint__availability">' . '<span class="wpbc_in_date_hint__availability_number">' . intval( $availability_per_this_day['day_availability'] ) . ' ' . '</span>' . $tooltip_title_word . '</span>'; $tooltip = html_entity_decode($tooltip); } } return $tooltip; } /** * Set tooltip summary -- Booking Details * * @param $availability_per_this_day * @param $my_day_tag * @param $resource_id_arr * * @return string - tooltip content or '' */ function wpbc_support_capacity__tooltip__summary__booked_details( $availability_per_this_day, $my_day_tag, $resource_id_arr ){ $tooltip = ''; if ( 'On' == get_bk_option( 'booking_is_show_booked_data_in_tooltips' ) ) { //FixIn: 9.5.0.2.2 $tooltip_title_word = '<div class="wpbc_tooltip_title">' . esc_html__('Booking details','booking') . '</div>'; $status_summary_tooltip_times = array(); foreach ( $resource_id_arr as $resource_id ) { if ( ! empty( $availability_per_this_day[ $resource_id ]->tooltips['details'] ) ) { if ( ! empty( $availability_per_this_day[ $resource_id ]->tooltips['resource_title'] ) ){ $tooltip_content_header = '<div class="wpbc_tooltip_header">' . $availability_per_this_day[ $resource_id ]->tooltips['resource_title'] . ': ' . '</div>'; } else{ $tooltip_content_header = ''; } $booking_details_text = '<div class="wpbc_tooltip_resource_container">' . $tooltip_content_header . implode( ' ', $availability_per_this_day[ $resource_id ]->tooltips['details'] ) . '</div>'; $status_summary_tooltip_times[] = $booking_details_text; } } if ( ! empty( $status_summary_tooltip_times ) ) { $tooltip = '<div class="wpbc_tooltip_section tooltip__booking_details">' . $tooltip_title_word . implode( '', $status_summary_tooltip_times ) . '</div>'; } } return $tooltip; } /** * Set Tooltip -- Booking Details * * @param $availability_per_day * @param $my_day_tag * @param $resource_id * @param $this_date_bookings * @param $booked_times__key * @param $resources_obj * * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ]; */ 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 ) { // Get booking details for tooltip, if needed if ( 'On' == get_bk_option( 'booking_is_show_booked_data_in_tooltips' ) ) { $booking_id = $this_date_bookings[ $booked_times__key ]->booking_id; $this_booking_resource_id = $this_date_bookings[ $booked_times__key ]->type; $booking_details_text = wpbc_support_capacity__get_booking_details( $this_date_bookings[ $booked_times__key ], $resources_obj->get__booking_resource_obj( $this_booking_resource_id ) ); $tooltip_text = ''; $tooltip_text .= '<div class="wpbc_tooltip_item tooltip_booked_time">' . $booked_time . '</div>'; // Booked time $tooltip_text .= '<div class="wpbc_tooltip_item">' . $booking_details_text . '</div>'; // Booking details $availability_per_day[ $my_day_tag ][ $resource_id ]->tooltips['details'][ $booking_id ] = $tooltip_text; } return $availability_per_day[ $my_day_tag ][ $resource_id ]; } /** * Set Tooltip Times -- Time-Slots * * @param $availability_per_day * @param $my_day_tag * @param $resource_id * @param $resource_id_arr * * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ]; */ function wpbc_support_capacity__tooltip_times__set_for_times( $availability_per_day, $my_day_tag, $resource_id, $resource_id_arr ){ // Times Tooltip - time slot list -------------------------------------------------------------------- $tooltip_content_header = ''; if ( count( $resource_id_arr ) > 1 ) { $class_name = 'tooltip_items_count_' . count( $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots['merged_readable'] ); $tooltip_content_header = '<div class="wpbc_tooltip_header ' . $class_name . ' ">' . $availability_per_day[ $my_day_tag ][ $resource_id ]->tooltips['resource_title'] . ': ' . '</div>'; } $tooltip_content_arr = array_map( function ( $item ) { return '<div class="wpbc_tooltip_item">' . $item . '</div>'; } , $availability_per_day[ $my_day_tag ][ $resource_id ]->booked_time_slots['merged_readable'] ); $availability_per_day[ $my_day_tag ][ $resource_id ]->tooltips['times'] = '<div class="wpbc_tooltip_resource_container">' . $tooltip_content_header . implode( '', $tooltip_content_arr ) . '</div>'; return $availability_per_day[ $my_day_tag ][ $resource_id ]; } /** * Set Tooltip Times -- Full Day * * @param $availability_per_day * @param $my_day_tag * @param $resource_id * @param $resource_id_arr * @param $status_title * * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ]; */ function wpbc_support_capacity__tooltip_times__set_full_day( $availability_per_day, $my_day_tag, $resource_id, $resource_id_arr, $status_title ){ // Times Tooltip - FULL DAY -------------------------------------------------------------------- $tooltip_content_header = ''; if ( count( $resource_id_arr ) > 1 ) { $class_name = 'tooltip_items_count_1'; $tooltip_content_header = '<div class="wpbc_tooltip_header ' . $class_name . ' ">' . $availability_per_day[ $my_day_tag ][ $resource_id ]->tooltips['resource_title'] . ': ' . '</div>'; } $tooltip_content_text = '<div class="wpbc_tooltip_item">' . $status_title . '</div>'; $availability_per_day[ $my_day_tag ][ $resource_id ]->tooltips['times'] = '<div class="wpbc_tooltip_resource_container">' . $tooltip_content_header . $tooltip_content_text . '</div>'; return $availability_per_day[ $my_day_tag ][ $resource_id ]; } /** * Get parsed booking data, if required * * @param object $this_date_bookings * @param object $resource_obj * * @return string */ function wpbc_support_capacity__get_booking_details( $this_date_bookings, $resource_obj ) { if ( ( ! class_exists( 'wpdev_bk_biz_m' ) ) || ( 'On' !== get_bk_option( 'booking_is_show_booked_data_in_tooltips' ) ) ){ return ''; } $booking_details_for_hint = ''; if ( isset( $this_date_bookings->form ) ) { // Get shortcodes $booking_shortcodes_in_tooltips = get_bk_option( 'booking_booked_data_in_tooltips' ); // '[name] [secondname]' $resource_id = $this_date_bookings->type; // Get parsed booking data field values -- e.g.: [ "rangetime":"12:00 - 14:00", "secondname":"Smith",... ] $booking_data_arr = wpbc_get_parsed_booking_data_arr( $this_date_bookings->form, $resource_id, array( 'get' => 'value' ) ); $booking_data_arr['booking_id'] = $this_date_bookings->booking_id; $booking_data_arr['resource_id'] = $resource_id; $booking_data_arr['resource_title'] = ( ! empty( $resource_obj ) ) ? wpbc_lang( $resource_obj->title ) : ''; // Replace existing shortcodes foreach ( $booking_data_arr as $replace_shortcode => $replace_value ) { if ( is_null( $replace_value ) ) { $replace_value = ''; }; $replace_value = wpbc_replace__true_false__to__yes_no( $replace_value ); // FixIn: 9.8.9.1. $booking_shortcodes_in_tooltips = str_replace( array( '[' . $replace_shortcode . ']' , '{' . $replace_shortcode . '}' ) , $replace_value , $booking_shortcodes_in_tooltips ); } $booking_details_for_hint = $booking_shortcodes_in_tooltips; // Remove all shortcodes, which is not replaced early. $booking_details_for_hint = preg_replace( '/[\[\{][a-zA-Z0-9.,_-]{0,}[\]\}]/', '', $booking_details_for_hint ); } return $booking_details_for_hint; } /** * Unset some fields from booking data for do not show personal data at front-end side * * @param object $this_date_bookings * * @return object */ function wpbc_support_capacity__unset_some_fields( $this_date_bookings ) { if ( isset( $this_date_bookings->form ) ) { unset( $this_date_bookings->form ); // Hide booking details } if ( isset( $this_date_bookings->booking_date ) ) { 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 } return $this_date_bookings; } // D A Y S T A T U S U N A V A I L A B L E /** * Set > _day_status = 'limit_available_from_today' depends on Booking > Settings General page ---> "Limit available days from today" * * @param $availability_per_day [ ... ] * @param $my_day_tag - '2023-08-08' * @param $resource_id - 2 * * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ] */ function wpbc_support_capacity__day_status__limit_available_from_today( $availability_per_day, $my_day_tag, $resource_id ){ // ----------------------------------------------------------------------------------------------------- // limit_available_from_today // 3. Limit available days from today if ( function_exists( 'wpbc_is_day_available__relative__limit_available_from_today' ) ) { if ( ! wpbc_is_day_available__relative__limit_available_from_today( $my_day_tag ) ) { // this date unavailable $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true; $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'limit_available_from_today'; if ( empty( $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details ) ) { $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details = array(); // Reset bookings details } } } return $availability_per_day[ $my_day_tag ][ $resource_id ]; } /** * Set > _day_status = 'from_today_unavailable' depends on Booking > Settings General page ---> "Unavailable days from today" * * @param $availability_per_day [ ... ] * @param $my_day_tag - '2023-08-08' * @param $resource_id - 2 * * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ] */ function wpbc_support_capacity__day_status__from_today_unavailable( $availability_per_day, $my_day_tag, $resource_id ){ // FixIn: 10.8.1.4. // ----------------------------------------------------------------------------------------------------- // from_today_unavailable // 2. Unavailable days from today $unavailable_days_num_from_today = get_bk_option( 'booking_unavailable_days_num_from_today' ); // FixIn: 10.8.1.4. if ( ! empty( $unavailable_days_num_from_today ) ) { if ( 'm' === substr( $unavailable_days_num_from_today, - 1 ) ) { $start_date_unix = strtotime( '+' . ( intval( $unavailable_days_num_from_today ) - 1 ) . ' minutes' ); // + 0 days } else { $start_date_unix = strtotime( '+' . intval( $unavailable_days_num_from_today ) . ' days' ); // + 0 days } } else { $start_date_unix = strtotime( 'now' ); } $date_start__gmt = gmdate( 'Y-m-d H:i:s', $start_date_unix ); // '2025-01-25 12:50:10' $date_start__midnight__wp_timezone = wpbc_datetime_localized__use_wp_timezone( $date_start__gmt, 'Y-m-d 00:00:00' ); // Local Midnight. // 'Today Midnight' - 'Calendar Day Cell' . $days_number = intval( ( strtotime( $date_start__midnight__wp_timezone ) - strtotime( $my_day_tag ) ) / 86400 ); if ( $days_number > 0 ) { // This date Unavailable. $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true; $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'from_today_unavailable'; if ( empty( $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details ) ) { $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details = array(); // Reset bookings details } } return $availability_per_day[ $my_day_tag ][ $resource_id ]; } /** * Set > _day_status = 'weekday_unavailable' depends on Booking > Settings General page ---> "Week Days unavailable" * * @param $availability_per_day [ ... ] * @param $my_day_tag - '2023-08-08' * @param $resource_id - 2 * * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ] */ function wpbc_support_capacity__day_status__weekday_unavailable( $availability_per_day, $my_day_tag, $resource_id ){ // 1. Week Days unavailable -------------------------------------------------------------------------------- // weekday_unavailable $unavailable_weekdays = array(); foreach ( range( 0, 6 ) as $week_day_num ) { $unavailable_weekdays[ $week_day_num ] = ( 'On' == get_bk_option( 'booking_unavailable_day' . $week_day_num ) ) ? true : false; } $this_day_week_num = gmdate( 'w', strtotime( $my_day_tag ) ); // 0 - 6 if ( $unavailable_weekdays[ $this_day_week_num ] ) { // this date unavailable $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true; $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'weekday_unavailable'; if ( empty( $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details ) ) { $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details = array(); // Reset bookings details } } return $availability_per_day[ $my_day_tag ][ $resource_id ]; } /** * Set > _day_status = 'resource_availability' depends on Booking > Availability page * * @param $availability_per_day [ ... ] * @param $my_day_tag - '2023-08-08' * @param $resource_id - 2 * @param array $unavailable_dates__per_resources__arr - [ 2: ['2023-08-01', '2023-08-02'], 10: ['2023-08-05', '2023-08-06'] ] * * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ] */ function wpbc_support_capacity__day_status__resource_availability( $availability_per_day, $my_day_tag, $resource_id, $unavailable_dates__per_resources__arr ){ // Booking > Availability page ----------------------------------------------------------------------------- // resource_availability /** * $unavailable_dates__per_resources__arr = Array ( [2] => Array( [0] => 2023-08-01 [1] => 2023-08-02 ) [10] => Array( [0] => 2023-08-05 [1] => 2023-08-06 ) ) */ if ( ( isset( $unavailable_dates__per_resources__arr[ $resource_id ] ) ) && ( in_array( $my_day_tag, $unavailable_dates__per_resources__arr[ $resource_id ] ) ) ) { $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true; $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'resource_availability'; if ( empty( $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details ) ) { $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details = array(); // Reset bookings details } } return $availability_per_day[ $my_day_tag ][ $resource_id ]; } /** * Set > _day_status = 'season_filter' depends on Booking > Resources > Availability page * * @param $availability_per_day [ ... ] * @param $my_day_tag - '2023-08-08' * @param $resource_id - 2 * @param array $season_filters_availability - [...] * * @return array - $availability_per_day[ $my_day_tag ][ $resource_id ] */ function wpbc_support_capacity__day_status__season_filter( $availability_per_day, $my_day_tag, $resource_id, $season_filters_availability ){ if ( function_exists( 'wpbc_is_this_day_available_in_season_filters' ) ) { // BM and higher $is_date_available = wpbc_is_this_day_available_in_season_filters( $my_day_tag, $resource_id, $season_filters_availability[ $resource_id ] ); // Get availability if ( ! $is_date_available ) { $availability_per_day[ $my_day_tag ][ $resource_id ]->is_day_unavailable = true; $availability_per_day[ $my_day_tag ][ $resource_id ]->_day_status = 'season_filter'; if ( empty( $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details ) ) { $availability_per_day[ $my_day_tag ][ $resource_id ]->__booked__times__details = array(); // Reset bookings details } } } return $availability_per_day[ $my_day_tag ][ $resource_id ]; } // D A Y C O S T /** * Get day cost depend on Rates * @param $my_day_tag - '2023-08-08' * @param $resource_id - 2 * @param $base_cost - 25 * * @return int|string */ function wpbc_support_capacity__get_day_cost( $my_day_tag, $resource_id, $base_cost ) { $fin_day_cost = 0; if ( function_exists( 'wpbc_get_1_day_cost_apply_rates' ) ) { list( $year, $month, $day ) = explode( '-', $my_day_tag ); $day = intval( $day ); $month = intval( $month ); $year = intval( $year ); $fin_day_cost = wpbc_get_1_day_cost_apply_rates( $resource_id, $base_cost, $day, $month, $year ); } return $fin_day_cost; } // </editor-fold> //TODO: M I G R A T E to 9.8 // . // instead of this: <script type="text/javascript"> wpbc_settings.set_option( 'pending_days_selectable', true ); </script> // use this: <script type="text/javascript"> _wpbc.calendar__set_param_value( " . intval( $resource_id ) . ", 'pending_days_selectable' , true ); </script> // Booking Calendar - JavaScript Settings // Example or redefine some settings: // <script type="text/javascript"> wpbc_settings.set_option( 'pending_days_selectable', true ); </script> // [booking type=1] // . // . // 1. Define parameters for calendar(s): // _wpbc.calendar__set_parameters( " . intval( $resource_id ) . ", {'days_select_mode': 'single'} ); // _wpbc.calendar__set_parameters( " . intval( $resource_id ) . ", {'days_select_mode': 'multiple'} ); // _wpbc.calendar__set_parameters( " . intval( $resource_id ) . ", {'days_select_mode': 'fixed'} ); // _wpbc.calendar__set_parameters( " . intval( $resource_id ) . ", {'fixed__days_num' : 7 } ); // _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 } // _wpbc.calendar__set_parameters( " . intval( $resource_id ) . ", {'days_select_mode': 'dynamic'} ); // _wpbc.calendar__set_param_value( " . intval( $resource_id ) . ", 'dynamic__days_min' , 7 ); // _wpbc.calendar__set_param_value( " . intval( $resource_id ) . ", 'dynamic__days_max' , 14 ); // _wpbc.calendar__set_param_value( " . intval( $resource_id ) . ", 'dynamic__days_specific' , [] ); // Example [5,7] // _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 } // JavaScript functions changes: // wpbc_unselect_all_days( resource_id ) -> wpbc_calendar__unselect_all_dates( resource_id ) // showErrorMessage( element , errorMessage , isScrollStop ); -> wpbc_front_end__show_message__warning( jq_node, message ); // showMessageUnderElement( element , errorMessage , message_type); -> wpbc_front_end__show_message__warning_under_element( jq_node, message ); // makeScroll( object_name ); -> wpbc_do_scroll( jq_node ); // . // JavaScript hooks changes: // jQuery( ".booking_form_div" ).trigger( "date_selected", [ resource_id, date ] ); // become // jQuery( ".booking_form_div" ).trigger( "date_selected", [ resource_id, mouse_clicked_dates, all_selected_dates_arr ] ); // where: // mouse_clicked_dates Can be: "05.10.2023 - 07.10.2023" | "10.10.2023 - 10.10.2023" | // all_selected_dates_arr Can be: [ "2023-10-05", "2023-10-06", "2023-10-07", … ] // PHP actions: // from: make_bk_action('wpdev_booking_post_inserted', $booking_id, $bktype, $str_dates__dd_mm_yyyy, array($start_time, $end_time ) , $formdata ); // removed! // . // from: apply_filters('wpdev_booking_form_content', $form , $resource_id); // to: apply_filters( 'wpbc_booking_form_html__update__append_change_over_times', $form, $resource_id ); // . // Removed PHP actions: // . 'show_payment_forms__for_ajax' // * make_bk_action('wpbc_ add_new_booking' , array( // * 'bktype' => 1 // * , 'dates' => '27.08.2014, 28.08.2014, 29.08.2014' // * , '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' // * , 'is_send_emeils' => 0 // * // , 'booking_form_type' => '' // * // , 'wpdev_active_locale' => 'en_US' // * ) ); // . // add_bk_filter('wpbc_add_new_booking_filter' , 'wpbc_add_new_booking' ); // TODO: recheck hooks in wpbc-dev-api.php
Save
Back