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